Blog der Heimetli Software AG

Temperatur in Thingspeak

Thingspeak ist ein Online-Service mit dem man sehr einfach ein Dashboard erstellen kann. Sofern der Account nicht kommerziell genutzt wird, bekommt anscheinend jeder einen Gratis-Account.

Mit wenigen Klicks erstellt man ein Dashboard mit einem Liniendiagramm und einer runden Anzeige.

Thingspeak Dashboard

Selbstverständlich ist die Darstellung nicht wirklich flexibel, aber man kann doch einige Optionen setzen. Es ist auch möglich eine Graphik mit Matlab zu erstellen, aber das habe ich nicht genauer angesehen.

Die Thingspeak-API

Die Thingspeak-API könnte nicht einfacher sein. Schon ein simples HTTP GET reicht aus um Messwerte in Thingspeak zu laden. Wer will, kann auch ein POST verwenden, aber warum kompliziert wenn es auch einfach geht?

Die Feldnamen sind allerding fest vorgeschrieben, daran kann man nichts ändern.

Der Sensor

Als Sensor diente ein DS18S20. Das ist die Billigversion eines DS18B20. Der war gterade verfügbar, ein besserer Sensor war nicht auf Lager...

Der DS18S20 hat per Default nur eine Auflösung von 9 Bits, der DS18B20 dagegen 12 Bit. Softwaremässig sind die beiden bis auf die Kennung zum Glück kompatibel. Der DS18S20 hat eine Kennung die mit 10- startet, während der DS18B20 mit 28- beginnt.

Die Schaltung

Der Sensor war an einen Raspberry Pi angeschlossen, mit der üblichen Schaltung wie man sie überall im Internet findet. Ich habe den Sensor mit 3.3V betrieben und nicht mit der parasitären Speisung. Als Pullup diente ein Widerstand mit 4.7 kOhm.

Das Script

#!/usr/bin/python3

import time
import sys
import requests

# Path to the sensor data
SENSOR = "/sys/bus/w1/devices/10-00080316317a/w1_slave"

# Write key for thingspeak
KEY = "8NB4M6SP17E47L1S"

def read_sensor( filename ):
    """Reads the sensor and returns its value.

    When the read fails it is retried two times.
    After that, the function prints a message to stderr
    and returns None.
    """

    for i in range(3):
        try:
            with open(filename) as f:
                lines = f.readlines()
            if (len(lines) == 2) and ("YES" in lines[0]):
                tokens = lines[1].split( "t=" )
                if len(tokens) == 2:
                    return float(tokens[1].strip()) / 1000
        except:
            time.sleep( 1 )

    print( "Read failed", file=sys.stderr, flush=True )
    return None

def update_channel( temperature, key ):
    """Updates the thingspeak channel.

    If that fails, a message is printed to stderr.
    """

    try:
        url      = f"https://api.thingspeak.com/update?api_key={key}&field1={temperature}"
        response = requests.get( url )

        if response.status_code != 200:
            print( f"Update returned {response.status_code}", file=sys.stderr, flush=True )
    except Exception as ex:
        print( f"Update failed: {ex}", file=sys.stderr, flush=True )

def main():
    """Reads the sensor every 5 minutes and updates the thingspeak channel"""

    while True:
        temperature = read_sensor( SENSOR )

        print( temperature )

        if temperature != None:
            update_channel( temperature, KEY )

        time.sleep( 300 )

if __name__ == "__main__":
    main()