Registrera komponenter med Enhetsuppdatering
Den här artikeln visar en exempelimplementering av en enhetsuppdatering för IoT Hub-komponentuppräknaren. Du kan referera till det här exemplet för att implementera en anpassad komponentuppräknare för dina IoT-enheter. En komponent är en identitet under enhetsnivån som har en sammansättningsrelation med värdenheten.
Den här artikeln visar en komponentuppräkning med hjälp av en virtuell IoT-enhet med namnet Contoso Virtual Vacuum. Komponentuppräknare används för att implementera proxyuppdateringsfunktionen.
Proxyuppdatering gör det möjligt att uppdatera flera komponenter på samma IoT-enhet eller flera sensorer som är anslutna till IoT-enheten med en enda over-the-air-distribution. Proxyuppdatering stöder en installationsorder för uppdatering av komponenter. Den stöder även uppdatering i flera steg med funktioner för förinstallation, installation och efter installation.
Exempel på användningsfall där proxyuppdateringar är tillämpliga är:
- Rikta specifika uppdateringsfiler till partitioner på enheten.
- Rikta specifika uppdateringsfiler till appar eller komponenter på enheten.
- Rikta specifika uppdateringsfiler till sensorer som är anslutna till IoT-enheter via ett nätverksprotokoll (till exempel USB- eller CAN-buss).
Mer information finns i Proxyuppdateringar och uppdatering av flera komponenter.
Enhetsuppdateringsagenten körs på värdenheten. Den kan skicka varje uppdatering till en specifik komponent eller till en grupp komponenter i samma maskinvaruklass (dvs. kräver samma program eller uppdatering av inbyggd programvara).
Vad är en komponentuppräknare?
En komponentuppräknare är ett tillägg för enhetsuppdateringsagenten som innehåller information om varje komponent som du behöver för en over-the-air-uppdatering via en värdenhets Azure IoT Hub-anslutning.
Enhetsuppdateringsagenten är enhets- och komponentagnostisk. I sig själv vet agenten ingenting om komponenter på (eller anslutna till) en värdenhet vid tidpunkten för uppdateringen.
Om du vill aktivera proxyuppdateringar måste enhetsbyggare identifiera alla komponenter på enheten som kan uppdateras och tilldela varje komponent ett unikt namn. Dessutom kan ett gruppnamn tilldelas till komponenter i samma maskinvaruklass, så att samma uppdatering kan installeras på alla komponenter i samma grupp. Sedan kan uppdateringsinnehållshanteraren installera och tillämpa uppdateringen på rätt komponenter.
Här följer ansvarsområdena för varje del av proxyuppdateringsflödet:
Enhetsbyggare
Utforma och skapa enheten.
Integrera enhetsuppdateringsagenten och dess beroenden.
Implementera ett enhetsspecifikt komponentuppräkningstillägg och registrera dig med enhetsuppdateringsagenten.
Komponentuppräknaren använder informationen från en komponentinventering eller en konfigurationsfil för att utöka statiska komponentdata (Enhetsuppdatering krävs) med dynamiska data (till exempel version av inbyggd programvara, anslutningsstatus och maskinvaruidentitet).
Skapa en proxyuppdatering som innehåller en eller flera underordnade uppdateringar som riktar sig mot en eller flera komponenter på (eller anslutna till) enheten.
Skicka uppdateringen till lösningsoperatorn.
Lösningsoperator
Importera uppdateringen och manifestet till enhetsuppdateringstjänsten.
Distribuera uppdateringen till en grupp med enheter.
Enhetsuppdateringsagent
Hämta uppdateringsinformation från IoT Hub via enhetstvillingen eller modultvillingen.
Anropa en steghanterare för att bearbeta proxyuppdateringen som är avsedd för en eller flera komponenter på enheten.
Exemplet i den här artikeln innehåller två uppdateringar:
host-fw-1.1
ochmotors-fw-1.1
. För varje underordnad uppdatering anropar den överordnade steghanteraren en underordnad steghanterare för att räkna upp alla komponenter som matchar deCompatibilities
egenskaper som anges i den underordnade uppdateringens manifestfil. Därefter laddar hanteraren ned, installerar och tillämpar den underordnade uppdateringen på alla målkomponenter.För att hämta matchande komponenter anropar den underordnade uppdateringen ett
SelectComponents
API som tillhandahålls av komponentuppräknaren. Om det inte finns några matchande komponenter hoppas den underordnade uppdateringen över.Samla in alla uppdateringsresultat från överordnade och underordnade uppdateringar och rapportera dessa resultat till IoT Hub.
Underordnad steghanterare
- Iterera genom en lista över komponentinstanser som är kompatibla med det underordnade uppdateringsinnehållet. Mer information finns i Steghanterare.
I produktion kan enhetsbyggare använda befintliga hanterare eller implementera en anpassad hanterare som anropar alla installationsprogram som behövs för en over-the-air-uppdatering. Mer information finns i Implementera en anpassad uppdateringsinnehållshanterare.
Virtual Vacuum-komponenter
I den här artikeln använder vi en virtuell IoT-enhet för att demonstrera viktiga begrepp och funktioner. Contoso Virtual Vacuum-enheten består av fem logiska komponenter:
- Värd för inbyggd programvara
- Värdstartfilsystem
- Värdrotfilsystem
- Tre motorer (vänster hjul, höger hjul och vakuum)
- Två kameror (fram och bak)
Följande katalogstruktur simulerar komponenterna:
/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 */
Varje komponents katalog innehåller en JSON-fil som lagrar ett falskt programvaruversionsnummer för varje komponent. Exempel på JSON-filer är firmware.json och diskimage.json.
För den här demonstrationen kopierar vi firmware.json eller diskimage.json (uppdatera nyttolasten) till katalogen för målkomponenter för att uppdatera komponenternas inbyggda programvara.
Här är ett exempel firmware.json fil:
{
"version": "0.5",
"description": "This component is generated for testing purposes."
}
Kommentar
Contoso Virtual Vacuum innehåller programvara eller versioner av inbyggd programvara för att demonstrera proxyuppdatering. Den tillhandahåller inga andra funktioner.
Implementera en komponentuppräknare (C-språk)
Krav
Implementera alla API:er som deklarerats i component_enumerator_extension.hpp:
Funktion | Argument | Returer |
---|---|---|
char* GetAllComponents() |
Ingen | En JSON-sträng som innehåller en matris med alla ComponentInfo värden. Mer information finns i Exempel på returvärden. |
char* SelectComponents(char* selector) |
En JSON-sträng som innehåller ett eller flera namn/värde-par som används för att välja uppdateringsmålkomponenter | En JSON-sträng som innehåller en matris med ComponentInfo värden. Mer information finns i Exempel på returvärden. |
void FreeComponentsDataString(char* string) |
En pekare till strängbuffert som tidigare returnerats av GetAllComponents eller SelectComponents funktioner |
Ingen |
ComponentInfo
ComponentInfo
JSON-strängen måste innehålla följande egenskaper:
Namn | Type | Description |
---|---|---|
id |
sträng | En komponents unika identitet (enhetsomfång). Exempel är maskinvaruserienummer, diskpartitions-ID och komponentens unika filsökväg. |
name |
sträng | En komponents logiska namn. Den här egenskapen är det namn som en enhetsbyggare tilldelar en komponent som är tillgänglig i varje enhet i samma device klass.Till exempel innehåller varje Contoso Virtual Vacuum-enhet en motor som kör ett vänsterhjul. Contoso tilldelade vänster motor som ett vanligt (logiskt) namn för den här motorn för att enkelt referera till den här komponenten, i stället för maskinvaru-ID, som kan vara globalt unik. |
group |
sträng | En grupp som den här komponenten tillhör. Till exempel kan alla motorer tillhöra en motorgrupp . |
manufacturer |
sträng | För en fysisk maskinvarukomponent är den här egenskapen ett namn på tillverkare eller leverantör. För en logisk komponent, till exempel en diskpartition eller katalog, kan det vara valfri enhetsbyggares definierade värde. |
model |
sträng | För en fysisk maskinvarukomponent är den här egenskapen ett modellnamn. För en logisk komponent, till exempel en diskpartition eller katalog, kan den här egenskapen vara valfri enhetsbyggares definierade värde. |
properties |
objekt | Ett JSON-objekt som innehåller valfria enhetsspecifika egenskaper. |
Här är ett exempel ComponentInfo
på kod baserad på Contoso Virtual Vacuum-komponenterna:
{
"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"
}
}
Exempel på returvärden
Följande är ett JSON-dokument som returneras från GetAllComponents
funktionen. Den baseras på exempelimplementeringen av Contoso Virtual Vacuum-komponentuppräknaren.
{
"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"
}
}
]
}
Följande JSON-dokument returneras från SelectComponents
funktionen. Den baseras på exempelimplementeringen av Contoso-komponentuppräknaren.
Här är indataparametern för att välja motorkomponentgruppen :
{
"group" : "motors"
}
Här är utdata för parametern. Alla komponenter tillhör motorgruppen .
{
"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"
}
}
]
}
Här är indataparametern för att välja en enskild komponent med namnet hostfw:
{
"name" : "hostfw"
}
Här är parameterns utdata för hostfw-komponenten :
{
"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"
}
}
]
}
Kommentar
Föregående exempel visade att det vid behov är möjligt att skicka en nyare uppdatering till en instans av en komponent som har valts av name
egenskapen. Distribuera till exempel motor-fw-2.0
uppdateringen till vacuum-motor samtidigt som du fortsätter att använda motor-fw-1.0
på vänstermotor och högermotor.
Inventeringsfil
Exempelimplementeringen som visades tidigare för Contoso Virtual Vacuum-komponentens uppräkning läser informationen om enhetsspecifika komponenter från component-inventory.json-filen. Den här exempelimplementeringen är endast i demonstrationssyfte.
I ett produktionsscenario bör vissa egenskaper hämtas direkt från de faktiska komponenterna. Dessa egenskaper inkluderar id
, manufacturer
och model
.
Enhetsverktyget definierar name
egenskaperna och group
. Dessa värden bör aldrig ändras när de har definierats. Egenskapen name
måste vara unik i enheten.
Exempel på component-inventory.json fil
Kommentar
Innehållet i den här filen ser nästan likadant ut som det returnerade värdet från GetAllComponents
funktionen. ComponentInfo
Men i den här filen innehåller version
inte och status
egenskaper. Komponentuppräknaren fyller i dessa egenskaper vid körning.
För hostfw fylls till exempel värdet för egenskapen properties.version
från det angivna värdet (mock) 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",
}
}
]
}
Nästa steg
Exemplet i den här artikeln använde C. Information om hur du utforskar C++-exempelkällor finns i:
Olika exempeluppdateringar för komponenter som är anslutna till Contoso Virtual Vacuum-enheten finns i Proxyuppdateringsdemo.