diff options
Diffstat (limited to 'src/home/mqtt/relay.py')
-rw-r--r-- | src/home/mqtt/relay.py | 86 |
1 files changed, 37 insertions, 49 deletions
diff --git a/src/home/mqtt/relay.py b/src/home/mqtt/relay.py index a90f19c..cf657f7 100644 --- a/src/home/mqtt/relay.py +++ b/src/home/mqtt/relay.py @@ -1,71 +1,59 @@ +#!/usr/bin/env python3 import paho.mqtt.client as mqtt import re -import datetime +import logging -from .payload.relay import ( - PowerPayload, -) -from .esp import MqttEspBase +from .mqtt import MQTTBase -class MqttRelay(MqttEspBase): - TOPIC_LEAF = 'relay' +class MQTTRelayClient(MQTTBase): + _home_id: str - 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 __init__(self, home_id: str): + super().__init__(clean_session=True) + self._home_id = home_id - assert secret is not None, 'device secret not specified' + def on_connect(self, client: mqtt.Client, userdata, flags, rc): + super().on_connect(client, userdata, flags, rc) - 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() + topic = f'home/{self._home_id}/#' + self._logger.info(f"subscribing to {topic}") - def on_message(self, client: mqtt.Client, userdata, msg): - if super().on_message(client, userdata, msg): - return + client.subscribe(topic, qos=1) + def on_message(self, client: mqtt.Client, userdata, msg): try: - match = re.match(self.get_mqtt_topics(['power']), msg.topic) + match = re.match(r'^home/(.*?)/relay/(stat|power)(?:/(.+))?$', msg.topic) + self._logger.info(f'topic: {msg.topic}') if not match: return - device_id = match.group(1) + name = match.group(1) subtopic = match.group(2) - message = None - if subtopic == 'power': - message = PowerPayload.unpack(msg.payload) + if name != self._home_id: + return - if message and self._message_callback: - self._message_callback(device_id, message) + if subtopic == 'stat': + stat_name, stat_value = match.group(3).split('/') + self._logger.info(f'stat: {stat_name} = {stat_value}') 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 +class MQTTRelayController(MQTTBase): + _home_id: str + + def __init__(self, home_id: str): + super().__init__(clean_session=True) + self._home_id = home_id + + def set_power(self, enable: bool): + self._client.publish(f'home/{self._home_id}/relay/power', + payload=int(enable), + qos=1) + self._client.loop_write() + + def send_stat(self, stat: dict): + pass |