summaryrefslogtreecommitdiff
path: root/src/home/mqtt/relay.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/home/mqtt/relay.py')
-rw-r--r--src/home/mqtt/relay.py107
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