changeset 1754:92999dfbf321 default tip

add shelly support
author drewp@bigasterisk.com
date Tue, 04 Jun 2024 13:03:43 -0700
parents add4ce853035
children
files service/powerEagle/plugs/powermeter_exporter.py
diffstat 1 files changed, 55 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/service/powerEagle/plugs/powermeter_exporter.py	Sun May 05 17:59:05 2024 -0700
+++ b/service/powerEagle/plugs/powermeter_exporter.py	Tue Jun 04 13:03:43 2024 -0700
@@ -1,3 +1,4 @@
+import asyncio
 import json
 import logging
 
@@ -10,30 +11,66 @@
 
 powermeter_reports = Counter('powermeter_reports', 'mqtt messages from powermeter', labelnames=['sensor'])
 metrics = {}
-for sensor_field, metric_name in [
-    ('Power',         'powermeter_w'),
-    ('ApparentPower', 'powermeter_apparent_power_va'),
-    ('ReactivePower', 'powermeter_reactive_power_var'),
-    ('Factor',        'powermeter_factor'),
-    ('Voltage',       'powermeter_voltage_v'),
-    ('Current',       'powermeter_current_a'),
-]:  # yapf: disable
-    metrics[sensor_field] = Gauge(metric_name, documentation='', labelnames=['sensor'])
+for metric_name in [
+    ('powermeter_w'),
+    ('powermeter_apparent_power_va'),
+    ('powermeter_reactive_power_var'),
+    ('powermeter_factor'),
+    ('powermeter_voltage_v'),
+    ('powermeter_current_a'),
+    ('powermeter_temp_c'),
+]:
+    metrics[metric_name] = Gauge(metric_name, documentation='', labelnames=['sensor'])
 
 
-async def subscribe_to_sensor(topic, sensor_label):
+def sonoff(sensor_label, msg):
+    energy = msg['ENERGY']
+    metrics['powermeter_w'].labels(sensor=sensor_label).set(energy['Power'])
+    metrics['powermeter_apparent_power_va'].labels(sensor=sensor_label).set(energy['ApparentPower'])
+    metrics['powermeter_reactive_power_var'].labels(sensor=sensor_label).set(energy['ReactivePower'])
+    metrics['powermeter_factor'].labels(sensor=sensor_label).set(energy['Factor'])
+    metrics['powermeter_voltage_v'].labels(sensor=sensor_label).set(energy['Voltage'])
+    metrics['powermeter_current_a'].labels(sensor=sensor_label).set(energy['Current'])
+
+
+def shelly(sensor_label, msg):
+    metrics['powermeter_w'].labels(sensor=sensor_label).set(msg['apower'])
+    metrics['powermeter_voltage_v'].labels(sensor=sensor_label).set(msg['voltage'])
+    metrics['powermeter_current_a'].labels(sensor=sensor_label).set(msg['current'])
+    metrics['powermeter_apparent_power_va'].labels(sensor=sensor_label).set(msg['apower'])
+    metrics['powermeter_temp_c'].labels(sensor=sensor_label).set(msg['temperature']['tC'])
+
+
+async def subscribe_to_sensor(topic, sensor_label, onMsg):
     async with Client("mqtt2") as client:
         await client.subscribe(topic)
         async for message in client.messages:
-            msg = json.loads(message.payload)
-            for sf, m in metrics.items():
-                m.labels(sensor=sensor_label).set(msg['ENERGY'][sf])
-            powermeter_reports.labels(sensor=sensor_label).inc()
+            try:
+                msg = json.loads(message.payload)
+                onMsg(sensor_label, msg)
+                powermeter_reports.labels(sensor=sensor_label).inc()
+            except Exception:
+                log.error(f'{topic=} {sensor_label=}', exc_info=True)
+
+
+async def request_shelly_statuses(topic, period=10):
+    async with Client("mqtt2") as client:
+        while True:
+            # todo: this adds lag- better to publish upon a /metrics request
+            # then block until all the statuses come in.
+            await client.publish(topic, 'status_update')
+            await asyncio.sleep(period)
 
 
 server = StarletteServer()
 server.serve(startup_tasks=[
-    subscribe_to_sensor(topic="tele/st-wall-power/SENSOR", sensor_label='st_wall'),
-    subscribe_to_sensor(topic="tele/ki-fridge/SENSOR", sensor_label='ki_fridge'),
-    subscribe_to_sensor(topic="tt-console-power/SENSOR", sensor_label='tt_console'),
-])
+    subscribe_to_sensor(    topic="tele/st-wall-power/SENSOR",       sensor_label='st_wall',    onMsg=sonoff),
+    subscribe_to_sensor(    topic="tele/ki-fridge/SENSOR",           sensor_label='ki_fridge',  onMsg=sonoff),
+    subscribe_to_sensor(    topic="tt-console-power/SENSOR",         sensor_label='tt_console', onMsg=sonoff),
+    request_shelly_statuses(topic="ga-washer-power/command/switch:0"),
+    subscribe_to_sensor(    topic="ga-washer-power/status/switch:0", sensor_label='ga_washer',  onMsg=shelly),
+    request_shelly_statuses(topic="do-r-power/command/switch:0"),
+    subscribe_to_sensor(    topic="do-r-power/status/switch:0",      sensor_label='do_r',       onMsg=shelly),
+    request_shelly_statuses(topic="ws-atx-power/command/switch:0"),
+    subscribe_to_sensor(    topic="ws-atx-power/status/switch:0",    sensor_label='ws_atx',     onMsg=shelly),
+])  # yapf: disable