Introduzione alla gestione dei dispositivi (Java)

Le app back-end possono usare hub IoT di Azure primitive, ad esempio dispositivi gemelli e metodi diretti, per avviare e monitorare in remoto le azioni di gestione dei dispositivi nei dispositivi. Questo articolo illustra come un'app back-end e un'app per dispositivi può collaborare per avviare e monitorare un riavvio remoto del dispositivo usando hub IoT.

Nota

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

Usare un metodo diretto per avviare le operazioni di gestione dei dispositivi, ad esempio il riavvio, il ripristino delle impostazioni predefinite e l'aggiornamento del firmware, da un'applicazione back-end nel cloud. Il dispositivo è responsabile per:

  • La gestione della richiesta di metodo inviata dall'hub IoT.

  • L'avvio, nel dispositivo, dell'azione corrispondente specifica del dispositivo.

  • Gli aggiornamenti di stato tramite le proprietà segnalate nell'hub IoT.

È possibile usare un'applicazione back-end nel cloud per eseguire query di un dispositivo gemello in modo da creare report sullo stato di avanzamento delle operazioni di gestione del dispositivo.

Questo articolo illustra come creare:

  • simulato-dispositivo: un'app del dispositivo simulata con un metodo diretto che riavvia il dispositivo e segnala l'ultima volta di riavvio. I metodi diretti vengono richiamati dal cloud.

  • trigger-reboot: un'app Java che chiama il metodo diretto nell'app del dispositivo simulato tramite l'hub IoT. Visualizza la risposta e le proprietà segnalate aggiornate.

Nota

Per informazioni sugli SDK che consentono di compilare le applicazioni da eseguire nei dispositivi e i back-end della soluzione, vedere Azure IoT SDK.

Prerequisiti

  • Un hub IoT. Crearne uno con l'interfaccia della riga di comando o il portale di Azure.

  • Dispositivo registrato. Registrare una nella portale di Azure.

  • Java SE Development Kit 8. Assicurarsi di selezionare Java 8 in Supporto a lungo termine per passare ai download per JDK 8.

  • Maven 3

  • Assicurarsi che la porta 8883 sia aperta nel firewall. L'esempio di dispositivo di questo articolo usa il protocollo MQTT, che comunica tramite la porta 8883. Questa porta potrebbe essere bloccata in alcuni ambienti di rete aziendali e didattici. Per altre informazioni e soluzioni alternative per questo problema, vedere Connettersi all'hub IoT (MQTT).

Creare un'app per dispositivi con un metodo diretto

