Udostępnij za pośrednictwem


Przewodnik dewelopera usługi IoT Plug and Play

Usługa IoT Plug and Play umożliwia tworzenie urządzeń IoT, które anonsują ich możliwości w aplikacjach usługi Azure IoT. Urządzenia IoT Plug and Play nie wymagają ręcznej konfiguracji, gdy klient łączy je z aplikacjami IoT Plug and Play.

Usługa IoT Plug and Play umożliwia korzystanie z urządzeń, które ogłosiły identyfikator modelu w centrum IoT. Można na przykład uzyskać bezpośredni dostęp do właściwości i poleceń urządzenia.

Jeśli używasz usługi IoT Central, możesz użyć interfejsu użytkownika usługi IoT Central i interfejsu API REST do interakcji z urządzeniami IoT Plug and Play połączonymi z aplikacją.

Zestawy SDK usług

Użyj zestawów SDK usługi Azure IoT w rozwiązaniu, aby wchodzić w interakcje z urządzeniami i modułami. Na przykład można użyć zestawów SDK usługi do odczytywania i aktualizowania właściwości bliźniaczej reprezentacji oraz wywoływania poleceń. Obsługiwane języki to C#, Java, Node.js i Python.

Zestawy SDK usługi Azure IoT zawierają kod ułatwiający tworzenie aplikacji, które bezpośrednio wchodzą w interakcje z usługą IoT Hub w celu zarządzania urządzeniami i zabezpieczeniami.

Platforma Pakiet Repozytorium kodu Przykłady Odwołanie
.NET NuGet GitHub Samples Odwołanie
Java Maven GitHub Samples Odwołanie
Węzeł npm GitHub Samples Odwołanie
Python Pip GitHub Samples Odwołanie

Zestawy SDK usługi umożliwiają dostęp do informacji o urządzeniu ze składnika rozwiązania, takiego jak aplikacja klasyczna lub internetowa. Zestawy SDK usługi obejmują dwie przestrzenie nazw i modele obiektów, których można użyć do pobrania identyfikatora modelu:

  • Klient usługi Iot Hub. Ta usługa uwidacznia identyfikator modelu jako właściwość bliźniaczej reprezentacji urządzenia.

  • Klient usługi Digital Twins. Nowy interfejs API usługi Digital Twins działa w oparciu o konstrukcje modelu Digital Twins Definition Language (DTDL), takie jak składniki, właściwości i polecenia. Interfejsy API usługi Digital Twin ułatwiają konstruktorom rozwiązań tworzenie rozwiązań IoT Plug and Play.

Dostępne są również następujące zasoby:

Przykłady klientów usługi IoT Hub

W tej sekcji przedstawiono przykłady języka C# przy użyciu klienta usługi IoT Hub oraz klas RegistryManager i ServiceClient . Klasa RegistryManager służy do interakcji ze stanem urządzenia przy użyciu bliźniaczych reprezentacji urządzeń. Możesz również użyć klasy RegistryManager do wykonywania zapytań dotyczących rejestracji urządzeń w usłudze IoT Hub. Klasa ServiceClient służy do wywoływania poleceń na urządzeniu. Model DTDL dla urządzenia definiuje właściwości i polecenia, które implementuje urządzenie. W fragmentach kodu zmienna deviceTwinId przechowuje identyfikator urządzenia urządzenia IoT Plug and Play zarejestrowanego w centrum IoT.

Pobieranie bliźniaczej reprezentacji urządzenia i identyfikatora modelu

Aby uzyskać bliźniacze reprezentacje urządzenia i identyfikator modelu urządzenia IoT Plug and Play połączonego z centrum IoT:

RegistryManager registryManager = RegistryManager.CreateFromConnectionString(parameters.HubConnectionString);

Twin twin = await registryManager.GetTwinAsync(deviceTwinId);
Console.WriteLine($"Device twin: \n{JsonConvert.SerializeObject(twin, Formatting.Indented)}");
Console.WriteLine($"Model ID: {twin.ModelId}.");

Aktualizowanie bliźniaczej reprezentacji urządzenia

Poniższy fragment kodu przedstawia sposób aktualizowania targetTemperature właściwości na urządzeniu. W przykładzie pokazano, jak należy pobrać reprezentację bliźniaczą ETag przed jej zaktualizowaniem. Właściwość jest definiowana w domyślnym składniku urządzenia:

Twin twin = await registryManager.GetTwinAsync(deviceTwinId);

int desiredTargetTemperature = 60;

// Update the twin
var twinPatch = new Twin();
twinPatch.Properties.Desired["targetTemperature"] = desiredTargetTemperature;

Console.WriteLine($"Update the targetTemperature property to {desiredTargetTemperature}.");

await registryManager.UpdateTwinAsync(deviceTwinId, twinPatch, twin.ETag);

Poniższy fragment kodu pokazuje, jak zaktualizować targetTemperature właściwość składnika. W przykładzie pokazano, jak należy pobrać reprezentację bliźniaczą ETag przed jej zaktualizowaniem. Właściwość jest zdefiniowana w składniku Termostat1 :

Twin twin = await registryManager.GetTwinAsync(deviceTwinId);

int desiredTargetTemperature = 60;

var twinPatch = CreatePropertyPatch("targetTemperature", desiredTargetTemperature, "thermostat1");

await registryManager.UpdateTwinAsync(deviceTwinId, twinPatch, twin.ETag);

// ...

private static Twin CreatePropertyPatch(string propertyName, object propertyValue, string componentName)
{
    var twinPatch = new Twin();
    twinPatch.Properties.Desired[componentName] = new
    {
        __t = "c"
    };
    twinPatch.Properties.Desired[componentName][propertyName] = JsonConvert.SerializeObject(propertyValue);
    return twinPatch;
}

W przypadku właściwości w składniku poprawka właściwości wygląda jak w poniższym przykładzie:

{
"sampleComponentName":
  {
    "__t": "c",
    "samplePropertyName": 20
  }
}

Wywołaj polecenie

Poniższy fragment kodu pokazuje, jak wywołać getMaxMinReport polecenie zdefiniowane w składniku domyślnym:

ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(parameters.HubConnectionString);

var commandInvocation = new CloudToDeviceMethod("getMaxMinReport") { ResponseTimeout = TimeSpan.FromSeconds(30) };

// Set command payload
DateTimeOffset since = DateTimeOffset.Now.Subtract(TimeSpan.FromMinutes(2));
string componentCommandPayload = JsonConvert.SerializeObject(since);
commandInvocation.SetPayloadJson(componentCommandPayload);

