bundles/mosquitto: rewrite tasmota-telegraf-plugin using paho-mqtt library
All checks were successful
bundlewrap/pipeline/head This commit looks good

This commit is contained in:
Franzi 2021-06-06 15:17:34 +02:00
parent fa4fe51155
commit 94dba9139b
Signed by: kunsi
GPG key ID: 12E3D2136B818350
3 changed files with 81 additions and 41 deletions

View file

@ -1,53 +1,84 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from json import loads from json import loads
from subprocess import Popen, PIPE from os import getpid
from sys import argv, stderr from sys import argv, stderr
from time import sleep from time import sleep
while True: import paho.mqtt.client as mqtt
BROKER_HOST = argv[1]
BROKER_TOPIC = argv[2]
def log(msg):
print(msg, file=stderr, flush=True)
def out(msg):
print(msg, flush=True)
def on_connect(client, userdata, flags, rc):
log(f'connected to mqtt broker at {BROKER_HOST} with status: {mqtt.connack_string(rc)}')
client.subscribe(BROKER_TOPIC)
def on_disconnect(client, userdata, rc):
log(f'disconnected from mqtt broker at {BROKER_HOST} with status: {mqtt.error_string(rc)}')
def on_message(client, userdata, msg):
try: try:
proc = Popen(['mosquitto_sub', '-h', argv[1], '-v', '-t', argv[2]], stdout=PIPE) message = msg.payload.decode()
while True: if not any(message.startswith(i) for i in ['{', '[']):
try: # probably not json
line = proc.stdout.readline().decode().strip() return
if not line: json = loads(message)
continue topic_split = msg.topic.strip('/').split('/')
sensor_name = '_'.join(topic_split[:-1])
topic, message = line.split(' ', 1) if topic_split[-1] == 'STATE':
# /switch/wohnzimmer/ambilight/STATE {"Time":"2021-05-15T07:40:16","Uptime":"4T18:48:43","Vcc":3.108,"Heap":19,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"POWER":"OFF","Wifi":{"AP":1,"SSId":"NSA Surveillance Van 2342","BSSId":"DA:CC:46:87:58:F7","Channel":6,"RSSI":100,"LinkCount":2,"Downtime":"0T00:00:27"}}
power_state = bool(json['POWER'] == 'ON')
out(f'tasmota,device={sensor_name} state={power_state}')
out(f'tasmota,device={sensor_name} rssi={json["Wifi"]["RSSI"]}i')
if not any(message.startswith(i) for i in ['{', '[']): if topic_split[-1] == 'SENSOR':
# probably not json # /switch/wohnzimmer/ambilight/SENSOR {"Time":"2021-05-15T07:40:16","ENERGY":{"TotalStartTime":"2019-08-02T13:56:56","Total":2.324,"Yesterday":0.004,"Today":0.000,"Period":0,"Power":0,"ApparentPower":0,"ReactivePower":0,"Factor":0.00,"Voltage":237,"Current":0.000}}
continue out(f'tasmota,device={sensor_name} energy_total={json["ENERGY"]["Total"]}')
out(f'tasmota,device={sensor_name} energy_today={json["ENERGY"]["Today"]}')
json = loads(message) out(f'tasmota,device={sensor_name} energy_yesterday={json["ENERGY"]["Yesterday"]}')
topic_split = topic.strip('/').split('/') out(f'tasmota,device={sensor_name} power={json["ENERGY"]["Power"]}')
sensor_name = '_'.join(topic_split[:-1]) out(f'tasmota,device={sensor_name} apparent_power={json["ENERGY"]["ApparentPower"]}')
out(f'tasmota,device={sensor_name} reactive_power={json["ENERGY"]["ReactivePower"]}')
if topic_split[-1] == 'STATE': out(f'tasmota,device={sensor_name} powerfactor={json["ENERGY"]["Factor"]}')
# /switch/wohnzimmer/ambilight/STATE {"Time":"2021-05-15T07:40:16","Uptime":"4T18:48:43","Vcc":3.108,"Heap":19,"SleepMode":"Dynamic","Sleep":50,"LoadAvg":19,"POWER":"OFF","Wifi":{"AP":1,"SSId":"NSA Surveillance Van 2342","BSSId":"DA:CC:46:87:58:F7","Channel":6,"RSSI":100,"LinkCount":2,"Downtime":"0T00:00:27"}} out(f'tasmota,device={sensor_name} voltage={json["ENERGY"]["Voltage"]}i')
power_state = bool(json['POWER'] == 'ON') out(f'tasmota,device={sensor_name} current={json["ENERGY"]["Current"]}')
print(f'tasmota,device={sensor_name} state={power_state}', flush=True)
print(f'tasmota,device={sensor_name} rssi={json["Wifi"]["RSSI"]}i', flush=True)
if topic_split[-1] == 'SENSOR':
# /switch/wohnzimmer/ambilight/SENSOR {"Time":"2021-05-15T07:40:16","ENERGY":{"TotalStartTime":"2019-08-02T13:56:56","Total":2.324,"Yesterday":0.004,"Today":0.000,"Period":0,"Power":0,"ApparentPower":0,"ReactivePower":0,"Factor":0.00,"Voltage":237,"Current":0.000}}
print(f'tasmota,device={sensor_name} energy_total={json["ENERGY"]["Total"]}', flush=True)
print(f'tasmota,device={sensor_name} energy_today={json["ENERGY"]["Today"]}', flush=True)
print(f'tasmota,device={sensor_name} energy_yesterday={json["ENERGY"]["Yesterday"]}', flush=True)
print(f'tasmota,device={sensor_name} power={json["ENERGY"]["Power"]}', flush=True)
print(f'tasmota,device={sensor_name} apparent_power={json["ENERGY"]["ApparentPower"]}', flush=True)
print(f'tasmota,device={sensor_name} reactive_power={json["ENERGY"]["ReactivePower"]}', flush=True)
print(f'tasmota,device={sensor_name} powerfactor={json["ENERGY"]["Factor"]}', flush=True)
print(f'tasmota,device={sensor_name} voltage={json["ENERGY"]["Voltage"]}i', flush=True)
print(f'tasmota,device={sensor_name} current={json["ENERGY"]["Current"]}', flush=True)
except Exception as e:
if line:
print('parse error while parsing a line:', file=stderr)
print(line, file=stderr)
print(repr(e), file=stderr, flush=True)
except Exception as e: except Exception as e:
print(repr(e), file=stderr, flush=True) log(f'parse error while parsing a message on topic {msg.topic}:')
sleep(10) log(repr(e))
log(repr(msg.payload))
def on_subscribe(client, userdata, mid, granted_qos):
log(f'subscription {mid} was successful')
if __name__ == '__main__':
client = mqtt.Client(
client_id=f'tasmota-telegraf-plugin_{getpid()}'
)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_message = on_message
client.on_subscribe = on_subscribe
client.connect(BROKER_HOST, 1883, 30)
client.loop_forever()

View file

@ -7,6 +7,9 @@ files = {
}, },
'/usr/local/bin/tasmota-telegraf-plugin': { '/usr/local/bin/tasmota-telegraf-plugin': {
'mode': '0755', 'mode': '0755',
'needs': {
'pkg_apt:python3-paho-mqtt',
},
}, },
} }
@ -18,3 +21,8 @@ svc_systemd = {
}, },
}, },
} }
if node.has_bundle('telegraf'):
files['/usr/local/bin/tasmota-telegraf-plugin']['triggers'] = {
'svc_systemd:telegraf:restart',
}

View file

@ -6,6 +6,7 @@ defaults = {
'packages': { 'packages': {
'mosquitto': {}, 'mosquitto': {},
'mosquitto-clients': {}, 'mosquitto-clients': {},
'python3-paho-mqtt': {}, # for telegraf plugin
}, },
}, },
'icinga2_api': { 'icinga2_api': {