Sdílet prostřednictvím


Úlohy plánování a vysílání (Java)

Pomocí služby Azure IoT Hub můžete plánovat a sledovat úlohy, které aktualizují miliony zařízení. Použití úloh k:

  • Aktualizace požadovaných vlastností
  • Aktualizace značek
  • Vyvolání přímých metod

Úloha zabalí jednu z těchto akcí a sleduje provádění proti sadě zařízení. Dotaz dvojčete zařízení definuje sadu zařízení, pro která se úloha provede. Back-endová aplikace může například pomocí úlohy vyvolat přímou metodu na 10 000 zařízeních, která zařízení restartuje. Zadáte sadu zařízení s dotazem dvojčete zařízení a naplánujete spuštění úlohy v budoucnu. Úloha sleduje průběh, když každé zařízení přijímá a spouští přímou metodu restartování.

Další informace o každé z těchto funkcí najdete tady:

Poznámka:

Funkce popsané v tomto článku jsou k dispozici pouze na úrovni Standard služby IoT Hub. Další informace o úrovních Služby IoT Hub úrovně Basic a Standard/Free najdete v tématu Volba správné úrovně IoT Hubu pro vaše řešení.

V tomto článku se dozvíte, jak vytvořit dvě aplikace v Javě:

  • Aplikace zařízení simulované zařízení, která implementuje přímou metodu s názvem lockDoor, kterou může volat back-endová aplikace.

  • Back-endová aplikace, úlohy plánu, která vytvoří dvě úlohy. Jedna úloha volá přímou metodu lockDoor a jiná úloha odesílá aktualizace požadovaných vlastností do více zařízení.

Poznámka:

Další informace o dostupných nástrojích SDK pro sestavení zařízení i back-endových aplikací najdete v sadách SDK .

Požadavky

  • IoT Hub. Vytvořte ho pomocí rozhraní příkazového řádku nebo webu Azure Portal.

  • Zařízení zaregistrované ve službě IoT Hub. Pokud ve službě IoT Hub nemáte zařízení, postupujte podle pokynů v části Registrace zařízení.

  • Java SE Development Kit 8. Ujistěte se, že v části Dlouhodobá podpora vyberete Javu 8, abyste se dostali ke stažení sady JDK 8.

  • Maven 3

  • Ujistěte se, že je v bráně firewall otevřený port 8883. Ukázka zařízení v tomto článku používá protokol MQTT, který komunikuje přes port 8883. Tento port může být blokovaný v některých podnikových a vzdělávacích síťových prostředích. Další informace a způsoby řešení tohoto problému najdete v tématu Připojení ke službě IoT Hub (MQTT).

Poznámka:

Aby bylo všechno jednoduché, tento článek neimplementuje zásadu opakování. V produkčním kódu byste měli implementovat zásady opakování (například exponenciální zpoždování), jak je doporučeno v článku Zpracování přechodných chyb.

Získání připojovací řetězec ioT Hubu

V tomto článku vytvoříte back-endovou službu, která naplánuje úlohu, která vyvolá přímou metodu na zařízení, naplánuje úlohu pro aktualizaci dvojčete zařízení a sleduje průběh každé úlohy. K provedení těchto operací potřebuje vaše služba oprávnění ke čtení registru a zápisudo registru. Ve výchozím nastavení se vytvoří každé centrum IoT se zásadami sdíleného přístupu s názvem registryReadWrite , které těmto oprávněním udělí.

Pokud chcete získat připojovací řetězec ioT Hubu pro zásadu registryReadWrite, postupujte takto:

  1. Na webu Azure Portal vyberte skupiny prostředků. Vyberte skupinu prostředků, ve které se nachází vaše centrum, a pak vyberte centrum ze seznamu prostředků.

  2. V levém podokně centra vyberte zásady sdíleného přístupu.

  3. V seznamu zásad vyberte zásadu registryReadWrite .

  4. Zkopírujte primární připojovací řetězec a uložte hodnotu.

    Snímek obrazovky, který ukazuje, jak načíst připojovací řetězec

Další informace ozásadách

Vytvoření aplikace služby

V této části vytvoříte konzolovou aplikaci Java, která používá úlohy k:

  • Volejte přímou metodu lockDoor na více zařízeních.

  • Odeslání požadovaných vlastností do více zařízení

Vytvoření aplikace:

  1. Na vývojovém počítači vytvořte prázdnou složku s názvem iot-java-schedule-jobs.

  2. Ve složce iot-java-schedule-jobs vytvořte projekt Maven s názvem schedule-jobs pomocí následujícího příkazu na příkazovém řádku. Všimněte si, že se jedná o jeden dlouhý příkaz:

    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=schedule-jobs -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    
  3. Na příkazovém řádku přejděte do složky schedule-jobs .

  4. Pomocí textového editoru otevřete soubor pom.xml ve složce úlohy plánu a přidejte do uzlu závislostí následující závislost. Tato závislost umožňuje používat balíček iot-service-client ve vaší aplikaci ke komunikaci s centrem IoT:

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

    Poznámka:

    Můžete vyhledat nejnovější verzi iot-service-client pomocí vyhledávání Maven.

  5. Za uzel závislostí přidejte následující uzel sestavení. Tato konfigurace dává Mavenu pokyn, aby k sestavení aplikace použil Javu 1.8:

    <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. Uložte a zavřete soubor pom.xml.

  7. Pomocí textového editoru otevřete soubor schedule-jobs\src\main\java\com\mycompany\app\App.java .

  8. Do souboru přidejte následující příkazy pro import:

    import com.microsoft.azure.sdk.iot.service.devicetwin.DeviceTwinDevice;
    import com.microsoft.azure.sdk.iot.service.devicetwin.Pair;
    import com.microsoft.azure.sdk.iot.service.devicetwin.Query;
    import com.microsoft.azure.sdk.iot.service.devicetwin.SqlQuery;
    import com.microsoft.azure.sdk.iot.service.jobs.JobClient;
    import com.microsoft.azure.sdk.iot.service.jobs.JobResult;
    import com.microsoft.azure.sdk.iot.service.jobs.JobStatus;
    
    import java.util.Date;
    import java.time.Instant;
    import java.util.HashSet;
    import java.util.Set;
    import java.util.UUID;
    
  9. Do třídy App přidejte následující proměnné na úrovni třídy. Nahraďte {youriothubconnectionstring} připojovací řetězec IoT Hub, který jste zkopírovali dříve v připojovací řetězec Get the IoT Hub:

    public static final String iotHubConnectionString = "{youriothubconnectionstring}";
    public static final String deviceId = "myDeviceId";
    
    // How long the job is permitted to run without
    // completing its work on the set of devices
    private static final long maxExecutionTimeInSeconds = 30;
    
  10. Přidejte do třídy aplikace následující metodu, která naplánuje úlohu pro aktualizaci požadovaných vlastností budovy a podlahy ve dvojčeti zařízení:

    private static JobResult scheduleJobSetDesiredProperties(JobClient jobClient, String jobId) {
      DeviceTwinDevice twin = new DeviceTwinDevice(deviceId);
      Set<Pair> desiredProperties = new HashSet<Pair>();
      desiredProperties.add(new Pair("Building", 43));
      desiredProperties.add(new Pair("Floor", 3));
      twin.setDesiredProperties(desiredProperties);
      // Optimistic concurrency control
      twin.setETag("*");
    
      // Schedule the update twin job to run now
      // against a single device
      System.out.println("Schedule job " + jobId + " for device " + deviceId);
      try {
        JobResult jobResult = jobClient.scheduleUpdateTwin(jobId, 
          "deviceId='" + deviceId + "'",
          twin,
          new Date(),
          maxExecutionTimeInSeconds);
        return jobResult;
      } catch (Exception e) {
        System.out.println("Exception scheduling desired properties job: " + jobId);
        System.out.println(e.getMessage());
        return null;
      }
    }
    
  11. Pokud chcete naplánovat úlohu pro volání metody lockDoor, přidejte do třídy App následující metodu:

    private static JobResult scheduleJobCallDirectMethod(JobClient jobClient, String jobId) {
      // Schedule a job now to call the lockDoor direct method
      // against a single device. Response and connection
      // timeouts are set to 5 seconds.
      System.out.println("Schedule job " + jobId + " for device " + deviceId);
      try {
        JobResult jobResult = jobClient.scheduleDeviceMethod(jobId,
          "deviceId='" + deviceId + "'",
          "lockDoor",
          5L, 5L, null,
          new Date(),
          maxExecutionTimeInSeconds);
        return jobResult;
      } catch (Exception e) {
        System.out.println("Exception scheduling direct method job: " + jobId);
        System.out.println(e.getMessage());
        return null;
      }
    };
    
  12. Pokud chcete monitorovat úlohu, přidejte do třídy aplikace následující metodu:

    private static void monitorJob(JobClient jobClient, String jobId) {
      try {
        JobResult jobResult = jobClient.getJob(jobId);
        if(jobResult == null)
        {
          System.out.println("No JobResult for: " + jobId);
          return;
        }
        // Check the job result until it's completed
        while(jobResult.getJobStatus() != JobStatus.completed)
        {
          Thread.sleep(100);
          jobResult = jobClient.getJob(jobId);
          System.out.println("Status " + jobResult.getJobStatus() + " for job " + jobId);
        }
        System.out.println("Final status " + jobResult.getJobStatus() + " for job " + jobId);
      } catch (Exception e) {
        System.out.println("Exception monitoring job: " + jobId);
        System.out.println(e.getMessage());
        return;
      }
    }
    
  13. Pokud chcete zadat dotaz na podrobnosti o spuštěných úlohách, přidejte následující metodu:

    private static void queryDeviceJobs(JobClient jobClient, String start) throws Exception {
      System.out.println("\nQuery device jobs since " + start);
    
      // Create a jobs query using the time the jobs started
      Query deviceJobQuery = jobClient
          .queryDeviceJob(SqlQuery.createSqlQuery("*", SqlQuery.FromType.JOBS, "devices.jobs.startTimeUtc > '" + start + "'", null).getQuery());
    
      // Iterate over the list of jobs and print the details
      while (jobClient.hasNextJob(deviceJobQuery)) {
        System.out.println(jobClient.getNextJob(deviceJobQuery));
      }
    }
    
  14. Aktualizujte podpis hlavní metody tak, aby zahrnoval následující throws klauzuli:

    public static void main( String[] args ) throws Exception
    
  15. Pokud chcete spouštět a monitorovat dvě úlohy postupně, nahraďte kód v hlavní metodě následujícím kódem:

    // Record the start time
    String start = Instant.now().toString();
    
    // Create JobClient
    JobClient jobClient = JobClient.createFromConnectionString(iotHubConnectionString);
    System.out.println("JobClient created with success");
    
    // Schedule twin job desired properties
    // Maximum concurrent jobs is 1 for Free and S1 tiers
    String desiredPropertiesJobId = "DPCMD" + UUID.randomUUID();
    scheduleJobSetDesiredProperties(jobClient, desiredPropertiesJobId);
    monitorJob(jobClient, desiredPropertiesJobId);
    
    // Schedule twin job direct method
    String directMethodJobId = "DMCMD" + UUID.randomUUID();
    scheduleJobCallDirectMethod(jobClient, directMethodJobId);
    monitorJob(jobClient, directMethodJobId);
    
    // Run a query to show the job detail
    queryDeviceJobs(jobClient, start);
    
    System.out.println("Shutting down schedule-jobs app");
    
  16. Uložte a zavřete soubor schedule-jobs\src\main\java\com\mycompany\app\App.java

  17. Sestavte aplikaci plánovačů a opravte případné chyby. Na příkazovém řádku přejděte do složky schedule-jobs a spusťte následující příkaz:

    mvn clean package -DskipTests
    

