在使用ESP-IDF(非Arduino)和azure-iot-middleware-freertos(具体为sample_azure_iot_pnp. c)的ESP 32 S3上,ESP 32 S3-Device正在向IoTHub发送遥测数据,我可以使用Azure IoT Explorer查看到达的数据。
我已经设置了一个路由和一个自定义端点,以路由到NoSQL CosmosDB。消息没有被路由,即使在IoTExplorer的遥测窗格中显示的正文是正确的。
如果我将此正文的内容剪切并粘贴到“测试路由正文”,则路由测试符合我设置的查询条件。
我怀疑这与设置ContentEncoding =“utf-8”,ContentType =“application/json”有关。还要确保消息以utf-8编码。
示例代码使用以下函数设置遥测数据:
uint32_t ulCreateTelemetry( uint8_t * pucTelemetryData,
uint32_t ulTelemetryDataSize,
uint32_t * ulTelemetryDataLength )
{
int result = snprintf( ( char * ) pucTelemetryData, ulTelemetryDataSize,
myTELEMETRY_MESSAGE, myACTION); //sampleazureiotMESSAGE, xDeviceCurrentTemperature
if( ( result >= 0 ) && ( result < ulTelemetryDataSize ) )
{
*ulTelemetryDataLength = result;
result = 0;
}
else
{
result = 1;
}
return result;
}
以下是RTOS任务循环中的调用函数:
/* Publish messages with QoS1, send and process Keep alive messages. */
for( ; ; )
{
/* Hook for sending Telemetry */
if( ( ulCreateTelemetry( ucScratchBuffer, sizeof( ucScratchBuffer ), &ulScratchBufferLength ) == 0 ) &&
( ulScratchBufferLength > 0 ) )
{
xResult = AzureIoTHubClient_SendTelemetry( &xAzureIoTHubClient,
ucScratchBuffer, ulScratchBufferLength,
NULL, eAzureIoTHubMessageQoS1, NULL );
configASSERT( xResult == eAzureIoTSuccess );
}
/* Hook for sending update to reported properties */
ulReportedPropertiesUpdateLength = ulCreateReportedPropertiesUpdate( ucReportedPropertiesUpdate, sizeof( ucReportedPropertiesUpdate ) );
if( ulReportedPropertiesUpdateLength > 0 )
{
xResult = AzureIoTHubClient_SendPropertiesReported( &xAzureIoTHubClient, ucReportedPropertiesUpdate, ulReportedPropertiesUpdateLength, NULL );
configASSERT( xResult == eAzureIoTSuccess );
}
LogInfo( ( "Attempt to receive publish message from IoT Hub.\r\n" ) );
xResult = AzureIoTHubClient_ProcessLoop( &xAzureIoTHubClient,
sampleazureiotPROCESS_LOOP_TIMEOUT_MS );
configASSERT( xResult == eAzureIoTSuccess );
/* Leave Connection Idle for some time. */
LogInfo( ( "Keeping Connection Idle...\r\n\r\n" ) );
vTaskDelay( sampleazureiotDELAY_BETWEEN_PUBLISHES_TICKS );
}
遥测数据定义如下:
#define myTELEMETRY_MESSAGE "{\"action\":\"%s\",\"ph_weight_device_mac\":\"XXXXXXXXXXXX\",\"ph_weight_index\":99,\"ph_weight_dev_nr\":0,\"ph_weight_block\":\"TEST\",\"ph_weight_activity\":\"ACTIVITY 2\",\"ph_weight_mode\":105,\"ph_weight_tag\":\"6D2517EBB4\",\"ph_weight_weight\":2.6202,\"ph_weight_date\":\"2022-12-07\",\"ph_weight_time\":\"13:45:12\"}"
myACTION为:
#define myACTION "addPackhouseWeight"
实际发布消息的Azure IoT功能:
AzureIoTResult_t AzureIoTHubClient_SendTelemetry( AzureIoTHubClient_t * pxAzureIoTHubClient,
const uint8_t * pucTelemetryData,
uint32_t ulTelemetryDataLength,
AzureIoTMessageProperties_t * pxProperties,
AzureIoTHubMessageQoS_t xQOS,
uint16_t * pusTelemetryPacketID )
{
AzureIoTMQTTResult_t xMQTTResult;
AzureIoTResult_t xResult;
AzureIoTMQTTPublishInfo_t xMQTTPublishInfo = { 0 };
uint16_t usPublishPacketIdentifier = 0;
size_t xTelemetryTopicLength;
az_result xCoreResult;
if( pxAzureIoTHubClient == NULL )
{
AZLogError( ( "AzureIoTHubClient_SendTelemetry failed: invalid argument" ) );
xResult = eAzureIoTErrorInvalidArgument;
}
else if( az_result_failed(
xCoreResult = az_iot_hub_client_telemetry_get_publish_topic( &pxAzureIoTHubClient->_internal.xAzureIoTHubClientCore,
( pxProperties != NULL ) ? &pxProperties->_internal.xProperties : NULL,
( char * ) pxAzureIoTHubClient->_internal.pucWorkingBuffer,
pxAzureIoTHubClient->_internal.ulWorkingBufferLength,
&xTelemetryTopicLength ) ) )
{
AZLogError( ( "Failed to get telemetry topic: core error=0x%08lx", xCoreResult ) );
xResult = AzureIoT_TranslateCoreError( xCoreResult );
}
else
{
xMQTTPublishInfo.xQOS = xQOS == eAzureIoTHubMessageQoS1 ? eAzureIoTMQTTQoS1 : eAzureIoTMQTTQoS0;
xMQTTPublishInfo.pcTopicName = pxAzureIoTHubClient->_internal.pucWorkingBuffer;
xMQTTPublishInfo.usTopicNameLength = ( uint16_t ) xTelemetryTopicLength;
xMQTTPublishInfo.pvPayload = ( const void * ) pucTelemetryData;
xMQTTPublishInfo.xPayloadLength = ulTelemetryDataLength;
/* Get a unique packet id. Not used if QOS is 0 */
if( xQOS == eAzureIoTHubMessageQoS1 )
{
usPublishPacketIdentifier = AzureIoTMQTT_GetPacketId( &( pxAzureIoTHubClient->_internal.xMQTTContext ) );
}
/* Send PUBLISH packet. */
if( ( xMQTTResult = AzureIoTMQTT_Publish( &( pxAzureIoTHubClient->_internal.xMQTTContext ),
&xMQTTPublishInfo, usPublishPacketIdentifier ) ) != eAzureIoTMQTTSuccess )
{
AZLogError( ( "Failed to publish telemetry: MQTT error=0x%08x", xMQTTResult ) );
xResult = eAzureIoTErrorPublishFailed;
}
else
{
if( ( xQOS == eAzureIoTHubMessageQoS1 ) && ( pusTelemetryPacketID != NULL ) )
{
*pusTelemetryPacketID = usPublishPacketIdentifier;
}
AZLogInfo( ( "Successfully sent telemetry message" ) );
xResult = eAzureIoTSuccess;
}
}
return xResult;
}
数据显示在Azure IoT Explorer的遥测窗格中:
Fri Dec 09 2022 12:35:24 GMT+0200 (South Africa Standard Time):
{
"body": {
"action": "addPackhouseWeight",
"ph_weight_device_mac": "XXXXXXXXXXXX",
"ph_weight_index": 99,
"ph_weight_dev_nr": 0,
"ph_weight_block": "TEST",
"ph_weight_activity": "ACTIVITY 2",
"ph_weight_mode": 105,
"ph_weight_tag": "AD2512EBB4",
"ph_weight_weight": 2.6202,
"ph_weight_date": "2022-12-07",
"ph_weight_time": "13:45:12"
},
"enqueuedTime": "Fri Dec 09 2022 12:35:24 GMT+0200 (South Africa Standard Time)",
"systemProperties": {
"iothub-connection-device-id": "XXXXXXXXXXXX",
"iothub-connection-auth-method": "{\"scope\":\"device\",\"type\":\"sas\",\"issuer\":\"iothub\",\"acceptingIpFilterRule\":null}",
"iothub-connection-auth-generation-id": "638052575116976851",
"iothub-enqueuedtime": 1670582124804,
"iothub-message-source": "Telemetry",
"dt-dataschema": "dtmi:com:loadassist:Packhouse;2"
}
}
所以,它到达了,但可能是Base64编码和Azure IoT Explorer只是处理它并正确显示。
但是我怀疑路由不起作用,因为示例代码没有设置编码和数据类型。有Arduino的例子,他们设置和编码消息,但在这个SDK中没有任何效果。
我看不出他们是否在示例代码的其他地方这样做。
我不知道如何使用SDK和使用的MQTT WebSocket来实现这一点。
我还想设置一个属性值,这样我就可以在该属性上进行查询和路由,而不必执行“action”:“addPackhousWeight”与重量数据一起存储到cosmosDB中。
好吧,我希望我已经足够清楚了。我尝试了与微软的支持票,但它被他们关闭,没有回答。Thx
**添加的注解:**我在sample_azure_iot_pnp. c中发现以下内容,但sample_azure_iot_pnp. c中不包含这些内容:
/* Create a bag of properties for the telemetry */
xResult = AzureIoTMessage_PropertiesInit( &xPropertyBag, ucPropertyBuffer, 0, sizeof( ucPropertyBuffer ) );
configASSERT( xResult == eAzureIoTSuccess );
xResult = AzureIoTMessage_PropertiesAppend( &xPropertyBag, ( uint8_t * ) "content-encoding", sizeof( "content-encoding" ) - 1,
( uint8_t * ) "utf-8", sizeof( "utf-8" ) - 1 );
configASSERT( xResult == eAzureIoTSuccess );
xResult = AzureIoTMessage_PropertiesAppend( &xPropertyBag, ( uint8_t * ) "content-type", sizeof( "content-type" ) - 1,
( uint8_t * ) "application%2Fjson", sizeof( "application%2Fjson" ) - 1 );
configASSERT( xResult == eAzureIoTSuccess );
或如下所示:
/* Create a bag of properties for the telemetry */
xResult = AzureIoTMessage_PropertiesInit( &xPropertyBag, ucPropertyBuffer, 0, sizeof( ucPropertyBuffer ) );
configASSERT( xResult == eAzureIoTSuccess );
xResult = AzureIoTMessage_PropertiesAppend( &xPropertyBag, ( uint8_t * ) "contentEncoding", sizeof( "contentEncoding" ) - 1,
( uint8_t * ) "utf-8", sizeof( "utf-8" ) - 1 );
configASSERT( xResult == eAzureIoTSuccess );
xResult = AzureIoTMessage_PropertiesAppend( &xPropertyBag, ( uint8_t * ) "contentType", sizeof( "contentType" ) - 1,
( uint8_t * ) "application%2Fjson", sizeof( "application%2Fjson" ) - 1 );
configASSERT( xResult == eAzureIoTSuccess );
尝试了content-type和contentType等,但还是无法路由...
1条答案
按热度按时间o7jaxewo1#
最后我让它工作:
我在这里找到了解决方案:https://azure.microsoft.com/sv-se/blog/iot-hub-message-routing-now-with-routing-on-message-body/
因此,添加“$.ce”和“$.ct”有助于让它工作。字面上花了我几天的时间。希望它能帮助其他人。
我还学到了: