Comprendere e usare i moduli gemelli nell'hub IoT

Questo articolo presuppone che sia già stato letto l'articolo Comprendere e usare i dispositivi gemelli nell'hub IoT. In hub IoT, in ogni identità del dispositivo, è possibile creare fino a 50 identità del modulo. Ogni identità del modulo genera implicitamente un modulo gemello. Simili ai dispositivi gemelli, i moduli gemelli sono documenti JSON nei quali vengono archiviate informazioni sullo stato dei moduli, tra cui metadati, configurazioni e condizioni. L'hub IoT di Azure mantiene un modulo gemello per ogni modulo che viene connesso all'hub IoT.

Sul lato del dispositivo, gli SDK per dispositivi dell'hub IoT consentono di creare moduli ognuno dei quali apre una connessione indipendente all'hub IoT. Questa funzionalità permette di usare spazi dei nomi distinti per i diversi componenti nel dispositivo. Supponiamo ad esempio di avere un distributore automatico con tre diversi sensori. Ogni sensore è controllato da reparti diversi dell'azienda. È possibile creare un modulo per ogni sensore. In questo modo ogni reparto può inviare processi o metodi diretti solo al sensore che controlla, evitando conflitti ed errori degli utenti.

L'identità del modulo e il modulo gemello offrono le stesse funzionalità dell'identità del dispositivo e dei dispositivi gemelli, ma con una granularità superiore. Questa granularità superiore consente a determinati dispositivi, ad esempio i dispositivi basati su sistema operativo o i dispositivi firmware che gestiscono più componenti, di isolare la configurazione e le condizioni di ognuno di questi componenti. L'identità del modulo e i moduli gemelli consentono di gestire separatamente i diversi problemi quando si usano dispositivi IoT con componenti software modulari. L'obiettivo di Microsoft è supportare tutte le funzionalità dei dispositivi gemelli a livello di modulo gemello in base alla disponibilità generale dei moduli gemelli.

Nota

Le funzionalità descritte in questo articolo sono disponibili solo nel livello Standard dell'hub IoT. Per altre informazioni sui livelli di hub IoT basic e standard/gratuiti, vedere Scegliere il livello di hub IoT appropriato per la soluzione.

L'articolo illustra:

  • la struttura del modulo gemello: tag, proprietà desiderate e proprietà segnalate.
  • Le operazioni che i moduli e i back-end possono eseguire sui moduli gemelli.

Vedere Indicazioni sulle comunicazioni da dispositivo a cloud per informazioni sull'uso delle proprietà indicate, dei messaggi da dispositivo a cloud o del caricamento di file.

Vedere Indicazioni sulle comunicazioni da cloud a dispositivo per informazioni sull'uso delle proprietà specifiche, dei metodi diretti o dei messaggi da cloud a dispositivo.

Moduli gemelli

I moduli gemelli consentono di archiviare informazioni sul modulo che possono essere usate:

  • Dai moduli nel dispositivo e dall'hub IoT per sincronizzare le condizioni e la configurazione del modulo.

  • Dal back-end della soluzione per eseguire query e come destinazione delle operazioni a esecuzione prolungata.

Il ciclo di vita di un modulo gemello è correlato all'identità del modulo corrispondente. I moduli gemelli vengono creati ed eliminati implicitamente quando viene creata o eliminata un'identità del modulo nell'hub IoT.

Un modulo gemello è un documento JSON che include:

  • Tag. Una sezione del documento JSON che il back-end della soluzione è in grado di leggere e in cui può scrivere. I tag non sono visibili per i moduli nel dispositivo. I tag vengono impostati per consentire l'esecuzione di query.

  • Proprietà desiderate. Sono usate insieme alle proprietà segnalate per sincronizzare la configurazione o le condizioni del modulo. Il back-end della soluzione è in grado di impostare le proprietà desiderate e l'app per modulo è in grado di leggerle. L'app per modulo può anche ricevere notifiche relative alle modifiche apportate alle proprietà desiderate.

  • Proprietà segnalate. Sono usate insieme alle proprietà desiderate per sincronizzare la configurazione o le condizioni del modulo. L'app per modulo è in grado di impostare le proprietà segnalate, mentre il back-end della soluzione è in grado di leggerle ed eseguire query su di esse.

  • Proprietà dell'identità del modulo. La radice del documento JSON del modulo gemello contiene le proprietà di sola lettura dell'identità del modulo corrispondente archiviata nel registro delle identità.

Architectural representation of device twin

L'esempio seguente illustra un documento JSON del modulo gemello:

{
    "deviceId": "devA",
    "moduleId": "moduleA",
    "etag": "AAAAAAAAAAc=", 
    "status": "enabled",
    "statusReason": "provisioned",
    "statusUpdateTime": "0001-01-01T00:00:00",
    "connectionState": "connected",
    "lastActivityTime": "2015-02-30T16:24:48.789Z",
    "cloudToDeviceMessageCount": 0, 
    "authenticationType": "sas",
    "x509Thumbprint": {     
        "primaryThumbprint": null, 
        "secondaryThumbprint": null 
    }, 
    "version": 2, 
    "tags": {
        "deploymentLocation": {
            "building": "43",
            "floor": "1"
        }
    },
    "properties": {
        "desired": {
            "telemetryConfig": {
                "sendFrequency": "5m"
            },
            "$metadata" : {...},
            "$version": 1
        },
        "reported": {
            "telemetryConfig": {
                "sendFrequency": "5m",
                "status": "success"
            },
            "batteryLevel": 55,
            "$metadata" : {...},
            "$version": 4
        }
    }
}

Nell'oggetto radice si trovano le proprietà dell'identità del modulo e gli oggetti contenitore per tags e per entrambe le proprietà reported e desired. Il properties contenitore contiene alcuni elementi di sola lettura ($metadata e $version) descritti nelle sezioni Metadati del modulo gemello e Concorrenza ottimistica.

Esempio di proprietà segnalata

Nell'esempio precedente, il dispositivo gemello contiene la proprietà batteryLevel che viene segnalata dall'app per modulo. Questa proprietà consente di eseguire query e di operare sui moduli in base al livello di carica della batteria più recente segnalato. Altri esempi sono l'app per modulo che segnala le funzionalità o le opzioni di connettività del modulo.

Nota

Le proprietà segnalate semplificano gli scenari in cui il back-end della soluzione è interessato all'ultimo valore noto di una proprietà. Usare i messaggi dal dispositivo al cloud se il back-end della soluzione deve elaborare la telemetria del modulo in forma di sequenze di eventi con timestamp, ad esempio una serie temporale.

Esempio di proprietà desiderata

Nell'esempio precedente le proprietà desiderate e segnalate del modulo gemello telemetryConfig vengono usate dal back-end della soluzione e dall'app per modulo per sincronizzare la configurazione della telemetria per questo modulo. Ad esempio:

  1. Il back-end della soluzione imposta la proprietà desiderata sul valore di configurazione desiderato. Questa è la parte del documento con il set di proprietà desiderate:

    ...
    "desired": {
        "telemetryConfig": {
            "sendFrequency": "5m"
        },
        ...
    },
    ...
    
  2. L'app del modulo riceve una notifica immediata della modifica se il modulo è connesso. Se non è connesso, l'app del modulo segue il flusso di riconnessione del modulo quando si connette. L'app segnala quindi la configurazione aggiornata o una condizione di errore riscontrata nell'uso della proprietà status. Questa è la parte con le proprietà segnalate:

    "reported": {
        "telemetryConfig": {
            "sendFrequency": "5m",
            "status": "success"
        }
        ...
    }
    
  3. Il back-end della soluzione può tenere traccia dei risultati dell'operazione di configurazione su più moduli, eseguendo query sui moduli gemelli.

Nota

I frammenti di codice precedenti sono esempi, ottimizzati per una migliore leggibilità, di un modo per codificare una configurazione del modulo e il relativo stato. L'hub IoT non impone uno schema specifico per l'uso delle proprietà desiderate e segnalate del modulo gemello nei moduli gemelli.

Importante

Plug and Play IoT definisce uno schema che usa diverse proprietà aggiuntive per sincronizzare le modifiche alle proprietà desiderate e segnalate. Se la soluzione usa Plug and Play IoT, è necessario seguire le convenzioni Plug and Play durante l'aggiornamento delle proprietà dei dispositivi gemelli. Per altre informazioni e un esempio, vedere Proprietà scrivibili in Plug and Play IoT.

Operazioni di back-end