In questa sezione si crea un'app console Java che simula un dispositivo. L'app è in attesa della chiamata al metodo diretto di riavvio dall'hub IoT e risponde immediatamente. L'app viene quindi sospesa per un periodo di tempo per simulare il processo di riavvio prima di usare una proprietà segnalata per notificare all'app di back-end trigger-reboot il completamento del riavvio.

  1. Nella cartella dm-get-started creare un progetto Maven denominato simulated-device usando il comando seguente nel prompt dei comandi:

    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=simulated-device -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    
  2. Al prompt dei comandi passare alla cartella simulated-device.

  3. In un editor di testo aprire il file pom.xml nella cartella simulated-device e aggiungere la dipendenza seguente al nodo dependencies. Questa dipendenza consente di usare il pacchetto iot-service-client nell'app per comunicare con l'hub IoT:

    <dependency>
      <groupId>com.microsoft.azure.sdk.iot</groupId>
      <artifactId>iot-device-client</artifactId>
      <version>1.17.5</version>
    </dependency>
    

    Nota

    È possibile cercare la versione più recente di iot-device-client usando la ricerca di Maven.

  4. Aggiungere la dipendenza seguente al nodo dependencies. Questa dipendenza configura un NOP per l’interfaccia di registrazione Apache SLF4J, che viene usata dall'SDK del client per dispositivi per implementare la registrazione. Questa configurazione è facoltativa, ma se la si omette, è possibile che venga visualizzato un avviso nella console quando si esegue l'app. Per altre informazioni sulla registrazione nell’SDK del client per dispositivi, vedere Registrazione nel file Leggimi Samples for the Azure IoT device SDK for Java (Esempi per l’Azure IoT SDK per dispositivi per Java).

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-nop</artifactId>
      <version>1.7.28</version>
    </dependency>
    
  5. Aggiungere il nodo build seguente dopo il nodo dependencies. Questa configurazione indica a Maven di usare Java 1.8 per compilare l'app:

    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.3</version>
          <configuration>
            <source>1.8</source>
            <target>1.8</target>
          </configuration>
        </plugin>
      </plugins>
    </build>
    
  6. Salvare e chiudere il file pom.xml.

  7. Usando un editor di testo, aprire il file di origine simulated-device\src\main\java\com\mycompany\app\App.java.

  8. Aggiungere al file le istruzioni import seguenti:

    import com.microsoft.azure.sdk.iot.device.*;
    import com.microsoft.azure.sdk.iot.device.DeviceTwin.*;
    
    import java.io.IOException;
    import java.net.URISyntaxException;
    import java.time.LocalDateTime;
    import java.util.Scanner;
    import java.util.Set;
    import java.util.HashSet;
    
  9. Aggiungere le variabili a livello di classe seguenti alla classe App . Sostituire {yourdeviceconnectionstring} con la stringa di connessione del dispositivo visualizzata quando è stato registrato un dispositivo nella hub IoT:

    private static final int METHOD_SUCCESS = 200;
    private static final int METHOD_NOT_DEFINED = 404;
    
    private static IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;
    private static String connString = "{yourdeviceconnectionstring}";
    private static DeviceClient client;
    
  10. Per implementare un gestore di callback per gli eventi di stato del metodo diretto, aggiungere la classe nidificata seguente alla classe App:

    protected static class DirectMethodStatusCallback implements IotHubEventCallback
    {
      public void execute(IotHubStatusCode status, Object context)
      {
        System.out.println("IoT Hub responded to device method operation with status " + status.name());
      }
    }
    
  11. Per implementare un gestore di callback per gli eventi di stato del dispositivo gemello, aggiungere la classe nidificata seguente alla classe App:

    protected static class DeviceTwinStatusCallback implements IotHubEventCallback
    {
        public void execute(IotHubStatusCode status, Object context)
        {
            System.out.println("IoT Hub responded to device twin operation with status " + status.name());
        }
    }
    
  12. Per implementare un gestore di callback per gli eventi delle proprietà, aggiungere la classe nidificata seguente alla classe App:

    protected static class PropertyCallback implements PropertyCallBack<String, String>
    {
      public void PropertyCall(String propertyKey, String propertyValue, Object context)
      {
        System.out.println("PropertyKey:     " + propertyKey);
        System.out.println("PropertyKvalue:  " + propertyKey);
      }
    }
    
  13. Per implementare un thread per simulare il riavvio del dispositivo, aggiungere la classe nidificata seguente alla classe App. Il thread rimane inattivo per cinque secondi e quindi imposta la proprietà segnalata lastReboot:

    protected static class RebootDeviceThread implements Runnable {
      public void run() {
        try {
          System.out.println("Rebooting...");
          Thread.sleep(5000);
          Property property = new Property("lastReboot", LocalDateTime.now());
          Set<Property> properties = new HashSet<Property>();
          properties.add(property);
          client.sendReportedProperties(properties);
          System.out.println("Rebooted");
        }
        catch (Exception ex) {
          System.out.println("Exception in reboot thread: " + ex.getMessage());
        }
      }
    }
    
  14. Per implementare il metodo diretto nel dispositivo, aggiungere la classe nidificata seguente alla classe App. Quando l'app simulata riceve una chiamata al metodo diretto di riavvio, restituisce una conferma al chiamante e quindi avvia un thread per elaborare il riavvio:

    protected static class DirectMethodCallback implements com.microsoft.azure.sdk.iot.device.DeviceTwin.DeviceMethodCallback
    {
      @Override
      public DeviceMethodData call(String methodName, Object methodData, Object context)
      {
        DeviceMethodData deviceMethodData;
        switch (methodName)
        {
          case "reboot" :
          {
            int status = METHOD_SUCCESS;
            System.out.println("Received reboot request");
            deviceMethodData = new DeviceMethodData(status, "Started reboot");
            RebootDeviceThread rebootThread = new RebootDeviceThread();
            Thread t = new Thread(rebootThread);
            t.start();
            break;
          }
          default:
          {
            int status = METHOD_NOT_DEFINED;
            deviceMethodData = new DeviceMethodData(status, "Not defined direct method " + methodName);
          }
        }
        return deviceMethodData;
      }
    }
    
  15. Modificare la firma del metodo main escludendo le eccezioni seguenti:

    public static void main(String[] args) throws IOException, URISyntaxException
    
  16. Per creare un'istanza di DeviceClient, sostituire il codice nel metodo main con il codice seguente:

    System.out.println("Starting device client sample...");
    client = new DeviceClient(connString, protocol);
    
  17. Per avviare l'ascolto delle chiamate al metodo diretto, aggiungere il codice seguente al metodo main:

    try
    {
      client.open();
      client.subscribeToDeviceMethod(new DirectMethodCallback(), null, new DirectMethodStatusCallback(), null);
      client.startDeviceTwin(new DeviceTwinStatusCallback(), null, new PropertyCallback(), null);
      System.out.println("Subscribed to direct methods and polling for reported properties. Waiting...");
    }
    catch (Exception e)
    {
      System.out.println("On exception, shutting down \n" + " Cause: " + e.getCause() + " \n" +  e.getMessage());
      client.close();
      System.out.println("Shutting down...");
    }
    
  18. Per arrestare il simulatore del dispositivo, aggiungere il codice seguente al metodo main:

    System.out.println("Press any key to exit...");
    Scanner scanner = new Scanner(System.in);
    scanner.nextLine();
    scanner.close();
    client.close();
    System.out.println("Shutting down...");
    
  19. Salvare e chiudere il file simulated-device\src\main\java\com\mycompany\app\App.java.

  20. Compilare l'app simulated-device e correggere eventuali errori. Al prompt dei comandi passare alla cartella simulated-device ed eseguire il comando seguente:

    mvn clean package -DskipTests
    

