Portierung des Terkin-Datenlogger auf Genuine MicroPython für ESP32

Warum ist denn die Logik für den Start des mode- und http-server invertiert?

def start_services(self):

    # Start UDP server for pulling device into maintenance mode.
    if self.settings.get('services.api.modeserver.enabled', False):
        try:
            self.start_modeserver()
        except Exception as ex:
            log.exc(ex, 'Starting mode server failed')

    # Start HTTP server
    if self.settings.get('services.api.http.enabled', False):
        try:
            self.start_httpserver()
        except Exception as ex:
            log.exc(ex, 'Starting HTTP server failed')

Äh, ist klar, was ich hier meine?

if self.settings.get('services.api.modeserver.enabled', False):

Normalerweise würde bei ‘enabled’ ‘false’ ja irgendwas NICHT starten.

Nächste Frage. In ‘telemetry.py’ gibt es folgende Zeilen:

        # Signal connection error in order to reconnect on next submission attempt.
        # [Errno 104] ECONNRESET
        # [Errno 113] ECONNABORTED
        if ex.errno in [104, 113]:
            self.connected = False

Das kommt von einem fehlgeschlagenen Publish:

58202.0426 [terkin.telemetry         ] ERROR  : MQTT publishing failed
Traceback (most recent call last):
  File "terkin/telemetry.py", line 542, in publish
  File "/dist-packages/mqtt.py", line 120, in publish
OSError: [Errno 113] EHOSTUNREACH
58202.3621 [terkin.telemetry         ] ERROR  : Telemetry to mqtt://xxx@swarm.hiveeyes.org/hiveeyes/KLQpNG/garten/stock05 failed
Traceback (most recent call last):
  File "terkin/telemetry.py", line 119, in transmit
  File "terkin/telemetry.py", line 279, in transmit
  File "terkin/telemetry.py", line 460, in send
  File "terkin/telemetry.py", line 456, in send
  File "terkin/telemetry.py", line 556, in publish
  File "terkin/telemetry.py", line 552, in publish
AttributeError: 'OSError' object has no attribute 'errno'

Da steig ich jetzt nicht durch, was da passiert. Hilfe! :slight_smile:

Hi Markus,

Ja, ist klar. Hier ist aber alles korrekt: False ist der default.

Das heißt, dass, wenn diese Konfigurationseinstellung services.api.modeserver.enabled überhaupt nicht existiert, dafür False angenommen wird. Das wiederum bedeutet, dass die entsprechenden Dienste dann nicht gestartet werden – ganz im Sinne des Erfinders.

Die Logik ist also nicht invertiert, hier lag ein Mißverständnis vor.

Viele Grüße,
Andreas.

1 Like

In dem Fall hat das Fehlerobjekt wohl im Gegensatz zur ursprünglichen Umgebung kein errno Attribut – tut mir leid. Das müsste man wohl entsprechend umgestalten, z.B. per if hasattr(ex, 'errno') and ex.errno in [104, 113]

1 Like

Naming things

Using mboot as a name for the application loader was a bad idea, as this name is already taken within the MicroPython ecosystem.

See also micropython/ports/stm32/mboot/README.md at master · micropython/micropython · GitHub

Welcome, UMAL

So, we just renamed this guy to Universal MicroPython Application Loader (umal) per https://github.com/hiveeyes/hiveeyes-micropython-firmware/commit/21314d93 and mitigated all references to the former name throughout the codebase and the forum.

>>>
PYB: soft reboot
[boot.py] INFO: Python module search path is: ['', '/flash', '/flash/lib']
[boot.py] INFO: Invoking the Universal MicroPython Application Loader (umal)
[mub]     INFO: Python module search path is: ['/flash/lib-mpy-1.11-pycom', '', '/flash', '/flash/lib', '/flash/dist-packages', '/flash/terkin']

Hallo Markus,

zu Deiner Frage nach einer optimaleren Gestaltung der Plattformweiche habe ich Dir folgendes vorbereitet:

else:
    raise NotImplementedError('Reading the ADC for vbatt is '
                              'not implemented on this platform')

a) Verwenden wir so Vanilla MicroPython als “first-citizen” und b) besteht so nicht die Gefahr, dass die Routine ins Leere läuft. Gleichzeitig wird der Anwender optimal informiert.

Ich hoffe das hilft Dir für die folgenden Arbeiten weiter.

Viele Grüße,
Andreas.

1 Like

Wir sollten den onewire.py aus dist-packages umbenennen. Der aus uPy heißt genauso.

1 Like

Erledigt. Der native heißt nun onewire_native.py und der bisherige onewire_python.py. Die entsprechende Ansteuerung berücksichtigt dies nun auch (untested!).

Dabei kommt a) die Plattformweiche zum Einsatz, um die Modulimporte handzuhaben und b) der neue DS18X20NativeDriverAdapter, um die Ansteuerung der Treiber-API zur Laufzeit auszugleichen.

This came in at almost the same time. Unfortunately, I have not been quicker to push the improvements with Improve multi-platform support for 1-Wire and DS18X20 driver · hiveeyes/terkin-datalogger@7330d65 · GitHub.

Within the comment on your PR you mentioned

The DS18X20 needs some further care.

Can you see if this further care now might have been done already?

Ich werde den PR dann nochmal nachziehen…

Ich versteh gerade nur Dein Umbennungsschema nicht. Der von uPy heißt ‘onewire’ - den können wir schlecht umbenennen, der ist integriert. Den bisherigen könnten wir vielleicht ‘onewire_pycom’ nennen - dann ist klar, für was der gut ist.
Der DS18X20NativeDriverAdapter vereinheitlicht dann die Schnittstelle, korrekt?

1 Like

Ok, wenn der schon automatisch integriert ist, sieht die Sache anders aus. Das war mir nicht klar. Ich werde es verbessern. Das heißt, auch die Datei ds18x20.py ist bereits als eingefrorenes Modul automatisch ohne weiteres in der Firmware enthalten?

Ja, so zumindest die Intention, nachdem ich mich durch die API gewühlt habe. Leider konnte ich den Code noch nicht auf echter Hardware testen.

Erledigt per Fix 1-Wire multi-platform support again · hiveeyes/terkin-datalogger@bfc1fad · GitHub, jetzt könnte es stimmen.

New PR up.

1 Like

Weil wir auch gerade beim umbenennen sind: hx711.py gibts zweimal - einmal in driver und einmal in lib.
Python kommt bestimmt damit klar, mich verwirt es aber. :slight_smile:
Vielleicht bei einem/beiden ein Präfix? Für den MAX17043 wird es das gleiche Problem.

1 Like

I hear you. Das eine ist der lowlevel/hardwarenahe Teil, das andere ist der Adapter für die Terkin-Sensordomäne. Dass beide Dateien gleich heißen, kann in der Tat verwirrend sein, so dass ich ebenfalls gerne eine bessere Benamsung dafür haben wollen würde.

Vielleicht finden wir hier gemeinsam passende Vorschläge dafür. Naheliegend wäre z.B. hx711_adapter.py oder hx711_sensor.py. Durch die Länge trägt das allerdings im Logfile recht auf, dort stünde dann [terkin.driver.hx711_sensor ] als Präfix vor jeder entsprechenden Zeile im Log. Das ist aber vielleicht das geringere Übel als die Verwirrung durch die identische Namensgebung.

Erledigt. Danke!

Last but not least: Vielen vielen Dank dafür!

24 posts were merged into an existing topic: Entwicklung der Terkin-Sandbox

Nachdem ich bei Entwicklung der Terkin-Sandbox ff. erfolgreich war, bekomme ich nun folgende Meldung auf einem TTGO T-Call:

MicroPython v1.12 on 2019-12-20; ESP32 module (spiram) with ESP32
Type "help()" for more information.
>>>
>>> import machine ; machine.reset()
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:4844
load:0x40078000,len:10532
load:0x40080400,len:6736
entry 0x400806f0
I (525) psram: This chip is ESP32-D0WD
I (526) spiram: Found 64MBit SPI RAM device
I (526) spiram: SPI RAM mode: flash 40m sram 40m
I (529) spiram: PSRAM initialized, cache is in low/high (2-core) mode.
I (536) cpu_start: Pro cpu up.
I (540) cpu_start: Application information:
I (544) cpu_start: Compile time:     Dec 20 2019 07:52:43
I (550) cpu_start: ELF file SHA256:  0000000000000000...
I (556) cpu_start: ESP-IDF:          v3.3
I (561) cpu_start: Starting app cpu, entry point is 0x40083d90
I (553) cpu_start: App cpu up.
I (1437) spiram: SPI SRAM memory test OK
I (1438) heap_init: Initializing. RAM available for dynamic allocation:
I (1438) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (1444) heap_init: At 3FFBA658 len 000259A8 (150 KiB): DRAM
I (1450) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (1457) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (1463) heap_init: At 400973F0 len 00008C10 (35 KiB): IRAM
I (1469) cpu_start: Pro cpu start user code
I (146) cpu_start: Chip Revision: 1
W (146) cpu_start: Chip revision is higher than the one configured in menuconfig. Suggest to upgrade it.
I (150) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
[boot.py] INFO: Python module search path is: ['', '/lib']
[boot.py] INFO: Universal MicroPython Application Loader (umal)
[umal]    INFO: Python module search path is: ['/lib-mpy-1.11-bytecode', '', '/lib', '/dist-packages', '/terkin']
[main.py] INFO: Loading settings
[main.py] INFO: Starting logging
[main.py] INFO: Loading Terkin Datalogger
[main.py] INFO: Loading modules
I (18440) modsocket: Initializing
   22.7680 [terkin.datalogger           ] INFO   : Starting Terkin datalogger
   22.9930 [terkin.configuration        ] INFO   : Starting TerkinConfiguration on path "/"
   23.2160 [terkin.configuration        ] INFO   : Ensuring existence of backup directory at "/backup"
   23.5140 [terkin.configuration        ] INFO   : User settings: None
   23.7810 [terkin.device               ] ERROR  : Enabling Terminal failed
Traceback (most recent call last):
  File "/lib/terkin/device.py", line 45, in __init__
  File "/lib/terkin/device.py", line 470, in start