Il back-end della soluzione opera sul modulo gemello tramite le seguenti operazioni atomiche esposte tramite HTTPS:

  • Recupero del modulo gemello in base all'ID. Questa operazione restituisce il documento del modulo gemello, inclusi tag e proprietà di sistema desiderate e segnalate.

  • Aggiornamento parziale del modulo gemello. Questa operazione consente al back-end della soluzione di aggiornare parzialmente i tag o le proprietà desiderate di un modulo gemello. L'aggiornamento parziale è espresso come documento JSON che aggiunge o aggiorna tutte le proprietà. Le proprietà impostate su null vengono rimosse. L'esempio seguente crea una nuova proprietà desiderata con valore {"newProperty": "newValue"}, sostituisce il valore esistente di existingProperty con "otherNewValue", e rimuove otherOldProperty. Non vengono apportate altre modifiche alle altre proprietà desiderate o ai tag esistenti:

    {
        "properties": {
            "desired": {
                "newProperty": {
                    "nestedProperty": "newValue"
                },
                "existingProperty": "otherNewValue",
                "otherOldProperty": null
            }
        }
    }
    
  • Sostituzione di proprietà desiderate. Questa operazione consente al back-end della soluzione di sovrascrivere completamente tutte le proprietà desiderate esistenti e di sostituirle con un nuovo documento JSON properties/desired.

  • Sostituzione di tag. Questa operazione consente al back-end della soluzione di sovrascrivere completamente tutti i tag esistenti e di sostituirli con un nuovo documento JSON tags.

  • Ricezione di notifiche relative al dispositivo gemello. Questa operazione invia notifiche al back-end della soluzione a ogni modifica del dispositivo gemello. A questo scopo, la soluzione IoT deve creare una route e impostare l'origine dati su twinChangeEvents. Per impostazione predefinita, non esiste alcuna route di questo tipo, quindi non vengono inviate notifiche gemelle. Se la frequenza delle modifiche è troppo elevata o per altri motivi, ad esempio un errore interno, l'hub IoT potrebbe inviare solo una notifica che contiene tutte le modifiche. Se pertanto l'applicazione ha bisogno di controllo e registrazione affidabili di tutti gli stati intermedi, è consigliabile usare messaggi da dispositivo a cloud. Per altre informazioni sulle proprietà e sul corpo restituito nel messaggio di notifica del gemello, vedere Schemi di eventi non di telemetria.

Tutte le operazioni precedenti supportano la concorrenza ottimistica e richiedono l'autorizzazione ServiceConnect, come indicato nell'articolo Controllare l'accesso all'hub IoT.

Oltre a queste operazioni, il back-end della soluzione può eseguire una query sui dispositivi gemelli usando un linguaggio di query dell'hub IoT simile a SQL.

Operazioni sui moduli

L'app per modulo opera sul modulo gemello usando le seguenti operazioni atomiche:

  • Recupero del modulo gemello. Questa operazione restituisce il documento del modulo gemello (incluse le proprietà di sistema desiderate e segnalate) per il modulo attualmente connesso.

  • Aggiornamento parziale delle proprietà segnalate. Questa operazione consente l'aggiornamento parziale delle proprietà segnalate del modulo attualmente connesso. Questa operazione usa lo stesso formato di aggiornamento JSON che il back-end della soluzione usa per un aggiornamento parziale delle proprietà desiderate.

  • Osservazione di proprietà desiderate. Il modulo attualmente connesso può scegliere di ricevere la notifica degli aggiornamenti delle proprietà desiderate quando vengono eseguiti. Il modulo riceve lo stesso modulo di aggiornamento che segnala la sostituzione parziale o completa eseguita dal back-end della soluzione.

Tutte le operazioni precedenti richiedono l'autorizzazione Device Connessione, come definito nell'articolo Controllare l'accesso a hub IoT.

Azure IoT SDK per dispositivi semplifica l'uso delle operazioni precedenti con linguaggi e piattaforme diversi.

Formato di tag e proprietà

I tag e le proprietà desiderate e segnalate sono oggetti JSON soggetti alle restrizioni indicate di seguito:

  • Chiavi: tutte le chiavi negli oggetti JSON sono con codifica UTF-8, con distinzione tra maiuscole e minuscole e fino a 1 KB. I caratteri consentiti escludono i caratteri di controllo UNICODE (segmenti C0 e C1) e ., $ e SP.

  • Valori: tutti i valori negli oggetti JSON possono essere dei tipi JSON seguenti: boolean, number, string, object. Sono supportate anche matrici.

    • I numeri interi possono avere un valore minimo pari a -4503599627370496 e un valore massimo di 4503599627370495.

    • I valori stringa sono codificati con UTF-8 e possono avere una lunghezza massima di 4 KB.

  • Profondità: la profondità massima degli oggetti JSON nei tag, nelle proprietà desiderate e nelle proprietà segnalate è 10. Ad esempio, l'oggetto seguente è valido:

    {
         ...
         "tags": {
             "one": {
                 "two": {
                     "three": {
                         "four": {
                             "five": {
                                 "six": {
                                     "seven": {
                                         "eight": {
                                             "nine": {
                                                 "ten": {
                                                     "property": "value"
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         },
         ...
    }
    

Dimensioni del modulo gemello

hub IoT applica un limite di dimensioni di 8 KB per il valore di e un limite di tagsdimensioni di 32 KB ciascuno per il valore di properties/desired e properties/reported. Questi totali sono esclusivi di elementi di sola lettura come $version e $metadata/$lastUpdated.

Le dimensioni dei dispositivi gemelli vengono calcolate nel modo seguente:

  • Per ogni proprietà nel documento JSON, hub IoT calcola in modo cumulativo e aggiunge la lunghezza della chiave e del valore della proprietà.

  • Le chiavi delle proprietà vengono considerate come stringhe con codifica UTF8.

  • I valori delle proprietà semplici vengono considerati come stringhe con codifica UTF8, valori numerici (8 byte) o valori booleani (4 byte).

  • Le dimensioni delle stringhe con codifica UTF8 vengono calcolate con il conteggio di tutti i caratteri, esclusi i caratteri di controllo UNICODE (segmenti C0 e C1).

  • I valori delle proprietà complesse (oggetti annidati) vengono calcolati in base alle dimensioni aggregate delle chiavi delle proprietà e ai valori delle proprietà che contengono.

L'hub IoT rifiuta con errore tutte le operazioni che aumentano le dimensioni dei documenti oltre il limite specificato.

Metadati del modulo gemello

L'hub IoT conserva il timestamp dell'ultimo aggiornamento di ogni oggetto JSON nelle proprietà desiderate e segnalate del modulo gemello. I timestamp sono in formato UTC e codificati in formato ISO8601YYYY-MM-DDTHH:MM:SS.mmmZ. Ad esempio:

{
    ...
    "properties": {
        "desired": {
            "telemetryConfig": {
                "sendFrequency": "5m"
            },
            "$metadata": {
                "telemetryConfig": {
                    "sendFrequency": {
                        "$lastUpdated": "2016-03-30T16:24:48.789Z"
                    },
                    "$lastUpdated": "2016-03-30T16:24:48.789Z"
                },
                "$lastUpdated": "2016-03-30T16:24:48.789Z"
            },
            "$version": 23
        },
        "reported": {
            "telemetryConfig": {
                "sendFrequency": "5m",
                "status": "success"
            },
            "batteryLevel": "55%",
            "$metadata": {
                "telemetryConfig": {
                    "sendFrequency": "5m",
                    "status": {
                        "$lastUpdated": "2016-03-31T16:35:48.789Z"
                    },
                    "$lastUpdated": "2016-03-31T16:35:48.789Z"
                },
                "batteryLevel": {
                    "$lastUpdated": "2016-04-01T16:35:48.789Z"
                },
                "$lastUpdated": "2016-04-01T16:24:48.789Z"
            },
            "$version": 123
        }
    }
    ...
}

Queste informazioni vengono mantenute a ogni livello (non solo al livello foglia della struttura JSON) per conservare gli aggiornamenti che rimuovono le chiavi dell'oggetto.

Concorrenza ottimistica

I tag, le proprietà desiderate e le proprietà segnalate supportano la concorrenza ottimistica. Se è necessario garantire l'ordine degli aggiornamenti delle proprietà gemelle, valutare la possibilità di implementare la sincronizzazione a livello di applicazione attendendo il callback delle proprietà segnalate prima di inviare l'aggiornamento successivo.

I moduli gemelli hanno una proprietà ETag (etag ), in base RFC7232, che rappresenta la rappresentazione JSON del gemello. È possibile usare la etag proprietà nelle operazioni di aggiornamento condizionale dal back-end della soluzione per garantire la coerenza. Questa è l'unica opzione per garantire la coerenza nelle operazioni che coinvolgono il tags contenitore.

Le proprietà desiderate e segnalate del modulo gemello hanno anche un $version valore garantito come incrementale. In modo analogo a un valore ETag, la versione può essere usata dall'entità di aggiornamento per garantire la coerenza degli aggiornamenti. Ad esempio, un'app per modulo per una proprietà segnalata o il back-end della soluzione per una proprietà desiderata.

Le versioni sono utili anche quando un agente di osservazione, ad esempio l'app per modulo che osserva le proprietà desiderate, deve riconciliare le concorrenze tra il risultato di un'operazione di recupero e una notifica di aggiornamento. La sezione Flusso di riconnessione del modulo fornisce altre informazioni.

Flusso di riconnessione del modulo

hub IoT non mantiene le notifiche di aggiornamento delle proprietà desiderate per i moduli disconnessi. Segue che un modulo che si connette deve recuperare il documento completo delle proprietà desiderate, oltre alla sottoscrizione per le notifiche di aggiornamento. Data la possibilità di concorrenza tra le notifiche di aggiornamento e il recupero completo, deve essere assicurato il flusso seguente:

  1. L'app per i moduli si connette a un hub IoT.
  2. L'app per i moduli sottoscrive le notifiche di aggiornamento delle proprietà desiderate.
  3. L'app modulo recupera il documento completo per le proprietà desiderate.

L'app per i moduli può ignorare tutte le notifiche con $version meno o uguale alla versione del documento recuperato completo. Questo approccio è possibile poiché l'hub IoT garantisce l'incremento delle versioni.

Passaggi successivi

Per provare alcuni dei concetti descritti in questo articolo, vedere le esercitazioni sull'hub IoT seguenti: