#!/usr/bin/env -S uv run --script # /// script # dependencies = [ # "paho-mqtt>=2.0", # "docker>=7.0", # ] # /// import os import stat import time import docker import paho.mqtt.client as mqtt MQTT_HOST = os.environ.get("MQTT_HOST", "mosquitto") MQTT_PORT = int(os.environ.get("MQTT_PORT", "1883")) ACL_PATH = "/mosquitto/config/acl.conf" locked = False def rebuild_acl(): lines = [] if locked: lines.append("topic deny zigbee2mqtt/+/set") lines.append("topic readwrite #") with open(ACL_PATH, "w") as f: f.write("\n".join(lines) + "\n") os.chmod(ACL_PATH, stat.S_IRWXU) os.chown(ACL_PATH, 1883, 1883) try: dc = docker.DockerClient(base_url="unix://var/run/docker.sock") mosq = dc.containers.get("mosquitto") mosq.kill(signal="HUP") except Exception: pass time.sleep(0.05) def on_message(client, userdata, msg): global locked payload = msg.payload.decode().strip().upper() if payload == "ON": locked = True elif payload == "OFF": locked = False else: return rebuild_acl() def main(): rebuild_acl() client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2) client.on_message = on_message while True: try: client.connect(MQTT_HOST, MQTT_PORT, 60) break except Exception as e: print(f"mqtt connect failed: {e}; retrying in 5s", flush=True) time.sleep(5) client.subscribe("party-lock/set", qos=1) client.loop_forever() if __name__ == "__main__": main()