简体   繁体   中英

Python paho MQTT Client not recieving Messages as expected

Hello I'm new to IOT and trying to create a simulated device which sends the temperature data to IoT Edge Device. Temperature sensor is sending data after 4 seconds, and the data is published to IoT Device "refine-data", What I want is to collect published data in Edge device, remove duplicate data and republish this data to IoT Hub Device where I'll save the messages to Blob Storage as Json. I've been following many blogs/GitHub Repos to achieve my goal as I'm new to IoT. I have three file "publish_mqtt.py", "receive_mqtt.py" and "helper.py" as follows

helper.py

# Python 2.7 Sas generator https://azure.microsoft.com/en-us/documentation/articles/iot-hub-sas-tokens/#comments/

import base64
import hmac
import urllib.parse
import time

class Helper():

    hubAddress, hubName, SharedAccessKey = ['','','']

    endpoint, hubUser, hubTopicPublish, hubTopicSubscribe = ['','','','']

    def __init__(self, hubAddress, hubName, SharedAccessKey):
        self.hubAddress = hubAddress
        self.hubName = hubName
        self.SharedAccessKey = SharedAccessKey

        self.endpoint = hubAddress + '/devices/' + hubName
        self.hubUser = hubAddress + '/' + hubName
        self.hubTopicPublish = 'devices/' + hubName + '/messages/events/'
        self.hubTopicSubscribe = 'devices/' + hubName + '/messages/#'


    # sas generator from https://github.com/bechynsky/AzureIoTDeviceClientPY/blob/master/DeviceClient.py
    def generate_sas_token(self, uri, key, expiry=3600):
        ttl = int(time.time()) + expiry
        urlToSign = urllib.parse.quote(uri, safe='') 
        sign_key = "%s\n%d" % (urlToSign, int(ttl))
        h = hmac.new(base64.b64decode(key), msg = "{0}\n{1}".format(urlToSign, ttl).encode('utf-8'),digestmod = 'sha256')
        signature = urllib.parse.quote(base64.b64encode(h.digest()), safe = '')
        return "SharedAccessSignature sr={0}&sig={1}&se={2}".format(urlToSign, urllib.parse.quote(base64.b64encode(h.digest()), safe = ''), ttl)

publish_mqtt.py

# https://azure.microsoft.com/en-us/documentation/articles/iot-hub-mqtt-support/
# http://stackoverflow.com/questions/35452072/python-mqtt-connection-to-azure-iot-hub/35473777
# https://azure.microsoft.com/en-us/documentation/samples/iot-hub-python-get-started/


# Mqtt Support https://www.eclipse.org/paho/clients/python/
# pip3 install paho-mqtt

# Weather data Open Weather Map using https://github.com/csparpa/pyowm
# pip3 install pyowm

import paho.mqtt.client as mqtt
import time
import helper
import sys
import json

sensor = hubAddress = deviceId = sharedAccessKey = owmApiKey = owmLocation = None

def config_load():
    global sensor, hubAddress, deviceId, sharedAccessKey, owmApiKey, owmLocation
    print('Loading default config settings')

    import sensor_openweather as sensor
    hubAddress = 'test-iot-hub-007.azure-devices.net'
    deviceId = 'refine-data'
    sharedAccessKey= 'iPap+QGyxif9AcYTv7FALlN1QoqyH831tvGTEIDUf+s='
    owmApiKey = '1dc59d7c0b60ed24edacfa27536235c3'
    owmLocation = 'Melbourne, AU'
def on_connect(client, userdata, flags, rc):
    print("Connected with result code: %s" % rc)
    client.subscribe(help.hubTopicSubscribe)

def on_disconnect(client, userdata, rc):
    print("Disconnected with result code: %s" % rc)
    client.username_pw_set(help.hubUser, help.generate_sas_token(help.endpoint, sharedAccessKey))

def on_message(client, userdata, msg):
    print("Messgae recieved - {0} - {1} ".format(msg.topic, str(msg.payload)))
    # Do this only if you want to send a reply message every time you receive one
    # client.publish("devices/mqtt/messages/events", "REPLY", qos=1)

def on_publish(client, userdata, mid):
    print("Message {0} sent from {1}".format(str(mid), deviceId))

def publish():
    while True:
        try:
            client.publish(help.hubTopicPublish, mysensor.measure())            
            time.sleep(4)
        
        except KeyboardInterrupt:
            print("IoTHubClient sample stopped")
            return

        except:
            print("Unexpected error")
            time.sleep(4)

config_load()

mysensor = sensor.Sensor(owmApiKey, owmLocation)
help = helper.Helper(hubAddress, deviceId, sharedAccessKey)

client = mqtt.Client(deviceId, mqtt.MQTTv311)

client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_message = on_message
client.on_publish = on_publish

client.username_pw_set(help.hubUser, help.generate_sas_token(help.endpoint, sharedAccessKey))

#client.tls_set("/etc/ssl/certs/ca-certificates.crt") # use builtin cert on Raspbian
client.tls_set("baltimorebase64.cer") # Baltimore Cybertrust Root exported from Windows 10 using certlm.msc in base64 format
client.connect(hubAddress, 8883)

client.loop_start()

publish()

receive_mqtt.py

# https://azure.microsoft.com/en-us/documentation/articles/iot-hub-mqtt-support/
# http://stackoverflow.com/questions/35452072/python-mqtt-connection-to-azure-iot-hub/35473777
# https://azure.microsoft.com/en-us/documentation/samples/iot-hub-python-get-started/


# Mqtt Support https://www.eclipse.org/paho/clients/python/
# pip3 install paho-mqtt

# Weather data Open Weather Map using https://github.com/csparpa/pyowm
# pip3 install pyowm

import paho.mqtt.client as mqtt
import time
import helper
import sys
import json
sensor = hubAddress = deviceId = sharedAccessKey = owmApiKey = owmLocation = None

def config_load():
    global sensor, hubAddress, deviceId, sharedAccessKey, owmApiKey, owmLocation
    print('Loading default config settings')
    hubAddress = 'test-iot-hub-007.azure-devices.net'
    deviceId = 'refine-data'
    sharedAccessKey= 'iPap+QGyxif9AcYTv7FALlN1QoqyH831tvGTEIDUf+s='

def on_connect(client, userdata, flags, rc):
    print("Connected with result code: %s" % rc)
    client.subscribe(help.hubTopicSubscribe)

def on_disconnect(client, userdata, rc):
    print("Disconnected with result code: %s" % rc)
    client.username_pw_set(help.hubUser, help.generate_sas_token(help.endpoint, sharedAccessKey))
def on_message(client, userdata, msg):
    print("received message =", str(msg.payload.decode()))
config_load()

help = helper.Helper(hubAddress, deviceId, sharedAccessKey)

client = mqtt.Client(deviceId, mqtt.MQTTv311)

client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_message = on_message
client.username_pw_set(help.hubUser, help.generate_sas_token(help.endpoint, sharedAccessKey))
#client.tls_set("/etc/ssl/certs/ca-certificates.crt") # use builtin cert on Raspbian
client.tls_set("baltimorebase64.cer") # Baltimore Cybertrust Root exported from Windows 10 using certlm.msc in base64 format
client.connect(hubAddress, 8883)
client.loop_forever()

The publish script works fine and I can see the out put by monitoring the IoT (Monitor-Events).

codingtron@ubuntu:~/Projects/iothub-new-py/weather_mqtt$ az iot hub monitor-events --output table --hub-name test-iot-hub-007 
Starting event monitor, use ctrl-c to stop...
 

event:   origin: refine-data   payload: '{"Geo":"Melbourne, AU","Humidity":87,"HPa":1011,"Celsius": 19.00,"Light":0,"Id":9}'

event:   origin: refine-data   payload: '{"Geo":"Melbourne, AU","Humidity":87,"HPa":1011,"Celsius": 19.00,"Light":0,"Id":10}'

event:   origin: refine-data   payload: '{"Geo":"Melbourne, AU","Humidity":87,"HPa":1011,"Celsius": 19.00,"Light":0,"Id":11}'

Now the problem is that i don't receive any messages when i run python3 receive_mqtt.py It stucked on "connected with code 0" and continue waiting.

It should prints the message send by publish script.

Can someone please help identifying the issue I'm heading my mind from last 7 days on this. Thank you.

As hardillb said, you cant have multiple clients using same client ID connected to same broker. This creates the inter dependency and will end up in infinite loop situation.

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