how to get the data from iothub into digital Twins?

HonConfiance 20 Reputation points
2023-05-22T14:13:46.76+00:00

i want to send the data from opc ua in iot hub with the following python code.

# OPC UA Node-IDs
opc_node_ids = {
    "Auto": 'ns=3;s="Send"."Auto"',
}

# OPC UA Client initialisieren
def opcua_init():
    opcua_client = Client("XXX")  # OPC UA-Adresse einsetzen
    while True:
        try:
            print("Trying to connect to the OPC UA server...")
            opcua_client.connect()
            return opcua_client
        except:
            print("Connection failed. Trying again after 5 seconds...")
            sleep(5)

# IoT Hub-Client initialisieren
def iot_hub_init():
    while True:
        try:
            iot_client = IoTHubDeviceClient.create_from_connection_string("HostName=MoXXX.azure-devices.net;DeviceId=modeltest;SharedAccessKey=XXXXX", websockets=True)  # IoT-Verbindungszeichenfolge einsetzen
            print("Trying to connect to the IoT Hub...")
            iot_client.connect()
            return iot_client
        except:
            print("Connection failed. Trying again after 5 seconds...")
            sleep(5)

# Daten von OPC UA-Server abrufen und als JSON-String zurückgeben
def opcua_get_value(client):
    opcua_data = {}
    for node_name, node_id in opc_node_ids.items():
        ba_node = client.get_node(node_id)
        ba_value = ba_node.get_value()
        #ba_value = 26.0
        ba_displayname = ba_node.get_display_name().to_string()
        #ba_displayname = "Temperatur"

        opcua_data[ba_displayname] = ba_value

    return json.dumps(opcua_data)

# Zyklisch Daten abrufen und an IoT Hub senden
def send_cycle(opcua_client, iot_client):
    try:
        while True:
            opcua_value = opcua_get_value(opcua_client)
            print(opcua_value)
            message = Message(opcua_value)

            currentEncoding = message.content_encoding;
            contentType = message.content_type;

            #print("aktuelle conting ist: ",currentEncoding)
            #print("aktuelle type ist:  ",contentType)

            #anpassung der nachtricht schlüsseln
            message.content_encoding = "utf-8"
            message.content_type = "application/json"
            #ende der Anpassung
            print("Sending message to IoT Hub: {}".format(message))
            iot_client.send_message(message)
            print("Message sent successfully")
            sleep(5)
    except KeyboardInterrupt:
        print("IoT Hub client sampling stopped")
        opcua_client.disconnect()
        iot_client.disconnect()

# Hauptfunktion
if __name__ == '__main__':
    opcua_client = opcua_init()
    iot_client = iot_hub_init()
    send_cycle(opcua_client, iot_client)

The function to update the data in Digital Twins is defined as follows.

public static class Function1
    {
        private static readonly string adtInstanceUrl = Environment.GetEnvironmentVariable("ADT_SERVICE_URL");

        private static readonly HttpClient singletonHttpClientIntance = new HttpClient();

        [FunctionName("IOTHubtoADTwins")]
        public static async Task Run([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log)
        {

            if (adtInstanceUrl == null) log.LogError("Application setting \"ADT_SERVICE_URL\" not set");

            try
            {
                //log.LogInformation(eventGridEvent.Data.ToString());

                //manager für die identity
                var cred = new ManagedIdentityCredential("https://digitaltwins.azure.net");


                var client = new DigitalTwinsClient(new Uri(adtInstanceUrl), cred,
                new DigitalTwinsClientOptions
                {
                    Transport = new HttpClientTransport(singletonHttpClientIntance)
                });


                log.LogInformation($" ADT service client connection created.");


                if (eventGridEvent != null && eventGridEvent.Data != null)
                {
                    JObject deviceMessage = (JObject)JsonConvert.DeserializeObject(eventGridEvent.Data.ToString());

                    string deviceId = (string)deviceMessage["systemProperties"]["iothub-connection-device-id"];

                    var Auto = deviceMessage["body"]["Auto"];

                    log.LogInformation($"Device:{deviceId} Auto is: {Auto}");

                    var updateTwinData = new JsonPatchDocument();
                    updateTwinData.AppendReplace("/Temperatur", Auto.Value<bool>());
                    log.LogInformation("Funktioniert jetzt einwandfrei");
                    await client.UpdateDigitalTwinAsync(deviceId, updateTwinData);
                }
            }
            catch (Exception ex)
            {
                log.LogError($"Error in ingest function: {ex.Message}");
            }
        }
    }

the data digital Twins model is defined as follows.

{
 "@id": "dtmi:demo:Factory;1",
 "@type": "Interface",
 "@context": "dtmi:dtdl:context;2",
 "displayName": "Factory Interface Model",
 "contents": [
  {
   "name": "Auto",
   "@type": "Property",
   "schema": "boolean"
  }
 ]
}

User's image

in iothub have defined the device ID exactly like this.
User's image

at the Azure digital Twins have allowed the access of the Mehode.
User's image

When I try to update the data at Azure digital Twins Explorer with

await client.UpdateDigitalTwinAsync(deviceId, updateTwinData);

, I get the following error message.
User's image

Should I define the device id differently? do I have a problem when I define the model with Azure Digital Twins Explorer? should I set the access somewhere else?

Thanks

Azure Digital Twins
Azure Digital Twins
An Azure platform that is used to create digital representations of real-world things, places, business processes, and people.
220 questions
Azure
Azure
A cloud computing platform and infrastructure for building, deploying and managing applications and services through a worldwide network of Microsoft-managed datacenters.
984 questions
Azure IoT Hub
Azure IoT Hub
An Azure service that enables bidirectional communication between internet of things (IoT) devices and applications.
1,128 questions
0 comments No comments
{count} votes

Accepted answer
  1. Sander van de Velde 29,286 Reputation points MVP
    2023-05-22T15:47:54.8166667+00:00

    Hello @HonConfiance ,

    these are two main ways to update Azure Digital Twins' twin properties using properties.

    The first way is using an Azure Function as you describe.

    Quickly scanning your docs shows it to be quite complete.

    Though, I suggest using these credentials:

    var cred = new DefaultAzureCredential();
    var client = new DigitalTwinsClient(new Uri(adtServiceUrl), cred);
    

    This is seen in this example coming from this blog post.

    Another way is using Logic Apps.

    I recommend researching this because it gives you more flexibility over the 'hardcoded' functions.


    If the response helped, do "Accept Answer". If it doesn't work, please let us know the progress. All community members with similar issues will benefit by doing so. Your contribution is highly appreciated.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful