Rejestrowanie składników za pomocą usługi Device Update
W tym artykule przedstawiono przykładową implementację modułu wyliczającego składników usługi IoT Hub w usłudze Device Update. Możesz odwołać się do tego przykładu, aby zaimplementować moduł wyliczający składników niestandardowych dla urządzeń IoT. Składnik to tożsamość poniżej poziomu urządzenia, która ma relację kompozycji 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 czujnikach połączonych z urządzeniem IoT za pomocą jednego wdrożenia w powietrzu. Aktualizacja serwera proxy obsługuje kolejność instalacji aktualizacji składnikó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:
- Określanie wartości docelowej określonych plików aktualizacji na partycje na urządzeniu.
- Określanie wartości docelowej określonych plików aktualizacji do aplikacji lub składnikó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?
Moduł wyliczający składników to rozszerzenie agenta usługi Device Update, które udostępnia informacje o każdym składniku potrzebnym do aktualizacji over-the-air za pośrednictwem połączenia usługi Azure IoT Hub urządzenia hosta.
Agent usługi Device Update jest niezależny od urządzeń i składników. Sam agent nie wie nic o składnikach (lub połączeniu z) urządzeniem hosta w momencie 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ę serwera proxy zawierającą co najmniej jedną aktualizację podrzędną docelową co najmniej jednego składnika na urządzeniu (lub połączonym z nim).
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 usługi Device Update
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 procedurę obsługi , aby przetworzyć aktualizację serwera proxy przeznaczoną dla co najmniej jednego składnika na urządzeniu.
Przykład w tym artykule zawiera dwie aktualizacje:
host-fw-1.1
imotors-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 zCompatibilities
wł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
SelectComponents
interfejs API dostarczony przez moduł wyliczający składników. Jeśli nie ma pasujących składników, aktualizacja podrzędna zostanie pominięta.Zbierz wszystkie wyniki aktualizacji z aktualizacji nadrzędnych i podrzędnych oraz zgłoś te wyniki 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, zobacz Procedura obsługi 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.
Składniki próżni wirtualnej
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
- Główny system plików hosta
- Trzy silniki (lewe koło, prawe koło i próżnia)
- 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 są firmware.json i diskimage.json.
W tym pokazie, aby zaktualizować oprogramowanie układowe składników, skopiujemy firmware.json lub diskimage.json (ładunek aktualizacji) do katalogu składników docelowych.
Oto przykładowy plik firmware.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:
Function | Argumenty | Zwraca |
---|---|---|
char* GetAllComponents() |
Brak | Ciąg JSON zawierający tablicę wszystkich ComponentInfo 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 zwróconego wcześniej przez GetAllComponents funkcje lub SelectComponents |
Brak |
ComponentInfo
Ciąg ComponentInfo
JSON musi zawierać następujące właściwości:
Nazwisko | Pisz | opis |
---|---|---|
id |
string | 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 |
string | 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ł lewy silnik jako wspólną (logiczną) nazwę tego silnika, aby łatwo odwoływać się do tego składnika, zamiast identyfikatora sprzętu, który może być globalnie unikatowy. |
group |
string | Grupa, do którego należy ten składnik. Na przykład wszystkie silniki mogą należeć do grupy silników . |
manufacturer |
string | 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 |
string | 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 |
obiekt | Obiekt JSON, który zawiera dowolne opcjonalne właściwości specyficzne dla urządzenia. |
Oto przykład kodu opartego na składnikach ComponentInfo
virtual vacuum 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. Jest ona oparta na przykładowej implementacji modułu wyliczającego składnika virtual vacuum 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 on oparty na przykładowej implementacji modułu wyliczającego składników Firmy 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
W poprzednim przykładzie pokazano, że w razie potrzeby można wysłać nowszą aktualizację do dowolnego wystąpienia składnika wybranego przez name
właściwość. Na przykład wdróż aktualizację motor-fw-2.0
silnika próżniowego, kontynuując korzystanie motor-fw-1.0
z lewego silnika i prawej silnika.
Plik spisu
Przykładowa implementacja pokazana wcześniej dla modułu wyliczającego składnika 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
, manufacturer
i model
.
Konstruktor urządzenia definiuje name
właściwości i group
. Te wartości nigdy nie powinny się zmieniać po ich zdefiniowaniu. Właściwość musi być unikatowa name
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. ComponentInfo
Jednak w tym pliku nie zawiera version
właściwości i status
. Moduł wyliczający składników wypełni te właściwości w czasie wykonywania.
Na przykład w przypadku hostafw 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.