简体   繁体   中英

Run paho mqtt client loop_forever

I am trying to run the following code on loop continuously. But the following code only runs once and takes only one message entry.

What ia trying to do inside the on_message function is run a cron task using python apscheduler.

def on_message(mqttc, obj, msg):
        global val
        val = str(msg.payload)
        print val
        dow = val[0:3]
        print dow
        hr = val[4:6]
        print hr
        min = val[7:9]
        print min
        status = val[10:11]
        print status
        def plugON():
                publish.single("plug/status","0", hostname="localhost")
        def plugOFF():
                publish.single("plug/status","1", hostname="localhost")
        def cronon():
                print "cron on"
        def cronoff():
                print "cron off"
        if status == '0':
                sched.add_job(plugON, trigger='cron', year='*', month='*', day='*', week='*', day_of_week=dow, hour=hr, minute=min, id='plugon')
                sched.add_job(cronon, trigger='cron', year='*', month='*', day='*', week='*', day_of_week=dow, hour=hr, minute=min)

        if status == '1':
                sched.add_job(plugOFF, trigger='cron', year='*', month='*', day='*', week='*', day_of_week=dow, hour=hr, minute=min, id='plugoff')
                sched.add_job(cronoff, trigger='cron', year='*', month='*', day='*', week='*', day_of_week=dow, hour=hr, minute=min)

        sched.start()

The mqtt connect script:

mqttc = mqtt.Client()
mqttc.on_message = on_message
mqttc.on_connect = on_connect
mqttc.on_publish = on_publish
mqttc.on_subscribe = on_subscribe
mqttc.connect("localhost", 1883, 60)
mqttc.subscribe("plug/#", 0)

#mqtt loop
mqttc.loop_forever()

during the execution, it connects to localhost, takes a single entry. On sending something like thu:05:47:0 , waits till the 5:47 to run plugON/plugOFF. At 5:47 it runs the function and disconnects with the localhost.

How can i get my code to take another entry and continue loop?

a few issues.

you have not detailed which version of python, apscheduler, mqtt and you have omitted your imports and some useful functions for troubleshooting like on_connect

so testing this on python3 and apscheduler3.2 i think that you;

  1. you are using BlockingScheduler instead of BackgroundScheduler (this is likely why seeing it all halt on the first msg). the bgscheduler will not stop and wait for the event.
  2. you are starting the scheduler in your function, do this once when you declare sched. you can add_job later no worries.
  3. you have not declared sched (or you cut it our of your paste)
  4. you failed to call publish correctly with your declared mqtt instance. or your doing something else that i cant see in your pasted code.
  5. paho publish has no method called 'single'?
  6. your static id on the add_job will cause you issues scheduling a second job. you will throw an exception from id being reused. but i dont know the details of your use.

if you are using aps<3 then looking at this you should be able to set standalone=false

The concept of “standalone mode” is gone. For standalone=True, use BlockingScheduler instead, and for standalone=False, use BackgroundScheduler. BackgroundScheduler matches the old default semantics.

#!/usr/bin/env python
import paho.mqtt.client as mqtt
#from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.schedulers.background import BackgroundScheduler

# Start the scheduler
sched = BackgroundScheduler()
sched.start()

def on_message(mqttc, obj, msg):
        global val
        val = str(msg.payload.decode('utf-8'))
        dow = val[0:3]
        hr = val[4:6]
        minu = val[7:9]
        status = val[10:11]

        print(str(val) +" "+ dow +" "+ hr +" "+ minu +" "+ status)

        def plugON():
                mqttc.publish("plug/status","0")
        def plugOFF():
                mqttc.publish("plug/status","1")
        def cronon():
                print("cron on")
        def cronoff():
                print("cron off")

        try:
                if status == '0':
                        sched.add_job(plugON, trigger='cron', year='*', month='*', day='*', week='*', day_of_week=dow, hour=hr, minute=minu, id='plugon')
                        sched.add_job(cronon, trigger='cron', year='*', month='*', day='*', week='*', day_of_week=dow, hour=hr, minute=minu)

                if status == '1':
                        sched.add_job(plugOFF, trigger='cron', year='*', month='*', day='*', week='*', day_of_week=dow, hour=hr, minute=minu, id='plugoff')
                        sched.add_job(cronoff, trigger='cron', year='*', month='*', day='*', week='*', day_of_week=dow, hour=hr, minute=minu)
        except:
                print("whoops")
                sched.print_jobs()




mqttc = mqtt.Client()
mqttc.on_message = on_message
#mqttc.on_connect = on_connect
#mqttc.on_publish = on_publish
#mqttc.on_subscribe = on_subscribe
mqttc.connect("local", 1883, 60)
mqttc.subscribe("plug/#")

#mqtt loop
mqttc.loop_forever()

code TESTED as working on python3.5.2 and apschedulerv3.2 and paho-mqttv1.2

TL:DR

  • you are using apsheduler in blocking mode
  • you are starting the scheduler on every on_message call

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM