lwt actually working. i hate how it works though

This commit is contained in:
Jono Targett 2026-03-15 21:24:49 +10:30
parent 85a5f400bc
commit bbb12a5a94
2 changed files with 47 additions and 15 deletions

View File

@ -2,6 +2,8 @@ import aiomqtt
import asyncio
import inspect
import paho
import signal
from dataclasses import dataclass
from command import (
Command,
@ -11,20 +13,43 @@ from command import (
)
@dataclass
class MQTTConfig:
host: str
port: int = 1883
username: str | None = None
password: str | None = None
keepalive: int = 60
class MQTTHandler:
def __init__(
self,
mqtt_client: aiomqtt.Client,
mqtt_config: MQTTConfig,
handler_id: str,
):
self.handler_id = handler_id
self.mqtt_client = mqtt_client
self.mqtt_config = mqtt_config
self.topic_base = f"asset/{handler_id}"
self.status_topic = f"{self.topic_base}/status"
self.command_topic = f"{self.topic_base}/command"
self.property_topic = f"{self.topic_base}/property"
self._shutdown_event = asyncio.Event()
will = aiomqtt.Will(
topic=self.status_topic, payload="OFFLINE", qos=1, retain=True
)
self.mqtt_client = aiomqtt.Client(
self.mqtt_config.host,
port=self.mqtt_config.port,
identifier=handler_id,
protocol=paho.mqtt.client.MQTTv5,
will=will,
)
def get_available_commands(self):
commands = {}
for base in self.__class__.__mro__:
@ -93,6 +118,14 @@ class MQTTHandler:
command_name = topic.removeprefix(f"{self.command_topic}/")
await self.execute_command(command_name, payload, message.properties)
async def shutdown_watcher(self):
await self._shutdown_event.wait()
await self.mqtt_client.publish(self.status_topic, "OFFLINE", qos=1, retain=True)
def stop(self):
self._shutdown_event.set()
signal.signal(signal.SIGINT, signal.SIG_DFL)
async def run(self):
INTERVAL = 5
while True:
@ -101,7 +134,12 @@ class MQTTHandler:
await client.subscribe(f"{self.command_topic}/+")
await self.publish_commands()
tasks = [self.mqtt_command_writer_task()]
# announce that we are online
await client.publish(
self.status_topic, "ONLINE", qos=1, retain=True
)
tasks = [self.mqtt_command_writer_task(), self.shutdown_watcher()]
# Inspect instance methods
for attr_name in dir(self):

18
main.py
View File

@ -4,26 +4,18 @@ import aiomqtt
import aioserial
import asyncio
import paho
import uuid
import socket
import signal
from ubxhandler import UBXHandler
from handler import MQTTConfig
BAUD = 115200
async def main():
handler_id = f"example-gps-{socket.gethostname()}"
mqtt_host = "127.0.0.1"
mqtt_port = 1883
client_id = f"{handler_id}-{uuid.uuid4()}"
mqtt_client = aiomqtt.Client(
mqtt_host,
port=mqtt_port,
identifier=client_id,
protocol=paho.mqtt.client.MQTTv5,
)
mqtt_config = MQTTConfig(host="127.0.0.1", port=1883)
serial_port = aioserial.AioSerial(
port="/tmp/ttyV0",
@ -31,7 +23,9 @@ async def main():
timeout=0.05, # 50 ms
)
handler = UBXHandler(mqtt_client, handler_id, serial_port)
handler = UBXHandler(mqtt_config, handler_id, serial_port)
signal.signal(signal.SIGINT, lambda signum, frame: handler.stop())
await handler.run()