Ottenere la stringa di connessione dell'hub IoT

In questo articolo viene creato un servizio back-end che richiama un metodo diretto in un dispositivo. Per richiamare un metodo diretto in un dispositivo tramite l'hub IoT, è necessario che il servizio disponga delle autorizzazioni di connessione al servizio. Per impostazione predefinita, ogni hub IoT viene creato con un servizio con nome di criteri di accesso condiviso che concede tale autorizzazione.

Per ottenere la stringa di connessione dell'hub IoT per i criteri del servizio, seguire questa procedura:

  1. Nel portale di Azure fare clic su Gruppi di risorse. Selezionare il gruppo di risorse in cui si trova l'hub e quindi selezionare l'hub dall'elenco di risorse.

  2. Nel riquadro sinistro dell'hub IoT selezionare Criteri di accesso condiviso.

  3. Dall'elenco dei criteri selezionare i criteri del servizio.

  4. Copiare la stringa di connessione primaria e salvare il valore.

Screenshot che mostra come recuperare la stringa di connessione dal hub IoT nell'portale di Azure.

Per altre informazioni sui criteri di accesso condiviso e sulle autorizzazioni dell'hub IoT, vedere Controllo dell'accesso e autorizzazioni.

Creare un'app del servizio per attivare un riavvio

In questa sezione si crea un'app console Java che:

  1. Richiama il metodo diretto reboot nell'app per dispositivo simulato.

  2. Visualizza la risposta.

  3. Esegue il polling delle proprietà segnalate inviate dal dispositivo per determinare quando viene completato il riavvio.

