import paho.mqtt.client as mqtt import re import datetime from .payload.relay import ( PowerPayload, ) from .esp import MqttEspBase class MqttRelay(MqttEspBase): TOPIC_LEAF = 'relay' def set_power(self, device_id, enable: bool, secret=None): device = next(d for d in self._devices if d.id == device_id) secret = secret if secret else device.secret assert secret is not None, 'device secret not specified' payload = PowerPayload(secret=secret, state=enable) self._client.publish(f'hk/{device.id}/{self.TOPIC_LEAF}/power', payload=payload.pack(), qos=1) self._client.loop_write() def on_message(self, client: mqtt.Client, userdata, msg): if super().on_message(client, userdata, msg): return try: match = re.match(self.get_mqtt_topics(['power']), msg.topic) if not match: return device_id = match.group(1) subtopic = match.group(2) message = None if subtopic == 'power': message = PowerPayload.unpack(msg.payload) if message and self._message_callback: self._message_callback(device_id, message) except Exception as e: self._logger.exception(str(e)) class MqttRelayState: enabled: bool update_time: datetime.datetime rssi: int fw_version: int ever_updated: bool def __init__(self): self.ever_updated = False self.enabled = False self.rssi = 0 def update(self, enabled: bool, rssi: int, fw_version=None): self.ever_updated = True self.enabled = enabled self.rssi = rssi self.update_time = datetime.datetime.now() if fw_version: self.fw_version = fw_version