relay_mqtt_*: add monitoring util, improve overall support

This commit is contained in:
Evgeny Zinoviev 2023-01-01 02:33:33 +03:00
parent ebdedacf2f
commit d2a5d8c6c2
5 changed files with 51 additions and 16 deletions

View File

@ -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

View File

@ -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()

View File

@ -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']})

31
src/relay_mqtt_util.py Executable file
View File

@ -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()

View File

@ -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)