Quest'app console si connette all'hub IoT per richiamare il metodo diretto e leggere le proprietà segnalate.

  1. Creare una cartella vuota denominata dm-get-started.

  2. Nella cartella dm-get-started creare un progetto Maven denominato trigger-reboot usando il comando seguente al prompt dei comandi:

    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=trigger-reboot -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    
  3. Al prompt dei comandi passare alla cartella trigger-reboot.

  4. In un editor di testo aprire il file pom.xml nella cartella trigger-reboot e aggiungere la dipendenza seguente al nodo dependencies. Questa dipendenza consente di usare il pacchetto iot-service-client nell'app per comunicare con l'hub IoT:

    <dependency>
      <groupId>com.microsoft.azure.sdk.iot</groupId>
      <artifactId>iot-service-client</artifactId>
      <version>1.17.1</version>
      <type>jar</type>
    </dependency>
    

    Nota

    È possibile cercare la versione più recente di iot-service-client usando la ricerca di Maven.

  5. Aggiungere il nodo build seguente dopo il nodo dependencies. Questa configurazione indica a Maven di usare Java 1.8 per compilare l'app:

    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.3</version>
          <configuration>
            <source>1.8</source>
            <target>1.8</target>
          </configuration>
        </plugin>
      </plugins>
    </build>
    
  6. Salvare e chiudere il file pom.xml.

  7. Usando un editor di testo, aprire il file di origine trigger-reboot\src\main\java\com\mycompany\app\App.java.

  8. Aggiungere al file le istruzioni import seguenti:

    import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceMethod;
    import com.microsoft.azure.sdk.iot.service.devicetwin.MethodResult;
    import com.microsoft.azure.sdk.iot.service.exceptions.IotHubException;
    import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceTwin;
    import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceTwinDevice;
    
    import java.io.IOException;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ExecutorService;
    
  9. Aggiungere le variabili a livello di classe seguenti alla classe App . Sostituire {youriothubconnectionstring} con la stringa di connessione dell'hub IoT copiata in precedenza in Ottenere la stringa di connessione dell’hub IoT:

    public static final String iotHubConnectionString = "{youriothubconnectionstring}";
    public static final String deviceId = "myDeviceId";
    
    private static final String methodName = "reboot";
    private static final Long responseTimeout = TimeUnit.SECONDS.toSeconds(30);
    private static final Long connectTimeout = TimeUnit.SECONDS.toSeconds(5);
    
  10. Per implementare un thread che legge le proprietà segnalate da un dispositivo gemello ogni 10 secondi, aggiungere la seguente classe nidificata alla classe App:

    private static class ShowReportedProperties implements Runnable {
      public void run() {
        try {
          DeviceTwin deviceTwins = DeviceTwin.createFromConnectionString(iotHubConnectionString);
          DeviceTwinDevice twinDevice = new DeviceTwinDevice(deviceId);
          while (true) {
            System.out.println("Get reported properties from device twin");
            deviceTwins.getTwin(twinDevice);
            System.out.println(twinDevice.reportedPropertiesToString());
            Thread.sleep(10000);
          }
        } catch (Exception ex) {
          System.out.println("Exception reading reported properties: " + ex.getMessage());
        }
      }
    }
    
  11. Modificare la firma del metodo main escludendo le eccezioni seguenti:

    public static void main(String[] args) throws IOException
    
  12. Per richiamare il metodo diretto di riavvio sul dispositivo simulato, sostituire il codice nel metodo main con il codice seguente:

    System.out.println("Starting sample...");
    DeviceMethod methodClient = DeviceMethod.createFromConnectionString(iotHubConnectionString);
    
    try
    {
      System.out.println("Invoke reboot direct method");
      MethodResult result = methodClient.invoke(deviceId, methodName, responseTimeout, connectTimeout, null);
    
      if(result == null)
      {
        throw new IOException("Invoke direct method reboot returns null");
      }
      System.out.println("Invoked reboot on device");
      System.out.println("Status for device:   " + result.getStatus());
      System.out.println("Message from device: " + result.getPayload());
    }
    catch (IotHubException e)
    {
        System.out.println(e.getMessage());
    }
    
  13. Per avviare il thread per eseguire il polling delle proprietà segnalate dal dispositivo simulato, aggiungere il codice seguente al metodo main:

    ShowReportedProperties showReportedProperties = new ShowReportedProperties();
    ExecutorService executor = Executors.newFixedThreadPool(1);
    executor.execute(showReportedProperties);
    
  14. Per consentire all'utente di arrestare l'app, aggiungere il codice seguente al metodo main:

    System.out.println("Press ENTER to exit.");
    System.in.read();
    executor.shutdownNow();
    System.out.println("Shutting down sample...");
    
  15. Salvare e chiudere il file trigger-reboot\src\main\java\com\mycompany\app\App.java.

  16. Compilare l'app di back-end trigger riavvio e correggere eventuali errori. Al prompt dei comandi passare alla cartella trigger-reboot ed eseguire il comando seguente:

    mvn clean package -DskipTests
    

Eseguire le app

A questo punto è possibile eseguire le app.

  1. Eseguire questo comando al prompt dei comandi nella cartella simulated-device per iniziare ad ascoltare le chiamate ai metodi di riavvio dell'hub IoT:

    mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
    

    App per il dispositivo simulato dell'hub IoT per Java per ascoltare le chiamate al metodo diretto di riavvio

  2. Eseguire questo comando al prompt dei comandi nella cartella trigger-reboot per chiamare un metodo di riavvio sul dispositivo simulato dell'hub IoT:

    mvn exec:java -Dexec.mainClass="com.mycompany.app.App"
    

    App del servizio hub IoT per Java per chiamare il metodo diretto di riavvio

  3. Il dispositivo simulato risponde alla chiamata al metodo diretto di riavvio:

    L'app del dispositivo simulato dell'hub IoT per Java risponde alla chiamata al metodo diretto

Personalizzare ed estendere le operazioni di gestione dei dispositivi

Le soluzioni IoT possono espandere il set definito di modelli di gestione dei dispositivi o abilitare modelli personalizzati mediante l'uso di primitive di metodo da cloud a dispositivo e del dispositivo gemello. Altri esempi di operazioni di gestione dei dispositivi includono il ripristino delle informazioni predefinite, l'aggiornamento del firmware, l'aggiornamento del software, il risparmio energia, la gestione di rete e connettività e la crittografia dei dati.

Finestre di manutenzione del dispositivo

Configurare i dispositivi in modo che eseguano le azioni in un momento che riduce al minimo le interruzioni e i tempi di inattività. Le finestre di manutenzione del dispositivo costituiscono un modello comunemente usato per definire il momento in cui un dispositivo deve eseguire l'aggiornamento della configurazione. Le soluzioni di back-end possono usare le proprietà desiderate del dispositivo gemello per definire e attivare un criterio sul dispositivo che attiva una finestra di manutenzione. Quando un dispositivo riceve il criterio della finestra di manutenzione, può usare la proprietà segnalata del dispositivo gemello per segnalare lo stato del criterio. L'applicazione back-end può quindi usare le query del dispositivo gemello per attestare la conformità dei dispositivi e di tutti i criteri.

Passaggi successivi

In questo articolo è stato usato un metodo diretto per attivare un riavvio remoto in un dispositivo. Sono state usate le proprietà segnalate per indicare l'ora dell'ultimo riavvio dal dispositivo ed è stata eseguita una query sul dispositivo gemello per ottenere l'ora dell'ultimo riavvio del dispositivo dal cloud.

ToTo continua a iniziare a usare hub IoT e modelli di gestione dei dispositivi, ad esempio l'aggiornamento basato su immagini end-to-end nell'articolo Aggiornamento dispositivi per hub IoT di Azure usando l'immagine di riferimento Raspberry Pi 3 B+.

Per informazioni su come estendere la soluzione IoT e pianificare le chiamate al metodo su più dispositivi, vedere Pianificare e trasmettere processi.