Mercurial > code > home > repos > homeauto
comparison service/powerEagle/plugs/powermeter_exporter.py @ 1754:92999dfbf321 default tip
add shelly support
author | drewp@bigasterisk.com |
---|---|
date | Tue, 04 Jun 2024 13:03:43 -0700 |
parents | add4ce853035 |
children |
comparison
equal
deleted
inserted
replaced
1753:add4ce853035 | 1754:92999dfbf321 |
---|---|
1 import asyncio | |
1 import json | 2 import json |
2 import logging | 3 import logging |
3 | 4 |
4 from aiomqtt import Client | 5 from aiomqtt import Client |
5 from prometheus_client import Counter, Gauge | 6 from prometheus_client import Counter, Gauge |
8 logging.basicConfig(level=logging.DEBUG) | 9 logging.basicConfig(level=logging.DEBUG) |
9 log = logging.getLogger() | 10 log = logging.getLogger() |
10 | 11 |
11 powermeter_reports = Counter('powermeter_reports', 'mqtt messages from powermeter', labelnames=['sensor']) | 12 powermeter_reports = Counter('powermeter_reports', 'mqtt messages from powermeter', labelnames=['sensor']) |
12 metrics = {} | 13 metrics = {} |
13 for sensor_field, metric_name in [ | 14 for metric_name in [ |
14 ('Power', 'powermeter_w'), | 15 ('powermeter_w'), |
15 ('ApparentPower', 'powermeter_apparent_power_va'), | 16 ('powermeter_apparent_power_va'), |
16 ('ReactivePower', 'powermeter_reactive_power_var'), | 17 ('powermeter_reactive_power_var'), |
17 ('Factor', 'powermeter_factor'), | 18 ('powermeter_factor'), |
18 ('Voltage', 'powermeter_voltage_v'), | 19 ('powermeter_voltage_v'), |
19 ('Current', 'powermeter_current_a'), | 20 ('powermeter_current_a'), |
20 ]: # yapf: disable | 21 ('powermeter_temp_c'), |
21 metrics[sensor_field] = Gauge(metric_name, documentation='', labelnames=['sensor']) | 22 ]: |
23 metrics[metric_name] = Gauge(metric_name, documentation='', labelnames=['sensor']) | |
22 | 24 |
23 | 25 |
24 async def subscribe_to_sensor(topic, sensor_label): | 26 def sonoff(sensor_label, msg): |
27 energy = msg['ENERGY'] | |
28 metrics['powermeter_w'].labels(sensor=sensor_label).set(energy['Power']) | |
29 metrics['powermeter_apparent_power_va'].labels(sensor=sensor_label).set(energy['ApparentPower']) | |
30 metrics['powermeter_reactive_power_var'].labels(sensor=sensor_label).set(energy['ReactivePower']) | |
31 metrics['powermeter_factor'].labels(sensor=sensor_label).set(energy['Factor']) | |
32 metrics['powermeter_voltage_v'].labels(sensor=sensor_label).set(energy['Voltage']) | |
33 metrics['powermeter_current_a'].labels(sensor=sensor_label).set(energy['Current']) | |
34 | |
35 | |
36 def shelly(sensor_label, msg): | |
37 metrics['powermeter_w'].labels(sensor=sensor_label).set(msg['apower']) | |
38 metrics['powermeter_voltage_v'].labels(sensor=sensor_label).set(msg['voltage']) | |
39 metrics['powermeter_current_a'].labels(sensor=sensor_label).set(msg['current']) | |
40 metrics['powermeter_apparent_power_va'].labels(sensor=sensor_label).set(msg['apower']) | |
41 metrics['powermeter_temp_c'].labels(sensor=sensor_label).set(msg['temperature']['tC']) | |
42 | |
43 | |
44 async def subscribe_to_sensor(topic, sensor_label, onMsg): | |
25 async with Client("mqtt2") as client: | 45 async with Client("mqtt2") as client: |
26 await client.subscribe(topic) | 46 await client.subscribe(topic) |
27 async for message in client.messages: | 47 async for message in client.messages: |
28 msg = json.loads(message.payload) | 48 try: |
29 for sf, m in metrics.items(): | 49 msg = json.loads(message.payload) |
30 m.labels(sensor=sensor_label).set(msg['ENERGY'][sf]) | 50 onMsg(sensor_label, msg) |
31 powermeter_reports.labels(sensor=sensor_label).inc() | 51 powermeter_reports.labels(sensor=sensor_label).inc() |
52 except Exception: | |
53 log.error(f'{topic=} {sensor_label=}', exc_info=True) | |
54 | |
55 | |
56 async def request_shelly_statuses(topic, period=10): | |
57 async with Client("mqtt2") as client: | |
58 while True: | |
59 # todo: this adds lag- better to publish upon a /metrics request | |
60 # then block until all the statuses come in. | |
61 await client.publish(topic, 'status_update') | |
62 await asyncio.sleep(period) | |
32 | 63 |
33 | 64 |
34 server = StarletteServer() | 65 server = StarletteServer() |
35 server.serve(startup_tasks=[ | 66 server.serve(startup_tasks=[ |
36 subscribe_to_sensor(topic="tele/st-wall-power/SENSOR", sensor_label='st_wall'), | 67 subscribe_to_sensor( topic="tele/st-wall-power/SENSOR", sensor_label='st_wall', onMsg=sonoff), |
37 subscribe_to_sensor(topic="tele/ki-fridge/SENSOR", sensor_label='ki_fridge'), | 68 subscribe_to_sensor( topic="tele/ki-fridge/SENSOR", sensor_label='ki_fridge', onMsg=sonoff), |
38 subscribe_to_sensor(topic="tt-console-power/SENSOR", sensor_label='tt_console'), | 69 subscribe_to_sensor( topic="tt-console-power/SENSOR", sensor_label='tt_console', onMsg=sonoff), |
39 ]) | 70 request_shelly_statuses(topic="ga-washer-power/command/switch:0"), |
71 subscribe_to_sensor( topic="ga-washer-power/status/switch:0", sensor_label='ga_washer', onMsg=shelly), | |
72 request_shelly_statuses(topic="do-r-power/command/switch:0"), | |
73 subscribe_to_sensor( topic="do-r-power/status/switch:0", sensor_label='do_r', onMsg=shelly), | |
74 request_shelly_statuses(topic="ws-atx-power/command/switch:0"), | |
75 subscribe_to_sensor( topic="ws-atx-power/status/switch:0", sensor_label='ws_atx', onMsg=shelly), | |
76 ]) # yapf: disable |