Measure Humidity and Temperature at home with Phidgets and Prometheus (2024-01-05)

Here is how to build a Prometheus Dashboard showing the temperature and humidity of your home. This project leverages Phidgets (single-board computer + sensors) and another box running Debian.

Hardware

  1. Phidgets Humidity/Temperature Sensor - the sensor that will measure temperature and humidity
  2. PhidgetSBC4 - an armhf Debian Bullseye running on a tiny Allwinner A20 Dual-Core ARM Cortex-A7

Python packages

  • flask
  • prometheus_client
  • Phidget22

Run

The prom.py file stitches the Promethous gauge and the Phidgets libraries. This exposes a /metrics endpoint from where a Prometheus server can scrape metrics.

#!/usr/bin/env python3

import os
import sys
import time

from flask import Flask, jsonify, request
from prometheus_client import make_wsgi_app, Counter, Histogram, Gauge
from werkzeug.middleware.dispatcher import DispatcherMiddleware

from Phidget22.Phidget import *
from Phidget22.Devices.VoltageRatioInput import *

loc = os.environ.get("LOCATION")
if loc is not None:
    print("LOCATION:", loc)
else:
    print("LOCATION env var is not set. Create .env and add 'export LOCATION=xyz'")
    sys.exit(1)

phidgets_serial = os.environ.get("PHIDGETS_SERIAL")
if phidgets_serial is not None:
    print("PHIDGETS_SERIAL:", phidgets_serial)
else:
    print("PHIDGETS_SERIAL env var is not set. Create .env and add 'export PHIDGETS_SERIAL=123'")
    sys.exit(1)

app = Flask(__name__)

app.wsgi_app = DispatcherMiddleware(app.wsgi_app, {
    '/metrics': make_wsgi_app()
})

labels = [loc]

TEM_GAUGE = Gauge('temperature_gauge', 'Temperature', ['symbol', 'location'])
HUM_GAUGE = Gauge('humidity_gauge', 'Humidity', ['symbol', 'location'])
TEM_HIST = Histogram('temperature_histogram', 'Temperature', ['symbol', 'location'])
HUM_HIST = Histogram('humidity_histogram', 'Humidity', ['sybmol', 'location'])

@app.route('/')
def index():
    return redirect('/metrics')

def onTempChange(self, sensorValue, sensorUnit):
    temperature = sensorValue
    symbol = sensorUnit.symbol

    # sensorUnit.symbol for temperature sensor is "°C"
    # we are converting the temperature - so we rewrite symbol to "°F"
    temperature = (temperature * 9/5) + 32
    symbol = "°F"

    TEM_HIST.labels(symbol, loc).observe(temperature)
    TEM_GAUGE.labels(symbol, loc).set(temperature)

def onHumidityChange(self, sensorValue, sensorUnit):
    HUM_HIST.labels(sensorUnit.symbol, loc).observe(sensorValue)
    HUM_GAUGE.labels(sensorUnit.symbol, loc).set(sensorValue)

if __name__ == '__main__':
    voltageRatioInput0 = VoltageRatioInput()
    voltageRatioInput1 = VoltageRatioInput()

    voltageRatioInput0.setIsHubPortDevice(True)
    voltageRatioInput0.setHubPort(0)
    voltageRatioInput0.setDeviceSerialNumber(int(phidgets_serial))

    voltageRatioInput1.setIsHubPortDevice(True)
    voltageRatioInput1.setHubPort(1)
    voltageRatioInput1.setDeviceSerialNumber(int(phidgets_serial))

    voltageRatioInput0.setOnSensorChangeHandler(onTempChange)
    voltageRatioInput1.setOnSensorChangeHandler(onHumidityChange)

    voltageRatioInput0.openWaitForAttachment(5000)
    voltageRatioInput1.openWaitForAttachment(5000)

    # Sensor Types: SENSOR_TYPE_1125_HUMIDITY, SENSOR_TYPE_1125_TEMPERATURE
    voltageRatioInput0.setSensorType(VoltageRatioSensorType.SENSOR_TYPE_1125_TEMPERATURE)
    voltageRatioInput1.setSensorType(VoltageRatioSensorType.SENSOR_TYPE_1125_HUMIDITY)

    app.run(host='0.0.0.0', port=5000)

    voltageRatioInput0.close()
    voltageRatioInput1.close()

Prometheus

Prometheus is a free software application used for event monitoring and alerting. Install it on a server (more powerful than the Phidgets SBC), which is on the same network (tailscale) as your Phidgets SBC. This machine will be performing periodic HTTP GET calls to the Phidgets SBC box.

  1. Install Prometheus
  2. Configure it:
$ cat /etc/prometheus/prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s
scrape_configs:
  - job_name: "prometheus"
    static_configs:
      - targets:
        - 1.2.3.4:5000  ### This is your PhidgetSBC IP address here!
  1. Connect to the Prometheus server: http://your-prometheus-server:9090/
  2. Query for Humidity and Temperature