#!/usr/bin/env -S uv run --script # /// script # dependencies = [ # "paho-mqtt>=2.0", # ] # /// import os 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" PLUG_MAP = { "bamboo": "0xffffb40e06050af6", "dj-booth": "0xffffb40e0603ef11", } locked_plugs = set() def rebuild_acl(): lines = [] for plug in sorted(locked_plugs): ieee = PLUG_MAP.get(plug) if ieee: lines.append(f"topic deny zigbee2mqtt/{ieee}/set") lines.append("topic readwrite #") with open(ACL_PATH, "w") as f: f.write("\n".join(lines) + "\n") os.system("docker kill -s HUP mosquitto 2>/dev/null || true") def on_message(client, userdata, msg): topic = msg.topic payload = msg.payload.decode().strip().upper() parts = topic.split("/") if len(parts) >= 3 and parts[0] == "party-lock": plug_name = parts[1] if plug_name in PLUG_MAP and payload in ("ON", "OFF"): if payload == "ON": locked_plugs.add(plug_name) else: locked_plugs.discard(plug_name) rebuild_acl() def main(): rebuild_acl() client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2) client.on_message = on_message client.connect(MQTT_HOST, MQTT_PORT, 60) client.subscribe("party-lock/+/set", qos=1) client.loop_forever() if __name__ == "__main__": main()