From d754bb08613922a8d42325e79a2d38fcf7a169ab Mon Sep 17 00:00:00 2001 From: Valentin Ochs Date: Wed, 17 May 2023 16:04:53 +0200 Subject: [PATCH] Allow closing via mqtt --- door_pi_control/__init__.py | 7 ++----- door_pi_control/door/control.py | 8 +++++++- door_pi_control/mqtt.py | 17 +++++++++++++++-- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/door_pi_control/__init__.py b/door_pi_control/__init__.py index 1c16a87..0b441e2 100644 --- a/door_pi_control/__init__.py +++ b/door_pi_control/__init__.py @@ -1,9 +1,8 @@ #!/usr/bin/python -from . import nfc, socket, door, bell +from . import nfc, socket, door, bell, mqtt from .util import init_logging from collections import namedtuple -import paho.mqtt.client as mqcl import logging def main(): @@ -29,9 +28,7 @@ def main(): config = parser.parse_args() - mqttc = mqcl.Client() - mqttc.connect_async(config.mqtt_host, keepalive=60) - mqttc.loop_start() + mqttc = mqtt.reconnecting_client(config.mqtt_host) log_host = None if config.log_host != None: diff --git a/door_pi_control/door/control.py b/door_pi_control/door/control.py index b3ae482..1b71ea6 100644 --- a/door_pi_control/door/control.py +++ b/door_pi_control/door/control.py @@ -22,9 +22,15 @@ class Control(util.Loggable): self._position_task: Thread = None self._control_task: Thread = None + def handle_target(client, userdata, msg): + self._logger().debug("Incoming MQTT message on %s: %s", msg.topic, msg.payload) + if msg.topic == "door/state/target" and msg.payload == b'closed': + self.close() + self.target = mqtt.Value(mqtt_client, "door/state/target", persistent=True, - translate=state_names) + translate=state_names, + remote_update_callback = handle_target) self.state = mqtt.Value(mqtt_client, "door/state/value", persistent=True, translate=state_names) diff --git a/door_pi_control/mqtt.py b/door_pi_control/mqtt.py index 8ba7f4e..7536e75 100644 --- a/door_pi_control/mqtt.py +++ b/door_pi_control/mqtt.py @@ -1,6 +1,7 @@ import datetime import logging import typing +import time from typing import Any, Optional, Callable from paho.mqtt.client import Client as Client @@ -19,7 +20,8 @@ class Value: typing.Dict[Any, str], typing.Callable] = None, - max_update: float = 0.1): + max_update: float = 0.1, + remote_update_callback = None): self.client = client self.topic = topic self.persistent = persistent @@ -39,6 +41,13 @@ class Value: if start_value is not None: self.update(start_value) + if remote_update_callback is not None: + _logger.debug("Subscribing to topic %s", self.topic) + self.client.message_callback_add(self.topic, remote_update_callback) + while self.client.subscribe(self.topic, 2)[1] is None: + time.sleep(0.5) + _logger.warning("Retrying...") + def update(self, value: Any, *, force: bool = False, no_update: bool = False) -> None: @@ -73,12 +82,16 @@ class Value: return self.translate(self.value) def reconnecting_client(host: str, *, keepalive: int = 60): + _logger.debug("Creating MQTT client with keepalive interval %d", keepalive) client = Client() client.on_connect = lambda client, userdata, flags, rc: \ _logger.debug("Connected to mqtt host") client.on_disconnect = lambda client, userdata, rc: \ _logger.debug("Disconnected from mqtt host") - client.enable_logger(_logger.getChild("paho")) + # client.enable_logger(_logger.getChild("paho")) client.connect_async(host, keepalive=keepalive) + def on_message(client, userdata, msg): + _logger.debug("Unmatched message on %s: %s", msg.topic, msg.payload) + client.on_message = on_message client.loop_start() return client