def __init__(self): self._topics = {} # No RAM allocation for topic strings as they are passed by reference if saved in a variable in subclass. # self._topics is used by mqtt to know which component a message is for. self._next_component = None # needed to keep a list of registered components config.addComponent(self) asyncio.get_event_loop().create_task(self._init())
# This example provides the same configuration as the COMPONENT dict above: from pysmartnode import config import gc gc.collect() from pysmartnode.components.machine.i2c import I2C gc.collect( ) # It's important to call gc.collect() to keep the RAM fragmentation to a minimum from pysmartnode.components.sensors.htu21d import HTU21D gc.collect() from pysmartnode.components.machine.easyGPIO import GPIO gc.collect() i2c = I2C(SCL="D6", SDA="D5") config.addComponent("i2c", i2c) gc.collect() htu = HTU21D(i2c, precision_temp=2, precision_humid=1, temp_offset=-2.0, humid_offset=10.0) config.addComponent("htu", htu) gc.collect() gpio = GPIO(discover_pins=["D0", "D1", "D2"]) config.addComponent("gpio", gpio) # This is optional, it just puts # your component in the dictionary where all registered components are.
except Exception as e: _log.critical("Can't start webrepl: {!s}".format(e)) # webrepl started here to start it as quickly as possible. gc.collect() loop = asyncio.get_event_loop() print("free ram {!r}".format(gc.mem_free())) gc.collect() if hasattr(config, "USE_SOFTWARE_WATCHDOG") and config.USE_SOFTWARE_WATCHDOG: from pysmartnode.components.machine.watchdog import WDT wdt = WDT(timeout=config.MQTT_KEEPALIVE * 2) config.addComponent("wdt", wdt) gc.collect() if config.WIFI_LED is not None: from pysmartnode.components.machine.wifi_led import WIFILED wl = WIFILED(config.WIFI_LED, config.WIFI_LED_ACTIVE_HIGH) config.addComponent("wifi_led", wl) gc.collect() if not config.MQTT_RECEIVE_CONFIG: # otherwise ignore as config will be received try: import components except ImportError: _log.critical("components.py does not exist") except Exception as e:
async def await_last_log(): await asyncio.sleep(10) import machine machine.reset() print("free ram {!r}".format(gc.mem_free())) wifi.connect() if hasattr(config, "USE_SOFTWARE_WATCHDOG") and config.USE_SOFTWARE_WATCHDOG: from pysmartnode.components.machine.watchdog import WDT wdt = WDT(timeout=config.MQTT_KEEPALIVE * 2) config.addComponent("wdt", wdt) print("Starting uasyncio loop") if config.DEBUG_STOP_AFTER_EXCEPTION: # want to see the exception trace in debug mode loop.run_forever() else: # just log the exception and reset the microcontroller while True: try: loop.run_forever() except Exception as e: time.sleep(5) log.critical("Loop error, {!s}".format(e)) loop.create_task(await_last_log()) loop.close()
loop.create_task(callRegular(someinstance.getTemperature, interval=600)) # This is an alternative if <someinstance> does not provide a coroutine that checks temperature periodically. # callRegular() calls a coroutine or function periodically in the given interval. # The someinstance function still has to take care of publishing its values. # This can be done by using the mqtt.publish coroutine or the mqtt.schedulePublish synchronous function loop.create_task( callRegularPublish(someinstance.getTemperature, ".mymodule/temperature", interval=None, retain=None, qos=None)) # This function allows you to periodically read a sensor and publish its value to the given # mqtt topic without any additional effort. (mqtt topic starting with "." is "<home>/<device-id>/" config.addComponent("mycomponent", someinstance) # This is optional, it just puts your component in the dictionary where all registered components are # The 3rd way is to just use this module to start whatever code you like # and use the mqtt instance to subscribe/publish from pysmartnode import config from pysmartnode import logging import uasyncio as asyncio mqtt = config.getMQTT() loop = asyncio.get_event_loop() log = logging.getLogger("components.py") # do whatever you want (don't do long blocking calls or start a synchronous endless loop)