From d2a5d8c6c2a2ae27e650ec26183e7b9881b939c7 Mon Sep 17 00:00:00 2001 From: Evgeny Zinoviev Date: Sun, 1 Jan 2023 02:33:33 +0300 Subject: relay_mqtt_*: add monitoring util, improve overall support --- src/home/mqtt/relay.py | 30 +++++++++++++++++------------- src/pump_mqtt_bot.py | 2 +- src/relay_mqtt_bot.py | 2 +- src/relay_mqtt_util.py | 31 +++++++++++++++++++++++++++++++ tools/mcuota.py | 2 +- 5 files changed, 51 insertions(+), 16 deletions(-) create mode 100755 src/relay_mqtt_util.py diff --git a/src/home/mqtt/relay.py b/src/home/mqtt/relay.py index b481bf8..97a1689 100644 --- a/src/home/mqtt/relay.py +++ b/src/home/mqtt/relay.py @@ -3,7 +3,7 @@ import re import datetime from .mqtt import MQTTBase -from typing import Optional, Union, List +from typing import Optional, Union from .payload.relay import ( InitialStatPayload, StatPayload, @@ -13,11 +13,11 @@ from .payload.relay import ( class MQTTRelayDevice: - home_id: str - secret: str + id: str + secret: Optional[str] - def __init__(self, home_id: str, secret: str): - self.home_id = home_id + def __init__(self, id: str, secret: Optional[str] = None): + self.id = id self.secret = secret @@ -43,7 +43,7 @@ class MQTTRelay(MQTTBase): if self._subscribe_to_updates: for device in self._devices: - topic = f'hk/{device.home_id}/relay/#' + topic = f'hk/{device.id}/relay/#' self._logger.info(f"subscribing to {topic}") client.subscribe(topic, qos=1) @@ -61,10 +61,12 @@ class MQTTRelay(MQTTBase): if not match: return - name = match.group(1) + device_id = match.group(1) subtopic = match.group(2) - if name not in self._devices: + try: + next(d for d in self._devices if d.id == device_id) + except StopIteration: return message = None @@ -76,17 +78,18 @@ class MQTTRelay(MQTTBase): message = PowerPayload.unpack(msg.payload) if message and self._message_callback: - self._message_callback(name, message) + self._message_callback(device_id, message) except Exception as e: self._logger.exception(str(e)) def set_power(self, home_id, enable: bool): - device = next(d for d in self._devices if d.home_id == home_id) + device = next(d for d in self._devices if d.id == home_id) + assert device.secret is not None, 'device secret not specified' payload = PowerPayload(secret=device.secret, state=enable) - self._client.publish(f'hk/{device.home_id}/relay/power', + self._client.publish(f'hk/{device.id}/relay/power', payload=payload.pack(), qos=1) self._client.loop_write() @@ -96,11 +99,12 @@ class MQTTRelay(MQTTBase): filename: str, publish_callback: callable, qos: int): - device = next(d for d in self._devices if d.home_id == home_id) + device = next(d for d in self._devices if d.id == home_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.home_id}/relay/admin/ota', + publish_result = self._client.publish(f'hk/{device.id}/relay/admin/ota', payload=payload.pack(), qos=qos) self._ota_mid = publish_result.mid diff --git a/src/pump_mqtt_bot.py b/src/pump_mqtt_bot.py index f16ed36..accafcb 100755 --- a/src/pump_mqtt_bot.py +++ b/src/pump_mqtt_bot.py @@ -157,7 +157,7 @@ def markup(ctx: Optional[bot.Context]) -> Optional[ReplyKeyboardMarkup]: if __name__ == '__main__': - mqtt_relay = MQTTRelay(devices=MQTTRelayDevice(home_id=config['mqtt']['home_id'], + mqtt_relay = MQTTRelay(devices=MQTTRelayDevice(id=config['mqtt']['home_id'], secret=config['mqtt']['home_secret'])) mqtt_relay.set_message_callback(on_mqtt_message) mqtt_relay.configure_tls() diff --git a/src/relay_mqtt_bot.py b/src/relay_mqtt_bot.py index 9dddc4c..6fc981b 100755 --- a/src/relay_mqtt_bot.py +++ b/src/relay_mqtt_bot.py @@ -87,7 +87,7 @@ def markup(ctx: Optional[bot.Context]) -> Optional[ReplyKeyboardMarkup]: if __name__ == '__main__': devices = [] for device_id, data in config['relays'].items(): - devices.append(MQTTRelayDevice(home_id=device_id, + devices.append(MQTTRelayDevice(id=device_id, secret=data['secret'])) labels = data['labels'] bot.lang.ru(**{device_id: labels['ru']}) diff --git a/src/relay_mqtt_util.py b/src/relay_mqtt_util.py new file mode 100755 index 0000000..430af2c --- /dev/null +++ b/src/relay_mqtt_util.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +from typing import Optional +from argparse import ArgumentParser + +from home.config import config +from home.mqtt import MQTTRelay, MQTTRelayDevice +from home.mqtt.payload import MQTTPayload +from home.mqtt.payload.relay import InitialStatPayload, StatPayload + +mqtt_relay: Optional[MQTTRelay] = None + + +def on_mqtt_message(device_id, message: MQTTPayload): + if isinstance(message, InitialStatPayload) or isinstance(message, StatPayload): + message = f'[{device_id}] state={message.flags.state} rssi={message.rssi}' + if isinstance(message, InitialStatPayload): + message += f' fw={message.fw_version}' + print(message) + + +if __name__ == '__main__': + parser = ArgumentParser() + parser.add_argument('--device-id', type=str, required=True) + + config.load('relay_mqtt_util', parser=parser) + arg = parser.parse_args() + + mqtt_relay = MQTTRelay(devices=MQTTRelayDevice(id=arg.device_id)) + mqtt_relay.set_message_callback(on_mqtt_message) + mqtt_relay.configure_tls() + mqtt_relay.connect_and_loop() diff --git a/tools/mcuota.py b/tools/mcuota.py index 8d47c8c..75adf1b 100755 --- a/tools/mcuota.py +++ b/tools/mcuota.py @@ -34,7 +34,7 @@ def relayctl_publish_ota(filename: str, global stop stop = True - mqtt_relay = MQTTRelay(devices=MQTTRelayDevice(home_id=home_id, secret=home_secret)) + mqtt_relay = MQTTRelay(devices=MQTTRelayDevice(id=home_id, secret=home_secret)) mqtt_relay.configure_tls() mqtt_relay.connect_and_loop(loop_forever=False) mqtt_relay.push_ota(home_id, filename, published, qos) -- cgit v1.2.3