pflanzen-box/code/plant_node.py
2021-01-17 22:41:51 +01:00

132 lines
4.3 KiB
Python

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)