Files @ d2da7d83904c
Branch filter:

Location: ChaosStuff/mqtt2prometheus/mqtt2prometheus.py

Dennis Fink
Use try clause around setting values
import json
import time

import paho.mqtt.client as mqtt

from prometheus_client import start_http_server, Gauge

CONFIG = json.load(open("/etc/mqtt2prometheus.json", mode="r", encoding="utf-8"))

people_now_present = Gauge(
    "people_now_present", "People currently present in the space"
)

space_state = Gauge("space_state", "The current space state")
space_lastchange = Gauge(
    "space_lastchange", "The lastchange timestamp of the current space state"
)

member_count = Gauge(
    "member_count", "The current count of members", labelnames=["name"]
)

availability = Gauge(
    "availability",
    "The availability status of different MQTT clients",
    labelnames=["clientname"],
)

temperature = Gauge(
    "temperature_celsius", "The current temperature", labelnames=["location"]
)

humidity = Gauge("humidity_percent", "The current humidity", labelnames=["location"])

barometer = Gauge(
    "barometer_hectopascal", "The current air pressure", labelnames=["location"]
)

power_consumption = Gauge(
    "power_consumption_watt", "The current power used", labelnames=["location"]
)

co2_emission = Gauge(
    "co2_emission_kilogramm", "The CO2 emission in kilogramm", labelnames=["location"]
)

energy_consumption = Gauge(
    "energy_consumption_kilowatthour",
    "The energy consumption in kilowatthour",
    labelnames=["location"],
)


TOPIC_TO_HANDLER = {
    "availability/#": handle_availability,
    "space/status": handle_space_status,
    "space/member_count": handle_member_count,
    "sensors/people_now_present": handle_people_now_present,
    "sensors/temperature/#": handle_temperature,
    "sensors/humidity/#": handle_humidity,
    "sensors/barometer/#": handle_barometer,
    "sensors/power_consumption/#": handle_power_consumption,
    "sensors/co2_emission/#": handle_co2_emission,
    "sensors/energy_consumption/#": handle_energy_consumption,
}


def on_connect(client, userdata, flags, rc):
    client.publish("availability/mqtt2prometheus", "online", 2, True)

    for topic, handler in TOPIC_TO_HANDLER:
        client.message_callback_add(topic, handler)

    for topic in ["availability/#", "space/status", "space/member_count", "sensors/#"]:
        client.subscribe(topic)


def handle_people_now_present(client, userdata, msg):
    people_now_present.set(json.loads(msg.payload))


def handle_space_status(client, userdata, msg):
    state = json.loads(msg.payload)
    space_state.set(int(state["open"]))
    space_lastchange.set(state["lastchange"])


def handle_member_count(client, userdata, msg):
    count = json.loads(msg.payload)
    member_count.labels(count["name"]).set(count["value"])


def handle_availability(client, userdata, msg):
    t = msg.topic.split("/")
    if len(t) == 2:
        c = t[-1]
    else:
        c = "_".join(t[1:])
    v = 1 if msg.payload == b"online" else 0
    availability.labels(c).set(v)


def handle_temperature(client, userdata, msg):
    t = msg.topic.split("/")
    location = "-".join(t[2:])
    try:
        temperature.labels(location).set(float(msg.payload))
    except:
        pass


def handle_humidity(client, userdata, msg):
    t = msg.topic.split("/")
    location = "-".join(t[2:])
    try:
        humidity.labels(location).set(float(msg.payload))
    except:
        pass


def handle_barometer(client, userdata, msg):
    t = msg.topic.split("/")
    location = "-".join(t[2:])
    try:
        barometer.labels(location).set(float(msg.payload))
    except:
        pass


def handle_power_consumption(client, userdata, msg):
    t = msg.topic.split("/")
    location = "-".join(t[2:])
    try:
        power_consumption.labels(location).set(float(msg.payload))
    except:
        pass


def handle_co2_emission(client, userdata, msg):
    t = msg.topic.split("/")
    location = "-".join(t[2:])
    try:
        co2_emission.labels(location).set(float(msg.payload))
    except:
        pass


def handle_energy_consumption(client, userdata, msg):
    t = msg.topic.split("/")
    location = "-".join(t[2:])
    try:
        energy_consumption.labels(location).set(float(msg.payload))
    except:
        pass


def main():

    client = mqtt.Client("mqtt2prometheus")
    client.on_connect = on_connect
    client.username_pw_set(CONFIG["mqtt"]["username"], CONFIG["mqtt"]["password"])
    client.will_set("availability/mqtt2prometheus", "offline", 2, True)

    client.connect(CONFIG["mqtt"]["host"])
    client.loop_start()
    start_http_server(CONFIG["prometheus"]["port"])
    while True:
        time.sleep(1)


if __name__ == "__main__":
    main()