changeset 6:bc2a93b306e9

port over the powermeter measurements
author drewp@bigasterisk.com
date Sat, 10 Aug 2024 23:03:57 -0700
parents 8390d5d0d512
children a640efa9fb01
files convert.py mqtt_metrics.py
diffstat 2 files changed, 47 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/convert.py	Sat Aug 10 23:02:51 2024 -0700
+++ b/convert.py	Sat Aug 10 23:03:57 2024 -0700
@@ -1,6 +1,8 @@
 '''
 Note that these functions need to parse the message['payload'] into a float
 '''
+import json
+
 converters = []
 
 
@@ -43,3 +45,31 @@
         }],
         'value': f_from_c(float(message['payload'])),
     }]
+
+
+@topic(r'(tele/st-wall-power/SENSOR|tele/ki-fridge/SENSOR|tt-console-power/SENSOR)')
+def poorly_named_sonoff_powermeter(message, topicGroups: tuple[str]) -> list[dict]:
+    energy = json.loads(message['payload'])['ENERGY']
+    sensor = {
+        'tele/st-wall-power/SENSOR': 'st_wall',
+        'tele/ki-fridge/SENSOR': 'ki_fridge',
+        'tt-console-power/SENSOR': 'tt_console',
+    }[topicGroups[0]]
+    return [{ 'name': 'powermeter_w',                  'labels': [{'labelName': 'sensor', 'labelValue': sensor}], 'value': energy['Power'] },
+            { 'name': 'powermeter_apparent_power_va',  'labels': [{'labelName': 'sensor', 'labelValue': sensor}], 'value': energy['ApparentPower'] },
+            { 'name': 'powermeter_reactive_power_var', 'labels': [{'labelName': 'sensor', 'labelValue': sensor}], 'value': energy['ReactivePower'] },
+            { 'name': 'powermeter_factor',             'labels': [{'labelName': 'sensor', 'labelValue': sensor}], 'value': energy['Factor'] },
+            { 'name': 'powermeter_voltage_v',          'labels': [{'labelName': 'sensor', 'labelValue': sensor}], 'value': energy['Voltage'] },
+            { 'name': 'powermeter_current_a',          'labels': [{'labelName': 'sensor', 'labelValue': sensor}], 'value': energy['Current'] } ] # yapf: disable
+
+@topic(r'(.*)-power/status/switch:0')
+def shelly_powermeter(message, topicGroups: tuple[str]) -> list[dict]:
+    sensor = topicGroups[0].replace('-', '_')
+    msg = json.loads(message['payload'])
+    return [
+        { 'name': 'powermeter_w',                 'labels': [{'labelName': 'sensor', 'labelValue': sensor}], 'value': msg['apower'] },
+        { 'name': 'powermeter_voltage_v',         'labels': [{'labelName': 'sensor', 'labelValue': sensor}], 'value': msg['voltage'] },
+        { 'name': 'powermeter_current_a',         'labels': [{'labelName': 'sensor', 'labelValue': sensor}], 'value': msg['current'] },
+        { '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
--- a/mqtt_metrics.py	Sat Aug 10 23:02:51 2024 -0700
+++ b/mqtt_metrics.py	Sat Aug 10 23:03:57 2024 -0700
@@ -59,10 +59,27 @@
     return message
 
 
+async def requestStatuses(client: aiomqtt.Client, period=10):
+    '''shellys post status updates periodically, but I want them more often.'''
+    while True:
+        for topic in [
+                "do-r-power/command/switch:0",
+                "ga-fridge-power/command/switch:0",
+                "ga-washer-power/command/switch:0",
+                "tt-fridge-power/command/switch:0",
+                "ws-bench-power/command/switch:0",
+                "ws-desk-power/command/switch:0",
+                "ws-solder-power/command/switch:0",
+        ]:
+            await client.publish(topic, 'status_update')
+        await asyncio.sleep(period)
+
+
 async def mqttTask(metrics: MetricsWriter):
     try:
         client = aiomqtt.Client('mqtt2.bigasterisk.com', identifier="mqtt-exporter")
         async with client:
+            asyncio.create_task(requestStatuses(client))
             await client.subscribe('#')
             async for mqttMessage in client.messages:
                 try: