diff options
Diffstat (limited to 'src/home/mqtt/relay.py')
-rw-r--r-- | src/home/mqtt/relay.py | 107 |
1 files changed, 19 insertions, 88 deletions
diff --git a/src/home/mqtt/relay.py b/src/home/mqtt/relay.py index 53d43e4..a90f19c 100644 --- a/src/home/mqtt/relay.py +++ b/src/home/mqtt/relay.py @@ -2,83 +2,43 @@ import paho.mqtt.client as mqtt import re import datetime -from .mqtt import MQTTBase -from typing import Optional, Union from .payload.relay import ( - InitialStatPayload, - StatPayload, PowerPayload, - OTAPayload, - OTAResultPayload ) +from .esp import MqttEspBase -class MQTTRelayDevice: - id: str - secret: Optional[str] +class MqttRelay(MqttEspBase): + TOPIC_LEAF = 'relay' - def __init__(self, id: str, secret: Optional[str] = None): - self.id = id - self.secret = secret - - -class MQTTRelay(MQTTBase): - _devices: list[MQTTRelayDevice] - _message_callback: Optional[callable] - _ota_publish_callback: Optional[callable] - - def __init__(self, - devices: Union[MQTTRelayDevice, list[MQTTRelayDevice]], - subscribe_to_updates=True): - super().__init__(clean_session=True) - if not isinstance(devices, list): - devices = [devices] - self._devices = devices - self._message_callback = None - self._ota_publish_callback = None - self._subscribe_to_updates = subscribe_to_updates - self._ota_mid = None - - def on_connect(self, client: mqtt.Client, userdata, flags, rc): - super().on_connect(client, userdata, flags, rc) - - if self._subscribe_to_updates: - for device in self._devices: - topic = f'hk/{device.id}/relay/#' - self._logger.debug(f"subscribing to {topic}") - client.subscribe(topic, qos=1) + 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 - def on_publish(self, client: mqtt.Client, userdata, mid): - if self._ota_mid is not None and mid == self._ota_mid and self._ota_publish_callback: - self._ota_publish_callback() + assert secret is not None, 'device secret not specified' - def set_message_callback(self, callback: callable): - self._message_callback = callback + 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(r'^hk/(.*?)/relay/(stat|stat1|power|otares)$', msg.topic) - self._logger.debug(f'topic: {msg.topic}') + match = re.match(self.get_mqtt_topics(['power']), msg.topic) if not match: return device_id = match.group(1) subtopic = match.group(2) - try: - next(d for d in self._devices if d.id == device_id) - except StopIteration: - return - message = None - if subtopic == 'stat': - message = StatPayload.unpack(msg.payload) - elif subtopic == 'stat1': - message = InitialStatPayload.unpack(msg.payload) - elif subtopic == 'power': + if subtopic == 'power': message = PowerPayload.unpack(msg.payload) - elif subtopic == 'otares': - message = OTAResultPayload.unpack(msg.payload) if message and self._message_callback: self._message_callback(device_id, message) @@ -86,37 +46,8 @@ class MQTTRelay(MQTTBase): except Exception as e: self._logger.exception(str(e)) - 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}/relay/power', - payload=payload.pack(), - qos=1) - self._client.loop_write() - - def push_ota(self, - device_id, - filename: str, - publish_callback: callable, - qos: int): - device = next(d for d in self._devices if d.id == device_id) - assert device.secret is not None, 'device secret not specified' - - self._ota_publish_callback = publish_callback - payload = OTAPayload(secret=device.secret, filename=filename) - publish_result = self._client.publish(f'hk/{device.id}/relay/admin/ota', - payload=payload.pack(), - qos=qos) - self._ota_mid = publish_result.mid - self._client.loop_write() - -class MQTTRelayState: +class MqttRelayState: enabled: bool update_time: datetime.datetime rssi: int |