try
{
  CloudToDeviceMethodResult result = await serviceClient.InvokeDeviceMethodAsync(deviceTwinId, commandInvocation);

  Console.WriteLine($"Command getMaxMinReport was invoked." +
      $"\nDevice returned status: {result.Status}. \nReport: {result.GetPayloadAsJson()}");
}
catch (DeviceNotFoundException)
{
    Console.WriteLine($"Unable to execute command getMaxMinReport on {deviceTwinId}.";
}

Poniższy fragment kodu pokazuje, jak wywołać getMaxMinReport polecenie w składniku. Polecenie jest zdefiniowane w składniku Termostat1 :

// Create command name to invoke for component. The command is formatted as <component name>*<command name>
string commandToInvoke = "thermostat1*getMaxMinReport";
var commandInvocation = new CloudToDeviceMethod(commandToInvoke) { ResponseTimeout = TimeSpan.FromSeconds(30) };

// Set command payload
DateTimeOffset since = DateTimeOffset.Now.Subtract(TimeSpan.FromMinutes(2));
string componentCommandPayload = JsonConvert.SerializeObject(since);
commandInvocation.SetPayloadJson(componentCommandPayload);

try
{
    CloudToDeviceMethodResult result = await serviceClient.InvokeDeviceMethodAsync(deviceTwinId, commandInvocation);
    Console.WriteLine($"Command getMaxMinReport was invoked on component thermostat1." +
        $"\nDevice returned status: {result.Status}. \nReport: {result.GetPayloadAsJson()}");
}
catch (DeviceNotFoundException)
{
    Console.WriteLine("Unable to execute command getMaxMinReport on component thermostat1.");
}

Przykłady cyfrowej reprezentacji bliźniaczej usługi IoT Hub

Klasa DigitalTwinClient służy do interakcji ze stanem urządzenia przy użyciu cyfrowych reprezentacji bliźniaczych. Model DTDL dla urządzenia definiuje właściwości i polecenia, które implementuje urządzenie.

W tej sekcji przedstawiono przykłady języka C# przy użyciu interfejsu API usługi Digital Twins. Następujące fragmenty kodu używają następujących klas do reprezentowania cyfrowej reprezentacji bliźniaczej urządzeń termostatu i kontrolera temperatury:

using Microsoft.Azure.Devices.Serialization;
using Newtonsoft.Json;
using System;

namespace Microsoft.Azure.Devices.Samples
{
  internal class ThermostatTwin : BasicDigitalTwin
  {
    [JsonProperty("$metadata")]
    public new ThermostatMetadata Metadata { get; set; }

    [JsonProperty("maxTempSinceLastReboot")]
    public double? MaxTempSinceLastReboot { get; set; }

    [JsonProperty("targetTemperature")]
    public double? TargetTemperature { get; set; }
  }

  internal class ThermostatMetadata : DigitalTwinMetadata
  {
    [JsonProperty("maxTempSinceLastReboot")]
    public ReportedPropertyMetadata MaxTempSinceLastReboot { get; set; }

    [JsonProperty("targetTemperature")]
    public WritableProperty TargetTemperature { get; set; }
  }

  internal class ReportedPropertyMetadata
  {
    [JsonProperty("lastUpdateTime")]
    public DateTimeOffset LastUpdateTime { get; set; }
  }

  internal class TemperatureControllerTwin : BasicDigitalTwin
  {
    [JsonProperty("$metadata")]
    public new TemperatureControllerMetadata Metadata { get; set; }

    [JsonProperty("serialNumber")]
    public string SerialNumber { get; set; }

    [JsonProperty("thermostat1")]
    public ThermostatTwin Thermostat1 { get; set; }

    [JsonProperty("thermostat2")]
    public ThermostatTwin Thermostat2 { get; set; }
  }

  internal class TemperatureControllerMetadata : DigitalTwinMetadata
  {
    [JsonProperty("serialNumber")]
    public ReportedPropertyMetadata SerialNumber { get; set; }

    [JsonProperty("thermostat1")]
    public WritableProperty Thermostat1 { get; set; }

    [JsonProperty("thermostat2")]
    public WritableProperty Thermostat2 { get; set; }
  }
}

Zmienna digitalTwinId przechowuje identyfikator urządzenia urządzenia IoT Plug and Play zarejestrowanego w centrum IoT.

Pobieranie cyfrowej reprezentacji bliźniaczej i identyfikatora modelu

Aby uzyskać identyfikator cyfrowej reprezentacji bliźniaczej i modelu urządzenia IoT Plug and Play połączonego z centrum IoT:

DigitalTwinClient digitalTwinClient = DigitalTwinClient.CreateFromConnectionString(parameters.HubConnectionString);
HttpOperationResponse<ThermostatTwin, DigitalTwinGetHeaders> getDigitalTwinResponse = await digitalTwinClient
    .GetDigitalTwinAsync<ThermostatTwin>(digitalTwinId);
ThermostatTwin thermostatTwin = getDigitalTwinResponse.Body;
Console.WriteLine($"Model ID: {thermostatTwin.Metadata.ModelId}.");
Console.WriteLine($"Digital Twin: \n{JsonConvert.SerializeObject(thermostatTwin, Formatting.Indented)}");

Aktualizowanie cyfrowej reprezentacji bliźniaczej

Poniższy fragment kodu przedstawia sposób aktualizowania targetTemperature właściwości na urządzeniu. Właściwość jest definiowana w domyślnym składniku urządzenia:

var updateOperation = new UpdateOperationsUtility();

int desiredTargetTemperature = 60;

// Get the current value of the targetTemperature property
HttpOperationResponse<ThermostatTwin, DigitalTwinGetHeaders> getDigitalTwinResponse = await digitalTwinClient
    .GetDigitalTwinAsync<ThermostatTwin>(digitalTwinId);
double? currentTargetTemperature = getDigitalTwinResponse.Body.TargetTemperature;

// Has the targetTemperature property previously been set?
if (currentTargetTemperature != null)
{
  // Update the existing property
  // Prepend the property path with a '/'
  updateOperation.AppendReplacePropertyOp($"/targetTemperature",   desiredTargetTemperature);
}
else
{
  // Add a new property
  // Prepend the property path with a '/'
  updateOperation.AppendAddPropertyOp($"/targetTemperature", desiredTargetTemperature);
}

// Update the targetTemperature property on the digital twin
HttpOperationHeaderResponse<DigitalTwinUpdateHeaders> updateDigitalTwinResponse = await digitalTwinClient
    .UpdateDigitalTwinAsync(digitalTwinId, updateOperation.Serialize());

Console.WriteLine($"Update {digitalTwinId} digital twin response: {updateDigitalTwinResponse.Response.StatusCode}.");

Poniższy fragment kodu pokazuje, jak zaktualizować targetTemperature właściwość składnika. Właściwość jest zdefiniowana w składniku Termostat1 :

int desiredTargetTemperature = 60;

var updateOperation = new UpdateOperationsUtility();

// Look at when the property was updated and what was it set to.
HttpOperationResponse<TemperatureControllerTwin, DigitalTwinGetHeaders> getDigitalTwinResponse = await digitalTwinClient
  .GetDigitalTwinAsync<TemperatureControllerTwin>(digitalTwinId);

ThermostatTwin thermostat1 = getDigitalTwinResponse.Body.Thermostat1;

if (thermostat1 != null)
{
  // Thermostat1 is present in the TemperatureController twin. You can add/replace the component-level property "targetTemperature"
  double? currentComponentTargetTemperature = getDigitalTwinResponse.Body.Thermostat1.TargetTemperature;
  if (currentComponentTargetTemperature != null)
  {
      DateTimeOffset targetTemperatureDesiredLastUpdateTime = getDigitalTwinResponse.Body.Thermostat1.Metadata.TargetTemperature.LastUpdateTime;

      // The property path to be replaced should be prepended with a '/'
      updateOperation.AppendReplacePropertyOp("/thermostat1/targetTemperature", desiredTargetTemperature);
  }
  else
  {
      // The property path to be added should be prepended with a '/'
      updateOperation.AppendAddPropertyOp("/thermostat1/targetTemperature", desiredTargetTemperature);
  }
}
else
{
    // Thermostat1 is not present in the TemperatureController twin. Add the component.
    var componentProperty = new Dictionary<string, object> { { "targetTemperature", desiredTargetTemperature }, { "$metadata", new object() } };

    // The property path to be replaced should be prepended with a '/'
    updateOperation.AppendAddComponentOp("/thermostat1", componentProperty);
}

HttpOperationHeaderResponse<DigitalTwinUpdateHeaders> updateDigitalTwinResponse = await digitalTwinClient
    .UpdateDigitalTwinAsync(digitalTwinId, updateOperation.Serialize());

Console.WriteLine($"Update {digitalTwinId} digital twin response: {updateDigitalTwinResponse.Response.StatusCode}.");

Wywołaj polecenie

Poniższy fragment kodu pokazuje, jak wywołać getMaxMinReport polecenie zdefiniowane w składniku domyślnym:

DateTimeOffset since = DateTimeOffset.Now.Subtract(TimeSpan.FromMinutes(2));

try
{
  HttpOperationResponse<DigitalTwinCommandResponse, DigitalTwinInvokeCommandHeaders> invokeCommandResponse = await digitalTwinClient
    .InvokeCommandAsync(digitalTwinId, "getMaxMinReport", JsonConvert.SerializeObject(since));

  Console.WriteLine($"Command getMaxMinReport was invoked. \nDevice returned status: {invokeCommandResponse.Body.Status}." +
    $"\nReport: {invokeCommandResponse.Body.Payload}");
}
catch (HttpOperationException e)
{
  if (e.Response.StatusCode == HttpStatusCode.NotFound)
  {
    Console.WriteLine($"Unable to execute command getMaxMinReport on {digitalTwinId}.");
  }
}

Poniższy fragment kodu pokazuje, jak wywołać getMaxMinReport polecenie w składniku. Polecenie jest zdefiniowane w składniku Termostat1 :

DateTimeOffset since = DateTimeOffset.Now.Subtract(TimeSpan.FromMinutes(2));

try
{
    HttpOperationResponse<DigitalTwinCommandResponse, DigitalTwinInvokeCommandHeaders> invokeCommandResponse = await digitalTwinClient
        .InvokeComponentCommandAsync(digitalTwinId, "thermostat1", "getMaxMinReport", JsonConvert.SerializeObject(since));

    Console.WriteLine("Command getMaxMinReport was invoked on component thermostat1." +
        $"\nDevice returned status: {invokeCommandResponse.Body.Status}. \nReport: {invokeCommandResponse.Body.Payload}");
}
catch (HttpOperationException e)
{
    if (e.Response.StatusCode == HttpStatusCode.NotFound)
    {
        Console.WriteLine("Unable to execute command getMaxMinReport on component thermostat1.");
    }
}

Odczytywanie danych telemetrycznych urządzenia

Urządzenia IoT Plug and Play wysyłają dane telemetryczne zdefiniowane w modelu DTDL do usługi IoT Hub. Domyślnie usługa IoT Hub kieruje dane telemetryczne do punktu końcowego usługi Event Hubs, w którym można z niego korzystać. Aby dowiedzieć się więcej, zobacz Wysyłanie komunikatów z urządzenia do chmury do różnych punktów końcowych przy użyciu routingu komunikatów usługi IoT Hub.

Poniższy fragment kodu pokazuje, jak odczytywać dane telemetryczne z domyślnego punktu końcowego usługi Event Hubs. Kod w tym fragmencie kodu jest pobierany z przewodnika Szybki start usługi IoT Hub Wysyłanie danych telemetrycznych z urządzenia do centrum IoT i odczytywanie go za pomocą aplikacji zaplecza:

await using EventHubConsumerClient consumer = new EventHubConsumerClient(EventHubConsumerClient.DefaultConsumerGroupName, connectionString, EventHubName);

Console.WriteLine("Listening for messages on all partitions");

try
{
    await foreach (PartitionEvent partitionEvent in consumer.ReadEventsAsync(cancellationToken))
    {
        Console.WriteLine("Message received on partition {0}:", partitionEvent.Partition.PartitionId);

        string data = Encoding.UTF8.GetString(partitionEvent.Data.Body.ToArray());
        Console.WriteLine("\t{0}:", data);

        Console.WriteLine("Application properties (set by device):");
        foreach (var prop in partitionEvent.Data.Properties)
        {
            Console.WriteLine("\t{0}: {1}", prop.Key, prop.Value);
        }

        Console.WriteLine("System properties (set by IoT Hub):");
        foreach (var prop in partitionEvent.Data.SystemProperties)
        {
            Console.WriteLine("\t{0}: {1}", prop.Key, prop.Value);
        }
    }
}
catch (TaskCanceledException)
{
    // This is expected when the token is signaled; it should not be considered an
    // error in this scenario.
}

Poniższe dane wyjściowe z poprzedniego kodu pokazują dane telemetryczne temperatury wysyłane przez urządzenie IoT Plug and Play bez składnika termostatu , które ma tylko składnik domyślny. Właściwość dt-dataschema systemowa pokazuje identyfikator modelu:

Message received on partition 1:
        { "temperature": 25.5 }:
Application properties (set by device):
System properties (set by IoT Hub):
        iothub-connection-device-id: my-pnp-device
        iothub-connection-auth-method: {"scope":"device","type":"sas","issuer":"iothub","acceptingIpFilterRule":null}
        iothub-connection-auth-generation-id: 637375045610235418
        iothub-enqueuedtime: 05/10/2020 14:30:58
        iothub-message-source: Telemetry
        dt-dataschema: dtmi:com:example:Thermostat;1
        content-type: application/json
        content-encoding: utf-8

Poniższe dane wyjściowe z poprzedniego kodu pokazują dane telemetryczne temperatury wysyłane przez wieloskładnikowe urządzenie TemperatureController IoT Plug and Play. Właściwość dt-subject systemowa zawiera nazwę składnika, który wysłał dane telemetryczne. W tym przykładzie dwa składniki są thermostat1 i thermostat2 zgodnie z definicją w modelu DTDL. Właściwość dt-dataschema systemowa pokazuje identyfikator modelu:

Message received on partition 1:
        {"temperature":11.1}:
Application properties (set by device):
System properties (set by IoT Hub):
        dt-subject: thermostat1
        iothub-connection-device-id: my-pnp-device
        iothub-connection-auth-method: {"scope":"device","type":"sas","issuer":"iothub","acceptingIpFilterRule":null}
        iothub-connection-auth-generation-id: 637375045610235418
        iothub-enqueuedtime: 05/10/2020 14:23:36
        iothub-message-source: Telemetry
        dt-dataschema: dtmi:com:example:TemperatureController;1
        content-type: application/json
        content-encoding: utf-8
Message received on partition 1:
        {"temperature":41.2}:
Application properties (set by device):
System properties (set by IoT Hub):
        dt-subject: thermostat2
        iothub-connection-device-id: my-pnp-device
        iothub-connection-auth-method: {"scope":"device","type":"sas","issuer":"iothub","acceptingIpFilterRule":null}
        iothub-connection-auth-generation-id: 637375045610235418
        iothub-enqueuedtime: 05/10/2020 14:23:36
        iothub-message-source: Telemetry
        dt-dataschema: dtmi:com:example:TemperatureController;1
        content-type: application/json
        content-encoding: utf-8

Odczytywanie powiadomień o zmianie bliźniaczej reprezentacji urządzenia

Usługę IoT Hub można skonfigurować do generowania powiadomień o zmianie bliźniaczej reprezentacji urządzenia w celu kierowania do obsługiwanego punktu końcowego. Aby dowiedzieć się więcej, zobacz Używanie routingu komunikatów usługi IoT Hub do wysyłania komunikatów z urządzenia do chmury do różnych punktów końcowych zdarzeń niezwiązanych > z telemetrią.

Kod pokazany w poprzednim fragmencie kodu języka C# generuje następujące dane wyjściowe, gdy usługa IoT Hub generuje powiadomienia o zmianie bliźniaczej reprezentacji urządzenia dla urządzenia termostatu bez składnika. Właściwości iothub-message-schema aplikacji i opType podaj informacje o typie powiadomienia o zmianie:

Message received on partition 1:
        {"version":3,"properties":{"reported":{"maxTempSinceLastReboot":9.6,"$metadata":{"$lastUpdated":"2020-10-06T10:17:41.7408552Z","maxTempSinceLastReboot":{"$lastUpdated":"2020-10-06T10:17:41.7408552Z"}},"$version":2}}}:
Application properties (set by device):
        hubName: my-pnp-hub
        deviceId: my-pnp-device
        operationTimestamp: 2020-10-06T10:17:41.7408552+00:00
        iothub-message-schema: twinChangeNotification
        opType: updateTwin
System properties (set by IoT Hub):
        iothub-connection-device-id: my-pnp-device
        iothub-enqueuedtime: 06/10/2020 10:17:41
        iothub-message-source: twinChangeEvents
        user-id: System.ArraySegment`1[System.Byte]
        correlation-id: 61394e8ba7d
        content-type: application/json
        content-encoding: utf-8

Kod pokazany w poprzednim fragmencie kodu języka C# generuje następujące dane wyjściowe, gdy usługa IoT Hub generuje powiadomienia o zmianie bliźniaczej reprezentacji urządzenia dla urządzenia ze składnikami. W tym przykładzie pokazano dane wyjściowe, gdy urządzenie czujnika temperatury ze składnikiem termostatu generuje powiadomienia. Właściwości iothub-message-schema aplikacji i opType podaj informacje o typie powiadomienia o zmianie:

Message received on partition 1:
        {"version":5,"properties":{"reported":{"thermostat1":{"__t":"c","maxTempSinceLastReboot":9.6},"$metadata":{"$lastUpdated":"2020-10-06T10:27:59.515972Z","thermostat1":{"$lastUpdated":"2020-10-06T10:27:59.515972Z","__t":{"$lastUpdated":"2020-10-06T10:27:59.515972Z"},"maxTempSinceLastReboot":{"$lastUpdated":"2020-10-06T10:27:59.515972Z"}}},"$version":4}}}:
Application properties (set by device):
        hubName: my-pnp-hub
        deviceId: my-pnp-device
        operationTimestamp: 2020-10-06T10:27:59.5159720+00:00
        iothub-message-schema: twinChangeNotification
        opType: updateTwin
System properties (set by IoT Hub):
        iothub-connection-device-id: my-pnp-device
        iothub-enqueuedtime: 06/10/2020 10:27:59
        iothub-message-source: twinChangeEvents
        user-id: System.ArraySegment`1[System.Byte]
        correlation-id: 615051f364e
        content-type: application/json
        content-encoding: utf-8

Odczytywanie powiadomień o zmianie cyfrowej reprezentacji bliźniaczej

Usługę IoT Hub można skonfigurować tak, aby generowała powiadomienia o zmianie cyfrowej reprezentacji bliźniaczej w celu kierowania do obsługiwanego punktu końcowego. Aby dowiedzieć się więcej, zobacz Używanie routingu komunikatów usługi IoT Hub do wysyłania komunikatów z urządzenia do chmury do różnych punktów końcowych zdarzeń niezwiązanych > z telemetrią.

Kod pokazany w poprzednim fragmencie kodu języka C# generuje następujące dane wyjściowe, gdy usługa IoT Hub generuje powiadomienia o zmianie cyfrowej reprezentacji bliźniaczej dla urządzenia termostatu bez składnika. Właściwości iothub-message-schema aplikacji i opType podaj informacje o typie powiadomienia o zmianie:

Message received on partition 1:
        [{"op":"add","path":"/$metadata/maxTempSinceLastReboot","value":{"lastUpdateTime":"2020-10-06T10:39:16.0209836Z"}},{"op":"add","path":"/maxTempSinceLastReboot","value":34.9}]:
Application properties (set by device):
        hubName: my-pnp-hub
        deviceId: my-pnp-device
        operationTimestamp: 2020-10-06T10:39:16.0209836+00:00
        iothub-message-schema: digitalTwinChangeNotification
        opType: updateTwin
System properties (set by IoT Hub):
        iothub-connection-device-id: my-pnp-device
        iothub-enqueuedtime: 06/10/2020 10:39:16
        iothub-message-source: digitalTwinChangeEvents
        user-id: System.ArraySegment`1[System.Byte]
        correlation-id: 6169857bf8c
        content-type: application/json-patch+json
        content-encoding: utf-8

Kod pokazany w poprzednim fragmencie kodu języka C# generuje następujące dane wyjściowe, gdy usługa IoT Hub generuje powiadomienia o zmianie cyfrowej reprezentacji bliźniaczej dla urządzenia ze składnikami. W tym przykładzie pokazano dane wyjściowe, gdy urządzenie czujnika temperatury ze składnikiem termostatu generuje powiadomienia. Właściwości iothub-message-schema aplikacji i opType podaj informacje o typie powiadomienia o zmianie:

Message received on partition 1:
        [{"op":"add","path":"/thermostat1","value":{"$metadata":{"maxTempSinceLastReboot":{"lastUpdateTime":"2020-10-06T10:41:44.8312666Z"}},"maxTempSinceLastReboot":29.1}}]:
Application properties (set by device):
        hubName: my-pnp-hub
        deviceId: my-pnp-device
        operationTimestamp: 2020-10-06T10:41:44.8312666+00:00
        iothub-message-schema: digitalTwinChangeNotification
        opType: updateTwin
System properties (set by IoT Hub):
        iothub-connection-device-id: my-pnp-device
        iothub-enqueuedtime: 06/10/2020 10:41:44
        iothub-message-source: digitalTwinChangeEvents
        user-id: System.ArraySegment`1[System.Byte]
        correlation-id: 616f108f0e3
        content-type: application/json-patch+json
        content-encoding: utf-8

Dostępne są również następujące zasoby:

Przykłady klientów usługi IoT Hub

W tej sekcji przedstawiono przykłady języka Java przy użyciu klienta usługi IoT Hub oraz klas DeviceTwin i DeviceMethod z przestrzeni nazw com.microsoft.azure.sdk.iot.service.devicetwin . Klasa DeviceTwin służy do interakcji ze stanem urządzenia przy użyciu bliźniaczych reprezentacji urządzeń. Możesz również użyć klasy DeviceTwin do wykonywania zapytań dotyczących rejestracji urządzeń w usłudze IoT Hub. Klasa DeviceMethod służy do wywoływania poleceń na urządzeniu. Model DTDL dla urządzenia definiuje właściwości i polecenia, które implementuje urządzenie. W fragmentach kodu zmienna deviceId przechowuje identyfikator urządzenia urządzenia IoT Plug and Play zarejestrowanego w centrum IoT.

Pobieranie bliźniaczej reprezentacji urządzenia i identyfikatora modelu

Aby uzyskać bliźniacze reprezentacje urządzenia i identyfikator modelu urządzenia IoT Plug and Play połączonego z centrum IoT:

DeviceTwin twinClient = DeviceTwin.createFromConnectionString(iotHubConnectionString);

// ...

DeviceTwinDevice twin = new DeviceTwinDevice(deviceId);
twinClient.getTwin(twin);
System.out.println("Model Id of this Twin is: " + twin.getModelId());

Aktualizowanie bliźniaczej reprezentacji urządzenia

Poniższy fragment kodu przedstawia sposób aktualizowania targetTemperature właściwości na urządzeniu. Przed zaktualizowaniem bliźniaczej reprezentacji należy ją pobrać. Właściwość jest definiowana w domyślnym składniku urządzenia:

DeviceTwin twinClient = DeviceTwin.createFromConnectionString(iotHubConnectionString);
DeviceTwinDevice twin = new DeviceTwinDevice(deviceId);
twinClient.getTwin(twin);

double propertyValue = 60.2;
twin.setDesiredProperties(Collections.singleton(new Pair("targetTemperature", propertyValue)));
twinClient.updateTwin(twin);

Poniższy fragment kodu pokazuje, jak zaktualizować targetTemperature właściwość składnika. Przed zaktualizowaniem bliźniaczej reprezentacji należy ją pobrać. Właściwość jest zdefiniowana w składniku termostat1 :

public static Set<Pair> CreateComponentPropertyPatch(@NonNull String propertyName, @NonNull double propertyValue, @NonNull String componentName)
{
    JsonObject patchJson = new JsonObject();
    patchJson.addProperty("__t", "c");
    patchJson.addProperty(propertyName, propertyValue);
    return singleton(new Pair(componentName, patchJson));
}

// ...

DeviceTwin twinClient = DeviceTwin.createFromConnectionString(iotHubConnectionString);
DeviceTwinDevice twin = new DeviceTwinDevice(deviceId);
twinClient.getTwin(twin);

double propertyValue = 60.2;
twin.setDesiredProperties(CreateComponentPropertyPatch("targetTemperature", propertyValue, "thermostat1"));
twinClient.updateTwin(twin);

W przypadku właściwości w składniku poprawka właściwości wygląda jak w poniższym przykładzie:

{
  "thermostat1":
  {
    "__t": "c",
    "targetTemperature": 60.2
  }
}

Wywołaj polecenie

Poniższy fragment kodu pokazuje, jak wywołać getMaxMinReport polecenie zdefiniowane w składniku domyślnym:

DeviceMethod methodClient = DeviceMethod.createFromConnectionString(iotHubConnectionString);

Long responseTimeout = TimeUnit.SECONDS.toSeconds(200);
Long connectTimeout = TimeUnit.SECONDS.toSeconds(5);

String commandInput = ZonedDateTime.now(ZoneOffset.UTC).minusMinutes(5).format(DateTimeFormatter.ISO_DATE_TIME);
MethodResult result = methodClient.invoke(deviceId, "getMaxMinReport", responseTimeout, connectTimeout, commandInput);

System.out.println("Method result status is: " + result.getStatus());

Poniższy fragment kodu pokazuje, jak wywołać getMaxMinReport polecenie w składniku. Polecenie jest zdefiniowane w składniku termostat1 :

DeviceMethod methodClient = DeviceMethod.createFromConnectionString(iotHubConnectionString);

Long responseTimeout = TimeUnit.SECONDS.toSeconds(200);
Long connectTimeout = TimeUnit.SECONDS.toSeconds(5);

String commandInput = ZonedDateTime.now(ZoneOffset.UTC).minusMinutes(5).format(DateTimeFormatter.ISO_DATE_TIME);
MethodResult result = methodClient.invoke(deviceId, "thermostat1*getMaxMinReport", responseTimeout, connectTimeout, commandInput);

System.out.println("Method result status is: " + result.getStatus());

Przykłady cyfrowej reprezentacji bliźniaczej usługi IoT Hub

Klasa DigitalTwinAsyncClient jest używana w przestrzeni nazw com.microsoft.azure.sdk.iot.service.digitaltwin do interakcji ze stanem urządzenia przy użyciu cyfrowych reprezentacji bliźniaczych. W poniższych przykładach użyto również klas UpdateOperationUtility i BasicDigitalTwin z tej samej przestrzeni nazw. Model DTDL dla urządzenia definiuje właściwości i polecenia, które implementuje urządzenie.

Zmienna digitalTwinid przechowuje identyfikator urządzenia urządzenia IoT Plug and Play zarejestrowanego w centrum IoT.

Pobieranie cyfrowej reprezentacji bliźniaczej i identyfikatora modelu

Aby uzyskać identyfikator cyfrowej reprezentacji bliźniaczej i modelu urządzenia IoT Plug and Play połączonego z centrum IoT:

DigitalTwinAsyncClient asyncClient = DigitalTwinAsyncClient.createFromConnectionString(iotHubConnectionString);

CountDownLatch latch = new CountDownLatch(1);
asyncClient.getDigitalTwin(digitalTwinid, BasicDigitalTwin.class)
    .subscribe(
        getResponse ->
        {
            System.out.println("Digital Twin Model Id: " + getResponse.getMetadata().getModelId());
            System.out.println("Digital Twin: " + prettyBasicDigitalTwin(getResponse));
            latch.countDown();
        },
        error ->
        {
            System.out.println("Get Digital Twin failed: " + error);
            latch.countDown();
        });

latch.await(10, TimeUnit.SECONDS);

// ...

private static String prettyBasicDigitalTwin(BasicDigitalTwin basicDigitalTwin)
{
    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    return gson.toJson(basicDigitalTwin);
}

Aktualizowanie cyfrowej reprezentacji bliźniaczej

Poniższy fragment kodu przedstawia sposób aktualizowania targetTemperature właściwości na urządzeniu. Właściwość jest definiowana w domyślnym składniku urządzenia:

DigitalTwinAsyncClient asyncClient = DigitalTwinAsyncClient.createFromConnectionString(iotHubConnectionString);

CountDownLatch latch1 = new CountDownLatch(1);

UpdateOperationUtility updateOperationUtility = new UpdateOperationUtility();

// Add a new property.
updateOperationUtility.appendAddPropertyOperation("/" + "targetTemperature", 35);
asyncClient.updateDigitalTwin(digitalTwinid, updateOperationUtility.getUpdateOperations())
    .subscribe(
        getResponse ->
        {
            System.out.println("Updated Digital Twin");
            latch1.countDown();
        },
        error ->
        {
            System.out.println("Update Digital Twin failed: " + error);
            latch1.countDown();
        });
latch1.await(10, TimeUnit.SECONDS);
GetDigitalTwin();

// Replace an existing property.
CountDownLatch latch2 = new CountDownLatch(1);
updateOperationUtility.appendReplacePropertyOperation("/targetTemperature", 50);
asyncClient.updateDigitalTwin(digitalTwinid, updateOperationUtility.getUpdateOperations())
    .subscribe(
        getResponse ->
        {
            System.out.println("Updated Digital Twin");
            latch2.countDown();
        },
        error ->
        {
            System.out.println("Update Digital Twin failed: " + error);
            latch2.countDown();
        });

latch2.await(10, TimeUnit.SECONDS);
GetDigitalTwin();

Poniższy fragment kodu pokazuje, jak zaktualizować targetTemperature właściwość składnika. Właściwość jest zdefiniowana w składniku termostat1 :

DigitalTwinClient client = DigitalTwinClient.createFromConnectionString(iotHubConnectionString);

// Get digital twin.
ServiceResponseWithHeaders<String, DigitalTwinGetHeaders> getResponse = client.getDigitalTwinWithResponse(digitalTwinid, String.class);

// Construct the options for conditional update.
DigitalTwinUpdateRequestOptions options = new DigitalTwinUpdateRequestOptions();
options.setIfMatch(getResponse.headers().eTag());

UpdateOperationUtility updateOperationUtility = new UpdateOperationUtility();

Map<String, Object> t1properties = new HashMap<>();
t1properties.put("targetTemperature", 50);
updateOperationUtility.appendReplaceComponentOperation("/thermostat1", t1properties);

digitalTwinUpdateOperations = updateOperationUtility.getUpdateOperations();
updateResponse = client.updateDigitalTwinWithResponse(digitalTwinid, digitalTwinUpdateOperations, options);
System.out.println("Update Digital Twin response status: " + updateResponse.response().message());

getResponse = client.getDigitalTwinWithResponse(digitalTwinid, String.class);

Wywołaj polecenie

Poniższy fragment kodu pokazuje, jak wywołać getMaxMinReport polecenie zdefiniowane w składniku domyślnym:

CountDownLatch latch = new CountDownLatch(1);

String commandInput = ZonedDateTime.now(ZoneOffset.UTC).minusMinutes(5).format(DateTimeFormatter.ISO_DATE_TIME);

// Invoke a method on root level.
asyncClient.invokeCommand(digitalTwinid, "getMaxMinReport", commandInput)
    .subscribe(
        response ->
        {
            System.out.println("Invoked Command getMaxMinReport response: " + prettyString(response.getPayload()));
            latch.countDown();
        },
        error ->
        {
            RestException ex = (RestException)error;
            if(ex.response().code() == 404) {
                System.out.println("Invoked Command getMaxMinReport failed: " + error);
            }
            else {
                System.out.println("Ensure the device sample is running for this sample to succeed");
            }
            latch.countDown();
        });

latch.await(10, TimeUnit.SECONDS);

// ...

private static String prettyString(String str)
{
    Gson gson = new Gson();
    Gson gsonBuilder = new GsonBuilder().setPrettyPrinting().create();
    return gsonBuilder.toJson(gson.fromJson(str, Object.class));
}

Poniższy fragment kodu pokazuje, jak wywołać getMaxMinReport polecenie w składniku. Polecenie jest zdefiniowane w składniku termostat1 :

DigitalTwinClient client = DigitalTwinClient.createFromConnectionString(iotHubConnectionString);

String commandInput = ZonedDateTime.now(ZoneOffset.UTC).minusMinutes(5).format(DateTimeFormatter.ISO_DATE_TIME);

DigitalTwinInvokeCommandRequestOptions options = new DigitalTwinInvokeCommandRequestOptions();
try {
    ServiceResponseWithHeaders<DigitalTwinCommandResponse, DigitalTwinInvokeCommandHeaders> commandResponse = client.invokeComponentCommandWithResponse(digitalTwinid, "thermostat1", "getMaxMinReport", commandInput, options);
    System.out.println("Command getMaxMinReport, payload: " + prettyString(commandResponse.body().getPayload()));
    System.out.println("Command getMaxMinReport, status: " + commandResponse.body().getStatus());
} catch (RestException ex)
{
    if(ex.response().code() == 404)
    {
        System.out.println("Ensure the device sample is running for this sample to succeed.");
    }
    else
    {
        throw ex;
    }
}

// ...

private static String prettyString(String str)
{
    Gson gson = new Gson();
    Gson gsonBuilder = new GsonBuilder().setPrettyPrinting().create();
    return gsonBuilder.toJson(gson.fromJson(str, Object.class));
}

Odczytywanie danych telemetrycznych urządzenia

Urządzenia IoT Plug and Play wysyłają dane telemetryczne zdefiniowane w modelu DTDL do usługi IoT Hub. Domyślnie usługa IoT Hub kieruje dane telemetryczne do punktu końcowego usługi Event Hubs, w którym można z niego korzystać. Aby dowiedzieć się więcej, zobacz Wysyłanie komunikatów z urządzenia do chmury do różnych punktów końcowych przy użyciu routingu komunikatów usługi IoT Hub.

Poniższy fragment kodu pokazuje, jak odczytywać dane telemetryczne z domyślnego punktu końcowego usługi Event Hubs. Kod w tym fragmencie kodu jest pobierany z przewodnika Szybki start usługi IoT Hub Wysyłanie danych telemetrycznych z urządzenia do centrum IoT i odczytywanie go za pomocą aplikacji zaplecza:

import com.azure.messaging.eventhubs.EventHubClientBuilder;
import com.azure.messaging.eventhubs.EventHubConsumerAsyncClient;

// ...

EventHubClientBuilder eventHubClientBuilder = new EventHubClientBuilder()
    .consumerGroup(EventHubClientBuilder.DEFAULT_CONSUMER_GROUP_NAME)
    .connectionString(eventHubCompatibleConnectionString);

try (EventHubConsumerAsyncClient eventHubConsumerAsyncClient = eventHubClientBuilder.buildAsyncConsumerClient()) {

    receiveFromAllPartitions(eventHubConsumerAsyncClient);

}

// ...

private static void receiveFromAllPartitions(EventHubConsumerAsyncClient eventHubConsumerAsyncClient) {

eventHubConsumerAsyncClient
    .receive(false) // set this to false to read only the newly available events
    .subscribe(partitionEvent -> {
        System.out.println();
        System.out.printf("%nTelemetry received from partition %s:%n%s",
            partitionEvent.getPartitionContext().getPartitionId(), partitionEvent.getData().getBodyAsString());
        System.out.printf("%nApplication properties (set by device):%n%s", partitionEvent.getData().getProperties());
        System.out.printf("%nSystem properties (set by IoT Hub):%n%s",
            partitionEvent.getData().getSystemProperties());
    }, ex -> {
        System.out.println("Error receiving events " + ex);
    }, () -> {
        System.out.println("Completed receiving events");
    });
}

Poniższe dane wyjściowe z poprzedniego kodu pokazują dane telemetryczne temperatury wysyłane przez urządzenie IoT Plug and Play bez składnika termostatu , które ma tylko składnik domyślny. Właściwość dt-dataschema systemowa pokazuje identyfikator modelu:

Telemetry received from partition 1:
{"temperature": 10.700000}
Application properties (set by device):
{$.cdid=my-pnp-device}
System properties (set by IoT Hub):
{correlation-id=aaaa0000-bb11-2222-33cc-444444dddddd, content-encoding=UTF-8, iothub-connection-auth-method={"scope":"device","type":"sas","issuer":"iothub","acceptingIpFilterRule":null}, iothub-enqueuedtime=Tue Oct 20 12:28:10 BST 2020, dt-dataschema=dtmi:com:example:Thermostat;1, absolute-expiry-time=0, iothub-connection-device-id=my-pnp-device, iothub-connection-auth-generation-id=637375776990653481, group-sequence=0, iothub-message-source=Telemetry, creation-time=0, message-id=aaaabbbb-0000-cccc-1111-dddd2222eeee, content-type=application/json}

Telemetry received from partition 1:
{"temperature": 10.700000}
Application properties (set by device):
{$.cdid=my-pnp-device}
System properties (set by IoT Hub):
{correlation-id=bbbb1111-cc22-3333-44dd-555555eeeeee, content-encoding=UTF-8, iothub-connection-auth-method={"scope":"device","type":"sas","issuer":"iothub","acceptingIpFilterRule":null}, iothub-enqueuedtime=Tue Oct 20 12:28:15 BST 2020, dt-dataschema=dtmi:com:example:Thermostat;1, absolute-expiry-time=0, iothub-connection-device-id=my-pnp-device, iothub-connection-auth-generation-id=637375776990653481, group-sequence=0, iothub-message-source=Telemetry, creation-time=0, message-id=bbbbcccc-1111-dddd-2222-eeee3333ffff, content-type=application/json}

Poniższe dane wyjściowe z poprzedniego kodu pokazują dane telemetryczne temperatury wysyłane przez wieloskładnikowe urządzenie TemperatureController IoT Plug and Play. Właściwość dt-subject systemowa zawiera nazwę składnika, który wysłał dane telemetryczne. W tym przykładzie dwa składniki są thermostat1 i thermostat2 zgodnie z definicją w modelu DTDL. Właściwość dt-dataschema systemowa pokazuje identyfikator modelu:

Telemetry received from partition 1:
null
Application properties (set by device):
{$.cdid=my-pnp-device}
System properties (set by IoT Hub):
{correlation-id=cccc2222-dd33-4444-55ee-666666ffffff, content-encoding=UTF-8, iothub-connection-auth-method={"scope":"device","type":"sas","issuer":"iothub","acceptingIpFilterRule":null}, iothub-enqueuedtime=Tue Oct 20 12:31:14 BST 2020, dt-dataschema=dtmi:com:example:TemperatureController;1, absolute-expiry-time=0, iothub-connection-device-id=my-pnp-device, iothub-connection-auth-generation-id=637387902591517456, group-sequence=0, iothub-message-source=Telemetry, creation-time=0, message-id=ccccdddd-2222-eeee-3333-ffff4444aaaa, content-type=application/json, dt-subject=thermostat1}

Telemetry received from partition 1:
null
Application properties (set by device):
{$.cdid=my-pnp-device}
System properties (set by IoT Hub):
{correlation-id=dddd3333-ee44-5555-66ff-777777aaaaaa, content-encoding=UTF-8, iothub-connection-auth-method={"scope":"device","type":"sas","issuer":"iothub","acceptingIpFilterRule":null}, iothub-enqueuedtime=Tue Oct 20 12:31:14 BST 2020, dt-dataschema=dtmi:com:example:TemperatureController;1, absolute-expiry-time=0, iothub-connection-device-id=my-pnp-device, iothub-connection-auth-generation-id=637387902591517456, group-sequence=0, iothub-message-source=Telemetry, creation-time=0, message-id=ddddeeee-3333-ffff-4444-aaaa5555bbbb, content-type=application/json, dt-subject=thermostat2}

Odczytywanie powiadomień o zmianie bliźniaczej reprezentacji urządzenia

Usługę IoT Hub można skonfigurować do generowania powiadomień o zmianie bliźniaczej reprezentacji urządzenia w celu kierowania do obsługiwanego punktu końcowego. Aby dowiedzieć się więcej, zobacz Używanie routingu komunikatów usługi IoT Hub do wysyłania komunikatów z urządzenia do chmury do różnych punktów końcowych zdarzeń niezwiązanych > z telemetrią.

Kod pokazany w poprzednim fragmencie kodu Java generuje następujące dane wyjściowe, gdy usługa IoT Hub generuje powiadomienia o zmianie bliźniaczej reprezentacji urządzenia dla urządzenia termostatu bez składnika. Właściwości iothub-message-schema aplikacji i opType podaj informacje o typie powiadomienia o zmianie:

Telemetry received from partition 1:
{"version":11,"properties":{"reported":{"maxTempSinceLastReboot":43.4,"$metadata":{"$lastUpdated":"2020-10-20T11:50:41.123127Z","maxTempSinceLastReboot":{"$lastUpdated":"2020-10-20T11:50:41.123127Z"}},"$version":10}}}
Application properties (set by device):
{operationTimestamp=2020-10-20T11:50:41.1231270+00:00, opType=updateTwin, hubName=my-pnp-hub, deviceId=my-pnp-device, iothub-message-schema=twinChangeNotification}
System properties (set by IoT Hub):
{user-id=[B@12fd5bb4, correlation-id=11339418426a, content-encoding=utf-8, iothub-enqueuedtime=Tue Oct 20 12:50:41 BST 2020, absolute-expiry-time=0, iothub-connection-device-id=my-pnp-device, group-sequence=0, iothub-message-source=twinChangeEvents, creation-time=0, content-type=application/json}

Kod pokazany w poprzednim fragmencie kodu Java generuje następujące dane wyjściowe, gdy usługa IoT Hub generuje powiadomienia o zmianie bliźniaczej reprezentacji urządzenia dla urządzenia ze składnikami. W tym przykładzie pokazano dane wyjściowe, gdy urządzenie czujnika temperatury ze składnikiem termostatu generuje powiadomienia. Właściwości iothub-message-schema aplikacji i opType podaj informacje o typie powiadomienia o zmianie:

Telemetry received from partition 1:
{"version":9,"properties":{"reported":{"thermostat1":{"__t":"c","maxTempSinceLastReboot":32.5},"$metadata":{"$lastUpdated":"2020-10-20T11:48:01.2960851Z","thermostat1":{"$lastUpdated":"2020-10-20T11:48:01.2960851Z","__t":{"$lastUpdated":"2020-10-20T11:48:01.2960851Z"},"maxTempSinceLastReboot":{"$lastUpdated":"2020-10-20T11:48:01.2960851Z"}}},"$version":8}}}
Application properties (set by device):
{operationTimestamp=2020-10-20T11:48:01.2960851+00:00, opType=updateTwin, hubName=my-pnp-hub, deviceId=my-pnp-device, iothub-message-schema=twinChangeNotification}
System properties (set by IoT Hub):
{user-id=[B@23949bae, correlation-id=113334d542e1, content-encoding=utf-8, iothub-enqueuedtime=Tue Oct 20 12:48:01 BST 2020, absolute-expiry-time=0, iothub-connection-device-id=my-pnp-device, group-sequence=0, iothub-message-source=twinChangeEvents, creation-time=0, content-type=application/json}

Odczytywanie powiadomień o zmianie cyfrowej reprezentacji bliźniaczej

Usługę IoT Hub można skonfigurować tak, aby generowała powiadomienia o zmianie cyfrowej reprezentacji bliźniaczej w celu kierowania do obsługiwanego punktu końcowego. Aby dowiedzieć się więcej, zobacz Używanie routingu komunikatów usługi IoT Hub do wysyłania komunikatów z urządzenia do chmury do różnych punktów końcowych zdarzeń niezwiązanych > z telemetrią.

Kod pokazany w poprzednim fragmencie kodu Java generuje następujące dane wyjściowe, gdy usługa IoT Hub generuje powiadomienia o zmianie cyfrowej reprezentacji bliźniaczej dla urządzenia termostatu bez składnika. Właściwości iothub-message-schema aplikacji i opType podaj informacje o typie powiadomienia o zmianie:

Telemetry received from partition 1:
[{"op":"replace","path":"/$metadata/maxTempSinceLastReboot/lastUpdateTime","value":"2020-10-20T11:52:40.627628Z"},{"op":"replace","path":"/maxTempSinceLastReboot","value":16.9}]
Application properties (set by device):
{operationTimestamp=2020-10-20T11:52:40.6276280+00:00, opType=updateTwin, hubName=my-pnp-hub, deviceId=my-pnp-device, iothub-message-schema=digitalTwinChangeNotification}
System properties (set by IoT Hub):
{user-id=[B@4475ce2a, correlation-id=1133db52c0e0, content-encoding=utf-8, iothub-enqueuedtime=Tue Oct 20 12:52:40 BST 2020, absolute-expiry-time=0, iothub-connection-device-id=my-pnp-device, group-sequence=0, iothub-message-source=digitalTwinChangeEvents, creation-time=0, content-type=application/json-patch+json}

Kod pokazany w poprzednim fragmencie kodu Java generuje następujące dane wyjściowe, gdy usługa IoT Hub generuje powiadomienia o zmianie cyfrowej reprezentacji bliźniaczej dla urządzenia ze składnikami. W tym przykładzie pokazano dane wyjściowe, gdy urządzenie czujnika temperatury ze składnikiem termostatu generuje powiadomienia. Właściwości iothub-message-schema aplikacji i opType podaj informacje o typie powiadomienia o zmianie:

Telemetry received from partition 1:
[{"op":"add","path":"/thermostat1","value":{"$metadata":{"maxTempSinceLastReboot":{"lastUpdateTime":"2020-10-20T11:31:04.7811405Z"}},"maxTempSinceLastReboot":27.2}}]
Application properties (set by device):
{operationTimestamp=2020-10-20T11:31:04.7811405+00:00, opType=updateTwin, hubName=my-pnp-hub, deviceId=my-pnp-device, iothub-message-schema=digitalTwinChangeNotification}
System properties (set by IoT Hub):
{user-id=[B@75981aa, correlation-id=1130d6f4d212, content-encoding=utf-8, iothub-enqueuedtime=Tue Oct 20 12:31:04 BST 2020, absolute-expiry-time=0, iothub-connection-device-id=my-pnp-device, group-sequence=0, iothub-message-source=digitalTwinChangeEvents, creation-time=0, content-type=application/json-patch+json}

Dostępne są również następujące zasoby:

Przykłady klientów usługi IoT Hub

W tej sekcji przedstawiono przykłady języka JavaScript przy użyciu klienta usługi IoT Hub i klas Rejestru i klienta . Klasa Registry służy do interakcji ze stanem urządzenia przy użyciu bliźniaczych reprezentacji urządzeń. Możesz również użyć klasy Registry do wykonywania zapytań dotyczących rejestracji urządzeń w usłudze IoT Hub. Klasa Client służy do wywoływania poleceń na urządzeniu. Model DTDL dla urządzenia definiuje właściwości i polecenia, które implementuje urządzenie. W fragmentach kodu zmienna deviceId przechowuje identyfikator urządzenia urządzenia IoT Plug and Play zarejestrowanego w centrum IoT.

Pobieranie bliźniaczej reprezentacji urządzenia i identyfikatora modelu

Aby uzyskać bliźniacze reprezentacje urządzenia i identyfikator modelu urządzenia IoT Plug and Play połączonego z centrum IoT:

var Registry = require('azure-iothub').Registry;

// ...

var registry = Registry.fromConnectionString(connectionString);
registry.getTwin(deviceId, function(err, twin) {
  if (err) {
    console.error(err.message);
  } else {
    console.log('Model Id: ' + twin.modelId);
    console.log(JSON.stringify(twin, null, 2));
  }
}

Aktualizowanie bliźniaczej reprezentacji urządzenia

Poniższy fragment kodu przedstawia sposób aktualizowania targetTemperature właściwości na urządzeniu. W przykładzie pokazano, jak należy pobrać bliźniacze reprezentację przed jej zaktualizowaniem. Właściwość jest definiowana w domyślnym składniku urządzenia:

var Registry = require('azure-iothub').Registry;
var registry = Registry.fromConnectionString(connectionString);

registry.getTwin(deviceId, function(err, twin) {
  if (err) {
    console.error(err.message);
  } else {
    var twinPatch = {
      properties: {
        desired: {
          targetTemperature: 42
        }
      }
    };
    twin.update(twinPatch, function(err, twin) {
      if (err) {
        console.error(err.message);
      } else {
        console.log(JSON.stringify(twin, null, 2));
      }
    }
  }
}

Poniższy fragment kodu pokazuje, jak zaktualizować targetTemperature właściwość składnika. W przykładzie pokazano, jak należy pobrać bliźniacze reprezentację przed jej zaktualizowaniem. Właściwość jest zdefiniowana w składniku termostat1 :

var Registry = require('azure-iothub').Registry;
var registry = Registry.fromConnectionString(connectionString);

registry.getTwin(deviceId, function(err, twin) {
  if (err) {
    console.error(err.message);
  } else {
    var twinPatch = {
      properties: {
        desired: {
          thermostat1:
          {
            __t: "c",
            targetTemperature: 45
          }
        }
      }
    };
    twin.update(twinPatch, function(err, twin) {
      if (err) {
        console.error(err.message);
      } else {
        console.log(JSON.stringify(twin, null, 2));
      }
    }
  }
}

W przypadku właściwości w składniku poprawka właściwości wygląda jak w poniższym przykładzie:

{
  "thermostat1":
  {
    "__t": "c",
    "targetTemperature": 20
  }
}

Wywołaj polecenie

Poniższy fragment kodu pokazuje, jak wywołać getMaxMinReport polecenie zdefiniowane w składniku domyślnym:

var Client = require('azure-iothub').Client;

// ...

var client = Client.fromConnectionString(connectionString);

var methodParams = {
  methodName: "getMaxMinReport",
  payload: new Date().getMinutes -2,
  responseTimeoutInSeconds: 15
};

client.invokeDeviceMethod(deviceId, methodParams, function (err, result) {
  if (err) {
    console.error('Failed to invoke method \'' + methodParams.methodName + '\': ' + err.message);
  } else {
    console.log(methodParams.methodName + ' on ' + deviceId + ':');
    console.log(JSON.stringify(result, null, 2));
  }
});

Poniższy fragment kodu pokazuje, jak wywołać getMaxMinReport polecenie w składniku. Polecenie jest zdefiniowane w składniku termostat1 :

var Client = require('azure-iothub').Client;

// ...

var client = Client.fromConnectionString(connectionString);

var methodParams = {
  methodName: "thermostat1*getMaxMinReport",
  payload: new Date().getMinutes -2,
  responseTimeoutInSeconds: 15
};

client.invokeDeviceMethod(deviceId, methodParams, function (err, result) {
  if (err) {
    console.error('Failed to invoke method \'' + methodParams.methodName + '\': ' + err.message);
  } else {
    console.log(methodParams.methodName + ' on ' + deviceId + ':');
    console.log(JSON.stringify(result, null, 2));
  }
});

Przykłady cyfrowej reprezentacji bliźniaczej usługi IoT Hub

Klasa DigitalTwinClient służy do interakcji ze stanem urządzenia przy użyciu cyfrowych reprezentacji bliźniaczych. Model DTDL dla urządzenia definiuje właściwości i polecenia, które implementuje urządzenie.

W tej sekcji przedstawiono przykłady języka JavaScript korzystające z interfejsu API usługi Digital Twins.

Zmienna digitalTwinId przechowuje identyfikator urządzenia urządzenia IoT Plug and Play zarejestrowanego w centrum IoT.

Pobieranie cyfrowej reprezentacji bliźniaczej i identyfikatora modelu

Aby uzyskać identyfikator cyfrowej reprezentacji bliźniaczej i modelu urządzenia IoT Plug and Play połączonego z centrum IoT:

const IoTHubTokenCredentials = require('azure-iothub').IoTHubTokenCredentials;
const DigitalTwinClient = require('azure-iothub').DigitalTwinClient;
const { inspect } = require('util');

// ...

const credentials = new IoTHubTokenCredentials(connectionString);
const digitalTwinClient = new DigitalTwinClient(credentials);

const digitalTwin = await digitalTwinClient.getDigitalTwin(digitalTwinId);

console.log(inspect(digitalTwin));
console.log('Model Id: ' + inspect(digitalTwin.$metadata.$model));

Aktualizowanie cyfrowej reprezentacji bliźniaczej

Poniższy fragment kodu przedstawia sposób aktualizowania targetTemperature właściwości na urządzeniu. Właściwość jest definiowana w domyślnym składniku urządzenia:

const IoTHubTokenCredentials = require('azure-iothub').IoTHubTokenCredentials;
const DigitalTwinClient = require('azure-iothub').DigitalTwinClient;

// ...

const credentials = new IoTHubTokenCredentials(connString);
const digitalTwinClient = new DigitalTwinClient(credentials);

const patch = [{
  op: 'add',
  path: '/targetTemperature',
  value: 42
}];
await digitalTwinClient.updateDigitalTwin(digitalTwinId, patch);

Poniższy fragment kodu pokazuje, jak zaktualizować targetTemperature właściwość składnika. Właściwość jest zdefiniowana w składniku termostat1 :

const IoTHubTokenCredentials = require('azure-iothub').IoTHubTokenCredentials;
const DigitalTwinClient = require('azure-iothub').DigitalTwinClient;

// ...

const credentials = new IoTHubTokenCredentials(connString);
const digitalTwinClient = new DigitalTwinClient(credentials);

const patch = [{
  op: 'add',
  path: '/thermostat1/targetTemperature',
  value: 42
}];
await digitalTwinClient.updateDigitalTwin(digitalTwinId, patch);

Wywołaj polecenie

Poniższy fragment kodu pokazuje, jak wywołać getMaxMinReport polecenie zdefiniowane w składniku domyślnym:

const IoTHubTokenCredentials = require('azure-iothub').IoTHubTokenCredentials;
const DigitalTwinClient = require('azure-iothub').DigitalTwinClient;
const { inspect } = require('util');

// ...

const commandPayload = new Date().getMinutes -2;

const credentials = new IoTHubTokenCredentials(connectionString);
const digitalTwinClient = new DigitalTwinClient(credentials);

const options = {
  connectTimeoutInSeconds: 30,
  responseTimeoutInSeconds: 40
};
const commandResponse = await digitalTwinClient.invokeCommand(digitalTwinId, "getMaxMinReport", commandPayload, options);

console.log(inspect(commandResponse));

Poniższy fragment kodu pokazuje, jak wywołać getMaxMinReport polecenie w składniku. Polecenie jest zdefiniowane w składniku termostat1 :

const IoTHubTokenCredentials = require('azure-iothub').IoTHubTokenCredentials;
const DigitalTwinClient = require('azure-iothub').DigitalTwinClient;
const { inspect } = require('util');

// ...

const commandPayload = new Date().getMinutes -2;

const credentials = new IoTHubTokenCredentials(connectionString);
const digitalTwinClient = new DigitalTwinClient(credentials);

const options = {
  connectTimeoutInSeconds: 30,
  responseTimeoutInSeconds: 40
};
const commandResponse = await digitalTwinClient.invokeComponentCommand(digitalTwinId, "thermostat1", "getMaxMinReport", commandPayload, options);

console.log(inspect(commandResponse));

Odczytywanie danych telemetrycznych urządzenia

Urządzenia IoT Plug and Play wysyłają dane telemetryczne zdefiniowane w modelu DTDL do usługi IoT Hub. Domyślnie usługa IoT Hub kieruje dane telemetryczne do punktu końcowego usługi Event Hubs, w którym można z niego korzystać. Aby dowiedzieć się więcej, zobacz Wysyłanie komunikatów z urządzenia do chmury do różnych punktów końcowych przy użyciu routingu komunikatów usługi IoT Hub.

Poniższy fragment kodu pokazuje, jak odczytywać dane telemetryczne z domyślnego punktu końcowego usługi Event Hubs. Kod w tym fragmencie kodu jest pobierany z przewodnika Szybki start usługi IoT Hub Wysyłanie danych telemetrycznych z urządzenia do centrum IoT i odczytywanie go za pomocą aplikacji zaplecza:

const { EventHubConsumerClient } = require("@azure/event-hubs");

var printError = function (err) {
  console.log(err.message);
};

var printMessages = function (messages) {
  for (const message of messages) {
    console.log("Telemetry received: ");
    console.log(JSON.stringify(message.body));
    console.log("Properties (set by device): ");
    console.log(JSON.stringify(message.properties));
    console.log("System properties (set by IoT Hub): ");
    console.log(JSON.stringify(message.systemProperties));
    console.log("");
  }
};

// ...

const clientOptions = {};

const consumerClient = new EventHubConsumerClient("$Default", connectionString, clientOptions);

consumerClient.subscribe({
  processEvents: printMessages,
  processError: printError,
});

Poniższe dane wyjściowe z poprzedniego kodu pokazują dane telemetryczne temperatury wysyłane przez wieloskładnikowe urządzenie TemperatureController IoT Plug and Play. Właściwość dt-subject systemowa zawiera nazwę składnika, który wysłał dane telemetryczne. W tym przykładzie dwa składniki są thermostat1 i thermostat2 zgodnie z definicją w modelu DTDL. Właściwość dt-dataschema systemowa pokazuje identyfikator modelu:

Telemetry received:
{"temperature":68.77370855171125}
Properties (set by device):
undefined
System properties (set by IoT Hub):
{"iothub-connection-device-id":"my-pnp-device","iothub-connection-auth-method":"{\"scope\":\"device\",\"type\":\"sas\",\"issuer\":\"iothub\",\"acceptingIpFilterRule\":null}","iothub-connection-auth-generation-id":"637388034455888246","iothub-enqueuedtime":1603206669320,"iothub-message-source":"Telemetry","dt-subject":"thermostat1","dt-dataschema":"dtmi:com:example:TemperatureController;1","contentType":"application/json","contentEncoding":"utf-8"}

Telemetry received:
{"temperature":30.833394506549226}
Properties (set by device):
undefined
System properties (set by IoT Hub):
{"iothub-connection-device-id":"my-pnp-device","iothub-connection-auth-method":"{\"scope\":\"device\",\"type\":\"sas\",\"issuer\":\"iothub\",\"acceptingIpFilterRule\":null}","iothub-connection-auth-generation-id":"637388034455888246","iothub-enqueuedtime":1603206665835,"iothub-message-source":"Telemetry","dt-subject":"thermostat2","dt-dataschema":"dtmi:com:example:TemperatureController;1","contentType":"application/json","contentEncoding":"utf-8"}

Odczytywanie powiadomień o zmianie bliźniaczej reprezentacji urządzenia

Usługę IoT Hub można skonfigurować do generowania powiadomień o zmianie bliźniaczej reprezentacji urządzenia w celu kierowania do obsługiwanego punktu końcowego. Aby dowiedzieć się więcej, zobacz Używanie routingu komunikatów usługi IoT Hub do wysyłania komunikatów z urządzenia do chmury do różnych punktów końcowych zdarzeń niezwiązanych > z telemetrią.

Kod pokazany w poprzednim fragmencie kodu JavaScript generuje następujące dane wyjściowe, gdy usługa IoT Hub generuje powiadomienia o zmianie bliźniaczej reprezentacji urządzenia dla urządzenia termostatu bez składnika. Właściwości iothub-message-schema aplikacji i opType podaj informacje o typie powiadomienia o zmianie:

Telemetry received:
{"version":4,"properties":{"reported":{"maxTempSinceLastReboot":42.1415152639582,"$metadata":{"$lastUpdated":"2020-10-21T10:01:40.1281138Z","maxTempSinceLastReboot":{"$lastUpdated":"2020-10-21T10:01:40.1281138Z"}},"$version":3}}}
Properties (set by device):
{"hubName":"my-pnp-hub","deviceId":"my-pnp-device","operationTimestamp":"2020-10-21T10:01:40.1281138+00:00","iothub-message-schema":"twinChangeNotification","opType":"updateTwin"}
System properties (set by IoT Hub):
{"iothub-connection-device-id":"my-pnp-device","iothub-enqueuedtime":1603274500282,"iothub-message-source":"twinChangeEvents","userId":{"type":"Buffer","data":[109,121,45,112,110,112,45,104,117,98]},"correlationId":"11ed82d13f50","contentType":"application/json","contentEncoding":"utf-8"}

Kod pokazany w poprzednim fragmencie kodu JavaScript generuje następujące dane wyjściowe, gdy usługa IoT Hub generuje powiadomienia o zmianie bliźniaczej reprezentacji urządzenia dla urządzenia ze składnikami. W tym przykładzie pokazano dane wyjściowe, gdy urządzenie czujnika temperatury ze składnikiem termostatu generuje powiadomienia. Właściwości iothub-message-schema aplikacji i opType podaj informacje o typie powiadomienia o zmianie:

Telemetry received:
{"version":4,"properties":{"reported":{"thermostat1":{"maxTempSinceLastReboot":3.5592971602417913,"__t":"c"},"$metadata":{"$lastUpdated":"2020-10-21T10:07:51.8284866Z","thermostat1":{"$lastUpdated":"2020-10-21T10:07:51.8284866Z","maxTempSinceLastReboot":{"$lastUpdated":"2020-10-21T10:07:51.8284866Z"},"__t":{"$lastUpdated":"2020-10-21T10:07:51.8284866Z"}}},"$version":3}}}
Properties (set by device):
{"hubName":"my-pnp-hub","deviceId":"my-pnp-device","operationTimestamp":"2020-10-21T10:07:51.8284866+00:00","iothub-message-schema":"twinChangeNotification","opType":"updateTwin"}
System properties (set by IoT Hub):
{"iothub-connection-device-id":"my-pnp-device","iothub-enqueuedtime":1603274871951,"iothub-message-source":"twinChangeEvents","userId":{"type":"Buffer","data":[109,121,45,112,110,112,45,104,117,98]},"correlationId":"11ee605b195f","contentType":"application/json","contentEncoding":"utf-8"}

Odczytywanie powiadomień o zmianie cyfrowej reprezentacji bliźniaczej

Usługę IoT Hub można skonfigurować tak, aby generowała powiadomienia o zmianie cyfrowej reprezentacji bliźniaczej w celu kierowania do obsługiwanego punktu końcowego. Aby dowiedzieć się więcej, zobacz Używanie routingu komunikatów usługi IoT Hub do wysyłania komunikatów z urządzenia do chmury do różnych punktów końcowych zdarzeń niezwiązanych > z telemetrią.

Kod pokazany w poprzednim fragmencie kodu JavaScript generuje następujące dane wyjściowe, gdy usługa IoT Hub generuje powiadomienia o zmianie cyfrowej reprezentacji bliźniaczej dla urządzenia termostatu bez składnika. Właściwości iothub-message-schema aplikacji i opType podaj informacje o typie powiadomienia o zmianie:

Telemetry received:
[{"op":"add","path":"/$metadata/maxTempSinceLastReboot","value":{"lastUpdateTime":"2020-10-21T10:01:40.1281138Z"}},{"op":"add","path":"/maxTempSinceLastReboot","value":42.1415152639582}]
Properties (set by device):
{"hubName":"my-pnp-hub","deviceId":"my-pnp-device","operationTimestamp":"2020-10-21T10:01:40.1281138+00:00","iothub-message-schema":"digitalTwinChangeNotification","opType":"updateTwin"}
System properties (set by IoT Hub):
{"iothub-connection-device-id":"my-pnp-device","iothub-enqueuedtime":1603274500282,"iothub-message-source":"digitalTwinChangeEvents","userId":{"type":"Buffer","data":[109,121,45,112,110,112,45,104,117,98]},"correlationId":"11ed82d13f50","contentType":"application/json-patch+json","contentEncoding":"utf-8"}

Kod pokazany w poprzednim fragmencie kodu JavaScript generuje następujące dane wyjściowe, gdy usługa IoT Hub generuje powiadomienia o zmianie cyfrowej reprezentacji bliźniaczej dla urządzenia ze składnikami. W tym przykładzie pokazano dane wyjściowe, gdy urządzenie czujnika temperatury ze składnikiem termostatu generuje powiadomienia. Właściwości iothub-message-schema aplikacji i opType podaj informacje o typie powiadomienia o zmianie:

Telemetry received:
[{"op":"add","path":"/thermostat1","value":{"$metadata":{"maxTempSinceLastReboot":{"lastUpdateTime":"2020-10-21T10:07:51.8284866Z"}},"maxTempSinceLastReboot":3.5592971602417913}}]
Properties (set by device):
{"hubName":"my-pnp-hub","deviceId":"my-pnp-device","operationTimestamp":"2020-10-21T10:07:51.8284866+00:00","iothub-message-schema":"digitalTwinChangeNotification","opType":"updateTwin"}
System properties (set by IoT Hub):
{"iothub-connection-device-id":"my-pnp-device","iothub-enqueuedtime":1603274871951,"iothub-message-source":"digitalTwinChangeEvents","userId":{"type":"Buffer","data":[109,121,45,112,110,112,45,104,117,98]},"correlationId":"11ee605b195f","contentType":"application/json-patch+json","contentEncoding":"utf-8"}

Dostępne są również następujące zasoby:

Przykłady klientów usługi IoT Hub

W tej sekcji przedstawiono przykłady języka Python przy użyciu klienta usługi IoT Hub oraz klas IoTHubRegistryManager i CloudToDeviceMethod . Klasa IoTHubRegistryManager umożliwia interakcję ze stanem urządzenia przy użyciu bliźniaczych reprezentacji urządzeń. Możesz również użyć klasy IoTHubRegistryManager do wykonywania zapytań dotyczących rejestracji urządzeń w usłudze IoT Hub. Klasa CloudToDeviceMethod służy do wywoływania poleceń na urządzeniu. Model DTDL dla urządzenia definiuje właściwości i polecenia, które implementuje urządzenie. W fragmentach kodu zmienna device_id przechowuje identyfikator urządzenia urządzenia IoT Plug and Play zarejestrowanego w centrum IoT.

Pobieranie bliźniaczej reprezentacji urządzenia i identyfikatora modelu

Aby uzyskać bliźniacze reprezentacje urządzenia i identyfikator modelu urządzenia IoT Plug and Play połączonego z centrum IoT:

from azure.iot.hub import IoTHubRegistryManager
from azure.iot.hub.models import Twin, TwinProperties

iothub_registry_manager = IoTHubRegistryManager(iothub_connection_str)

# ...

twin = iothub_registry_manager.get_twin(device_id)
print("The device twin is: ")
print("")
print(twin)
print("")

additional_props = twin.additional_properties
if "modelId" in additional_props:
    print("The Model ID for this device is:")
    print(additional_props["modelId"])
    print("")

Aktualizowanie bliźniaczej reprezentacji urządzenia

Poniższy fragment kodu przedstawia sposób aktualizowania targetTemperature właściwości na urządzeniu. W przykładzie pokazano, jak należy pobrać reprezentację bliźniaczą etag przed jej zaktualizowaniem. Właściwość jest definiowana w domyślnym składniku urządzenia:

iothub_registry_manager = IoTHubRegistryManager(iothub_connection_str)

twin = iothub_registry_manager.get_twin(device_id)

twin_patch = Twin()

twin_patch.properties = TwinProperties(
    desired={"targetTemperature": 42}
)
updated_twin = iothub_registry_manager.update_twin(device_id, twin_patch, twin.etag)

Poniższy fragment kodu pokazuje, jak zaktualizować targetTemperature właściwość składnika. W przykładzie pokazano, jak należy pobrać reprezentację bliźniaczą ETag przed jej zaktualizowaniem. Właściwość jest zdefiniowana w składniku termostat1 :

iothub_registry_manager = IoTHubRegistryManager(iothub_connection_str)

twin = iothub_registry_manager.get_twin(device_id)

twin_patch = Twin()

twin_patch.properties = TwinProperties(
    desired={ "thermostat1": {
        "__t": "c",
        "targetTemperature": 42}
    }
)
updated_twin = iothub_registry_manager.update_twin(device_id, twin_patch, twin.etag)

W przypadku właściwości w składniku poprawka właściwości wygląda jak w poniższym przykładzie:

{
"thermostat1":
  {
    "__t": "c",
    "targetTemperature": 20
  }
}

Wywołaj polecenie

Poniższy fragment kodu pokazuje, jak wywołać getMaxMinReport polecenie zdefiniowane w składniku domyślnym:

from azure.iot.hub import IoTHubRegistryManager
from azure.iot.hub.models import CloudToDeviceMethod

# ...

iothub_registry_manager = IoTHubRegistryManager(iothub_connection_str)

method_payload = datetime.datetime.now() - datetime.timedelta(minutes=2)
device_method = CloudToDeviceMethod(method_name="getMaxMinReport", payload=method_payload)
result = iothub_registry_manager.invoke_device_method(device_id, device_method)
print(result.payload)

Poniższy fragment kodu pokazuje, jak wywołać getMaxMinReport polecenie w składniku. Polecenie jest zdefiniowane w składniku termostat1 :

from azure.iot.hub import IoTHubRegistryManager
from azure.iot.hub.models import CloudToDeviceMethod

# ...

iothub_registry_manager = IoTHubRegistryManager(iothub_connection_str)

method_payload = datetime.datetime.now() - datetime.timedelta(minutes=2)
device_method = CloudToDeviceMethod(method_name="thermostat1*getMaxMinReport", payload=method_payload)
result = iothub_registry_manager.invoke_device_method(device_id, device_method)
print(result.payload)

Przykłady cyfrowej reprezentacji bliźniaczej usługi IoT Hub

Klasa DigitalTwinClient służy do interakcji ze stanem urządzenia przy użyciu cyfrowych reprezentacji bliźniaczych. Model DTDL dla urządzenia definiuje właściwości i polecenia, które implementuje urządzenie.

Zmienna device_id przechowuje identyfikator urządzenia urządzenia IoT Plug and Play zarejestrowanego w centrum IoT.

Pobieranie cyfrowej reprezentacji bliźniaczej i identyfikatora modelu

Aby uzyskać identyfikator cyfrowej reprezentacji bliźniaczej i modelu urządzenia IoT Plug and Play połączonego z centrum IoT:

from azure.iot.hub import DigitalTwinClient

digital_twin_client = DigitalTwinClient(iothub_connection_str)

digital_twin = digital_twin_client.get_digital_twin(device_id)
if digital_twin:
    print(digital_twin)
    print("Model Id: " + digital_twin["$metadata"]["$model"])
else:
    print("No digital_twin found")

Aktualizowanie cyfrowej reprezentacji bliźniaczej

Poniższy fragment kodu przedstawia sposób aktualizowania targetTemperature właściwości na urządzeniu. Właściwość jest definiowana w domyślnym składniku urządzenia:

from azure.iot.hub import DigitalTwinClient

digital_twin_client = DigitalTwinClient(iothub_connection_str)

patch = [{"op": "add", "path": "/targetTemperature", "value": 42}]
digital_twin_client.update_digital_twin(device_id, patch)

Poniższy fragment kodu pokazuje, jak zaktualizować targetTemperature właściwość składnika. Właściwość jest zdefiniowana w składniku termostat1 :

from azure.iot.hub import DigitalTwinClient

digital_twin_client = DigitalTwinClient(iothub_connection_str)

patch = [{"op": "add", "path": "/targetTemperature", "value": 42}]
digital_twin_client.update_digital_twin(device_id, patch)

Wywołaj polecenie

Poniższy fragment kodu pokazuje, jak wywołać getMaxMinReport polecenie zdefiniowane w składniku domyślnym:

from azure.iot.hub import DigitalTwinClient

payload = datetime.datetime.now() - datetime.timedelta(minutes=2)

connect_timeout_in_seconds = 3
response_timeout_in_seconds = 7


digital_twin_client = DigitalTwinClient(iothub_connection_str)

invoke_command_result = digital_twin_client.invoke_command(
    device_id, "getMaxMinReport", payload, connect_timeout_in_seconds, response_timeout_in_seconds
)
if invoke_command_result:
    print(invoke_command_result)
else:
    print("No invoke_command_result found")

Poniższy fragment kodu pokazuje, jak wywołać getMaxMinReport polecenie w składniku. Polecenie jest zdefiniowane w składniku termostat1 :

from azure.iot.hub import DigitalTwinClient

payload = datetime.datetime.now() - datetime.timedelta(minutes=2)

connect_timeout_in_seconds = 3
response_timeout_in_seconds = 7


digital_twin_client = DigitalTwinClient(iothub_connection_str)

invoke_command_result = digital_twin_client.invoke_component_command(
    device_id, "thermostat1", "getMaxMinReport", payload, connect_timeout_in_seconds, response_timeout_in_seconds
)
if invoke_command_result:
    print(invoke_command_result)
else:
    print("No invoke_command_result found")

Odczytywanie danych telemetrycznych urządzenia

Urządzenia IoT Plug and Play wysyłają dane telemetryczne zdefiniowane w modelu DTDL do usługi IoT Hub. Domyślnie usługa IoT Hub kieruje dane telemetryczne do punktu końcowego usługi Event Hubs, w którym można z niego korzystać. Aby dowiedzieć się więcej, zobacz Wysyłanie komunikatów z urządzenia do chmury do różnych punktów końcowych przy użyciu routingu komunikatów usługi IoT Hub.

Poniższy fragment kodu pokazuje, jak odczytywać dane telemetryczne z domyślnego punktu końcowego usługi Event Hubs. Kod w tym fragmencie kodu jest pobierany z przewodnika Szybki start usługi IoT Hub Wysyłanie danych telemetrycznych z urządzenia do centrum IoT i odczytywanie go za pomocą aplikacji zaplecza:

import asyncio
from azure.eventhub import TransportType
from azure.eventhub.aio import EventHubConsumerClient

# Define callbacks to process events
async def on_event_batch(partition_context, events):
    for event in events:
        print("Received event from partition: {}.".format(partition_context.partition_id))
        print("Telemetry received: ", event.body_as_str())
        print("Properties (set by device): ", event.properties)
        print("System properties (set by IoT Hub): ", event.system_properties)
        print()
    await partition_context.update_checkpoint()

async def on_error(partition_context, error):
    # ...

loop = asyncio.get_event_loop()
client = EventHubConsumerClient.from_connection_string(
    conn_str=CONNECTION_STR,
    consumer_group="$default",
)

try:
    loop.run_until_complete(client.receive_batch(on_event_batch=on_event_batch, on_error=on_error))
except KeyboardInterrupt:
    print("Receiving has stopped.")
finally:
    loop.run_until_complete(client.close())
    loop.stop()

Poniższe dane wyjściowe z poprzedniego kodu pokazują dane telemetryczne temperatury wysyłane przez urządzenie IoT Plug and Play bez składnika termostatu , które ma tylko składnik domyślny. Właściwość dt-dataschema systemowa pokazuje identyfikator modelu:

Received event from partition: 1.
Telemetry received:  {"temperature": 12}
Properties (set by device):  None
System properties (set by IoT Hub):  {b'content-type': b'application/json', b'content-encoding': b'utf-8', b'iothub-connection-device-id': b'my-pnp-device', b'iothub-connection-auth-method': b'{"scope":"device","type":"sas","issuer":"iothub","acceptingIpFilterRule":null}', b'iothub-connection-auth-generation-id': b'637388855582764406', b'iothub-enqueuedtime': 1603288810715, b'iothub-message-source': b'Telemetry', b'dt-dataschema': b'dtmi:com:example:Thermostat;1', b'x-opt-sequence-number': 13280, b'x-opt-offset': b'12890070640', b'x-opt-enqueued-time': 1603288810824}

Poniższe dane wyjściowe z poprzedniego kodu pokazują dane telemetryczne temperatury wysyłane przez wieloskładnikowe urządzenie TemperatureController IoT Plug and Play. Właściwość dt-subject systemowa zawiera nazwę składnika, który wysłał dane telemetryczne. W tym przykładzie dwa składniki są thermostat1 i thermostat2 zgodnie z definicją w modelu DTDL. Właściwość dt-dataschema systemowa pokazuje identyfikator modelu:

Received event from partition: 1.
Telemetry received:  {"temperature": 45}
Properties (set by device):  None
System properties (set by IoT Hub):  {b'content-type': b'application/json', b'content-encoding': b'utf-8', b'iothub-connection-device-id': b'my-pnp-device', b'iothub-connection-auth-method': b'{"scope":"device","type":"sas","issuer":"iothub","acceptingIpFilterRule":null}', b'iothub-connection-auth-generation-id': b'637388858939631652', b'iothub-enqueuedtime': 1603289127844, b'iothub-message-source': b'Telemetry', b'dt-subject': b'thermostat1', b'dt-dataschema': b'dtmi:com:example:TemperatureController;1', b'x-opt-sequence-number': 13328, b'x-opt-offset': b'12890095440', b'x-opt-enqueued-time': 1603289128001}

Received event from partition: 1.
Telemetry received:  {"temperature": 49}
Properties (set by device):  None
System properties (set by IoT Hub):  {b'content-type': b'application/json', b'content-encoding': b'utf-8', b'iothub-connection-device-id': b'my-pnp-device', b'iothub-connection-auth-method': b'{"scope":"device","type":"sas","issuer":"iothub","acceptingIpFilterRule":null}', b'iothub-connection-auth-generation-id': b'637388858939631652', b'iothub-enqueuedtime': 1603289133017, b'iothub-message-source': b'Telemetry', b'dt-subject': b'thermostat2', b'dt-dataschema': b'dtmi:com:example:TemperatureController;1', b'x-opt-sequence-number': 13329, b'x-opt-offset': b'12890095928', b'x-opt-enqueued-time': 1603289133173}

Odczytywanie powiadomień o zmianie bliźniaczej reprezentacji urządzenia

Usługę IoT Hub można skonfigurować do generowania powiadomień o zmianie bliźniaczej reprezentacji urządzenia w celu kierowania do obsługiwanego punktu końcowego. Aby dowiedzieć się więcej, zobacz Używanie routingu komunikatów usługi IoT Hub do wysyłania komunikatów z urządzenia do chmury do różnych punktów końcowych zdarzeń niezwiązanych > z telemetrią.

Kod pokazany w poprzednim fragmencie kodu w języku Python generuje następujące dane wyjściowe, gdy usługa IoT Hub generuje powiadomienia o zmianie bliźniaczej reprezentacji urządzenia dla urządzenia termostatu bez składnika. Właściwości iothub-message-schema aplikacji i opType podaj informacje o typie powiadomienia o zmianie:

Received event from partition: 1.
Telemetry received:  {"version":3,"properties":{"reported":{"maxTempSinceLastReboot":10.96,"$metadata":{"$lastUpdated":"2020-10-21T14:10:42.4171263Z","maxTempSinceLastReboot":{"$lastUpdated":"2020-10-21T14:10:42.4171263Z"}},"$version":2}}}
Properties (set by device):  {b'hubName': b'my-pnp-hub', b'deviceId': b'my-pnp-device', b'operationTimestamp': b'2020-10-21T14:10:42.4171263+00:00', b'iothub-message-schema': b'twinChangeNotification', b'opType': b'updateTwin'}
System properties (set by IoT Hub):  {b'user-id': b'my-pnp-hub\x81\x0e\xa4\x7f', b'correlation-id': b'12104ced5402', b'content-type': b'application/json', b'content-encoding': b'utf-8', b'iothub-connection-device-id': b'my-pnp-device', b'iothub-enqueuedtime': 1603289442519, b'iothub-message-source': b'twinChangeEvents', b'x-opt-sequence-number': 13332, b'x-opt-offset': b'12890097392', b'x-opt-enqueued-time': 1603289442738}

Kod pokazany w poprzednim fragmencie kodu języka Python generuje następujące dane wyjściowe, gdy usługa IoT Hub generuje powiadomienia o zmianie bliźniaczej reprezentacji urządzenia dla urządzenia ze składnikami. W tym przykładzie pokazano dane wyjściowe, gdy urządzenie czujnika temperatury ze składnikiem termostatu generuje powiadomienia. Właściwości iothub-message-schema aplikacji i opType podaj informacje o typie powiadomienia o zmianie:

Received event from partition: 1.
Telemetry received:  {"version":4,"properties":{"reported":{"thermostat1":{"maxTempSinceLastReboot":98.34,"__t":"c"},"$metadata":{"$lastUpdated":"2020-10-21T14:13:39.36491Z","thermostat1":{"$lastUpdated":"2020-10-21T14:13:39.36491Z","maxTempSinceLastReboot":{"$lastUpdated":"2020-10-21T14:13:39.36491Z"},"__t":{"$lastUpdated":"2020-10-21T14:13:39.36491Z"}}},"$version":3}}}
Properties (set by device):  {b'hubName': b'my-pnp-hub', b'deviceId': b'my-pnp-device', b'operationTimestamp': b'2020-10-21T14:13:39.3649100+00:00', b'iothub-message-schema': b'twinChangeNotification', b'opType': b'updateTwin'}
System properties (set by IoT Hub):  {b'user-id': b'my-pnp-hub', b'correlation-id': b'1210b664ab83', b'content-type': b'application/json', b'content-encoding': b'utf-8', b'iothub-connection-device-id': b'my-pnp-device', b'iothub-enqueuedtime': 1603289619481, b'iothub-message-source': b'twinChangeEvents', b'x-opt-sequence-number': 13341, b'x-opt-offset': b'12890102216', b'x-opt-enqueued-time': 1603289619668}

Odczytywanie powiadomień o zmianie cyfrowej reprezentacji bliźniaczej

Usługę IoT Hub można skonfigurować tak, aby generowała powiadomienia o zmianie cyfrowej reprezentacji bliźniaczej w celu kierowania do obsługiwanego punktu końcowego. Aby dowiedzieć się więcej, zobacz Używanie routingu komunikatów usługi IoT Hub do wysyłania komunikatów z urządzenia do chmury do różnych punktów końcowych zdarzeń niezwiązanych > z telemetrią.

Kod pokazany w poprzednim fragmencie kodu w języku Python generuje następujące dane wyjściowe, gdy usługa IoT Hub generuje powiadomienia o zmianie cyfrowej reprezentacji bliźniaczej dla urządzenia termostatu bez składnika. Właściwości iothub-message-schema aplikacji i opType podaj informacje o typie powiadomienia o zmianie:

Received event from partition: 1.
Telemetry received:  [{"op":"add","path":"/$metadata/maxTempSinceLastReboot","value":{"lastUpdateTime":"2020-10-21T14:10:42.4171263Z"}},{"op":"add","path":"/maxTempSinceLastReboot","value":10.96}]
Properties (set by device):  {b'hubName': b'my-pnp-hub', b'deviceId': b'my-pnp-device', b'operationTimestamp': b'2020-10-21T14:10:42.4171263+00:00', b'iothub-message-schema': b'digitalTwinChangeNotification', b'opType': b'updateTwin'}
System properties (set by IoT Hub):  {b'user-id': b'my-pnp-hub\x81\x0e\xa4\x7f', b'correlation-id': b'12104ced5402', b'content-type': b'application/json-patch+json', b'content-encoding': b'utf-8', b'iothub-connection-device-id': b'my-pnp-device', b'iothub-enqueuedtime': 1603289442519, b'iothub-message-source': b'digitalTwinChangeEvents', b'x-opt-sequence-number': 13333, b'x-opt-offset': b'12890098024', b'x-opt-enqueued-time': 1603289442738}

Kod pokazany w poprzednim fragmencie kodu w języku Python generuje następujące dane wyjściowe, gdy usługa IoT Hub generuje powiadomienia o zmianie cyfrowej reprezentacji bliźniaczej dla urządzenia ze składnikami. W tym przykładzie pokazano dane wyjściowe, gdy urządzenie czujnika temperatury ze składnikiem termostatu generuje powiadomienia. Właściwości iothub-message-schema aplikacji i opType podaj informacje o typie powiadomienia o zmianie:

Received event from partition: 1.
Telemetry received:  [{"op":"add","path":"/thermostat1","value":{"$metadata":{"maxTempSinceLastReboot":{"lastUpdateTime":"2020-10-21T14:13:39.36491Z"}},"maxTempSinceLastReboot":98.34}}]
Properties (set by device):  {b'hubName': b'my-pnp-hub', b'deviceId': b'my-pnp-device', b'operationTimestamp': b'2020-10-21T14:13:39.3649100+00:00', b'iothub-message-schema': b'digitalTwinChangeNotification', b'opType': b'updateTwin'}
System properties (set by IoT Hub):  {b'user-id': b'my-pnp-hub', b'correlation-id': b'1210b664ab83', b'content-type': b'application/json-patch+json', b'content-encoding': b'utf-8', b'iothub-connection-device-id': b'my-pnp-device', b'iothub-enqueuedtime': 1603289619481, b'iothub-message-source': b'digitalTwinChangeEvents', b'x-opt-sequence-number': 13342, b'x-opt-offset': b'12890102984', b'x-opt-enqueued-time': 1603289619668}

Następne kroki

Teraz, gdy znasz już modelowanie urządzeń, oto kilka dodatkowych zasobów: