添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
As part of our work, we need to apply routing queries to the payload receives at IoTHub via MQTT protocol. For that purpose, the properties of payload should be as {'content-encoding': 'utf-8','content_type':'application/json'} . So that we have applied these properties to this payload Payload:{"datetime": "2023-03-30 06:20:30","RaR": 123, "level": 750, "id": "1234"}. Attaching the code snippet.

final_payload={"datetime": "2023-03-30 06:20:30","RaR": 123, "level": 750, "id": "1234"}
publish_properties = props.Properties(PacketTypes.CONNECT)
publish_properties.UserProperty = ("application/json","3")
publish_properties.UserProperty = ("content_encoding", "UTF-8")
client.publish(topic, payload=final_payload, qos=1,properties=publish_properties)

But the properties are not getting applied on the payload. It is not getting filtered out. Please suggest some solution to resolve this issue. Thanks Athira

Hi @Athira Gopinath(UST,IN) Greetings! Thank you for posting the question here on community. Since you are trying to To route messages based on message body, you must first add property 'contentType' (ct) to the end of the MQTT topic and set its value to be application/json;charset=utf-8 as shown in the following example. devices/{device-id}/messages/events/$.ct=application%2Fjson%3Bcharset%3Dutf-8 The IoT Hub documentation provides a sample of Python code demonstrating how to use MQTT protocol. Please refer the following URL -- Use the MQTT protocol directly. Find the below code I have used to publish the data to an IoT device using Python SDK

from paho.mqtt import client as mqtt
import time
import ssl
import base64
import hmac
import hashlib
import urllib
import paho.mqtt.properties as props
from paho.mqtt.packettypes import PacketTypes
path_to_root_cert = "<local path to digicert.cer>"
device_id = "<Device ID>"
endpoint ="<IoT Hub Name>.azure-devices.net/devices/<Device ID>"
deviceKey ="<Device Primary Key>"
def generateSasToken(resource_uri, signing_key, expires_in_mins):
    # Set expiration in seconds
    expires = int(time.time() + expires_in_mins * 60)
    # Use urllib to encode resourceUri 
    encoded_resource_uri = urllib.parse.quote(resource_uri, '')
    # Construct string to sign from joined encoded resourceUri and expiration
    to_sign = encoded_resource_uri + '\n' + str(expires)
    # Sign the string with the signing_key
    signed_hmac_sha256 = hmac.HMAC(base64.b64decode(signing_key), to_sign.encode('utf-8'), hashlib.sha256)
    signature = urllib.parse.quote(base64.b64encode(signed_hmac_sha256.digest()).decode('utf-8'))
    # Construct authorization string
    return "SharedAccessSignature sr={}&sig={}&se={}".format(encoded_resource_uri, signature, expires)
sas_token = generateSasToken(endpoint, deviceKey, 60)
iot_hub_name = "<IoT Hub Name>"
def on_connect(client, userdata, flags, rc):
    print("Device connected with result code: " + str(rc))
def on_disconnect(client, userdata, rc):
    print("Device disconnected with result code: " + str(rc))
def on_publish(client, userdata, mid):
    print("Device sent message")
client = mqtt.Client(client_id=device_id, protocol=mqtt.MQTTv311)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_publish = on_publish
client.username_pw_set(username=iot_hub_name+".azure-devices.net/" +
                       device_id + "/?api-version=2021-04-12", password=sas_token)
client.tls_set(ca_certs=path_to_root_cert, certfile=None, keyfile=None,
               cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)
client.tls_insecure_set(False)
client.connect(iot_hub_name+".azure-devices.net", port=8883)
final_payload = '{"datetime": "2023-03-30 06:20:30", "RaR": 123, "level": 750, "id": "1234"}'
while True:
    print("Publihing data")
    #client.publish("testtopic", '{"id":123}', qos=1)
    client.publish("devices/" + device_id + "/messages/events/$.ct=application%2Fjson%3Bcharset%3Dutf-8", final_payload, qos=1)
    time.sleep(10)    

Please make sure to provide correct IoT Hub name, device ID, device Key to the variables device__id, endpoint, deviceKey, iot_hub___nam_e

  • <local path to digicert.cer> is the path to a local file that contains the DigiCert Baltimore Root certificate. You can create this file by copying the certificate information from certs.c in the Azure IoT SDK for C. Include the lines -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----, remove the " marks at the beginning and end of every line, and remove the \r\n characters at the end of every line.
  • Once you have code running, you could see the value routed to a storage end point has JSON format data. Please find the below image capture from blob storage end point displaying the data in correct format.

    Please let us know if you have any additional questions or run into any issues as you implement the code in the comment below. We would be glad to help you further. If the response helped, please do click Accept Answer and Yes. Doing so would help other community members with similar issue identify the solution. I highly appreciate your contribution to the community.

    Yes, the extra properties must be part of the topic, not part of the user properties. Here is an example written in C#:

    var message = new MqttApplicationMessageBuilder()
        .WithTopic(topics.send_message_topic + "$.ct=application%2Fjson&$.ce=utf-8" + "&a=a1&b=bb2")
        .WithPayload(payloadString)
        .WithQualityOfServiceLevel(MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce)
    .Build();
    

    A full C# example as reference is found here.

    Is this code still correct for the Upcoming Azure IoT Hub Server Certificate Migration to DigiCert Global G2 Root ?

    Or we have to replace <local path to digicert.cer> from DigiCert Baltimore Root certificate to DigiCert Global G2 Root ?

    Best regards

    Hi @Sergi Sanchez I believe you would have to replace the path to the file once the certificate migration is done. But the rest of the code functioning should remain intact. You can report an issue to update the document to reference the correct certification details through the link - Report Issue

    If you face any additional issues with the code, I appreciate it if you can post a new question to address it.

    Hi LeelaRajeshSayana-MSFT,

    But there must be a period where both certificates work.

    We need a period to update our products in the field.

    Thanks

    Check the document for user properties [http://docs.oasis-open.org/mqtt/mqtt/v5.0/cs02/mqtt-v5.0-cs02.html#_Toc514345337] you can use the following

    import paho.mqtt.client as mqtt
    import paho.mqtt.properties as props
    from paho.mqtt.packettypes import PacketTypes
    final_payload = '{"datetime": "2023-03-30 06:20:30", "RaR": 123, "level": 750, "id": "1234"}'
    topic = "your_topic_here"
    # Your MQTT client connection code here
    publish_properties = props.Properties(PacketTypes.PUBLISH)
    publish_properties.UserProperty = ("Content-Type", "application/json")
    publish_properties.UserProperty = ("content-encoding", "UTF-8")
    client.publish(topic, payload=final_payload, qos=1, properties=publish_properties)
    												

    Thanks @Sedat SALMAN for the quick response. Actually, we tried the suggested code, but it was not working as expected. We referred the MQTT documentation provided by azure https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-mqtt-support and it is mentioned that the message properties can be set it from the topic itself and it is working as expected.