Vytvoření aplikace pro zařízení

V této části vytvoříte konzolovou aplikaci Java, která zpracovává požadované vlastnosti odeslané ze služby IoT Hub a implementuje volání přímé metody.

  1. Ve složce iot-java-schedule-jobs vytvořte projekt Maven s názvem simulated-device pomocí následujícího příkazu na příkazovém řádku. Všimněte si, že se jedná o jeden dlouhý příkaz:

    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=simulated-device -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    
  2. Na příkazovém řádku přejděte do složky simulated-device .

  3. Pomocí textového editoru otevřete soubor pom.xml ve složce simulovaného zařízení a přidejte do uzlu závislostí následující závislosti. Tato závislost umožňuje používat balíček iot-device-client ve vaší aplikaci ke komunikaci s centrem IoT:

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

    Poznámka:

    Můžete vyhledat nejnovější verzi iot-device-client pomocí vyhledávání Maven.

  4. Do uzlu závislostí přidejte následující závislost. Tato závislost nakonfiguruje NOP pro fasádu protokolování Apache SLF4J , která se používá klientskou sadou SDK zařízení k implementaci protokolování. Tato konfigurace je volitelná, ale pokud ji vynecháte, může se při spuštění aplikace v konzole zobrazit upozornění. Další informace o protokolování v klientské sadě SDK pro zařízení najdete v části Protokolovánív ukázkách sady SDK pro zařízení Azure IoT pro soubor Readme v Javě .

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-nop</artifactId>
      <version>1.7.28</version>
    </dependency>
    
  5. Za uzel závislostí přidejte následující uzel sestavení. Tato konfigurace dává Mavenu pokyn, aby k sestavení aplikace použil Javu 1.8:

    <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. Uložte a zavřete soubor pom.xml.

  7. V textovém editoru otevřete soubor simulated-device\src\main\java\com\mycompany\app\App.java .

  8. Do souboru přidejte následující příkazy pro import:

    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.util.Scanner;
    
  9. Do třídy App přidejte následující proměnné na úrovni třídy. Nahraďte {yourdeviceconnectionstring} zařízení připojovací řetězec, které jste viděli při registraci zařízení ve službě IoT Hub:

    private static String connString = "{yourdeviceconnectionstring}";
    private static IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;
    private static final int METHOD_SUCCESS = 200;
    private static final int METHOD_NOT_DEFINED = 404;
    

    Tato ukázková aplikace používá při vytváření instance objektu DeviceClient proměnnou protocol.

  10. Pokud chcete do konzoly vytisknout oznámení dvojčete zařízení, přidejte do třídy aplikace následující vnořenou třídu:

    // Handler for device twin operation notifications from IoT Hub
    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());
      }
    }
    
  11. Pokud chcete do konzoly vytisknout oznámení přímé metody, přidejte do třídy aplikace následující vnořenou třídu:

    // Handler for direct method notifications from IoT Hub
    protected static class DirectMethodStatusCallback implements IotHubEventCallback {
      public void execute(IotHubStatusCode status, Object context) {
        System.out.println("IoT Hub responded to direct method operation with status " + status.name());
      }
    }
    
  12. Pokud chcete zpracovávat volání přímých metod ze služby IoT Hub, přidejte do třídy aplikace následující vnořenou třídu:

    // Handler for direct method calls from IoT Hub
    protected static class DirectMethodCallback
        implements DeviceMethodCallback {
      @Override
      public DeviceMethodData call(String methodName, Object methodData, Object context) {
        DeviceMethodData deviceMethodData;
        switch (methodName) {
          case "lockDoor": {
            System.out.println("Executing direct method: " + methodName);
            deviceMethodData = new DeviceMethodData(METHOD_SUCCESS, "Executed direct method " + methodName);
            break;
          }
          default: {
            deviceMethodData = new DeviceMethodData(METHOD_NOT_DEFINED, "Not defined direct method " + methodName);
          }
        }
        // Notify IoT Hub of result
        return deviceMethodData;
      }
    }
    
  13. Aktualizujte podpis hlavní metody tak, aby zahrnoval následující throws klauzuli:

    public static void main( String[] args ) throws IOException, URISyntaxException
    
  14. Nahraďte kód v hlavní metodě následujícím kódem:

    • Vytvořte klienta zařízení pro komunikaci se službou IoT Hub.
    • Vytvořte objekt zařízení pro uložení vlastností dvojčete zařízení.
    // Create a device client
    DeviceClient client = new DeviceClient(connString, protocol);
    
    // An object to manage device twin desired and reported properties
    Device dataCollector = new Device() {
      @Override
      public void PropertyCall(String propertyKey, Object propertyValue, Object context)
      {
        System.out.println("Received desired property change: " + propertyKey + " " + propertyValue);
      }
    };
    
  15. Chcete-li spustit klientské služby zařízení, přidejte do hlavní metody následující kód:

    try {
      // Open the DeviceClient
      // Start the device twin services
      // Subscribe to direct method calls
      client.open();
      client.startDeviceTwin(new DeviceTwinStatusCallBack(), null, dataCollector, null);
      client.subscribeToDeviceMethod(new DirectMethodCallback(), null, new DirectMethodStatusCallback(), null);
    } catch (Exception e) {
      System.out.println("Exception, shutting down \n" + " Cause: " + e.getCause() + " \n" + e.getMessage());
      dataCollector.clean();
      client.closeNow();
      System.out.println("Shutting down...");
    }
    
  16. Pokud chcete počkat, až uživatel před vypnutím stiskne klávesu Enter , přidejte na konec hlavní metody následující kód:

    // Close the app
    System.out.println("Press any key to exit...");
    Scanner scanner = new Scanner(System.in);
    scanner.nextLine();
    dataCollector.clean();
    client.closeNow();
    scanner.close();
    
  17. Uložte a zavřete soubor simulated-device\src\main\java\com\mycompany\app\App.java .

  18. Sestavte aplikaci simulovaného zařízení a opravte případné chyby. Na příkazovém řádku přejděte do složky simulated-device a spusťte následující příkaz:

    mvn clean package -DskipTests
    

Spouštění aplikací

Teď jste připraveni spustit konzolové aplikace.

  1. Na příkazovém řádku ve složce simulated-device spusťte následující příkaz, který spustí aplikaci zařízení, která naslouchá změnám požadovaných vlastností a voláním přímé metody:

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

    Spustí se klient zařízení.

  2. Na příkazovém řádku ve schedule-jobs složce spusťte následující příkaz, který spustí aplikaci služby schedule-jobs a spustí dvě úlohy. První nastaví hodnoty požadované vlastnosti, druhá volá přímou metodu:

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

    Aplikace služby Java IoT Hub vytvoří dvě úlohy.

  3. Aplikace zařízení zpracovává změnu požadované vlastnosti a volání přímé metody:

    Klient zařízení reaguje na změny.

Další kroky

V tomto článku jste naplánovali úlohy, které spustí přímou metodu a aktualizují vlastnosti dvojčete zařízení.

Pokud chcete pokračovat ve zkoumání vzorů správy ioT Hubu a zařízení, aktualizujte image ve službě Device Update pro Azure IoT Hub pomocí referenční image Raspberry Pi 3 B+.