Search code examples
pythontimermqttgpio

Receive a message from mqtt whilst simultaneously using a timer


The project needs to have the light come on, and stay on 5 minutes after the last "ON" signal given by a motion sensor. My main problem is the logic in receiving the on message while in a loop to restart the timer, kinda new to python so here's what I've got so far:

import paho.mqtt.client as mqtt
import time
import RPi.GPIO as GPIO
import time


GPIO.setmode(GPIO.BCM)

GPIO.setwarnings(False)
GPIO.setup(13,GPIO.OUT)

def on_connect(client, userdata, flags, rc):
     print("Connected with result code "+str(rc))
     client.subscribe("Garage/Outside/+/PIR")

def on_message(client, userdata, msg):
     if msg.payload.decode() == "ON":
          GPIO.output(13,GPIO.HIGH)
          print("Light is on")
          startTime = time.perf_counter()
     endTime = startTime
     while True:
          print(endTime, startTime)
          endTime += 1
          time.sleep(1)
          if endTime - startTime >= 60:
               GPIO.output(13,GPIO.LOW)
               print("Light is off")

client = mqtt.Client()
client.connect("192.168.0.160",1883,60)

client.on_connect = on_connect
client.on_message = on_message



client.loop_forever()

Solution

  • You can not make blocking calls in the on_message callback, this function needs to return as soon as possible to allow the MQTT client to continue to receive messages and to handle pings to/from the broker.

    If you want to do long running tasks as the result of a received message then you need to run that task on a separate thread.

    So you need to move the while True: loop needs to be moved.