from homie.constants import BOOLEAN, FALSE, TRUE, FLOAT from homie.property import HomieProperty from update_homie_node import UpdateHomieNode # from homie.device import await_ready_state from machine import Pin, ADC import uasyncio as asyncio class PlantNode(UpdateHomieNode): def __init__( self, id, name, pin_watering, pin_moisture, pin_water_tank, waterlevel_sensor, interval=60*5, interval_watering=0.1): super().__init__( id=id, name=name, type="watering", interval=interval, interval_short=interval_watering) # Update Interval self.interval_normal = interval self.interval_watering = interval_watering # WaterLevelSensor self.waterlevel_sensor = waterlevel_sensor self.property_waterlevel = HomieProperty( id="waterlevel", name="Wassertankstand", datatype=FLOAT, unit="L", ) self.add_property(self.property_waterlevel) self.property_waterlevel_percent = HomieProperty( id="waterlevel_percent", name="Wassertankstand [%]", datatype=FLOAT, format="0.00:100.00", unit="%", ) self.add_property(self.property_waterlevel_percent) self.property_waterlevel_volume_liter = HomieProperty( id="waterlevel_volume_max", name="Wassertankgröße", settable=True, datatype=FLOAT, unit="L", on_message=self._set_waterlevel_volume ) self.add_property(self.property_waterlevel_volume_liter) # Moisture self.adc = ADC(pin_moisture) self.adc.atten(ADC.ATTN_11DB) self.property_moisture = HomieProperty( id="moisture", name="Feuchte", datatype=FLOAT, format="0.00:100.00", unit="%", ) self.add_property(self.property_moisture) # Watering Motor self.pin_watering_motor = pin_watering self.pin_watering_motor.init(mode=Pin.OUT, value=0) self.property_water_power = HomieProperty( id="power", name="Bewässerung", settable=True, datatype=BOOLEAN, default=FALSE, on_message=self.toggle_motor, ) self.add_property(self.property_water_power) self.property_watering_max_duration = HomieProperty( id="watering_duration_max", name="Bewässerungszeit", settable=True, datatype=FLOAT, default=3, unit="s", ) self.add_property(self.property_watering_max_duration) def update_data(self): self.property_moisture.value = "{:1.2f}".format( (4096 - self.adc.read()) / 40.96) self.property_waterlevel_percent.value = "{:1.0f}".format( self.waterlevel_sensor.level_percent) self.property_waterlevel.value = "{:1.2f}".format( self.waterlevel_sensor.level) self.property_waterlevel_volume_liter.value = "{:1.4f}".format( self.waterlevel_sensor.volume) if self.pin_watering_motor.value() == 1: self.interval_normal = self._interval self.set_interval(self.interval_watering) def toggle_motor(self, topic, payload, retained): ONOFF = {FALSE: 0, TRUE: 1} v = ONOFF[payload] self.pin_watering_motor(v) if v == 1: self.interval_normal = self._interval self.set_interval(self.interval_watering) asyncio.create_task(self.stop_motor()) def stop_motor(self): await asyncio.sleep_ms( int(float(self.property_watering_max_duration.value) * 1000)) self.pin_watering_motor.value(0) self.set_interval(self.interval_normal) self.property_water_power.value = FALSE def _set_waterlevel_min_value(self, topic, payload, retained): self.waterlevel_sensor.value_min = float(payload) def _set_waterlevel_max_value(self, topic, payload, retained): self.waterlevel_sensor.value_max = float(payload) def _set_waterlevel_volume(self, topic, payload, retained): self.waterlevel_sensor.volume = float(payload)