This repository has been archived by the owner on Nov 9, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Example command and control application for the Bosch IoT Hub
- Loading branch information
Sandy Meier
authored and
Sandy Meier
committed
Dec 11, 2018
1 parent
32d967d
commit fc7357e
Showing
8 changed files
with
327 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# Command & Control Application | ||
|
||
The application shows how to connect to the IoT Hub messaging endpoint and send a command to a device in one-way mode. | ||
It sends automatically a "switchLight" command with the payload "On" to a device which must be connected. | ||
|
||
For a more complex example see the [Hono example application](https://github.com/eclipse/hono/tree/master/example) | ||
The guide only works for Linux & Mac systems, for MS Windows you have to adapt the paths and options. | ||
|
||
# Prerequisites | ||
|
||
following software must be installed: | ||
|
||
* Java 8 (Oracle JDK or OpenJDK) or newer | ||
* maven 3.5.2 or newer | ||
* [mosquitto_sub](https://mosquitto.org/) for subscribing to receive commands | ||
|
||
|
||
An existing IoT Hub service instance and a valid tenant ID are needed to run the application. | ||
Please consult [IoT Hub documentation](https://docs.bosch-iot-hub.com/booktenant.html) on how to book a IoT Hub service instance. | ||
In the 'Credentials' information of a IoT Hub service subscription information, you will find the 'tenant-id', the 'messaging-username' and 'messaging-password'. | ||
Please register a device and setup password credentials. You will need the 'device-id', 'auth-id' and the matching secret for the 'auth-id'. | ||
|
||
## Subscribe to receive commands | ||
|
||
To receive commands, a device must subscribe to a specific control topic. | ||
As exemplary device the Eclipse Mosquitto MQTT client is used. Please make sure auth-id and the matching secret is set correctly. | ||
|
||
~~~ | ||
mosquitto_sub -d -h mqtt.bosch-iot-hub.com -p 8883 -u {auth-id}@{tenant-id} -P {secret} --capath /etc/ssl/certs/ -t control/+/+/req/# | ||
~~~ | ||
|
||
## Send commands | ||
|
||
To build and package the application as a runnable JAR file run: | ||
|
||
~~~ | ||
mvn clean package -DskipTests | ||
~~~ | ||
|
||
The command application needs a few parameters set to run. Please make sure the following are set correctly: | ||
|
||
* `messaging-username`: the username for the IoT Hub messaging endpoint (messaging@tenant-id) | ||
* `messaging-password`: the password for the IoT Hub messaging endpoint | ||
* `tenant-id`: the tenant ID | ||
* `device-id`: a device ID to send command | ||
|
||
|
||
To start the application, run: | ||
|
||
~~~ | ||
java -jar target/command-and-control-1.0-SNAPSHOT.jar --hono.client.tlsEnabled=true --hono.client.username={messaging-username} --hono.client.password={messaging-password} --tenant.id={tenant-id} --device.id={device-id} | ||
~~~ | ||
|
||
The application will connect to the IoT Hub and send the command to a subscribed device. You should see the received command in the 'mosquitto_sub' output. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>com.bosch.iothub</groupId> | ||
<artifactId>iot-hub-examples</artifactId> | ||
<version>1.0-SNAPSHOT</version> | ||
</parent> | ||
<artifactId>command-and-control</artifactId> | ||
<name>Bosch IoT Hub - Command & Control</name> | ||
<version>1.0-SNAPSHOT</version> | ||
|
||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
<maven.compiler.source>1.8</maven.compiler.source> | ||
<maven.compiler.target>1.8</maven.compiler.target> | ||
</properties> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version>3.6.1</version> | ||
<configuration> | ||
<source>${maven.compiler.source}</source> | ||
<target>${maven.compiler.target}</target> | ||
<encoding>${project.build.sourceEncoding}</encoding> | ||
</configuration> | ||
</plugin> | ||
<plugin> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-maven-plugin</artifactId> | ||
</plugin> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-surefire-plugin</artifactId> | ||
<configuration> | ||
<systemProperties> | ||
<property> | ||
<name>iot-hub.messaging.host</name> | ||
<value>messaging.bosch-iot-hub.com</value> | ||
</property> | ||
<property> | ||
<name>hono.client.user</name> | ||
<value>UNSET</value> | ||
</property> | ||
<property> | ||
<name>hono.client.password</name> | ||
<value>UNSET</value> | ||
</property> | ||
<property> | ||
<name>iot-hub.tenant.id</name> | ||
<value>UNSET</value> | ||
</property> | ||
</systemProperties> | ||
<includes> | ||
<include>**/*Test.java</include> | ||
</includes> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-autoconfigure</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-logging</artifactId> | ||
<scope>runtime</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.yaml</groupId> | ||
<artifactId>snakeyaml</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.eclipse.hono</groupId> | ||
<artifactId>hono-client</artifactId> | ||
<version>0.8</version> | ||
</dependency> | ||
<!-- testing dependencies --> | ||
<dependency> | ||
<groupId>junit</groupId> | ||
<artifactId>junit</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.vertx</groupId> | ||
<artifactId>vertx-unit</artifactId> | ||
<version>3.5.4</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
</project> |
74 changes: 74 additions & 0 deletions
74
command-and-control/src/main/java/com/bosch/iothub/examples/AppConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/* | ||
* Copyright 2018 Bosch Software Innovations GmbH ("Bosch SI"). All rights reserved. | ||
*/ | ||
package com.bosch.iothub.examples; | ||
|
||
import io.vertx.core.Vertx; | ||
import io.vertx.core.VertxOptions; | ||
import io.vertx.core.dns.AddressResolverOptions; | ||
import org.eclipse.hono.client.HonoClient; | ||
import org.eclipse.hono.client.impl.HonoClientImpl; | ||
import org.eclipse.hono.config.ClientConfigProperties; | ||
import org.eclipse.hono.connection.ConnectionFactory; | ||
import org.eclipse.hono.connection.impl.ConnectionFactoryImpl; | ||
import org.springframework.boot.context.properties.ConfigurationProperties; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
/** | ||
* Configuration for Example application. | ||
*/ | ||
@Configuration | ||
public class AppConfiguration { | ||
|
||
private static final int DEFAULT_ADDRESS_RESOLUTION_TIMEOUT = 2000; | ||
|
||
/** | ||
* Exposes a Vert.x instance as a Spring bean. | ||
* | ||
* @return The Vert.x instance. | ||
*/ | ||
@Bean | ||
public Vertx vertx() { | ||
VertxOptions options = new VertxOptions() | ||
.setAddressResolverOptions(new AddressResolverOptions() | ||
.setCacheNegativeTimeToLive(0) // discard failed DNS lookup results immediately | ||
.setCacheMaxTimeToLive(0) // support DNS based service resolution | ||
.setRotateServers(true) | ||
.setQueryTimeout(DEFAULT_ADDRESS_RESOLUTION_TIMEOUT)); | ||
return Vertx.vertx(options); | ||
} | ||
|
||
/** | ||
* Exposes client configuration properties as a Spring bean. | ||
* | ||
* @return The properties. | ||
*/ | ||
@ConfigurationProperties(prefix = "hono.client") | ||
@Bean | ||
public ClientConfigProperties honoClientConfig() { | ||
return new ClientConfigProperties(); | ||
} | ||
|
||
/** | ||
* Exposes a factory for connections to the Hono server | ||
* as a Spring bean. | ||
* | ||
* @return The connection factory. | ||
*/ | ||
@Bean | ||
public ConnectionFactory honoConnectionFactory() { | ||
return new ConnectionFactoryImpl(vertx(), honoClientConfig()); | ||
} | ||
|
||
|
||
/** | ||
* Exposes a {@code HonoClient} as a Spring bean. | ||
* | ||
* @return The Hono client. | ||
*/ | ||
@Bean | ||
public HonoClient honoClient() { | ||
return new HonoClientImpl(vertx(), honoConnectionFactory(), honoClientConfig()); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
command-and-control/src/main/java/com/bosch/iothub/examples/Application.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/* | ||
* Copyright 2018 Bosch Software Innovations GmbH ("Bosch SI"). All rights reserved. | ||
*/ | ||
package com.bosch.iothub.examples; | ||
|
||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
|
||
@SpringBootApplication | ||
public class Application { | ||
public static void main(final String[] args) { | ||
SpringApplication.run(Application.class, args); | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
command-and-control/src/main/java/com/bosch/iothub/examples/OneWayCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/* | ||
* Copyright 2018 Bosch Software Innovations GmbH ("Bosch SI"). All rights reserved. | ||
*/ | ||
package com.bosch.iothub.examples; | ||
|
||
import io.vertx.core.Future; | ||
import io.vertx.core.buffer.Buffer; | ||
import io.vertx.proton.ProtonClientOptions; | ||
import org.eclipse.hono.client.CommandClient; | ||
import org.eclipse.hono.client.HonoClient; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.boot.ExitCodeGenerator; | ||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.context.ApplicationContext; | ||
import org.springframework.stereotype.Component; | ||
|
||
import javax.annotation.PostConstruct; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
@Component | ||
public class OneWayCommand { | ||
private static final Logger LOG = LoggerFactory.getLogger(OneWayCommand.class); | ||
|
||
@Value(value = "${tenant.id}") | ||
protected String tenantId; | ||
|
||
@Value(value = "${device.id}") | ||
protected String deviceId; | ||
|
||
private final HonoClient client; | ||
private final ApplicationContext appContext; | ||
|
||
@Autowired | ||
public OneWayCommand(HonoClient client, ApplicationContext appContext) { | ||
this.client = client; | ||
this.appContext = appContext; | ||
} | ||
|
||
@PostConstruct | ||
private void start() { | ||
LOG.info("Connecting to IoT Hub messaging endpoint..."); | ||
client.connect(new ProtonClientOptions()).compose(connectedClient -> { | ||
LOG.info("Connected to IoT Hub messaging endpoint."); | ||
final Future<CommandClient> commandClientFuture = connectedClient.getOrCreateCommandClient(tenantId, deviceId); | ||
commandClientFuture.setHandler(commandClientResult -> { | ||
final CommandClient commandClient = commandClientResult.result(); | ||
sendOneWayCommand(commandClient); | ||
}); | ||
return Future.succeededFuture(); | ||
}).otherwise(connectException -> { | ||
LOG.info("Connecting or creating a command client failed with an exception: ", connectException); | ||
return null; | ||
}); | ||
} | ||
|
||
private void sendOneWayCommand(CommandClient commandClient) { | ||
LOG.info("Send command (one-way mode) to device '{}'", deviceId); | ||
commandClient.setRequestTimeout(TimeUnit.SECONDS.toMillis(2)); // increase to avoid errors with 200 ms default timeout | ||
final Buffer data = Buffer.buffer("on"); | ||
final Future<Void> commandResult = commandClient.sendOneWayCommand("switchLight", data); | ||
commandResult.setHandler(result -> { | ||
if (result.succeeded()) { | ||
LOG.info("Command successfully send"); | ||
SpringApplication.exit(appContext, (ExitCodeGenerator) () -> 0); | ||
} else { | ||
LOG.error("Command not successfully send: {}", result.cause().getMessage()); | ||
SpringApplication.exit(appContext, (ExitCodeGenerator) () -> 1); | ||
} | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
hono: | ||
client: | ||
host: messaging.bosch-iot-hub.com |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters