Read Temperature with Python and forward to MQTT

Anybody who wants to read the Temperature and Humidity on his RPI 3 GPIO with OH2 installed.

Thanks to the Python Script from


# Import required Python libraries
import paho.mqtt.client as mqtt
import pigpio
import time
import DHT22

# Define GPIO to use on Pi

print "Temperature Module Test (CTRL-C to exit)"

# Set pin as input


def checkBound(new, prev, maxdiff):
  if ((new < (prev - maxdiff)) or (new > (prev + maxdiff)) ):
    result = True
    result = False
  return result


  #print "  Ready"
  mqttc = mqtt.Client()
  mqttc.connect("", 1883)

  # Loop until users quits with CTRL-C
  while True :

    #print "T:%3.2f TD:%3.2f H:%3.2f HD:%3.2f" % (temp_temp, abs(lastpubtemp-tem
p_temp), temp_humi, abs(lastpubhumi-temp_humi))
    #if ((abs(lastpubtemp-temp_temp) >= 0.1) and (temp_temp > 0.0)):
    if (checkBound(temp_temp,lastpubtemp,0.1) and (temp_temp > 0.0)):
      mqttc.publish("home/temperature", '{:3.2f}'.format(temp_temp), qos=0, retain=True )
      #print "PUB: T:%3.2f TD:%3.2f" % (temp_temp, abs(lastpubtemp-temp_temp))
    #if ((abs(lastpubhumi-temp_humi) >= 0.1) and (temp_humi > 0.0)):
    if (checkBound(temp_humi,lastpubhumi,0.1) and (temp_humi > 0.0)):
      mqttc.publish("home/humidity", '{:3.2f}'.format(temp_humi), qos=0, retain=True )
      #print "PUB: H:%3.2f HD:%3.2f" % (temp_humi, abs(lastpubhumi-temp_humi))

    # Wait for 10 seconds

except KeyboardInterrupt:
  #print "  Quit"

Install pigpio

cd pigpio-master
make -j4
sudo make install

Download DHT22 Python script and add to the same directory like the Python script above:

Add to items/mqtt.items

        "Innen Temperatur [%.1f °C]"

        "Innen Feuchtigkeit [%.1f %%]"

Now run

sudo python

You can enjoy it with homekit too :wink:


Nice write-up.

I did something very similar. I used Adafruit_DHT instead of pigpio. It simplifies the code slightly. I hadn’t realized that the paho.mqtt had a client class. I switched my code over to using that. Not using it causes a TCP connect every time one sends a message (I suspect). I also have a PIR on my Pi that fires an event in my script. I like to keep the lights on when there is someone in the garage, at least after sunset.

I thought this was an interesting article that I thought I might implement: I have heard that the DHT22 can be a little jumpy and this will smooth the numbers.


My script with temperature smoothing (and PIR which is irrelevant to the subject but might be interesting to someone). Some of the code didn’t really appear to format as it was written. Anyway, the smoothing algorithm worked well.

import sys
import signal
import time
import json
import Adafruit_DHT
import RPi.GPIO as GPIO
import paho.mqtt.client as mqtt
from datetime import datetime
print('Version 0.03')   
sensorType = Adafruit_DHT.DHT22
sensorPin = 4                       # Connected to DHT22
occupiedPin = 22                    # LED turned on when motion is detected
unoccupiedPin = 17                  # LED turned on when motion is not detected
motionPin = 12                      # Connected to HC-SR501
mqttServer = "<server>"
mqttTopicPrefix = "State/Garage/{0}"
mqttTopicOccupied = "Occupied"
mqttTopicTemperature = "Temperature"
mqttTopicHumity = "Humidity"
mqttUserId = "<userid>"
mqttPassword = "<password>"
jsonMotion = '{{ "status": {{ "occupied": "{0}", "timestamp": {1} }}}}';                    # JSON for motion
jsonHumidity = '{{ "status": {{ "humidity": {0:0.2f}, "timestamp": {1} }}}}';               # JSON for humidity
jsonTemperature  = '{{ "status": {{ "temperature": {0:0.2f}, "timestamp": {1} }}}}';        # JSON for temperature    
motionStates = [ "OPEN", "CLOSED" ]

mqttc = mqtt.Client()

def getTime():
    # Save a few key strokes
def signalHandler(signal, frame):
    # Clean up on CTRL-C
    print '\r\n' + getTime() + ': Exiting...'
def mqttPublish(topic, msg):
    # Publish to MQTT server
    thisTopic = mqttTopicPrefix.format(topic)
    mqttc.publish(thisTopic, msg)
def motionHandler(channel):
    # Called when motion sensor state changes
    motionValue = GPIO.input(motionPin)
    if (motionValue):
        GPIO.output(occupiedPin, GPIO.HIGH)
        GPIO.output(unoccupiedPin, GPIO.LOW)
        GPIO.output(unoccupiedPin, GPIO.HIGH)
        GPIO.output(occupiedPin, GPIO.LOW)

    msg = jsonMotion.format(motionStates[motionValue], getTime())
        mqttPublish(mqttTopicOccupied, msg)

def smoothTemps(period=10):
    Exponential moving average. Smooths the values over the period.  Send
    in values - at first it'll return a simple average, but as soon as it's
    gathered 'period' values, it'll start to use the Exponential Moving
    Averge to smooth the values.

    period: int - how many values to smooth over (default=1000). 
    Gratitude to Rikard Anglerud -
    multiplier = 2 / float(1 + period)
    cumulative_temp = yield None  # We are being primed

    # Start by just returning the simple average until we have enough data.
    for i in xrange(1, period + 1):
        cumulative_temp += yield cumulative_temp / float(i)

    # Grab the simple average,
    ema = cumulative_temp / period

    # and start calculating the exponentially smoothed average we want.
    while True:
        ema = (((yield ema) - ema) * multiplier) + ema

def CtoF(value):
    return value * 9 / 5.0 + 32
signal.signal(signal.SIGINT, signalHandler)
GPIO.setup(occupiedPin, GPIO.OUT)
GPIO.setup(unoccupiedPin, GPIO.OUT)
GPIO.setup(motionPin, GPIO.IN)
GPIO.add_event_detect(motionPin, GPIO.BOTH, callback=motionHandler)
GPIO.output(unoccupiedPin, GPIO.HIGH)
GPIO.output(occupiedPin, GPIO.LOW)
mqttc.username_pw_set(mqttUserId, mqttPassword)
mqttc.connect(mqttServer, 1883)

# Initialize and prime the temperature value smoother
st = smoothTemps()

while True:
    humidity, temperature = Adafruit_DHT.read_retry(sensorType, sensorPin)
    if humidity is not None and temperature is not None:
        temperature = CtoF(st.send(temperature))
        timestamp = getTime()
        msg = jsonHumidity.format(humidity, timestamp)
        mqttPublish(mqttTopicHumity, msg)
        msg = jsonTemperature.format(temperature, timestamp)
        mqttPublish(mqttTopicTemperature, msg)
        print(getTime() + ': Error - Failed to get reading')
    time.sleep(60 * 10)     # Every ten minutes


I will try ro build on weekend Leds under my bed with PIR which should turn on if it detects my feeds. The LEDs will be SK6812 with Warmwhite LED and RGB.

If somebody interested we can build together.

EDIT: It will run over an ESP8266 -> MQTT -> OH2

1 Like

Hmm, I used LinkSprite based ESP8266 with a HC-SR501 motion sensor. I used that particular board because it has a +5v out which is required by that particular sensor. Unfortunately I found that it threw a lot of false positives and I ended up replacing it with a Raspberry Pi. Let me know if you have better success.

HI, I have tried with your code and can’t run with below error,
I have tried either python 2.7 or python 3 all fail

with python 2.7 : sudo python
File “”, line 74
cumulative_temp = yield None # We are being primed

with python 3:sudo python3
File “”, line 37
print ‘\r\n’ + getTime() + ‘: Exiting…’
SyntaxError: invalid syntax

How am I able to run your code, I believe I have all the required library installed

P.S. after check on, I found it’s due to some spacing in the code, after reformat few line of code, it runs.

Glad you found the issue. Sometimes stuff gets messed up when pasted into this box I am currently typing in. By the way the smoothing value is way too high. It will average the temperatures out over about a week. I should edit that.

oh, I was also wonder why the temp can keep all day almost no change (within 1 degree),
that was the reason,

I modified the post to smooth over ten. I’m at work so I don’t actually remember what value I settled on. Do you have any feedback on a good value for this?

I got this error:

File “”, line 40
SyntaxError: invalid syntax

If you had used my script I would have been able to help you. The only suggestion I have is that the script you copied on line 40 reads:


Note the period after the one.

Do you have a current working version of this script?

Is the version posted above not working? If not then yes I do and can repost.

I tried to remove the format errors but failed.