Azure / azure-iot-sdk-java

A Java SDK for connecting devices to Microsoft Azure IoT services
https://azure.github.io/azure-iot-sdk-java/
Other
198 stars 237 forks source link

[Device Client] Digital twin interface support #839

Closed tafitzgerald closed 4 years ago

tafitzgerald commented 4 years ago

We are attempting to certify our device with Azure Plug-and-Play. We are provisioning our device with the X.509 Security Provider before connection. We now connect using the DeviceClient() constructor passing in our model id to the new constructor using the ClientOptions field.

Our device also supports DPS but getting a ‘Failed to get modelInfo on device due to NoDigitalTwinInterface’ error [1] when connecting through the portal. This is worrisome since we are passing in the model id information upon connection.

I am also using the Azure Java Samples repo for reference. The digital-twin samples connect using a DigitalTwinDeviceClient and then register model information using that client. But there is no "device-twin" source folder or any classes contained within available in azure-iot-sdk-java.

Should the device client twin pub/sub be enough for certifying plug-and-play or do you plan on releasing further "digital-twin capability" soon?

[1] azure-certified-portal-error

AB#7623175

tafitzgerald commented 4 years ago

I have updated sdk version I am using to release_2020-07-08 release. I can see the device-twin updates but the certification portal is still unable to locate the model id.

abhipsaMisra commented 4 years ago

@tafitzgerald Could you explain a bit about the flow that you are trying to achieve with the device client here? I see that you've mentioned wanting to use DPS for provisioning, I want to understand if that is what you are using to create the device identity on your hub.

For a sample application, you can refer to a simple pnp device sample here. This sample demonstrates the behavior of a plug and play enabled device client, which has only a root interface. It shows you how to pass the model Id, in order to have the device identifiable as a plug and play certified device: https://github.com/Azure/azure-iot-sdk-java/blob/master/device/iot-device-samples/pnp-device-sample/thermostat-device-sample/src/main/java/samples/com/microsoft/azure/sdk/iot/device/Thermostat.java#L107

tafitzgerald commented 4 years ago

@abhipsaMisra Yes, I use DPS to add an enrollment, which serves as my device identity in our IoT Hub. I follow the steps in the Thermostat sample, passing our "urn:" model id during initialization.

The error I see references the DeviceTwinInterface, which should be implemented by Azure SDK. I did just see this in your latest 2020-07-08 release and it could be the missing piece.

I also see that you set the DigitalTwinDeviceClient to report device properties in a test here. But the lombok setter has the package modifier and is not visible to me. Could this missing SdkInformation be the root cause of my error?

abhipsaMisra commented 4 years ago

A couple of things to note here:

The error I see references the DeviceTwinInterface, which should be implemented by Azure SDK

Where do you see this error? Is this in the sample that you are trying to run, or in some portal/ explorer tool?

Could this missing SdkInformation be the root cause of my error?

This should not be causing any issue in having your device being discovered as a plug and play device, but I cannot answer definitively until I know where exactly you are seeing this error.

Could you answer the following questions about the exact steps that you are carrying out? This will solve our need from having multiple back-and-forth about the scenario.

  1. Use DPS to add an enrollment - do you pass in the model Id here, during provisioning?
  2. Create a device client instance - the model Id is passed to the device client, during initialization.
  3. Error occurs - where? Is this in the sample, or some tool/ portal that you are using to view device information?
tafitzgerald commented 4 years ago
  1. Yes, I pass in the model id exactly as shown in the PnP samples.
  2. Yes, the model is passed in using the DeviceClient constructor that authenticates with the SecurityProvider here.
  3. The error I am seeing is in the Azure Certified for IoT Portal here. I am certifying our company device as a plug and play device. The error is happening in the "Connect and test" phase with AICS for qualifying our product. I am authenticating using an X.509 certificate.
tafitzgerald commented 4 years ago

Hi @abhipsaMisra I also notice that common interfaces show beginning with "urn:" but the pnp samples define the model id beginning with "dtmi:". And all devices in the plug and play catalog provide a capability model id of "urn:". This is very confusing as to which documentation to follow for becoming a certified plug and play device.

abhipsaMisra commented 4 years ago

Thanks for sharing your questions and concerns, @tafitzgerald ! The current certification system is undergoing a change, and will soon be ready with the new features, so as to enable it to work according to current requirements. This will solve the error that you are seeing above.

Could you also create a support ticket, following the steps here, so that our certification team can get in touch with you and share the updated instructions.

tafitzgerald commented 4 years ago

Hi @abhipsaMisra, using the updated LTS release and new certification portal, I still am failing for certifying my device. I now see why after testing with the Azure CLI. I now only use the DTDL v2 interface - DeviceInformation.json.

I pass the ClientOptions::modelId "dtmi:azure:DeviceManagement:DeviceInformation;1" to the DeviceClient constructor authenticating with a SecurityProvider. I follow the Thermostat sample almost directly but still fail to pass the certify tests. The error from the CLI I get is:

"name": "Validate DigitalTwin DPS registration", "rawData": [ "{\"payload\":null}" ], "startTime": "2020-09-02T16:57:34.5182246+00:00", "status": "Failed"

While the DigitalTwin test cases pass and my PnP properties are all validated. I see here that it mentions to include the modelID during DPS as a JSON payload. But am I supposed the set the ClientOptions::modelId as a String representation of a payload?

I see why my test is failing now but do not understand how to make the fix. Can you clarify please?

abhipsaMisra commented 4 years ago

Hi @tafitzgerald , yes, you are correct. When you register your device, you need to pass in the model Id as dps payload. The below example should help you out:

This is how you would pass your model Id to DPS, during registration:

String globalEndpoint = "<value_here>";
String idScope = "<value_here>";
String deviceRegistrationId = "<value_here>";
String deviceSymmetricKey = "<value_here>";
SecurityProviderSymmetricKey securityProviderSymmetricKey = new SecurityProviderSymmetricKey(deviceSymmetricKey.getBytes(), deviceRegistrationId);
ProvisioningDeviceClient pdc = ProvisioningDeviceClient.create(globalEndpoint, idScope, ProvisioningDeviceClientTransportProtocol.MQTT, securityProviderSymmetricKey);

AdditionalData pnpDpsPayload = new AdditionalData();
pnpDpsPayload.setProvisioningPayload(String.format("{\"modelId\": \"%s\"}", MODEL_ID));
pdc.registerDevice(new ProvisioningDeviceClientRegistrationCallbackImpl(), new ProvisioningStatus(), pnpDpsPayload);

For an example on how to monitor the provisioning status and then connect to IoT Hub, please see: https://github.com/Azure/azure-iot-sdk-java/blob/master/provisioning/provisioning-samples/provisioning-symmetrickey-sample/src/main/java/samples/com/microsoft/azure/sdk/iot/ProvisioningSymmetricKeySample.java#L80

Let me know if you still have questions!

tafitzgerald commented 4 years ago

Hi @abhipsaMisra , AdditonalData registering the ProvisoningDeviceClient with the new constructor is what was missing from the samples. Azure documentation hinted at that but I wasn't sure what that meant since the PnP and Provisioning samples don't include this.

Thank you for all of your help with this! It finally works!!

abhipsaMisra commented 4 years ago

I am glad it worked! Also, fyi - we are updating our PnP sample to demonstrate the flow with DPS integration.

az-iot-builder-01 commented 4 years ago

@tafitzgerald, @abhipsaMisra, thank you for your contribution to our open-sourced project! Please help us improve by filling out this 2-minute customer satisfaction survey