Run paho mqtt client loop_forever
<p>I am trying to run the following code on loop continuously. But the following code only runs once and takes only one message entry. </p>

<p>What i a trying to do inside the on_message function is run a cron task using python apscheduler. </p>

<pre><code>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()
</code></pre>

<p>The mqtt connect script:</p>

<pre><code>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()
</code></pre>

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

<p>How can i get my code to take another entry and continue loop?</p>

<p>a few issues.</p>

<p>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</p>

<p>so testing this on python3 and apscheduler3.2 i think that you;</p>

<ol>
<li>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.</li>
<li>you are starting the scheduler in your function, do this once when you declare sched. you can add_job later no worries.</li>
<li>you have not declared sched (or you cut it our of your paste)</li>
<li>you failed to call publish correctly with your declared mqtt instance. or your doing something else that i cant see in your pasted code.</li>
<li>paho publish has no method called 'single'?</li>
<li>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.</li>
</ol>

<p>if you are using aps&lt;3 then looking at <a href="https://apscheduler.readthedocs.io/en/latest/migration.html" rel="nofollow">this</a> you should be able to set <code>standalone=false</code></p>

<blockquote>
  <p>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.</p>
</blockquote>

<pre><code>#!/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></pre>

<p>code <strong>TESTED</strong> as working on python3.5.2 and apschedulerv3.2 and paho-mqttv1.2</p>

<p><strong>TL:DR</strong></p>

<ul>
<li>you are using apsheduler in blocking mode</li>
<li>you are starting the scheduler on every on_message call</li>
</ul>

python apscheduler