Can someone help me on that ? I try to break a timelapse (written as looping a function) on my RPI started with a message "StartScanning", by receiving a "Quit" message. I am sorry for my knowledge on programming, but I am really stuck at this last step! Here the code block of the subscriber ( which is the RPI and its PiCamera )
import time
import paho.mqtt.client as mqtt
from time import sleep
from datetime import datetime, timedelta
from picamera import PiCamera
import subprocess
import pathlib
import socket
camera = PiCamera()
Broker = "192.168.1.100"
Port = 1883
# topics
pub_topic = "DIC/scanning"
sub_topic = "DIC/keyboard"
# on connect
def on_connect(mqttc, obj, flags, reason_code):
print(f"rc :" + str(reason_code))
mqttc.subscribe(sub_topic)
# on message
def on_message(mqttc, obj, msg):
print(str(msg.topic) + " " + str(msg.qos) + " " + str(msg.payload))
if msg.payload.decode() == "StartScanning":
while True:
timelapse()
elif msg.payload.decode() == "Quit" :
timelapse.hasbeencalled=False
#fonction scanning avec timelapse
def timelapse():
hostName = socket.gethostname()
pathlib.Path('/home/pi/Desktop/DIC_' + hostName).mkdir(parents=True,exist_ok=True)
fileName= datetime.now().strftime("%Y%m%d_%H-%M-%S-%f")+".jpg"
camera.resolution = (2592, 1944) #picture resolution
camera.capture('/home/pi/Desktop/DIC_' + hostName + '/' + fileName)
#camera.capture('/home/pi/Desktop/DIC_RPI1/RPI1_' + fileName)
sleep(1)
#on subscribe
def on_subscribe(mqttc, obj, mid, reason_code_list):
print("Subscribed: " + str(mid) + " " + str(reason_code_list))
#on log
def on_log(mqttc, obj, level, string):
print(string)
# on publish
def on_publish(mqttc, obj, mid):
print(f"risposta inviata con message id:" + str(mid))
# connect MQTT client
mqttc = mqtt.Client() #(mqtt.CallbackAPIVersion.VERSION1)
mqttc.on_subscribe = on_subscribe
mqttc.on_connect = on_connect
mqttc.on_message = on_message
mqttc.on_publish = on_publish
mqttc.connect("192.168.1.100", 1883, 60)
#mqttc.subscribe(sub_topic)
mqttc.loop_forever()
I tried to insert inside the function timelapse() a ' while msg.payload=="StartScanning": ' but it didn't work. I also tried to publish the 2 messages "StartScanning" and "Quit" on two topics and subscribe o them, but since the loop function runs, I can't receive other message from a publisher.
while True
(or any long-running code) blocks your code and it can't get messages.
You have to run timelapse
(with while
-loop) in separate thread
, and it needs queue
to get messages which can control while
-loop
def timelapse(queue):
while True:
if not queue.empty():
message = queue.get()
if message == 'quit':
break # exit `while`-loop and finish thread
# ... your code ...
sleep(1)
if msg.payload.decode() == "StartScanning":
global queue # inform function that it has to keep it as global variable
queue = queue.Queue()
thread.Thread(targe=timelapse, args=(queue,) ).start() # it has to be comma in `(queue,)`
if msg.payload.decode() == "Quit":
queue.put('quit')