Ú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:
Dvojče zařízení a vlastnosti: Začínáme s dvojčaty zařízení a principy a používání dvojčat zařízení ve službě IoT Hub
Přímé metody: Příručka pro vývojáře ioT Hubu – přímé metody
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
Centrum IoT ve vašem předplatném Azure Pokud centrum ještě nemáte, můžete postupovat podle kroků v tématu Vytvoření centra IoT.
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.
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ápisu do 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:
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ů.
V levém podokně centra vyberte zásady sdíleného přístupu.
V seznamu zásad vyberte zásadu registryReadWrite .
Zkopírujte primární připojovací řetězec a uložte hodnotu.
Důležité
Tento článek obsahuje postup připojení ke službě pomocí sdíleného přístupového podpisu. Tato metoda ověřování je vhodná pro testování a vyhodnocení, ale ověřování ve službě pomocí MICROSOFT Entra ID nebo spravovaných identit je bezpečnější přístup. Další informace najdete v tématu Osvědčené postupy > zabezpečení cloudu.
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:
Na vývojovém počítači vytvořte prázdnou složku s názvem iot-java-schedule-jobs.
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
Na příkazovém řádku přejděte do složky schedule-jobs .
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.
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>
Uložte a zavřete soubor pom.xml.
Pomocí textového editoru otevřete soubor schedule-jobs\src\main\java\com\mycompany\app\App.java .
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;
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;
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; } }
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; } };
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; } }
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)); } }
Aktualizujte podpis hlavní metody tak, aby zahrnoval následující
throws
klauzuli:public static void main( String[] args ) throws Exception
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");
Uložte a zavřete soubor schedule-jobs\src\main\java\com\mycompany\app\App.java
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.
Důležité
Tento článek obsahuje postup připojení zařízení pomocí sdíleného přístupového podpisu, označovaného také jako ověřování symetrického klíče. Tato metoda ověřování je vhodná pro testování a vyhodnocení, ale ověřování zařízení pomocí certifikátů X.509 je bezpečnější přístup. Další informace najdete v tématu Zabezpečení osvědčených postupů > zabezpečení připojení.
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
Na příkazovém řádku přejděte do složky simulated-device .
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.
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>
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>
Uložte a zavřete soubor pom.xml.
V textovém editoru otevřete soubor simulated-device\src\main\java\com\mycompany\app\App.java .
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;
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.
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()); } }
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()); } }
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; } }
Aktualizujte podpis hlavní metody tak, aby zahrnoval následující
throws
klauzuli:public static void main( String[] args ) throws IOException, URISyntaxException
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); } };
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..."); }
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();
Uložte a zavřete soubor simulated-device\src\main\java\com\mycompany\app\App.java .
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.
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"
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 zařízení zpracovává změnu požadované vlastnosti a volání přímé metody:
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+.