Megosztás a következőn keresztül:


Feladatok ütemezése és szórása (Java)

A Azure IoT Hub segítségével több millió eszközt frissítő feladatokat ütemezhet és követhet nyomon. Feladatok használata a következő feladatokhoz:

  • Eszköz kívánt tulajdonságainak frissítése
  • Címkék frissítése
  • Közvetlen metódusok meghívása

A feladatok a műveletek egyikét burkolják, és nyomon követik a végrehajtást egy eszközkészleten. Az ikereszköz-lekérdezés határozza meg azokat az eszközöket, amelyekkel a feladat végrehajtható. Egy háttéralkalmazás például egy feladat használatával meghívhat egy közvetlen metódust 10 000 olyan eszközön, amely újraindítja az eszközöket. Megadhatja az eszközök halmazát egy ikereszköz-lekérdezéssel, és ütemezheti a feladat későbbi futtatását. A feladat nyomon követi az előrehaladást, amint az egyes eszközök megkapják és végrehajtják a közvetlen újraindítási módszert.

Az egyes funkciókkal kapcsolatos további információkért lásd:

Megjegyzés

A cikkben ismertetett funkciók csak a IoT Hub standard szintjén érhetők el. Az alapszintű és standard/ingyenes IoT Hub szintekkel kapcsolatos további információkért lásd: A megoldáshoz megfelelő IoT Hub szint kiválasztása.

Ez a cikk bemutatja, hogyan hozhat létre két Java-alkalmazást:

  • A simulated-device eszközalkalmazás, amely egy lockDoor nevű közvetlen metódust implementál, amelyet a háttéralkalmazás hívhat meg.

  • Egy két feladatot létrehozó , schedule-jobs nevű háttéralkalmazás. Az egyik feladat meghívja a lockDoor közvetlen metódust, egy másik feladat pedig több eszközre küldi a kívánt tulajdonságfrissítéseket.

Megjegyzés

Az eszköz- és háttéralkalmazások készítéséhez elérhető SDK-eszközökkel kapcsolatos további információkért lásd: Azure IoT SDK-k .

Előfeltételek

  • Egy IoT Hub. Hozzon létre egyet a parancssori felülettel vagy a Azure Portal.

  • Regisztrált eszköz. Regisztráljon egyet a Azure Portal.

  • Java SE Development Kit 8. A JDK 8 letöltéséhez válassza a Java 8lehetőséget a Hosszú távú támogatás területen.

  • Maven 3

  • Győződjön meg arról, hogy a 8883-as port nyitva van a tűzfalon. A cikkben szereplő eszközminta MQTT protokollt használ, amely a 8883-es porton keresztül kommunikál. Ez a port bizonyos vállalati és oktatási hálózati környezetekben blokkolható. További információkért és a probléma megoldásának módjaiért lásd: Csatlakozás IoT Hub (MQTT)-hez.

Megjegyzés

Az egyszerűség érdekében ez a cikk nem implementál újrapróbálkozési szabályzatot. Az éles kódban újrapróbálkozási szabályzatokat (például exponenciális visszalépést) kell implementálnia az Átmeneti hibakezelés című cikkben leírtak szerint.

A IoT Hub kapcsolati sztring lekérése

Ebben a cikkben létrehoz egy háttérszolgáltatást, amely ütemez egy feladatot egy közvetlen metódus meghívására egy eszközön, ütemez egy feladatot az ikereszköz frissítésére, és figyeli az egyes feladatok előrehaladását. Ezeknek a műveleteknek a végrehajtásához a szolgáltatásnak olvasási és beállításjegyzék-írási engedélyekkel kell rendelkeznie. Alapértelmezés szerint minden IoT Hub egy registryReadWrite nevű megosztott hozzáférési szabályzattal jön létre, amely megadja ezeket az engedélyeket.

A registryReadWrite szabályzat IoT Hub kapcsolati sztring az alábbi lépésekkel szerezheti be:

  1. A Azure Portal válassza az Erőforráscsoportok lehetőséget. Válassza ki azt az erőforráscsoportot, ahol a központ található, majd válassza ki a központot az erőforrások listájából.

  2. A központ bal oldali paneljén válassza a Megosztott hozzáférési szabályzatok lehetőséget.

  3. A szabályzatok listájából válassza a beállításjegyzékReadWrite szabályzatot .

  4. Másolja ki az Elsődleges kapcsolati sztring, és mentse az értéket.

    Képernyőkép a kapcsolati sztring lekéréséről

A IoT Hub megosztott hozzáférési szabályzatokkal és engedélyekkel kapcsolatos további információkért lásd: Hozzáférés-vezérlés és engedélyek.

A szolgáltatásalkalmazás létrehozása

Ebben a szakaszban egy Java-konzolalkalmazást hoz létre, amely a következő feladatokhoz használja a következőket:

  • Hívja meg a lockDoor közvetlen metódust több eszközön.

  • A kívánt tulajdonságok elküldése több eszközre.

Az alkalmazás létrehozása:

  1. A fejlesztői gépen hozzon létre egy üres mappát iot-java-schedule-jobs néven.

  2. Az iot-java-schedule-jobs mappában hozzon létre egy schedule-jobs nevű Maven-projektet a parancssorban található alábbi paranccsal. Látható, hogy ez egyetlen hosszú parancs:

    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=schedule-jobs -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    
  3. A parancssorban lépjen a schedule-jobs mappára.

  4. Egy szövegszerkesztővel nyissa meg a pom.xml fájlt a schedule-jobs mappában, és adja hozzá a következő függőséget a függőségek csomóponthoz. Ez a függőség lehetővé teszi, hogy az alkalmazás iot-service-client csomagjával kommunikáljon az IoT Hubbal:

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

    Megjegyzés

    Az iot-service-client legújabb verzióját a Maven keresési funkciójával tekintheti meg.

  5. Adja hozzá a következő buildcsomópontot a függőségi csomópont után. Ez a konfiguráció arra utasítja a Mavent, hogy a Java 1.8-mal hozza létre az alkalmazást:

    <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. Mentse és zárja be a pom.xml fájlt.

  7. Szövegszerkesztővel nyissa meg a schedule-jobs\src\main\java\com\mycompany\app\App.java fájlt.

  8. Adja hozzá a következő importálási utasításokat a fájlhoz:

    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. Adja hozzá a következő osztályszintű változókat az App osztályhoz. Cserélje le a elemet {youriothubconnectionstring} a korábban az IoT Hub lekérése kapcsolati sztring című kapcsolati sztring:

    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. Adja hozzá a következő metódust az alkalmazásosztályhoz , hogy ütemezzen egy feladatot az ikereszköz Épület és Padló kívánt tulajdonságainak frissítéséhez:

    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. Ha ütemezni szeretne egy feladatot a lockDoor metódus meghívásához, adja hozzá a következő metódust az Alkalmazás osztályhoz:

    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. Feladat figyeléséhez adja hozzá a következő metódust az Alkalmazás osztályhoz:

    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. A futtatott feladatok részleteinek lekérdezéséhez adja hozzá a következő metódust:

    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. Frissítse a főmetódus aláírását úgy, hogy tartalmazza a következő throws záradékot:

    public static void main( String[] args ) throws Exception
    
  15. Két feladat egymás utáni futtatásához és monitorozásához cserélje le a metódus kódját a következő kódra:

    // 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. Mentse és zárja be a schedule-jobs\src\main\java\com\mycompany\app\App.java fájlt

  17. Hozza létre a schedule-jobs alkalmazást, és javítsa ki a hibákat. A parancssorban lépjen a schedule-jobs mappába, és futtassa a következő parancsot:

    mvn clean package -DskipTests
    

Eszközalkalmazás létrehozása

Ebben a szakaszban egy Java-konzolalkalmazást hoz létre, amely kezeli a IoT Hub által küldött kívánt tulajdonságokat, és implementálja a közvetlen metódushívást.

  1. Az iot-java-schedule-jobs mappában hozzon létre egy simulated-device nevű Maven-projektet a parancssorban található alábbi paranccsal. Látható, hogy ez egyetlen hosszú parancs:

    mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=simulated-device -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    
  2. A parancssorban keresse meg a simulated-device mappát.

  3. Egy szövegszerkesztővel nyissa meg a pom.xml fájlt a simulated-device mappában, és adja hozzá a következő függőségeket a függőségek csomóponthoz. Ez a függőség lehetővé teszi, hogy az alkalmazás iot-device-client csomagjával kommunikáljon az IoT Hubbal:

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

    Megjegyzés

    Az iot-device-client legújabb verzióját a Maven keresési funkciójával tekintheti meg.

  4. Adja hozzá a következő függőséget a függőségek csomóponthoz. Ez a függőség egy NOP-t konfigurál az Apache SLF4J naplózási homlokzatához, amelyet az eszközügyfél SDK használ a naplózás implementálásához. Ez a konfiguráció nem kötelező, de ha kihagyja, figyelmeztetés jelenhet meg a konzolon az alkalmazás futtatásakor. További információ az eszközügyfél SDK-jában való naplózásról: Loggingin the Samples for the Azure IoT device SDK for Java readme file (Naplózás a Javához készült Azure IoT-eszközoldali SDK-ra vonatkozó mintákban ).

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-nop</artifactId>
      <version>1.7.28</version>
    </dependency>
    
  5. Adja hozzá a következő buildcsomópontot a függőségi csomópont után. Ez a konfiguráció arra utasítja a Mavent, hogy java 1.8-tal hozza létre az alkalmazást:

    <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. Mentse és zárja be a pom.xml fájlt.

  7. Szövegszerkesztővel nyissa meg a simulated-device\src\main\java\com\mycompany\app\App.java fájlt.

  8. Adja hozzá a következő importálási utasításokat a fájlhoz:

    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. Adja hozzá a következő osztályszintű változókat az App osztályhoz. Cserélje le a elemet {yourdeviceconnectionstring} arra az eszközre, kapcsolati sztring, amikor regisztrált egy eszközt a 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;
    

    Ez a mintaalkalmazás a protocol változót használja egy DeviceClient objektum példányának létrehozásakor.

  10. Ha ikereszköz-értesítéseket szeretne nyomtatni a konzolra, adja hozzá a következő beágyazott osztályt az alkalmazásosztályhoz :

    // 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. Ha közvetlen metódusértesítéseket szeretne nyomtatni a konzolra, adja hozzá a következő beágyazott osztályt az alkalmazásosztályhoz :

    // 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. A IoT Hub közvetlen metódushívásainak kezeléséhez adja hozzá a következő beágyazott osztályt az alkalmazásosztályhoz:

    // 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. Frissítse a főmetódus-aláírást, hogy tartalmazza a következő throws záradékot:

    public static void main( String[] args ) throws IOException, URISyntaxException
    
  14. Cserélje le a metódusban lévő kódot a következő kódra:

    • Hozzon létre egy eszközügyfélt a IoT Hub való kommunikációhoz.
    • Hozzon létre egy Eszközobjektumot az ikereszköz tulajdonságainak tárolásához.
    // 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. Az eszközügyfél-szolgáltatások elindításához adja hozzá a következő kódot a metódushoz:

    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. Ha meg szeretné várni, hogy a felhasználó lenyomja az Enter billentyűt a leállítás előtt, adja hozzá a következő kódot a metódus végéhez:

    // 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. Mentse és zárja be a simulated-device\src\main\java\com\mycompany\app\App.java fájlt.

  18. Hozza létre a szimulált eszköz alkalmazást, és javítsa ki a hibákat. A parancssorban keresse meg a simulated-device mappát, és futtassa a következő parancsot:

    mvn clean package -DskipTests
    

Az alkalmazások futtatása

Most már készen áll a konzolalkalmazások futtatására.

  1. A simulated-device mappában található parancssorban futtassa a következő parancsot az eszközalkalmazás kívánt tulajdonságmódosításainak és közvetlen metódushívásainak figyeléséhez:

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

    Az eszközügyfél elindul

  2. A mappában található parancssorban schedule-jobs futtassa a következő parancsot az schedule-jobs szolgáltatásalkalmazás futtatásához két feladat futtatásához. Az első beállítja a kívánt tulajdonságértékeket, a második pedig a közvetlen metódust:

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

    A Java IoT Hub szolgáltatásalkalmazás két feladatot hoz létre

  3. Az eszközalkalmazás kezeli a kívánt tulajdonságmódosítást és a közvetlen metódushívást:

    Az eszközügyfél válaszol a változásokra

Következő lépések

Ebben a cikkben a feladatokat egy közvetlen metódus futtatására és az ikereszköz tulajdonságainak frissítésére ütemezte.

A IoT Hub és az eszközkezelési minták megismeréséhez frissítsen egy képet az Eszközfrissítésben Azure IoT Hub oktatóanyaghoz a Raspberry Pi 3 B+ referenciarendszerkép használatával.