Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym artykule przedstawiono przykładową implementację enumeratora składników w usłudze Device Update dla IoT Hub. Możesz odwołać się do tego przykładu, aby zaimplementować enumerator niestandardowych komponentów dla urządzeń IoT. Składnik to element na poziomie niższym niż urządzenie, który ma relację składową z urządzeniem hosta.
W tym artykule przedstawiono moduł wyliczający składników przy użyciu wirtualnego urządzenia IoT o nazwie Contoso Virtual Vacuum. Moduły wyliczania składników służą do implementowania funkcji aktualizacji serwera proxy .
Aktualizacja serwera proxy umożliwia aktualizowanie wielu składników na tym samym urządzeniu IoT lub wielu czujników połączonych z urządzeniem IoT za pomocą jednego bezprzewodowego wdrożenia. Aktualizacja serwera proxy obsługuje porządek instalacji aktualizacji komponentów. Obsługuje również aktualizację wieloetapową dzięki możliwościom przed instalacją, instalacją i po instalacji.
Przypadki użycia, w których mają zastosowanie aktualizacje serwera proxy:
- Kierowanie określonych plików aktualizacji na partycje urządzenia.
- Kierowanie określonych plików aktualizacji do aplikacji lub komponentów na urządzeniu.
- Kierowanie określonych plików aktualizacji do czujników podłączonych do urządzeń IoT za pośrednictwem protokołu sieciowego (na przykład usb lub magistrali CAN).
Aby uzyskać więcej informacji, zobacz Aktualizacje serwera proxy i aktualizowanie wielu składników.
Agent usługi Device Update działa na urządzeniu hosta. Może wysyłać każdą aktualizację do określonego składnika lub do grupy składników tej samej klasy sprzętu (czyli wymagającej tej samej aktualizacji oprogramowania lub oprogramowania układowego).
Co to jest moduł wyliczający składników?
Enumerator składników to rozszerzenie agenta Device Update, które udostępnia informacje o każdym składniku wymaganym do aktualizacji bezprzewodowej za pośrednictwem połączenia z Azure IoT Hub urządzenia hosta.
Agent usługi Device Update jest niezależny od urządzeń i składników. Sam w sobie agent nie wie nic o składnikach na urządzeniu gospodarza (lub połączonych z nim) w chwili aktualizacji.
Aby włączyć aktualizacje serwera proxy, konstruktorzy urządzeń muszą zidentyfikować wszystkie składniki na urządzeniu, które można zaktualizować i przypisać unikatową nazwę do każdego składnika. Ponadto nazwę grupy można przypisać do składników tej samej klasy sprzętu, aby można było zainstalować tę samą aktualizację na wszystkich składnikach w tej samej grupie. Następnie program obsługi zawartości aktualizacji może zainstalować i zastosować aktualizację do odpowiednich składników.
Poniżej przedstawiono obowiązki każdej części przepływu aktualizacji serwera proxy:
Konstruktor urządzeń
Projektowanie i tworzenie urządzenia.
Zintegruj agenta usługi Device Update i jego zależności.
Zaimplementuj rozszerzenie modułu wyliczającego specyficznego dla urządzenia i zarejestruj się w agencie usługi Device Update.
Moduł wyliczający składników używa informacji ze spisu składników lub pliku konfiguracji do rozszerzania danych statycznych składników (wymagana aktualizacja urządzenia) z danymi dynamicznymi (na przykład wersja oprogramowania układowego, stan połączenia i tożsamość sprzętu).
Utwórz aktualizację proxy, która zawiera jedną lub więcej aktualizacji podrzędnych, skierowane do co najmniej jednego składnika na urządzeniu (lub połączonym z urządzeniem).
Wyślij aktualizację do operatora rozwiązania.
Operator rozwiązania
Zaimportuj aktualizację i manifest do usługi Device Update.
Wdróż aktualizację w grupie urządzeń.
Agent aktualizacji urządzenia
Uzyskaj informacje o aktualizacji z usługi IoT Hub za pośrednictwem bliźniaczej reprezentacji urządzenia lub bliźniaczej reprezentacji modułu.
Wywołaj obsługę kroków, aby przetworzyć aktualizację proxy przeznaczoną dla jednego lub więcej składników na urządzeniu.
Przykład w tym artykule zawiera dwie aktualizacje:
host-fw-1.1imotors-fw-1.1. Dla każdej aktualizacji podrzędnej procedura obsługi kroków nadrzędnych wywołuje procedurę obsługi kroków podrzędnych, aby wyliczyć wszystkie składniki zgodne zCompatibilitieswłaściwościami określonymi w pliku manifestu aktualizacji podrzędnej. Następnie program obsługi pobiera, instaluje i stosuje aktualizację podrzędną do wszystkich docelowych składników.Aby uzyskać pasujące składniki, aktualizacja podrzędna wywołuje
SelectComponentsinterfejs API dostarczony przez moduł wyliczający składników. Jeśli nie ma pasujących komponentów, aktualizacja elementu podrzędnego zostanie pominięta.Zbierz wszystkie wyniki z aktualizacji rodziców i dzieci, a następnie przekaż je do usługi IoT Hub.
Procedura obsługi kroków podrzędnych
- Iterowanie po liście wystąpień składników zgodnych z zawartością aktualizacji podrzędnej. Aby uzyskać więcej informacji, zapoznaj się z Obsługą kroków.
W środowisku produkcyjnym konstruktorzy urządzeń mogą używać istniejących procedur obsługi lub implementować niestandardową procedurę obsługi, która wywołuje dowolnego instalatora wymaganego do aktualizacji nadmiarowej. Aby uzyskać więcej informacji, zobacz Implementowanie niestandardowej procedury obsługi zawartości aktualizacji.
Komponenty wirtualnej próżni
W tym artykule użyjemy wirtualnego urządzenia IoT do zademonstrowania kluczowych pojęć i funkcji. Urządzenie Contoso Virtual Vacuum składa się z pięciu składników logicznych:
- Oprogramowanie układowe hosta
- System plików rozruchu hosta
- System plików root hosta
- Trzy silniki (lewe koło, prawe koło i silnik próżniowy)
- Dwie kamery (z przodu i z tyłu)
Następująca struktura katalogów symuluje składniki:
/usr/local/contoso-devices/vacuum-1/hostfw
/usr/local/contoso-devices/vacuum-1/bootfs
/usr/local/contoso-devices/vacuum-1/rootfs
/usr/local/contoso-devices/vacuum-1/motors/0 /* left motor */
/usr/local/contoso-devices/vacuum-1/motors/1 /* right motor */
/usr/local/contoso-devices/vacuum-1/motors/2 /* vacuum motor */
/usr/local/contoso-devices/vacuum-1/cameras/0 /* front camera */
/usr/local/contoso-devices/vacuum-1/cameras/1 /* rear camera */
Katalog każdego składnika zawiera plik JSON, który przechowuje pozorny numer wersji oprogramowania każdego składnika. Przykładowe pliki JSON to firmware.json i diskimage.json.
W tym pokazie demonstracyjnym, aby zaktualizować oprogramowanie układowe składników, skopiujemy firmware.json lub diskimage.json (pakiet aktualizacji) do docelowego katalogu składników.
Oto przykładowy plikfirmware.json :
{
"version": "0.5",
"description": "This component is generated for testing purposes."
}
Uwaga
Virtual Vacuum firmy Contoso zawiera wersje oprogramowania lub oprogramowania układowego na potrzeby demonstrowania aktualizacji serwera proxy. Nie zapewnia żadnych innych funkcji.
Implementowanie modułu wyliczającego składników (język C)
Wymagania
Zaimplementuj wszystkie interfejsy API zadeklarowane w pliku component_enumerator_extension.hpp:
| Funkcja | Argumenty (w programowaniu) | Zwraca |
|---|---|---|
char* GetAllComponents() |
Żaden | Ciąg JSON zawierający tablicę wszystkichComponentInfo wartości. Aby uzyskać więcej informacji, zobacz Przykładowe wartości zwracane. |
char* SelectComponents(char* selector) |
Ciąg JSON zawierający co najmniej jedną parę nazw/wartości używanych do wybierania składników docelowych aktualizacji | Ciąg JSON zawierający tablicę ComponentInfo wartości. Aby uzyskać więcej informacji, zobacz Przykładowe wartości zwracane. |
void FreeComponentsDataString(char* string) |
Wskaźnik do buforu ciągu, który został wcześniej zwrócony przez funkcje GetAllComponents lub SelectComponents |
Żaden |
Informacje o komponencie
Ciąg ComponentInfo JSON musi zawierać następujące właściwości:
| Nazwa | Typ | Opis |
|---|---|---|
id |
sznurek | Unikatowa tożsamość składnika (zakres urządzenia). Przykłady obejmują sprzętowy numer seryjny, identyfikator partycji dysku i unikatową ścieżkę pliku składnika. |
name |
sznurek | Nazwa logiczna składnika. Ta właściwość to nazwa przypisywana przez konstruktora urządzeń do składnika dostępnego na każdym urządzeniu tej samej device klasy.Na przykład każde urządzenie Contoso Virtual Vacuum zawiera silnik, który napędza lewe koło. Firma Contoso przypisała lewy silnik jako wspólną (logiczną) nazwę tego silnika, aby łatwo odwoływać się do tego elementu, zamiast identyfikatora sprzętowego, który może być globalnie unikatowy. |
group |
sznurek | Grupa, do którego należy ten składnik. Na przykład wszystkie silniki mogą należeć do grupy silników . |
manufacturer |
sznurek | W przypadku składnika sprzętu fizycznego ta właściwość jest nazwą producenta lub dostawcy. W przypadku składnika logicznego, takiego jak partycja dysku lub katalog, może to być dowolna wartość zdefiniowana przez konstruktora urządzeń. |
model |
sznurek | W przypadku składnika sprzętu fizycznego ta właściwość jest nazwą modelu. W przypadku składnika logicznego, takiego jak partycja dysku lub katalog, ta właściwość może być dowolną zdefiniowaną wartością konstruktora urządzeń. |
properties |
przedmiot | Obiekt JSON, który zawiera dowolne opcjonalne właściwości specyficzne dla urządzenia. |
Oto przykład kodu opartego na składnikach odkurzacza wirtualnego firmy Contoso:
{
"id": "contoso-motor-serial-00000",
"name": "left-motor",
"group": "motors",
"manufacturer": "contoso",
"model": "virtual-motor",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/0",
"firmwareDataFile": "firmware.json",
"status": "connected",
"version" : "motor-fw-1.0"
}
}
Przykładowe wartości zwracane
Poniżej znajduje się dokument JSON zwrócony z GetAllComponents funkcji. Opiera się na przykładowej implementacji enumeratora składnika wirtualnego odkurzacza firmy Contoso.
{
"components": [
{
"id": "hostfw",
"name": "hostfw",
"group": "firmware",
"manufacturer": "contoso",
"model": "virtual-firmware",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/hostfw",
"firmwareDataFile": "firmware.json",
"status": "ok",
"version" : "host-fw-1.0"
}
},
{
"id": "bootfs",
"name": "bootfs",
"group": "boot-image",
"manufacturer": "contoso",
"model": "virtual-disk",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/bootfs",
"firmwareDataFile": "diskimage.json",
"status": "ok",
"version" : "boot-fs-1.0"
}
},
{
"id": "rootfs",
"name": "rootfs",
"group": "os-image",
"manufacturer": "contoso",
"model": "virtual-os",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/rootfs",
"firmwareDataFile": "diskimage.json",
"status": "ok",
"version" : "root-fs-1.0"
}
},
{
"id": "contoso-motor-serial-00000",
"name": "left-motor",
"group": "motors",
"manufacturer": "contoso",
"model": "virtual-motor",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/0",
"firmwareDataFile": "firmware.json",
"status": "ok",
"version" : "motor-fw-1.0"
}
},
{
"id": "contoso-motor-serial-00001",
"name": "right-motor",
"group": "motors",
"manufacturer": "contoso",
"model": "virtual-motor",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/1",
"firmwareDataFile": "firmware.json",
"status": "ok",
"version" : "motor-fw-1.0"
}
},
{
"id": "contoso-motor-serial-00002",
"name": "vacuum-motor",
"group": "motors",
"manufacturer": "contoso",
"model": "virtual-motor",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/2",
"firmwareDataFile": "firmware.json",
"status": "ok",
"version" : "motor-fw-1.0"
}
},
{
"id": "contoso-camera-serial-00000",
"name": "front-camera",
"group": "cameras",
"manufacturer": "contoso",
"model": "virtual-camera",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/camera\/0",
"firmwareDataFile": "firmware.json",
"status": "ok",
"version" : "camera-fw-1.0"
}
},
{
"id": "contoso-camera-serial-00001",
"name": "rear-camera",
"group": "cameras",
"manufacturer": "contoso",
"model": "virtual-camera",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/camera\/1",
"firmwareDataFile": "firmware.json",
"status": "ok",
"version" : "camera-fw-1.0"
}
}
]
}
Poniższy dokument JSON jest zwracany z SelectComponents funkcji. Jest oparty na przykładowej implementacji enumeratora komponentu Contoso.
Oto parametr wejściowy do wybierania grupy składników silników :
{
"group" : "motors"
}
Oto dane wyjściowe parametru. Wszystkie elementy należą do grupy silników .
{
"components": [
{
"id": "contoso-motor-serial-00000",
"name": "left-motor",
"group": "motors",
"manufacturer": "contoso",
"model": "virtual-motor",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/0",
"firmwareDataFile": "firmware.json",
"status": "ok",
"version" : "motor-fw-1.0"
}
},
{
"id": "contoso-motor-serial-00001",
"name": "right-motor",
"group": "motors",
"manufacturer": "contoso",
"model": "virtual-motor",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/1",
"firmwareDataFile": "firmware.json",
"status": "ok",
"version" : "motor-fw-1.0"
}
},
{
"id": "contoso-motor-serial-00002",
"name": "vacuum-motor",
"group": "motors",
"manufacturer": "contoso",
"model": "virtual-motor",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/2",
"firmwareDataFile": "firmware.json",
"status": "ok",
"version" : "motor-fw-1.0"
}
}
]
}
Oto parametr wejściowy do wybierania pojedynczego składnika o nazwie hostfw:
{
"name" : "hostfw"
}
Oto dane wyjściowe parametru dla składnika hostfw :
{
"components": [
{
"id": "hostfw",
"name": "hostfw",
"group": "firmware",
"manufacturer": "contoso",
"model": "virtual-firmware",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/hostfw",
"firmwareDataFile": "firmware.json",
"status": "ok",
"version" : "host-fw-1.0"
}
}
]
}
Uwaga
Poprzedni przykład pokazał, że w razie potrzeby można wysłać nowszą aktualizację do dowolnego wystąpienia składnika, które jest wybrane przez właściwość name. Na przykład wdróż aktualizację na motor-fw-2.0silnik próżniowy, jednocześnie kontynuując korzystanie z motor-fw-1.0silnika lewego i silnika prawego.
Plik inwentarza
Przykładowa implementacja pokazana wcześniej dla enumeratora składników Virtual Vacuum firmy Contoso odczytuje informacje o składnikach specyficznych dla urządzenia z pliku component-inventory.json. Ta przykładowa implementacja służy tylko do celów demonstracyjnych.
W scenariuszu produkcyjnym niektóre właściwości powinny być pobierane bezpośrednio z rzeczywistych składników. Te właściwości obejmują id, manufactureri model.
Konstruktor urządzenia definiuje właściwości name i group. Te wartości nigdy nie powinny się zmieniać po ich zdefiniowaniu. Właściwość name musi być unikatowa w obrębie urządzenia.
Przykładowy plik component-inventory.json
Uwaga
Zawartość w tym pliku wygląda prawie tak samo jak zwracana wartość z GetAllComponents funkcji. Jednak w tym pliku nie ma właściwości ComponentInfo i version. Enumerator wypełni te właściwości w czasie działania programu.
Na przykład w przypadku hostfw wartość właściwości properties.version zostanie wypełniona z określonej wartości (makiety) firmwareDataFile (/usr/local/contoso-devices/vacuum-1/hostfw/firmware.json).
{
"components": [
{
"id": "hostfw",
"name": "hostfw",
"group": "firmware",
"manufacturer": "contoso",
"model": "virtual-firmware",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/hostfw",
"firmwareDataFile": "firmware.json",
}
},
{
"id": "bootfs",
"name": "bootfs",
"group": "boot-image",
"manufacturer": "contoso",
"model": "virtual-disk",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/bootfs",
"firmwareDataFile": "diskimage.json",
}
},
{
"id": "rootfs",
"name": "rootfs",
"group": "os-image",
"manufacturer": "contoso",
"model": "virtual-os",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/rootfs",
"firmwareDataFile": "diskimage.json",
}
},
{
"id": "contoso-motor-serial-00000",
"name": "left-motor",
"group": "motors",
"manufacturer": "contoso",
"model": "virtual-motor",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/0",
"firmwareDataFile": "firmware.json",
}
},
{
"id": "contoso-motor-serial-00001",
"name": "right-motor",
"group": "motors",
"manufacturer": "contoso",
"model": "virtual-motor",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/1",
"firmwareDataFile": "firmware.json",
}
},
{
"id": "contoso-motor-serial-00002",
"name": "vacuum-motor",
"group": "motors",
"manufacturer": "contoso",
"model": "virtual-motor",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/motors\/2",
"firmwareDataFile": "firmware.json",
}
},
{
"id": "contoso-camera-serial-00000",
"name": "front-camera",
"group": "cameras",
"manufacturer": "contoso",
"model": "virtual-camera",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/camera\/0",
"firmwareDataFile": "firmware.json",
}
},
{
"id": "contoso-camera-serial-00001",
"name": "rear-camera",
"group": "cameras",
"manufacturer": "contoso",
"model": "virtual-camera",
"properties": {
"path": "\/usr\/local\/contoso-devices\/vacuum-1\/camera\/1",
"firmwareDataFile": "firmware.json",
}
}
]
}
Następne kroki
W przykładzie w tym artykule użyto języka C. Aby zapoznać się z przykładowymi kodami źródłowymi języka C++, zobacz:
Aby uzyskać informacje o różnych przykładowych aktualizacjach składników połączonych z urządzeniem Contoso Virtual Vacuum, zobacz Pokaz aktualizacji serwera proxy.