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 asyncio
import inspect import inspect
import paho import paho
import signal
from dataclasses import dataclass
from command import ( from command import (
Command, 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: class MQTTHandler:
def __init__( def __init__(
self, self,
mqtt_client: aiomqtt.Client, mqtt_config: MQTTConfig,
handler_id: str, handler_id: str,
): ):
self.handler_id = handler_id self.handler_id = handler_id
self.mqtt_client = mqtt_client self.mqtt_config = mqtt_config
self.topic_base = f"asset/{handler_id}" self.topic_base = f"asset/{handler_id}"
self.status_topic = f"{self.topic_base}/status"
self.command_topic = f"{self.topic_base}/command" self.command_topic = f"{self.topic_base}/command"
self.property_topic = f"{self.topic_base}/property" 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): def get_available_commands(self):
commands = {} commands = {}
for base in self.__class__.__mro__: for base in self.__class__.__mro__:
@ -93,6 +118,14 @@ class MQTTHandler:
command_name = topic.removeprefix(f"{self.command_topic}/") command_name = topic.removeprefix(f"{self.command_topic}/")
await self.execute_command(command_name, payload, message.properties) 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): async def run(self):
INTERVAL = 5 INTERVAL = 5
while True: while True:
@ -101,7 +134,12 @@ class MQTTHandler:
await client.subscribe(f"{self.command_topic}/+") await client.subscribe(f"{self.command_topic}/+")
await self.publish_commands() 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 # Inspect instance methods
for attr_name in dir(self): for attr_name in dir(self):

18
main.py
View File

@ -4,26 +4,18 @@ import aiomqtt
import aioserial import aioserial
import asyncio import asyncio
import paho import paho
import uuid
import socket import socket
import signal
from ubxhandler import UBXHandler from ubxhandler import UBXHandler
from handler import MQTTConfig
BAUD = 115200 BAUD = 115200
async def main(): async def main():
handler_id = f"example-gps-{socket.gethostname()}" handler_id = f"example-gps-{socket.gethostname()}"
mqtt_host = "127.0.0.1" mqtt_config = MQTTConfig(host="127.0.0.1", port=1883)
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,
)
serial_port = aioserial.AioSerial( serial_port = aioserial.AioSerial(
port="/tmp/ttyV0", port="/tmp/ttyV0",
@ -31,7 +23,9 @@ async def main():
timeout=0.05, # 50 ms 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() await handler.run()