1

I have a custom application in Azure IoT Central. I have my device created and can send data up with basic data types (bool, float, int).

From the C api it looks like there is a mechanism to declare a struct, add it to the model, and send that data. So I did, and I see confirmation that my messages are sending and being received, but no data is showing...so I'm guessing either you can't really declare a struct and send it, or I don't have it configured correctly on the Azure side, but I haven't found any documentation that could help.

BEGIN_NAMESPACE(AzureModel);

DECLARE_STRUCT(MyData,
        int, num1,
        float, num2,
        int, num3);

DECLARE_MODEL(Azure1_t,
WITH_DATA(ascii_char_ptr, deviceId),
WITH_DATA(int, messageId),
WITH_DATA(MyData, myData),
WITH_DATA(EDM_DATE_TIME_OFFSET, ts),
/* Methods */
WITH_METHOD(Reboot),
WITH_METHOD(Quit),
WITH_METHOD(FirmwareUpdate, ascii_char_ptr, FwPackageUri),
/* Register Direct Methods with IoT Hub */
WITH_REPORTED_PROPERTY(ascii_char_ptr_no_quotes, SupportedMethods),
/* Telemetry Interval in Seconds... value from 1 to: 0xFFFF/2000 = About 30 Seconds */
WITH_REPORTED_PROPERTY(int,TelemetryInterval),
WITH_REPORTED_PROPERTY(ascii_char_ptr,AzureStatus),
WITH_REPORTED_PROPERTY(ascii_char_ptr, AzureFwVersion)
);

END_NAMESPACE(AzureModel);

Azure1_t *Azure1;

static void SendData(void)
{
     EVENT_INSTANCE *messages;
      unsigned char* destination;
      size_t destinationSize;
      time_t now;

      /* Read the Time  from RTC */
        now = TimingSystemGetSystemTime();
        /* Time Stamp */
        Azure1->ts = GetDateTimeOffset(now);

      messages = (EVENT_INSTANCE *) calloc(1,sizeof(EVENT_INSTANCE));
      if(messages==NULL) {
        AZURE_PRINTF("Err: Allocating Memory for messages to IoT Hub\r\n");
        HAL_NVIC_SystemReset();
      } else {
        messages->this = (void *)messages;
      }

      SentMessagesCount++;
      Azure1->messageId = messages->messageTrackingId = SentMessagesCount;

      if (SERIALIZE(&destination, &destinationSize,
                    Azure1->deviceId,
                    Azure1->messageId,
                    Azure1->myData,
                    Azure1->ts) != CODEFIRST_OK){
        AZURE_PRINTF("Err: Failed to serialize\r\n");
      }
      else
      {
          /* Only for Debug */
          //AZURE_PRINTF("MessageToSend=%.*s\r\n",destinationSize,destination);

          if ((messages->messageHandle = IoTHubMessage_CreateFromByteArray(destination, destinationSize)) == NULL) {
            AZURE_PRINTF("Err: iotHubMessageHandle is NULL!\r\n");
          } else {
            char msgText[32];
            MAP_HANDLE propMap = IoTHubMessage_Properties(messages->messageHandle);
            sprintf_s(msgText, sizeof(msgText), "PropMsg_%zu", SentMessagesCount);
            if (Map_AddOrUpdate(propMap, "PropName", msgText) != MAP_OK){
              AZURE_PRINTF("Err: Map_AddOrUpdate Failed!\r\n");
            }
            if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messages->messageHandle, SendConfirmationCallback, messages) != IOTHUB_CLIENT_OK) {
              AZURE_PRINTF("Err: IoTHubClient_LL_SendEventAsync..........FAILED!\r\n");
            } else {
              AZURE_PRINTF("IoTHubClient_LL_SendEventAsync accepted message [%d] for transmission to IoT Hub.\r\n", SentMessagesCount);
            }
            free(destination);
          }
          IoTHubMessage_Destroy(messages->messageHandle);
      }
}

Azure configuration

Dave S
  • 25
  • 4
  • what about serializing as json and receive it as string in the iot central side? – Thiago Custodio Dec 05 '19 at 22:08
  • It is currently being serialized as json ( I think) when it is sent.. the string that is sent is below. On the azure side, for an event, there isn't a place to specify a data type, only a field name. "{\"deviceId\":\"StructDev\", \"messageId\":2, \"myData\":{\"num1\":1635021666, \"num2\":0.000000, \"num3\":1852383802}, \"ts\":\"2019-12-06T13:57:54Z\"}:" – Dave S Dec 06 '19 at 13:59
  • I want to double triple confirm you mean to say IoT Central and not IoT Hub. If you mean IoT Central, then I don't see any capability in the Device Template to support any complex formats. You should expect to send individual values from your Device to the IoT Central endpoint. Let me know if you're really using IoT Central and provide more details as an answer. – Patrick Dec 18 '19 at 00:41

1 Answers1

0

In the case, that your IoT Central App is not a Legacy Application (2018), so it has been built using the latest updates such as the Plug and Play (Capability Model), the telemetry object can be consumed by IoTC application.

Create a new version of your device template and add new capability to the Interface instance. The following screen snippet shows my example: enter image description here

Clicking on the View, we can see the Schema of the telemetry object: enter image description here

Note, that the above schema is my example, basically you can created yours with more complex and nested levels.

Once you finished your device template updates and publishing, you need to assigned this new version of the device template to the real device.

For testing purposes (devices <-> IoTCentral App), the Azure IoT Hub Tester is used. The following screen snippet shows sending a telemetry samples to the IoTC from the PnP device sensor4. Note, that the device sensor4 has been setup with the device template capability model exported by IoT Central App.

enter image description here

and the IoTC application dashboard:

enter image description here

The new feature (still in preview) of the IoT Central such as creating a device template based on the Plug and Play capability model is a great feature allows to logical connected end-to-end entities in bidirectional manner.

Update:

I missed your Azure configuration picture, which it shown a Device Template of the Legacy Application (2018). Note, that this version doesn't have a support for your needs (custom complex schema, etc.).

I do recommend to migrate your legacy application to the newest one (still in the preview) with a capability of the Plug and Play Model.

Roman Kiss
  • 7,925
  • 1
  • 8
  • 21