2022年12月27日 星期二

MQTT and Python For Beginners -Subscribing To Topics (訂閱主題)

 MQTT and Python For Beginners -Tutorials

源自於 http://www.steves-internet-guide.com/into-mqtt-python-client/

Subscribing To Topics (訂閱主題)

To subscribe to a topic you use the subscribe method of the Paho MQTT Class object.

The subscribe method accepts 2 parameters – A topic or topics and a QOS (quality of Service) as shown below with their default values.

subscribe(topic, qos=0)


We will now subscribe to topics and in this example we will subscribe to the topic house/bulb1 which is also the same topic that I’m publishing on.

Doing this lets us see the messages we are publishing but we will need to subscribe before we publish.

So our script outline becomes.

  1. Create new client instance
  2. Connect to broker
  3. Subscribe to topic
  4. Publish message

Our new example script is shown below, and I have inserted some print statements to keep track of what is being done.


import paho.mqtt.client as mqtt #import the client1
broker_address="192.168.1.184" 
#broker_address="iot.eclipse.org"
print("creating new instance")
client = mqtt.Client("P1") #create new instance
print("connecting to broker")
client.connect(broker_address) #connect to broker
print("Subscribing to topic","house/bulbs/bulb1")
client.subscribe("house/bulbs/bulb1")
print("Publishing message to topic","house/bulbs/bulb1")
client.publish("house/bulbs/bulb1","OFF")

If we run the script this is what we see:




import paho.mqtt.client as mqtt #import the client1

broker_address="broker.hivemq.com" 

#broker_address="iot.eclipse.org"

print("creating new instance")

client = mqtt.Client("P1") #create new instance

print("connecting to broker")

client.connect(broker_address) #connect to broker

print("Subscribing to topic","house/bulbs/bulb1")

client.subscribe("house/bulbs/bulb1")

print("Publishing message to topic","house/bulbs/bulb1")

client.publish("house/bulbs/bulb1","OFF")


>>> %Run Beginners_2.py
creating new instance
connecting to broker
Subscribing to topic house/bulbs/bulb1
Publishing message to topic house/bulbs/bulb1

where is the message that I published?
看不到發行的訊息

所以要callback 

When a client subscribes to a topic it is basically telling the broker to send messages to it that are sent to the broker on that topic.

The broker is ,in effect, publishing messages on that topic.

When the client receives messages it generate the on_message callback.

To view those messages we need to activate and process the on_message callback.

However at this stage it may be better to just accept them and proceed with the script.

To process callbacks you need to:

  1. Create callback functions to Process any Messages
  2. Start a loop to check for callback messages.

The client docs describe the on_message callback and the parameters it excepts.

Here is my callback function, which basically just prints the received messages:

def on_message(client, userdata, message):
    print("message received " ,str(message.payload.decode("utf-8")))
    print("message topic=",message.topic)
    print("message qos=",message.qos)
    print("message retain flag=",message.retain)

Note the message parameter is a message class with members topic, qos, payload, retain.

I.e message.topic will give you the topic.

Now we need to attach our callback function to our client object as follows:

client.on_message=on_message        #attach function to callback

and finally we need to run a loop otherwise we won’t see the callbacks. The simplest method is to use loop_start() as follows.

client.loop_start()    #start the loop

We also need to stop the loop at the end of the script (loop_stop()), and in addition wait a little to give the script time to process the callback, which we accomplish using the time.sleep(4) function.

This what our completed example script now looks like:


import paho.mqtt.client as mqtt #import the client1
import time
############
def on_message(client, userdata, message):
    print("message received " ,str(message.payload.decode("utf-8")))
    print("message topic=",message.topic)
    print("message qos=",message.qos)
    print("message retain flag=",message.retain)
########################################
broker_address="192.168.1.184"
#broker_address="iot.eclipse.org"
print("creating new instance")
client = mqtt.Client("P1") #create new instance
client.on_message=on_message #attach function to callback
print("connecting to broker")
client.connect(broker_address) #connect to broker
client.loop_start() #start the loop
print("Subscribing to topic","house/bulbs/bulb1")
client.subscribe("house/bulbs/bulb1")
print("Publishing message to topic","house/bulbs/bulb1")
client.publish("house/bulbs/bulb1","OFF")
time.sleep(4) # wait
client.loop_stop() #stop the loop

If you run the script you should see the following


import paho.mqtt.client as mqtt #import the client1
import time
############
def on_message(client, userdata, message):
    print("message received " ,str(message.payload.decode("utf-8")))
    print("message topic=",message.topic)
    print("message qos=",message.qos)
    print("message retain flag=",message.retain)
########################################
broker_address="broker.hivemq.com"
#broker_address="iot.eclipse.org"
print("creating new instance")
client = mqtt.Client("P1") #create new instance
client.on_message=on_message #attach function to callback
print("connecting to broker")
client.connect(broker_address) #connect to broker
client.loop_start() #start the loop
print("Subscribing to topic","house/bulbs/bulb1")
client.subscribe("house/bulbs/bulb1")
print("Publishing message to topic","house/bulbs/bulb1")
client.publish("house/bulbs/bulb1","OFF")
time.sleep(4) # wait
client.loop_stop() #stop the loop

>>> %Run Beginners_4.py
creating new instance
connecting to broker
Subscribing to topic house/bulbs/bulb1
Publishing message to topic house/bulbs/bulb1
message received  OFF
message topic= house/bulbs/bulb1
message qos= 0
message retain flag= 0
>>> 



沒有留言:

張貼留言

Messaging API作為替代方案

  LINE超好用功能要沒了!LINE Notify明年3月底終止服務,有什麼替代方案? LINE Notify將於2025年3月31日結束服務,官方建議改用Messaging API作為替代方案。 //CHANNEL_ACCESS_TOKEN = 'Messaging ...