1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
| import prometheus_client
from prometheus_client import Gauge
from prometheus_client.core import CollectorRegistry
from flask import Response, Flask
from kasa import SmartStrip, SmartDevice
import asyncio
import threading
import traceback
import os
import sys
DEV_IP = os.environ.get("DEV_IP")
if not DEV_IP:
print('os.environ["DEV_IP"] is None')
sys.exit(1)
app = Flask(__name__)
dev = SmartStrip(DEV_IP)
labelnames = ['alias', 'id', 'host']
def labels(dev: SmartDevice):
return [dev.alias, dev.device_id, dev.host]
REGISTRY = CollectorRegistry(auto_describe=False)
kasa_on = Gauge("kasa_on", "On or off", registry=REGISTRY, labelnames=labelnames)
kasa_current = Gauge("kasa_current", "Current value", registry=REGISTRY, labelnames=labelnames)
kasa_voltage = Gauge("kasa_voltage", "Voltage value", registry=REGISTRY, labelnames=labelnames)
kasa_power = Gauge("kasa_power", "Power value", registry=REGISTRY, labelnames=labelnames)
kasa_total = Gauge("kasa_total", "Total value", registry=REGISTRY, labelnames=labelnames)
kasa_emeter_today = Gauge("kasa_emeter_today", "Energy today value", registry=REGISTRY, labelnames=labelnames)
kasa_emeter_this_month = Gauge("kasa_emeter_this_month", "Energy this month value", registry=REGISTRY, labelnames=labelnames)
kasa_rssi = Gauge("kasa_rssi", "RSSI value", registry=REGISTRY, labelnames=labelnames)
async def update_metrics():
while True:
try:
await dev.update()
dev_emeter_today = 0.0
dev_emeter_this_month = 0.0
for ch in dev.children:
kasa_on.labels(*labels(ch)).set(ch.is_on)
current = ch.emeter_realtime.current if ch.emeter_realtime.current else 0
voltage = ch.emeter_realtime.voltage if ch.emeter_realtime.voltage else 0
power = ch.emeter_realtime.power if ch.emeter_realtime.power else 0
total = ch.emeter_realtime.total if ch.emeter_realtime.total else 0
emeter_today = ch.emeter_today if ch.emeter_today else 0
emeter_this_month = ch.emeter_this_month if ch.emeter_this_month else 0
kasa_current.labels(*labels(ch)).set(current)
kasa_voltage.labels(*labels(ch)).set(voltage)
kasa_power.labels(*labels(ch)).set(power)
kasa_total.labels(*labels(ch)).set(total)
kasa_emeter_today.labels(*labels(ch)).set(emeter_today)
dev_emeter_today += emeter_today
kasa_emeter_this_month.labels(*labels(ch)).set(emeter_this_month)
dev_emeter_this_month += emeter_this_month
kasa_on.labels(*labels(dev)).set(dev.is_on)
kasa_emeter_today.labels(*labels(dev)).set(dev_emeter_today)
kasa_emeter_this_month.labels(*labels(dev)).set(dev_emeter_this_month)
current = dev.emeter_realtime.current if dev.emeter_realtime.current else 0
voltage = dev.emeter_realtime.voltage if dev.emeter_realtime.voltage else 0
power = dev.emeter_realtime.power if dev.emeter_realtime.power else 0
total = dev.emeter_realtime.total if dev.emeter_realtime.total else 0
kasa_current.labels(*labels(dev)).set(current)
kasa_voltage.labels(*labels(dev)).set(voltage)
kasa_power.labels(*labels(dev)).set(power)
kasa_total.labels(*labels(dev)).set(total)
if dev.rssi:
kasa_rssi.labels(*labels(dev)).set(dev.rssi)
except Exception as e:
print(f"update error: {e}")
print(traceback.format_exc())
await asyncio.sleep(1)
@app.route('/metrics')
def metrics():
return Response(prometheus_client.generate_latest(REGISTRY), mimetype="text/plain")
if __name__ == "__main__":
from waitress import serve
update_thread = threading.Thread(target=asyncio.run, args=(update_metrics(),))
update_thread.start()
serve(app, host='0.0.0.0', port=9100)
|