ValueError: UART(0) is disabled (dedicated to REPL)

   24.3980 [terkin.device               ] INFO   : Reset cause and wakeup reason: {'reset_cause': {'code': 5, 'message': 'SOFT'}, 'wakeup_reason': {'code': 0, 'message': 'UNKNOWN'}}
   24.6240 [terkin.watchdog             ] INFO   : Skipping watchdog timer (WDT)
   24.8450 [terkin.device               ] INFO   : Start curating the garbage collector
   25.2670 [terkin.device               ] INFO   : Collecting garbage
   25.7260 [terkin.device               ] INFO   : Curating the garbage collector finished. Free memory: 3912784
   25.9480 [terkin.device               ] WARNING: FIXME: Skip touching Bluetooth on vanilla MicroPython platforms as we don't use Bluetooth yet
   26.1750 [terkin.datalogger           ] INFO   : Starting Terkin MicroPython Datalogger 0.6.0
   26.4070 [terkin.configuration        ] INFO   : Configuration settings:
   26.6610 [terkin.configuration        ] INFO   : Section "telemetry": {"targets": [{"enabled": true, "topology": "mqttkit", "endpoint": "mqtt://daq.example.org", "address": {"network": "testdrive", "gateway": "area-42", "node": "node-01-mqtt-json", "realm": "workbench"}}, {"enabled": false, "topology": "mqttkit", "endpoint": "https://daq.example.org/api", "address": {"network": "testdrive", "gateway": "area-42", "node": "node-01-http-json", "realm": "workbench"}}, {"topology": "mqttkit", "interface": "gprs", "address": {"network": "testdrive", "gateway": "area-42", "node": "node-01-http-json", "realm": "workbench"}, "enabled": false, "endpoint": "https://daq.example.org/api"}, {"enabled": false, "data": {"key": "## redacted ##"}, "endpoint": "https://test.free.beeceptor.com/api/sensors"}, {"format": "lpp", "content_encoding": "base64", "address": {"network": "testdrive", "gateway": "area-42", "node": "node-01-mqtt-lpp", "realm": "workbench"}, "enabled": false, "endpoint": "mqtt://daq.example.org"}, {"enabled": true, "settings": {"size": 12, "datarate": 0}, "endpoint": "lora://", "format": "lpp"}]}
   26.9830 [terkin.configuration        ] INFO   : Section "interfaces": {"uart0": {"terminal": true}}
   27.2190 [terkin.configuration        ] INFO   : Section "main": {"interval": {"maintenance": 15.0, "field": 60.0}, "logging": {"enabled": true, "configuration": true}, "rgb_led": {"terkin": false, "heartbeat": true}, "deepsleep": false, "watchdog": {"enabled": false, "timeout": 60000}, "backup": {"file_count": 7}}
   27.4790 [terkin.configuration        ] INFO   : Section "networking": {"wifi": {"stations": [{"ssid": "FooBar", "password": "## redacted ##"}], "enabled": true, "phy": {"antenna_external": false, "antenna_pin": "P12"}}, "lora": {"enabled": false, "otaa": {"adr": false, "region": "EU868", "application_key": "## redacted ##", "application_eui": "## redacted ##", "device_eui": "<GENERATED_FROM_LORA_MAC>"}, "antenna_attached": false}, "gprs": {"pin_reset": "P5", "enabled": false, "apn": "apn.example.net", "pin_power": "P23", "driver": "pythings-sim800", "pin_txd": "P26", "pin_rxd": "P27", "pin_pwrkey": "P4"}}
   27.7940 [terkin.configuration        ] INFO   : Section "sensors": {"system": [{"type": "system.memfree"}, {"type": "system.temperature"}, {"type": "system.uptime"}, {"type": "system.wifi"}, {"enabled": false, "type": "system.touch-buttons"}, {"enabled": true, "resistor_r2": 1000, "pin": "P16", "description": "Battery", "type": "system.voltage.battery", "resistor_r1": 1000, "adc_attenuation_db": 6.0}, {"enabled": false, "resistor_r2": 100, "pin": "P17", "description": "Solar Panel", "type": "system.voltage.solar", "resistor_r1": 1000, "adc_attenuation_db": 11.0}], "environment": [{"pin_dout": "P22", "scale": 4.424242, "offset": -73000, "enabled": true, "name": "scale", "description": "Waage 1", "id": "scale-1", "number": 0, "pin_pdsck": "P21", "type": "HX711"}, {"enabled": true, "bus": "onewire:0", "name": "temperature", "description": "Wabengasse 1", "id": "ds18b20-1", "type": "DS18B20", "devices": [{"id": "ds18b20-r1c1", "enabled": true, "address": "1111111111111111", "description": "Reihe 1, Spalte 1"}, {"id": "ds18b20-r1c2", "enabled": true, "address": "2222222222222222", "description": "Reihe 1, Spalte 2"}]}, {"id": "bme280-1", "description": "Temperatur und Feuchte außen", "type": "BME280", "address": 119, "enabled": true, "bus": "i2c:0"}], "busses": [{"id": "bus-i2c-0", "family": "i2c", "number": 0, "pin_sda": "P9", "enabled": true, "pin_scl": "P10"}, {"id": "bus-i2c-1", "family": "i2c", "number": 1, "pin_sda": "P22", "enabled": false, "pin_scl": "P21"}, {"enabled": true, "family": "onewire", "pin_data": "P11", "id": "bus-onewire-0", "number": 0}], "prettify_log": true}
   28.1630 [terkin.configuration        ] INFO   : Section "services": {"api": {"modeserver": {"enabled": true}, "http": {"enabled": false}}}
   28.6630 [terkin.device               ] INFO   :

===================================
Terkin MicroPython Datalogger 0.6.0
===================================
Device id    30aea4c28138

CPU freq     160.0   MHz

Python  : 3.4.0
machine : ESP32 module (spiram) with ESP32
nodename: esp32
release : 1.12.0
sysname : esp32
version : v1.12 on 2019-12-20


   28.9060 [terkin.device               ] INFO   : Starting networking
   29.1470 [terkin.network.wifi         ] INFO   : Starting stopwatch
   29.7850 [terkin.network.wifi         ] INFO   : Started stopwatch successfully
   30.0160 [terkin.network.wifi         ] INFO   : WiFi STA: Will exclusively use STA mode on this platform. AP mode not implemented yet.
I (35000) wifi: wifi driver task: 3ffc5380, prio:23, stack:3584, core=0
I (43318) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (43328) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (43368) wifi: wifi firmware version: aeed694
I (43368) wifi: config NVS flash: enabled
I (43368) wifi: config nano formating: disabled
I (43368) wifi: Init dynamic tx buffer num: 32
I (43368) wifi: Init data frame dynamic rx buffer num: 32
I (43378) wifi: Init management frame dynamic rx buffer num: 32
I (43378) wifi: Init management short buffer num: 32
I (43388) wifi: Init static rx buffer size: 1600
I (43388) wifi: Init static rx buffer num: 10
I (43388) wifi: Init dynamic rx buffer num: 32
   30.3370 [terkin.network.wifi         ] INFO   : WiFi STA: Networking address (MAC): {}
   30.5580 [terkin.network.wifi         ] INFO   : WiFi STA: Networking address (IP):  ('0.0.0.0', '0.0.0.0', '0.0.0.0', '0.0.0.0')
   30.7800 [terkin.network.wifi         ] INFO   : WiFi: Starting interface
I (44158) phy: phy_version: 4102, 2fa7a43, Jul 15 2019, 13:06:06, 0, 0
I (44158) wifi: mode : sta (30:ae:a4:c2:81:38)
I (44158) wifi: STA_START
   31.1000 [terkin.network.wifi         ] INFO   : WiFi STA: Preparing connection to network "FooBar"
   31.3260 [terkin.network.wifi         ] INFO   : WiFi STA: Starting connection to "FooBar" with timeout of 15.0 seconds
   31.9720 [terkin.network.wifi         ] INFO   : WiFi STA: Waiting for network to come up within 2.0 seconds
I (46698) wifi: STA_DISCONNECTED, reason:201
no AP found
   34.4510 [terkin.network.wifi         ] INFO   : WiFi STA: Waiting for network to come up within 15.001 seconds
I (49188) wifi: STA_DISCONNECTED, reason:201
no AP found
   37.8870 [terkin.network.wifi         ] INFO   : WiFi STA: Waiting for network to come up within 11.565 seconds
I (51268) wifi: STA_DISCONNECTED, reason:201
no AP found
I (53348) wifi: STA_DISCONNECTED, reason:201
no AP found
   40.8620 [terkin.network.wifi         ] INFO   : WiFi STA: Waiting for network to come up within 8.59 seconds
I (55448) wifi: STA_DISCONNECTED, reason:201
no AP found
   43.8380 [terkin.network.wifi         ] INFO   : WiFi STA: Waiting for network to come up within 5.615 seconds
I (57538) wifi: STA_DISCONNECTED, reason:201
no AP found
I (59628) wifi: STA_DISCONNECTED, reason:201
no AP found
   46.8140 [terkin.network.wifi         ] INFO   : WiFi STA: Waiting for network to come up within 2.639 seconds
I (61718) wifi: STA_DISCONNECTED, reason:201
no AP found
   49.8000 [terkin.network.wifi         ] ERROR  : WiFi STA: Connecting to "FooBar" failed
Traceback (most recent call last):
  File "/lib/terkin/network/wifi.py", line 281, in connect_stations
  File "/lib/terkin/network/wifi.py", line 355, in connect_station
WiFiException: WiFi STA: Unable to connect to "FooBar"

   50.0420 [terkin.network.wifi         ] INFO   : WiFi STA: Forgetting NVRAM data for network "FooBar"
I (63808) wifi: STA_DISCONNECTED, reason:201
no AP found
   50.6920 [terkin.network.wifi         ] ERROR  : WiFi STA: Connecting to any network candidate failed. Please check your WiFi configuration for one of the 1 station candidates.
   50.9190 [terkin.network.wifi         ] WARNING: Todo: We might want to buffer telemetry data to flash memory to be scheduled for transmission later.
   51.1530 [terkin.network.wifi         ] ERROR  : WiFi STA: Connecting to configured networks "['FooBar']" failed
Traceback (most recent call last):
  File "/lib/terkin/network/wifi.py", line 176, in connect_once
  File "/lib/terkin/network/wifi.py", line 298, in connect_stations
WiFiException: WiFi STA: Connecting to any network candidate failed

   51.3960 [terkin.network.wifi         ] INFO   : Starting WiFi connection monitor
   52.0330 [terkin.network.core         ] INFO   : Waiting for the network stack to come up within 5 seconds
   52.2560 [terkin.network.wifi         ] INFO   : WiFi STA: Connecting to configured networks: ['FooBar']. Attempt: #1
I (65928) wifi: STA_DISCONNECTED, reason:201
no AP found
   52.6930 [terkin.network.wifi         ] INFO   : WiFi STA: Preparing connection to network "FooBar"
   52.9200 [terkin.network.wifi         ] INFO   : WiFi STA: Starting connection to "FooBar" with timeout of 15.0 seconds   53.1440 [terkin.network.core         ] INFO   : Network stack ready

   53.3850 [terkin.network.core         ] INFO   : Starting mode server on 0.0.0.0:666
   53.6250 [terkin.device               ] INFO   : [LoRa] This is not a LoRa capable device.
   53.8510 [terkin.network.ip           ] INFO   : Starting UdpServer on 0.0.0.0:666

***ERROR*** A stack overflow in task mp_thread has been detected.
abort() was called at PC 0x4008df38 on core 1

ELF file SHA256: 0000000000000000000000000000000000000000000000000000000000000000

Backtrace: 0x4008dbcb:0x3ffca300 0x4008df21:0x3ffca320 0x4008df38:0x3ffca340 0x40093702:0x3ffca360 0x4009540c:0x3ffca380 0x400953c2:0x00000000

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:4844
load:0x40078000,len:10532
load:0x40080400,len:6736
entry 0x400806f0
I (525) psram: This chip is ESP32-D0WD
I (526) spiram: Found 64MBit SPI RAM device
I (526) spiram: SPI RAM mode: flash 40m sram 40m
I (529) spiram: PSRAM initialized, cache is in low/high (2-core) mode.
I (536) cpu_start: Pro cpu up.
I (540) cpu_start: Application information:
I (544) cpu_start: Compile time:     Dec 20 2019 07:52:43
I (550) cpu_start: ELF file SHA256:  0000000000000000...
I (556) cpu_start: ESP-IDF:          v3.3
I (561) cpu_start: Starting app cpu, entry point is 0x40083d90
I (553) cpu_start: App cpu up.
I (1437) spiram: SPI SRAM memory test OK
I (1438) heap_init: Initializing. RAM available for dynamic allocation:
I (1438) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (1444) heap_init: At 3FFBA658 len 000259A8 (150 KiB): DRAM
I (1450) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (1457) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (1463) heap_init: At 400973F0 len 00008C10 (35 KiB): IRAM
I (1469) cpu_start: Pro cpu start user code
I (146) cpu_start: Chip Revision: 1
W (146) cpu_start: Chip revision is higher than the one configured in menuconfig. Suggest to upgrade it.
I (150) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
[boot.py] INFO: Python module search path is: ['', '/lib']
[boot.py] INFO: Universal MicroPython Application Loader (umal)
[umal]    INFO: Python module search path is: ['/lib-mpy-1.11-bytecode', '', '/lib', '/dist-packages', '/terkin']
[main.py] INFO: Loading settings
[main.py] INFO: Starting logging
[main.py] INFO: Loading Terkin Datalogger
[main.py] INFO: Loading modules