changeset 10:2a507e679d0d default tip

add zigbee covnerters
author drewp@bigasterisk.com
date Mon, 12 Aug 2024 13:15:07 -0700
parents 789042521535
children
files convert.py
diffstat 1 files changed, 34 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/convert.py	Mon Aug 12 13:14:39 2024 -0700
+++ b/convert.py	Mon Aug 12 13:15:07 2024 -0700
@@ -2,7 +2,9 @@
 Note that these functions need to parse the message['payload'] into a float
 '''
 import json
+import logging
 
+log = logging.getLogger('conv')
 converters = []
 
 
@@ -73,3 +75,35 @@
         { 'name': 'powermeter_apparent_power_va', 'labels': [{'labelName': 'sensor', 'labelValue': sensor}], 'value': msg['apower'] },
         { 'name': 'powermeter_temp_f',            'labels': [{'labelName': 'sensor', 'labelValue': sensor}], 'value': f_from_c(msg['temperature']['tC']) },
     ] # yapf: disable
+
+@topic(r'^zigbee/([^/]+)$')
+def zigbee(message, topicGroups: tuple[str]) -> list[dict]:
+    dev = topicGroups[0]
+    body = json.loads(message['payload'])
+    ret = []
+    for v in ['update_available', 'link_quality', 'battery', 'occupancy', 'brightness', 'contact']:
+        body_key = 'linkquality' if v == 'link_quality' else v
+        if body_key not in body:
+            continue
+        value = body[body_key]
+        if v in ['update_available', 'contact', 'occupancy']:
+            value = int(bool(value))
+        if v == 'brightness' and body.get('state', None) != 'ON':
+            value = 0
+        if v == 'link_quality' and value is None:
+            value = -1
+        if value is None:
+            logging.warning(f'zigbee {v=} {value=}')
+            continue
+        ret.append({'name': 'zigbee_' + v, 'labels': [{'labelName': 'dev', 'labelValue': dev}], 'value': value})
+    return ret
+
+
+@topic(r'^zigbee/([^/]+)/availability$')
+def zigbee_availability(message, topicGroups: tuple[str]) -> list[dict]:
+    dev = topicGroups[0]
+    online = message['payload'] == "online"
+    ret = [{'name': 'zigbee_online', 'labels': [{'labelName': 'dev', 'labelValue': dev}], 'value': int(online)}]
+    if online and dev.startswith('0x'):
+        ret.append({'name': 'zigbee_unnamed_dev', 'labels': [{'labelName': 'dev', 'labelValue': dev}], 'value': 1})
+    return ret