Implemented Z2M bridge
This commit is contained in:
parent
f2c8d6885d
commit
c2aa2f5adc
3 changed files with 96 additions and 3 deletions
|
@ -5,12 +5,12 @@ phue
|
||||||
fritzconnection
|
fritzconnection
|
||||||
|
|
||||||
# API
|
# API
|
||||||
requests
|
|
||||||
fastapi
|
fastapi
|
||||||
uvicorn[standard]
|
uvicorn[standard]
|
||||||
|
|
||||||
# Clients
|
# Bridges
|
||||||
requests
|
requests
|
||||||
|
paho-mqtt
|
||||||
|
|
||||||
# Config file
|
# Config file
|
||||||
pyyaml
|
pyyaml
|
||||||
|
|
|
@ -1,6 +1,76 @@
|
||||||
|
from typing import Optional
|
||||||
from mash.bridges.bridge import Bridge
|
from mash.bridges.bridge import Bridge
|
||||||
|
import paho.mqtt.client as mqtt
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
class Z2mBridge(Bridge):
|
class Z2mBridge(Bridge):
|
||||||
def __init__(self, *, id: str) -> None:
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
id: str,
|
||||||
|
ip: str,
|
||||||
|
port: int = 1883,
|
||||||
|
keepalive: int = 60,
|
||||||
|
topic: str = "zigbee2mqtt",
|
||||||
|
) -> None:
|
||||||
super().__init__(id=id, type="zigbee2mqtt")
|
super().__init__(id=id, type="zigbee2mqtt")
|
||||||
|
self._ip = ip
|
||||||
|
self._port = port
|
||||||
|
self._keepalive = keepalive
|
||||||
|
self._device_callbacks: dict[str, list] = {}
|
||||||
|
self._topic = topic.strip("/")
|
||||||
|
|
||||||
|
self._client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
|
||||||
|
|
||||||
|
self._client.on_connect = lambda client, userdata, flags, reason_code, properties: self.__on_connect__(
|
||||||
|
client, userdata, flags, reason_code, properties
|
||||||
|
)
|
||||||
|
self._client.on_message = lambda client, userdata, msg: self.__on_message__(
|
||||||
|
client, userdata, msg
|
||||||
|
)
|
||||||
|
|
||||||
|
def __del__(self) -> None:
|
||||||
|
self.disconnect()
|
||||||
|
|
||||||
|
def disconnect(self) -> None:
|
||||||
|
self._client.loop_stop()
|
||||||
|
self._client.disconnect()
|
||||||
|
|
||||||
|
def connect(self) -> None:
|
||||||
|
self._client.connect(self._ip, self._port, self._keepalive)
|
||||||
|
self._client.loop_start()
|
||||||
|
|
||||||
|
def __on_connect__(self, client, userdata, flags, reason_code, properties):
|
||||||
|
self._client.subscribe(f"{self._topic}/#")
|
||||||
|
|
||||||
|
def __on_message__(self, client, userdata, msg: any):
|
||||||
|
device_name = msg.topic.split(self._topic + "/", 2)[-1].split("/", 2)[0]
|
||||||
|
|
||||||
|
if device_name not in self._device_callbacks.keys():
|
||||||
|
return
|
||||||
|
|
||||||
|
for callback in self._device_callbacks[device_name]:
|
||||||
|
callback(device_name, json.loads(msg.payload))
|
||||||
|
|
||||||
|
def set_device(self, ieee_address: str, *, content: dict = {}) -> None:
|
||||||
|
self._client.publish(f"{self._topic}/{ieee_address}/set", json.dumps(content))
|
||||||
|
|
||||||
|
def get_device(self, ieee_address: str) -> None:
|
||||||
|
self._client.publish(
|
||||||
|
f"{self._topic}/{ieee_address}/get", json.dumps({"state": ""})
|
||||||
|
)
|
||||||
|
|
||||||
|
def subscribe_device(
|
||||||
|
self,
|
||||||
|
callback,
|
||||||
|
*,
|
||||||
|
ieee_address: Optional[str] = None,
|
||||||
|
friendly_name: Optional[str] = None,
|
||||||
|
) -> None:
|
||||||
|
for id in [ieee_address, friendly_name]:
|
||||||
|
if id not in self._device_callbacks.keys():
|
||||||
|
self._device_callbacks[id] = []
|
||||||
|
|
||||||
|
self._device_callbacks[id].append(callback)
|
||||||
|
|
23
src/mqtt_test.py
Normal file
23
src/mqtt_test.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
from time import sleep
|
||||||
|
from mash.bridges.zigbee2mqtt import Z2mBridge
|
||||||
|
|
||||||
|
|
||||||
|
z2m = Z2mBridge(id="z2m", ip="192.168.178.115")
|
||||||
|
|
||||||
|
|
||||||
|
def wardrobe_cb(device_name: str, payload: dict) -> None:
|
||||||
|
print(f"{device_name} - {'closed' if payload['contact'] else 'open'}")
|
||||||
|
|
||||||
|
|
||||||
|
z2m.subscribe_device(wardrobe_cb, friendly_name="max-wardrobe-door")
|
||||||
|
z2m.subscribe_device(wardrobe_cb, friendly_name="max-window-contact")
|
||||||
|
|
||||||
|
z2m.connect()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
sleep(3)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
break
|
||||||
|
|
||||||
|
z2m.disconnect()
|
Loading…
Reference in a new issue