Zarządzanie usługą Digital Twins
Jednostki w twoim środowisku są reprezentowane przez cyfrowe reprezentacje bliźniacze. Zarządzanie cyfrowymi reprezentacjami bliźniaczymi może obejmować tworzenie, modyfikowanie i usuwanie.
Ten artykuł koncentruje się na zarządzaniu cyfrowymi reprezentacjami bliźniaczymi; aby pracować z relacjami i grafem bliźniaczej reprezentacji jako całości, zobacz Zarządzanie grafem i relacjami bliźniaczych reprezentacji.
Napiwek
Wszystkie funkcje zestawu SDK są dostępne w wersjach synchronicznych i asynchronicznych.
Wymagania wstępne
Aby pracować z usługą Azure Digital Twins w tym artykule, musisz mieć wystąpienie usługi Azure Digital Twins i wymagane uprawnienia do korzystania z niego. Jeśli masz już skonfigurowane wystąpienie usługi Azure Digital Twins, możesz użyć tego wystąpienia i przejść do następnej sekcji. W przeciwnym razie postępuj zgodnie z instrukcjami w temacie Konfigurowanie wystąpienia i uwierzytelniania. Instrukcje zawierają informacje ułatwiające sprawdzenie, czy każdy krok został ukończony pomyślnie.
Po skonfigurowaniu wystąpienia zanotuj nazwę hosta wystąpienia. Nazwę hosta można znaleźć w witrynie Azure Portal.
Interfejsy deweloperskie
W tym artykule opisano sposób wykonywania różnych operacji zarządzania przy użyciu zestawu SDK platformy .NET (C#). Możesz również utworzyć te same wywołania zarządzania przy użyciu innych zestawów SDK języka opisanych w interfejsach API i zestawach SDK usługi Azure Digital Twins.
Inne interfejsy deweloperskie, których można użyć do wykonania tych operacji, to:
- Eksplorator usługi Azure Digital Twins
- Wywołania interfejsu API REST
- Polecenia interfejsu wiersza polecenia platformy Azure
Wizualizacja
Azure Digital Twins Explorer to wizualne narzędzie do eksplorowania danych na grafie usługi Azure Digital Twins. Eksplorator umożliwia wyświetlanie, wykonywanie zapytań i edytowanie modeli, reprezentacji bliźniaczych i relacji.
Aby dowiedzieć się więcej o narzędziu Azure Digital Twins Explorer, zobacz Azure Digital Twins Explorer. Aby uzyskać szczegółowe instrukcje dotyczące korzystania z jej funkcji, zobacz Korzystanie z eksploratora usługi Azure Digital Twins.
Oto jak wygląda wizualizacja:
Tworzenie cyfrowej reprezentacji bliźniaczej
Aby utworzyć bliźniacze reprezentację, użyj CreateOrReplaceDigitalTwinAsync()
metody na kliencie usługi w następujący sposób:
await client.CreateOrReplaceDigitalTwinAsync<BasicDigitalTwin>(twinId, initData);
Aby utworzyć cyfrową reprezentację bliźniaczą, należy podać następujące elementy:
- Wartość identyfikatora, którą chcesz przypisać do cyfrowej reprezentacji bliźniaczej (definiujesz ten identyfikator po utworzeniu reprezentacji bliźniaczej)
- Model, którego chcesz użyć
- Wszelkie żądane inicjowanie danych reprezentacji bliźniaczej, w tym...
- Właściwości (inicjowanie opcjonalne): możesz ustawić początkowe wartości właściwości cyfrowej reprezentacji bliźniaczej, jeśli chcesz. Właściwości są traktowane jako opcjonalne i można je ustawić później, ale należy pamiętać, że nie będą wyświetlane jako część bliźniaczej reprezentacji, dopóki nie zostaną ustawione.
- Składniki (wymagane inicjowanie, jeśli są obecne w bliźniaczej reprezentacji): jeśli reprezentacja bliźniacze zawiera jakiekolwiek składniki, należy je zainicjować podczas tworzenia reprezentacji bliźniaczej. Mogą być pustymi obiektami, ale same składniki muszą istnieć.
Model i wszystkie początkowe wartości właściwości są udostępniane za pośrednictwem parametru initData
, który jest ciągiem JSON zawierającym odpowiednie dane. Aby uzyskać więcej informacji na temat struktury tego obiektu, przejdź do następnej sekcji.
Napiwek
Po utworzeniu lub zaktualizowaniu bliźniaczej reprezentacji może wystąpić opóźnienie do 10 sekund, zanim zmiany zostaną odzwierciedlone w zapytaniach. Interfejs GetDigitalTwin
API (opisany w dalszej części tego artykułu) nie ma tego opóźnienia, więc jeśli potrzebujesz natychmiastowej odpowiedzi, użyj wywołania interfejsu API zamiast wykonywania zapytań, aby zobaczyć nowo utworzone reprezentacje bliźniacze.
Inicjowanie modelu i właściwości
Właściwości bliźniaczej reprezentacji bliźniaczej można zainicjować podczas tworzenia reprezentacji bliźniaczej.
Interfejs API tworzenia reprezentacji bliźniaczej akceptuje obiekt, który jest serializowany w prawidłowy opis JSON właściwości bliźniaczej reprezentacji. Aby uzyskać opis formatu JSON dla bliźniaczej reprezentacji bliźniaczej, zobacz Cyfrowe reprezentacje bliźniacze i graf bliźniaczych reprezentacji.
Najpierw można utworzyć obiekt danych reprezentujący reprezentację bliźniaczą i jego dane właściwości. Obiekt parametru można utworzyć ręcznie lub przy użyciu podanej klasy pomocniczej. Oto przykład każdego z nich.
Tworzenie reprezentacji bliźniaczych przy użyciu ręcznie utworzonych danych
Bez użycia żadnych niestandardowych klas pomocnika można reprezentować właściwości bliźniaczej reprezentacji w Dictionary<string, object>
obiekcie , gdzie string
jest nazwą właściwości, a object
obiekt jest obiektem reprezentującym właściwość i jej wartość.
// Define a custom model type for the twin to be created
internal class CustomDigitalTwin
{
[JsonPropertyName(DigitalTwinsJsonPropertyNames.DigitalTwinId)]
public string Id { get; set; }
[JsonPropertyName(DigitalTwinsJsonPropertyNames.DigitalTwinETag)]
public string ETag { get; set; }
[JsonPropertyName("temperature")]
public double Temperature { get; set; }
[JsonPropertyName("humidity")]
public double Humidity{ get; set; }
}
// Initialize properties and create the twin
public class TwinOperationsCreateTwin
{
public async Task CreateTwinAsync(DigitalTwinsClient client)
{
// Initialize the twin properties
var myTwin = new CustomDigitalTwin
{
Temperature = 25.0,
Humidity = 50.0,
};
// Create the twin
const string twinId = "<twin-ID>";
Response<CustomDigitalTwin> response = await client.CreateOrReplaceDigitalTwinAsync(twinId, myTwin);
Console.WriteLine($"Temperature value: {response.Value.Temperature}");
}
}
Tworzenie bliźniaczych reprezentacji z klasą pomocnika
Klasa BasicDigitalTwin
pomocnika klasy umożliwia przechowywanie pól właściwości bezpośrednio w obiekcie "bliźniaczej reprezentacji". Nadal możesz utworzyć listę właściwości przy użyciu Dictionary<string, object>
obiektu , który następnie można dodać do obiektu bliźniaczej reprezentacji jako bezpośrednio CustomProperties
.
string twinId = "myTwinID";
var initData = new BasicDigitalTwin
{
Id = twinId,
Metadata = { ModelId = "dtmi:example:Room;1" },
// Initialize properties
Contents =
{
{ "Temperature", 25.0 },
{ "Humidity", 50.0 },
},
};
await client.CreateOrReplaceDigitalTwinAsync<BasicDigitalTwin>(twinId, initData);
Uwaga
BasicDigitalTwin
obiekty są dostarczane z polem Id
. Możesz pozostawić to pole puste, ale jeśli dodasz wartość identyfikatora, musi być zgodny z parametrem ID przekazanym do wywołania CreateOrReplaceDigitalTwinAsync()
. Na przykład:
twin.Id = "myRoomId";
Zbiorcze tworzenie bliźniaczych reprezentacji za pomocą interfejsu API importowania zadań
Interfejs API importowania zadań umożliwia tworzenie wielu bliźniaczych reprezentacji jednocześnie w jednym wywołaniu interfejsu API. Ta metoda wymaga użycia usługi Azure Blob Storage i uprawnień do zapisu w wystąpieniu usługi Azure Digital Twins dla bliźniaczych reprezentacji bliźniaczych i zadań zbiorczych.
Napiwek
Interfejs API zadań importu umożliwia również importowanie modeli i relacji w tym samym wywołaniu w celu utworzenia wszystkich części grafu jednocześnie. Aby uzyskać więcej informacji na temat tego procesu, zobacz Przekazywanie modeli, reprezentacji bliźniaczych i relacji zbiorczo za pomocą interfejsu API importowania zadań.
Aby importować zbiorcze reprezentacje bliźniacze, należy sstrukturę bliźniaczych reprezentacji (i wszystkich innych zasobów zawartych w zadaniu importu zbiorczego ) jako pliku NDJSON . Sekcja Twins
znajduje się po Models
sekcji (i przed sekcją Relationships
). Bliźniacze reprezentacje zdefiniowane w pliku mogą odwoływać się do modeli zdefiniowanych w tym pliku lub już obecnych w wystąpieniu. Opcjonalnie mogą również obejmować inicjowanie właściwości bliźniaczej reprezentacji.
Przykładowy plik importu i przykładowy projekt służą do tworzenia tych plików w temacie Wprowadzenie do interfejsu API importu zadań.
Następnie należy przekazać plik do uzupełnialnych obiektów blob w usłudze Azure Blob Storage. Aby uzyskać instrukcje dotyczące tworzenia kontenera usługi Azure Storage, zobacz Tworzenie kontenera. Następnie przekaż plik przy użyciu preferowanej metody przekazywania (niektóre opcje to polecenie AzCopy, interfejs wiersza polecenia platformy Azure lub witryna Azure Portal).
Po przekazaniu pliku NDJSON do kontenera pobierz jego adres URL w kontenerze obiektów blob. Użyjesz tej wartości w dalszej części treści wywołania interfejsu API importu zbiorczego.
Oto zrzut ekranu przedstawiający wartość adresu URL pliku obiektu blob w witrynie Azure Portal:
Następnie plik można użyć w wywołaniu interfejsu API importu zadań. Podaj adres URL magazynu obiektów blob w pliku wejściowym i nowy adres URL magazynu obiektów blob, aby wskazać, gdzie ma być przechowywany dziennik wyjściowy po jego utworzeniu.
Pobieranie danych dla cyfrowej reprezentacji bliźniaczej
Aby uzyskać dostęp do szczegółów dowolnej cyfrowej reprezentacji bliźniaczej, wywołaj metodę GetDigitalTwin()
w następujący sposób:
Response<BasicDigitalTwin> twinResponse = await client.GetDigitalTwinAsync<BasicDigitalTwin>(twinId);
twin = twinResponse.Value;
To wywołanie zwraca dane bliźniaczej reprezentacji jako silnie typ obiektu, taki jak BasicDigitalTwin
. BasicDigitalTwin
to klasa pomocnika serializacji dołączona do zestawu SDK, która zwraca podstawowe metadane reprezentacji bliźniaczej i właściwości w postaci wstępnie utworzonej. Zawsze można deserializować dane reprezentacji bliźniaczej przy użyciu wybranej biblioteki JSON, takiej jak System.Text.Json
lub Newtonsoft.Json
. Aby uzyskać podstawowy dostęp do bliźniaczej reprezentacji, klasy pomocnicze mogą sprawić, że będzie to wygodniejsze.
Uwaga
BasicDigitalTwin
używa System.Text.Json
atrybutów. Aby można było używać elementu BasicDigitalTwin
DigitalTwinsClient, należy zainicjować klienta przy użyciu konstruktora domyślnego lub, jeśli chcesz dostosować opcję serializatora, użyj inicjatora JsonObjectSerializer.
Klasa BasicDigitalTwin
pomocnika zapewnia również dostęp do właściwości zdefiniowanych na bliźniaczej reprezentacji za pośrednictwem elementu Dictionary<string, object>
. Aby wyświetlić listę właściwości bliźniaczej reprezentacji bliźniaczej, możesz użyć:
BasicDigitalTwin twin;
Response<BasicDigitalTwin> twinResponse = await client.GetDigitalTwinAsync<BasicDigitalTwin>(twinId);
twin = twinResponse.Value;
Console.WriteLine($"Model id: {twin.Metadata.ModelId}");
foreach (string prop in twin.Contents.Keys)
{
if (twin.Contents.TryGetValue(prop, out object value))
Console.WriteLine($"Property '{prop}': {value}");
}
Tylko właściwości, które zostały ustawione co najmniej raz, są zwracane podczas pobierania bliźniaczej reprezentacji z GetDigitalTwin()
metodą .
Napiwek
Element displayName
dla bliźniaczej reprezentacji jest częścią metadanych modelu, więc nie będzie wyświetlany podczas pobierania danych dla wystąpienia reprezentacji bliźniaczej. Aby wyświetlić tę wartość, możesz pobrać ją z modelu.
Aby pobrać wiele reprezentacji bliźniaczych przy użyciu jednego wywołania interfejsu API, zobacz Przykłady interfejsu API zapytań w temacie Wykonywanie zapytań względem grafu bliźniaczej reprezentacji.
Rozważmy następujący model (napisany w języku Digital Twins Definition Language ( DTDL), który definiuje Księżyc:
{
"@id": "dtmi:example:Moon;1",
"@type": "Interface",
"@context": "dtmi:dtdl:context;3",
"contents": [
{
"@type": "Property",
"name": "radius",
"schema": "double",
"writable": true
},
{
"@type": "Property",
"name": "mass",
"schema": "double",
"writable": true
}
]
}
Wynik wywołania object result = await client.GetDigitalTwinAsync("my-moon");
bliźniaczej reprezentacji księżyca może wyglądać następująco:
{
"$dtId": "myMoon-001",
"$etag": "W/\"e59ce8f5-03c0-4356-aea9-249ecbdc07f9\"",
"radius": 1737.1,
"mass": 0.0734,
"$metadata": {
"$model": "dtmi:example:Moon;1",
"radius": {
"lastUpdateTime": "2022-12-06T20:00:32.8209188Z"
},
"mass": {
"lastUpdateTime": "2022-12-04T12:04:43.3859361Z"
}
}
}
Zdefiniowane właściwości cyfrowej reprezentacji bliźniaczej są zwracane jako właściwości najwyższego poziomu w cyfrowej reprezentacji bliźniaczej. Metadane lub informacje systemowe, które nie są częścią definicji DTDL, są zwracane z prefiksem $
. Właściwości metadanych obejmują następujące wartości:
$dtId
: identyfikator cyfrowej reprezentacji bliźniaczej w tym wystąpieniu usługi Azure Digital Twins$etag
: standardowe pole HTTP przypisane przez serwer internetowy. Ta wartość jest aktualizowana do nowej wartości za każdym razem, gdy bliźniacze reprezentacja jest aktualizowana, co może być przydatne do określenia, czy dane bliźniaczej reprezentacji zostały zaktualizowane na serwerze od czasu poprzedniego sprawdzenia. Za pomocąIf-Match
polecenia można wykonywać aktualizacje i usuwać je tylko wtedy, gdy element etag jednostki jest zgodny z podanym tagiem etag. Aby uzyskać więcej informacji na temat tych operacji, zobacz dokumentację dotyczącą funkcji DigitalTwins Update i DigitalTwins Delete.$metadata
: Zestaw właściwości metadanych, które mogą obejmować następujące elementy:$model
, dtMI modelu cyfrowej reprezentacji bliźniaczej.lastUpdateTime
dla właściwości bliźniaczej reprezentacji. Jest to znacznik czasu wskazujący datę i godzinę przetworzenia komunikatu aktualizacji właściwości przez usługę Azure Digital TwinssourceTime
dla właściwości bliźniaczej reprezentacji. Jest to opcjonalna, zapisywalna właściwość reprezentująca sygnaturę czasową obserwowanej aktualizacji właściwości w świecie rzeczywistym.
Więcej informacji na temat pól zawartych w cyfrowej reprezentacji bliźniaczej można przeczytać w formacie JSON cyfrowej reprezentacji bliźniaczej. Więcej informacji na temat klas pomocników serializacji, takich jak BasicDigitalTwin
w interfejsach API i zestawach SDK usługi Azure Digital Twins.
Wyświetlanie wszystkich cyfrowych reprezentacji bliźniaczych
Aby wyświetlić wszystkie cyfrowe reprezentacje bliźniacze w twoim wystąpieniu, użyj zapytania. Zapytanie można uruchomić za pomocą interfejsów API zapytań lub poleceń interfejsu wiersza polecenia.
Oto treść podstawowego zapytania, które zwraca listę wszystkich cyfrowych reprezentacji bliźniaczych w wystąpieniu:
SELECT * FROM DIGITALTWINS
Aktualizowanie cyfrowej reprezentacji bliźniaczej
Aby zaktualizować właściwości cyfrowej reprezentacji bliźniaczej, zapisz informacje, które chcesz zamienić w formacie poprawki JSON. Aby uzyskać pełną listę operacji poprawek JSON, które mogą być używane, w tym replace
add
, i remove
, zobacz Operacje dla poprawki JSON.
Po spreparowaniu dokumentu poprawki JSON zawierającego informacje o aktualizacji przekaż dokument do UpdateDigitalTwin()
metody :
await client.UpdateDigitalTwinAsync(twinId, updateTwinData);
Jedno wywołanie poprawki może zaktualizować dowolną liczbę właściwości pojedynczej reprezentacji bliźniaczej (nawet wszystkich). Jeśli musisz zaktualizować właściwości w wielu reprezentacjach bliźniaczych, potrzebujesz oddzielnego wywołania aktualizacji dla każdej reprezentacji bliźniaczej.
Napiwek
Po utworzeniu lub zaktualizowaniu bliźniaczej reprezentacji może wystąpić opóźnienie do 10 sekund, zanim zmiany zostaną odzwierciedlone w zapytaniach. Interfejs GetDigitalTwin
API (opisany wcześniej w tym artykule) nie ma tego opóźnienia, dlatego użyj wywołania interfejsu API zamiast wykonywania zapytań, aby zobaczyć nowo zaktualizowane reprezentacje bliźniacze, jeśli potrzebujesz natychmiastowej odpowiedzi.
Oto przykład kodu poprawki JSON. Ten dokument zastępuje wartości właściwości masy i promienia cyfrowej reprezentacji bliźniaczej, do których jest stosowana. W tym przykładzie pokazano operację JSON Patch replace
, która zastępuje wartość istniejącej właściwości.
[
{
"op": "replace",
"path": "/mass",
"value": 0.0799
},
{
"op": "replace",
"path": "/radius",
"value": 0.800
}
]
Podczas aktualizowania bliźniaczej reprezentacji z projektu kodu przy użyciu zestawu .NET SDK można utworzyć poprawki JSON przy użyciu narzędzia JsonPatchDocument zestawu .NET SDK platformy Azure. Oto przykład tworzenia dokumentu poprawki JSON i używania go UpdateDigitalTwin()
w kodzie projektu.
var updateTwinData = new JsonPatchDocument();
updateTwinData.AppendAdd("/Temperature", 25.0);
updateTwinData.AppendAdd("/myComponent/Property", "Hello");
// Un-set a property
updateTwinData.AppendRemove("/Humidity");
await client.UpdateDigitalTwinAsync("myTwin", updateTwinData).ConfigureAwait(false);
Napiwek
Znaczniki czasu źródłowego dla cyfrowych reprezentacji bliźniaczych można zachować, aktualizując $metadata.<property-name>.sourceTime
pole przy użyciu procesu opisanego w tej sekcji. Aby uzyskać więcej informacji na temat tego pola i innych pól zapisywalnych w cyfrowych reprezentacjach bliźniaczych, zobacz Format JSON reprezentacji cyfrowej reprezentacji bliźniaczej.
Aktualizowanie właściwości podrzędnych w składnikach cyfrowej reprezentacji bliźniaczej
Pamiętaj, że model może zawierać składniki, dzięki czemu może składać się z innych modeli.
Aby zastosować poprawki właściwości składników cyfrowej reprezentacji bliźniaczej, możesz użyć składni ścieżki w poprawce JSON:
[
{
"op": "replace",
"path": "/mycomponentname/mass",
"value": 0.0799
}
]
Aktualizowanie właściwości podrzędnych we właściwościach typu obiektu
Modele mogą zawierać właściwości typu obiektu. Te obiekty mogą mieć własne właściwości i można zaktualizować jedną z tych właściwości podrzędnych należących do właściwości typu obiektu. Ten proces jest podobny do procesu aktualizowania właściwości podrzędnych w składnikach, ale może wymagać wykonania pewnych dodatkowych kroków.
Rozważmy model z właściwością typu obiektu , ObjectProperty
. ObjectProperty
ma właściwość ciągu o nazwie StringSubProperty
.
Po utworzeniu bliźniaczej reprezentacji przy użyciu tego modelu nie jest konieczne utworzenie wystąpienia ObjectProperty
w tym czasie. Jeśli właściwość obiektu nie jest tworzona podczas tworzenia reprezentacji bliźniaczej, nie ma ścieżki domyślnej utworzonej do uzyskiwania dostępu ObjectProperty
i jej StringSubProperty
dla operacji poprawki. Musisz dodać ścieżkę do ObjectProperty
siebie, zanim będzie można zaktualizować jej właściwości.
Można to zrobić za pomocą operacji JSON Patch add
, w następujący sposób:
[
{
"op": "add",
"path": "/ObjectProperty",
"value": {"StringSubProperty":"<string-value>"}
}
]
Uwaga
Jeśli ObjectProperty
ma więcej niż jedną właściwość, należy uwzględnić wszystkie z nich w value
polu tej operacji, nawet jeśli aktualizujesz tylko jedną:
... "value": {"StringSubProperty":"<string-value>", "Property2":"<property2-value>", ...}
Po wykonaniu tej czynności ścieżka do istnieje i można ją zaktualizować StringSubProperty
bezpośrednio od teraz za pomocą typowej replace
operacji:
[
{
"op": "replace",
"path": "/ObjectProperty/StringSubProperty",
"value": "<string-value>"
}
]
Mimo że pierwszy krok nie jest konieczny w przypadkach, w których ObjectProperty
utworzono wystąpienie bliźniaczej reprezentacji, zaleca się jej użycie za każdym razem, gdy aktualizujesz właściwość podrzędną po raz pierwszy, ponieważ nie zawsze wiesz, czy właściwość obiektu została początkowo utworzona, czy nie.
Aktualizowanie modelu cyfrowej reprezentacji bliźniaczej
Funkcja UpdateDigitalTwin()
może również służyć do migrowania cyfrowej reprezentacji bliźniaczej do innego modelu.
Rozważmy na przykład następujący dokument poprawki JSON, który zastępuje pole metadanych $model
cyfrowej reprezentacji bliźniaczej:
[
{
"op": "replace",
"path": "/$metadata/$model",
"value": "dtmi:example:foo;1"
}
]
Ta operacja powiedzie się tylko wtedy, gdy cyfrowa reprezentacja bliźniaczej jest modyfikowana przez poprawkę zgodną z nowym modelem.
Rozważmy następujący przykład:
- Wyobraź sobie cyfrową reprezentację bliźniaczą z modelem foo_old. foo_old definiuje wymaganą masę właściwości.
- Nowy model foo_new definiuje masę właściwości i dodaje nową wymaganą temperaturę właściwości.
- Po wprowadzeniu poprawki cyfrowa reprezentacja bliźniaka musi mieć zarówno właściwość masy, jak i temperatury.
Poprawka dla tej sytuacji musi zaktualizować zarówno model, jak i właściwość temperatury bliźniaczej reprezentacji bliźniaczej, w następujący sposób:
[
{
"op": "replace",
"path": "/$metadata/$model",
"value": "dtmi:example:foo_new;1"
},
{
"op": "add",
"path": "/temperature",
"value": 60
}
]
Aktualizowanie właściwości sourceTime
Opcjonalnie możesz zdecydować się na użycie sourceTime
pola we właściwościach reprezentacji bliźniaczej, aby rejestrować znaczniki czasu, gdy aktualizacje właściwości są obserwowane w świecie rzeczywistym. Usługa Azure Digital Twins natywnie obsługuje sourceTime
metadane dla każdej właściwości bliźniaczej reprezentacji. Wartość musi być zgodna sourceTime
z formatem daty i godziny ISO 8601. Aby uzyskać więcej informacji na temat tego pola i innych pól dotyczących cyfrowych reprezentacji bliźniaczych, zobacz Format JSON reprezentacji cyfrowej reprezentacji bliźniaczej.
Minimalna stabilna wersja interfejsu API REST do obsługi tego pola to wersja 2022-05-31 . Aby pracować z tym polem przy użyciu zestawów SDK usługi Azure Digital Twins, zalecamy użycie najnowszej wersji zestawu SDK, aby upewnić się, że to pole jest uwzględnione.
Oto przykład dokumentu poprawki JSON, który aktualizuje zarówno wartość, jak i sourceTime
pole Temperature
właściwości:
[
{
"op": "replace",
"path": "/Temperature",
"value": "22.3"
},
{
"op": "replace",
"path": "/$metadata/Temperature/sourceTime",
"value": "2021-11-30T18:47:53.7648958Z"
}
]
Aby zaktualizować sourceTime
pole we właściwości będącej częścią składnika, dołącz składnik na początku ścieżki. W powyższym przykładzie można to zrobić, zmieniając wartość ścieżki z /$metadata/Temperature/sourceTime
na myComponent/$metadata/Temperature/sourceTime
.
Uwaga
Jeśli zaktualizujesz zarówno wartość , jak sourceTime
i we właściwości, a następnie zaktualizujesz tylko wartość właściwości, sourceTime
sygnatura czasowa z pierwszej aktualizacji pozostanie.
Obsługa wywołań aktualizacji powodującej konflikt
Usługa Azure Digital Twins zapewnia, że wszystkie żądania przychodzące są przetwarzane jeden po drugim. Oznacza to, że nawet jeśli wiele funkcji próbuje zaktualizować tę samą właściwość w bliźniaczej reprezentacji w tym samym czasie, nie ma potrzeby pisania jawnego kodu blokującego w celu obsługi konfliktu.
To zachowanie jest oparte na bliźniaczej reprezentacji.
Załóżmy na przykład scenariusz, w którym te trzy wywołania docierają w tym samym czasie:
- Zapis właściwości A w usłudze Twin1
- Zapis właściwości B w usłudze Twin1
- Zapis właściwości A w bliźniaczej reprezentacji Bliźniaczej 2
Dwa wywołania modyfikujące reprezentację Twin1 są wykonywane jeden po drugim, a komunikaty o zmianie są generowane dla każdej zmiany. Wywołanie modyfikowania usługi Twin2 można wykonać jednocześnie bez konfliktu, gdy tylko nadejdzie.
Usuwanie cyfrowej reprezentacji bliźniaczej
Bliźniacze reprezentacje można usunąć przy użyciu DeleteDigitalTwin()
metody . Można jednak usunąć bliźniacze reprezentację tylko wtedy, gdy nie ma więcej relacji. Dlatego najpierw usuń relacje przychodzące i wychodzące bliźniaczej reprezentacji bliźniaczej.
Oto przykład kodu do usuwania bliźniaczych reprezentacji i ich relacji. Wywołanie DeleteDigitalTwin
zestawu SDK zostało wyróżnione, aby wyjaśnić, gdzie znajduje się w szerszym kontekście przykładu.
private static async Task CustomMethod_DeleteTwinAsync(DigitalTwinsClient client, string twinId)
{
await CustomMethod_FindAndDeleteOutgoingRelationshipsAsync(client, twinId);
await CustomMethod_FindAndDeleteIncomingRelationshipsAsync(client, twinId);
try
{
await client.DeleteDigitalTwinAsync(twinId);
Console.WriteLine("Twin deleted successfully");
}
catch (RequestFailedException ex)
{
Console.WriteLine($"*** Error:{ex.Message}");
}
}
private static async Task CustomMethod_FindAndDeleteOutgoingRelationshipsAsync(DigitalTwinsClient client, string dtId)
{
// Find the relationships for the twin
try
{
// GetRelationshipsAsync will throw an error if a problem occurs
AsyncPageable<BasicRelationship> rels = client.GetRelationshipsAsync<BasicRelationship>(dtId);
await foreach (BasicRelationship rel in rels)
{
await client.DeleteRelationshipAsync(dtId, rel.Id).ConfigureAwait(false);
Console.WriteLine($"Deleted relationship {rel.Id} from {dtId}");
}
}
catch (RequestFailedException ex)
{
Console.WriteLine($"*** Error {ex.Status}/{ex.ErrorCode} retrieving or deleting relationships for {dtId} due to {ex.Message}");
}
}
private static async Task CustomMethod_FindAndDeleteIncomingRelationshipsAsync(DigitalTwinsClient client, string dtId)
{
// Find the relationships for the twin
try
{
// GetRelationshipsAsync will throw an error if a problem occurs
AsyncPageable<IncomingRelationship> incomingRels = client.GetIncomingRelationshipsAsync(dtId);
await foreach (IncomingRelationship incomingRel in incomingRels)
{
await client.DeleteRelationshipAsync(incomingRel.SourceId, incomingRel.RelationshipId).ConfigureAwait(false);
Console.WriteLine($"Deleted incoming relationship {incomingRel.RelationshipId} from {dtId}");
}
}
catch (RequestFailedException ex)
{
Console.WriteLine($"*** Error {ex.Status}/{ex.ErrorCode} retrieving or deleting incoming relationships for {dtId} due to {ex.Message}");
}
}
Usuń wszystkie cyfrowe reprezentacje bliźniacze
Aby zapoznać się z przykładem usuwania wszystkich bliźniaczych reprezentacji jednocześnie, pobierz przykładową aplikację używaną w sekcji Eksploruj podstawy z przykładową aplikacją kliencką. Plik CommandLoop.cs wykonuje to w CommandDeleteAllTwins()
funkcji.
Uwaga
Jeśli chcesz usunąć wszystkie modele, reprezentacje bliźniacze i relacje w wystąpieniu jednocześnie, użyj interfejsu API usuwania zadań.
Przykładowy kod z możliwością uruchamiania cyfrowej reprezentacji bliźniaczej
Poniższy przykładowy kod możliwy do uruchomienia umożliwia utworzenie bliźniaczej reprezentacji, zaktualizowanie jej szczegółów i usunięcie bliźniaczej reprezentacji.
Konfigurowanie przykładowych plików projektu
Fragment kodu używa przykładowej definicji modelu, Room.json. Aby pobrać plik modelu, aby można było go użyć w kodzie, użyj tego linku, aby przejść bezpośrednio do pliku w usłudze GitHub. Następnie kliknij prawym przyciskiem myszy w dowolnym miejscu na ekranie, wybierz polecenie Zapisz w menu prawym przyciskiem myszy przeglądarki i użyj okna Zapisz jako, aby zapisać plik jako jako Room.json.
Następnie utwórz nowy projekt aplikacji konsolowej w programie Visual Studio lub wybranym edytorze.
Następnie skopiuj następujący kod przykładu możliwego do uruchomienia do projektu:
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Azure;
using Azure.DigitalTwins.Core;
using Azure.Identity;
using System.IO;
namespace DigitalTwins_Samples
{
class TwinOperationsSample
{
public static async Task Main(string[] args)
{
Console.WriteLine("Hello World!");
// Create the Azure Digital Twins client for API calls
string adtInstanceUrl = "https://<your-instance-hostname>";
var credentials = new DefaultAzureCredential();
var client = new DigitalTwinsClient(new Uri(adtInstanceUrl), credentials);
Console.WriteLine($"Service client created – ready to go");
// Upload models
Console.WriteLine($"Upload a model");
string dtdl = File.ReadAllText("<path-to>/Room.json");
var models = new List<string> { dtdl };
// Upload the model to the service
await client.CreateModelsAsync(models);
// Create new digital twin
// <CreateTwin_withHelper>
string twinId = "myTwinID";
var initData = new BasicDigitalTwin
{
Id = twinId,
Metadata = { ModelId = "dtmi:example:Room;1" },
// Initialize properties
Contents =
{
{ "Temperature", 25.0 },
{ "Humidity", 50.0 },
},
};
// <CreateTwinCall>
await client.CreateOrReplaceDigitalTwinAsync<BasicDigitalTwin>(twinId, initData);
// </CreateTwinCall>
// </CreateTwin_withHelper>
Console.WriteLine("Twin created successfully");
//Print twin
Console.WriteLine("--- Printing twin details:");
await CustomMethod_FetchAndPrintTwinAsync(twinId, client);
Console.WriteLine("--------");
//Update twin data
var updateTwinData = new JsonPatchDocument();
updateTwinData.AppendAdd("/Temperature", 30.0);
// <UpdateTwinCall>
await client.UpdateDigitalTwinAsync(twinId, updateTwinData);
// </UpdateTwinCall>
Console.WriteLine("Twin properties updated");
Console.WriteLine();
//Print twin again
Console.WriteLine("--- Printing twin details (after update):");
await CustomMethod_FetchAndPrintTwinAsync(twinId, client);
Console.WriteLine("--------");
Console.WriteLine();
//Delete twin
await CustomMethod_DeleteTwinAsync(client, twinId);
}
private static async Task<BasicDigitalTwin> CustomMethod_FetchAndPrintTwinAsync(string twinId, DigitalTwinsClient client)
{
// <GetTwin>
BasicDigitalTwin twin;
// <GetTwinCall>
Response<BasicDigitalTwin> twinResponse = await client.GetDigitalTwinAsync<BasicDigitalTwin>(twinId);
twin = twinResponse.Value;
// </GetTwinCall>
Console.WriteLine($"Model id: {twin.Metadata.ModelId}");
foreach (string prop in twin.Contents.Keys)
{
if (twin.Contents.TryGetValue(prop, out object value))
Console.WriteLine($"Property '{prop}': {value}");
}
// </GetTwin>
return twin;
}
// <DeleteTwin>
private static async Task CustomMethod_DeleteTwinAsync(DigitalTwinsClient client, string twinId)
{
await CustomMethod_FindAndDeleteOutgoingRelationshipsAsync(client, twinId);
await CustomMethod_FindAndDeleteIncomingRelationshipsAsync(client, twinId);
try
{
await client.DeleteDigitalTwinAsync(twinId);
Console.WriteLine("Twin deleted successfully");
}
catch (RequestFailedException ex)
{
Console.WriteLine($"*** Error:{ex.Message}");
}
}
private static async Task CustomMethod_FindAndDeleteOutgoingRelationshipsAsync(DigitalTwinsClient client, string dtId)
{
// Find the relationships for the twin
try
{
// GetRelationshipsAsync will throw an error if a problem occurs
AsyncPageable<BasicRelationship> rels = client.GetRelationshipsAsync<BasicRelationship>(dtId);
await foreach (BasicRelationship rel in rels)
{
await client.DeleteRelationshipAsync(dtId, rel.Id).ConfigureAwait(false);
Console.WriteLine($"Deleted relationship {rel.Id} from {dtId}");
}
}
catch (RequestFailedException ex)
{
Console.WriteLine($"*** Error {ex.Status}/{ex.ErrorCode} retrieving or deleting relationships for {dtId} due to {ex.Message}");
}
}
private static async Task CustomMethod_FindAndDeleteIncomingRelationshipsAsync(DigitalTwinsClient client, string dtId)
{
// Find the relationships for the twin
try
{
// GetRelationshipsAsync will throw an error if a problem occurs
AsyncPageable<IncomingRelationship> incomingRels = client.GetIncomingRelationshipsAsync(dtId);
await foreach (IncomingRelationship incomingRel in incomingRels)
{
await client.DeleteRelationshipAsync(incomingRel.SourceId, incomingRel.RelationshipId).ConfigureAwait(false);
Console.WriteLine($"Deleted incoming relationship {incomingRel.RelationshipId} from {dtId}");
}
}
catch (RequestFailedException ex)
{
Console.WriteLine($"*** Error {ex.Status}/{ex.ErrorCode} retrieving or deleting incoming relationships for {dtId} due to {ex.Message}");
}
}
// </DeleteTwin>
}
}
Uwaga
Obecnie występuje znany problem dotyczący DefaultAzureCredential
klasy otoki, który może spowodować błąd podczas uwierzytelniania. Jeśli wystąpi ten problem, możesz spróbować utworzyć wystąpienie DefaultAzureCredential
za pomocą następującego opcjonalnego parametru, aby rozwiązać ten problem: new DefaultAzureCredential(new DefaultAzureCredentialOptions { ExcludeSharedTokenCacheCredential = true });
Aby uzyskać więcej informacji na temat tego problemu, zobacz Znane problemy usługi Azure Digital Twins.
Konfigurowanie projektu
Następnie wykonaj następujące kroki, aby skonfigurować kod projektu:
Dodaj pobrany wcześniej plik Room.json do projektu i zastąp
<path-to>
symbol zastępczy w kodzie, aby poinformować program, gdzie go znaleźć.Zastąp symbol zastępczy
<your-instance-hostname>
nazwą hosta wystąpienia usługi Azure Digital Twins.Dodaj dwie zależności do projektu, które są potrzebne do pracy z usługą Azure Digital Twins. Pierwszy to pakiet zestawu SDK usługi Azure Digital Twins dla platformy .NET, a drugi udostępnia narzędzia ułatwiające uwierzytelnianie na platformie Azure.
dotnet add package Azure.DigitalTwins.Core dotnet add package Azure.Identity
Należy również skonfigurować poświadczenia lokalne, jeśli chcesz uruchomić przykład bezpośrednio. W następnej sekcji opisano to.
Konfigurowanie lokalnych poświadczeń platformy Azure
W tym przykładzie użyto wartości DefaultAzureCredential (część Azure.Identity
biblioteki) do uwierzytelniania użytkowników przy użyciu wystąpienia usługi Azure Digital Twins podczas uruchamiania go na komputerze lokalnym. Aby uzyskać więcej informacji na temat różnych sposobów uwierzytelniania aplikacji klienckiej za pomocą usługi Azure Digital Twins, zobacz Pisanie kodu uwierzytelniania aplikacji.
W programie DefaultAzureCredential
przykład wyszuka poświadczenia w środowisku lokalnym, takie jak logowanie się platformy Azure w lokalnym interfejsie wiersza polecenia platformy Azure lub w programie Visual Studio lub Visual Studio Code. Z tego powodu należy zalogować się do platformy Azure lokalnie za pomocą jednego z tych mechanizmów, aby skonfigurować poświadczenia dla przykładu.
Jeśli używasz programu Visual Studio lub Visual Studio Code do uruchamiania przykładów kodu, upewnij się, że zalogowaliśmy się do tego edytora przy użyciu tych samych poświadczeń platformy Azure, których chcesz użyć do uzyskania dostępu do wystąpienia usługi Azure Digital Twins. Jeśli używasz lokalnego okna interfejsu wiersza polecenia, uruchom az login
polecenie , aby zalogować się do konta platformy Azure. Następnie po uruchomieniu przykładowego kodu powinno nastąpić automatyczne uwierzytelnienie.
Uruchamianie aplikacji przykładowej
Po zakończeniu instalacji możesz uruchomić przykładowy projekt kodu.
Oto dane wyjściowe konsoli powyższego programu:
Następne kroki
Zobacz, jak tworzyć relacje między bliźniaczymi reprezentacjami bliźniaczymi i zarządzać nimi: