Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Archived » Eclipse SmartHome » ESH Google IoT core binding
ESH Google IoT core binding [message #1790941] Wed, 20 June 2018 12:19 Go to next message
Paramesh  Surakod is currently offline Paramesh SurakodFriend
Messages: 15
Registered: January 2018
Junior Member
Hi,

I have created one java class for publishing the event message in cloud IoT core through ESH binding, if I try to run that java class by stand alone java class in Eclipse IDE it is executed but when I try to execute that java class through binding it is not executed.

Note: we created new binding using below command

./create_openhab_binding_skeleton.sh


I followed the instructions from https://github.com/GoogleCloudPlatform/java-docs-samples link.


I have created the device in google cloud through below code

mvn exec:java \
-Dexec.mainClass="com.example.cloud.iot.examples.MqttExample" \
-Dexec.args="-project_id=brss-711 \
-registry_id=reg1 \
-cloud_region=asia-east1 \
-device_id=java-device-1 \
-private_key_file=../rsa_private_pkcs8 \
-message_type=state \
-algorithm=RS256"

then I am publishing the event message through the below code

mvn exec:java \
-Dexec.mainClass="com.example.cloud.iot.examples.MqttExample" \
-Dexec.args="-project_id=brss-711 \
-registry_id=reg1 \
-cloud_region=asia-east1 \
-device_id=java-device-1 \
-private_key_file=../rsa_private_pkcs8 \
-algorithm=RS256"

I want to integrate these two program through Eclipse Smarthome Binding to create device at google IoT core and publish ESH event message.


Please help me to resolve this issue.
Re: ESH Google IoT core binding [message #1790942 is a reply to message #1790941] Wed, 20 June 2018 12:27 Go to previous messageGo to next message
Henning Treu is currently offline Henning TreuFriend
Messages: 44
Registered: April 2017
Member
Hi Paramesh,

please provide more information about the class you implemented. How is it running "standalone"? A java class embedded in a binding to the ESH framework is not able to run "standalone".

Cheers,
Henning
Re: ESH Google IoT core binding [message #1790992 is a reply to message #1790942] Thu, 21 June 2018 06:40 Go to previous messageGo to next message
Paramesh  Surakod is currently offline Paramesh SurakodFriend
Messages: 15
Registered: January 2018
Junior Member
Hi Henning thanks for the reply,

Here the java class that i have implemented

public class MqttExample {
// [START iot_mqtt_jwt]
/** Create a Cloud IoT Core JWT for the given project id, signed with the given RSA key. */
private static String createJwtRsa(String projectId, String privateKeyFile) throws Exception {
DateTime now = new DateTime();
// Create a JWT to authenticate this device. The device will be disconnected after the token
// expires, and will have to reconnect with a new token. The audience field should always be set
// to the GCP project id.
JwtBuilder jwtBuilder =
Jwts.builder()
.setIssuedAt(now.toDate())
.setExpiration(now.plusMinutes(20).toDate())
.setAudience(projectId);

byte[] keyBytes = Files.readAllBytes(Paths.get(privateKeyFile));
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");

return jwtBuilder.signWith(SignatureAlgorithm.RS256, kf.generatePrivate(spec)).compact();
}

/** Create a Cloud IoT Core JWT for the given project id, signed with the given ES key. */
private static String createJwtEs(String projectId, String privateKeyFile) throws Exception {
DateTime now = new DateTime();
// Create a JWT to authenticate this device. The device will be disconnected after the token
// expires, and will have to reconnect with a new token. The audience field should always be set
// to the GCP project id.
JwtBuilder jwtBuilder =
Jwts.builder()
.setIssuedAt(now.toDate())
.setExpiration(now.plusMinutes(20).toDate())
.setAudience(projectId);

byte[] keyBytes = Files.readAllBytes(Paths.get(privateKeyFile));
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("EC");

return jwtBuilder.signWith(SignatureAlgorithm.ES256, kf.generatePrivate(spec)).compact();
}
// [END iot_mqtt_jwt]

// [START iot_mqtt_configcallback]
static MqttCallback mCallback;

/** Attaches the callback used when configuration changes occur. */
public static void attachCallback(MqttClient client, String deviceId) throws MqttException {
mCallback = new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
// Do nothing...
}

@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
String payload = new String(message.getPayload());
System.out.println("Payload : " + payload);
// TODO: Insert your parsing / handling of the configuration message here.
}

@Override
public void deliveryComplete(IMqttDeliveryToken token) {
// Do nothing;
}
};

String configTopic = String.format("/devices/%s/config", deviceId);
client.subscribe(configTopic, 1);

client.setCallback(mCallback);
}
// [END iot_mqtt_configcallback]

/** Parse arguments, configure MQTT, and publish messages. */
public static void main(String[] args) throws Exception {
// [START iot_mqtt_configuremqtt]
MqttExampleOptions options = MqttExampleOptions.fromFlags(args);
if (options == null) {
// Could not parse.
System.exit(1);
}

// Build the connection string for Google's Cloud IoT Core MQTT server. Only SSL
// connections are accepted. For server authentication, the JVM's root certificates
// are used.
final String mqttServerAddress =
String.format("ssl://%s:%s", options.mqttBridgeHostname, options.mqttBridgePort);

// Create our MQTT client. The mqttClientId is a unique string that identifies this device. For
// Google Cloud IoT Core, it must be in the format below.
final String mqttClientId =
String.format(
"projects/%s/locations/%s/registries/%s/devices/%s",
options.projectId, options.cloudRegion, options.registryId, options.deviceId);

MqttConnectOptions connectOptions = new MqttConnectOptions();
// Note that the Google Cloud IoT Core only supports MQTT 3.1.1, and Paho requires that we
// explictly set this. If you don't set MQTT version, the server will immediately close its
// connection to your device.
connectOptions.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);

Properties sslProps = new Properties();
sslProps.setProperty("com.ibm.ssl.protocol", "TLSv1.2");
connectOptions.setSSLProperties(sslProps);

// With Google Cloud IoT Core, the username field is ignored, however it must be set for the
// Paho client library to send the password field. The password field is used to transmit a JWT
// to authorize the device.
connectOptions.setUserName("unused");

DateTime iat = new DateTime();
if (options.algorithm.equals("RS256")) {
connectOptions.setPassword(
createJwtRsa(options.projectId, options.privateKeyFile).toCharArray());
} else if (options.algorithm.equals("ES256")) {
connectOptions.setPassword(
createJwtEs(options.projectId, options.privateKeyFile).toCharArray());
} else {
throw new IllegalArgumentException(
"Invalid algorithm " + options.algorithm + ". Should be one of 'RS256' or 'ES256'.");
}
// [END iot_mqtt_configuremqtt]

// [START iot_mqtt_publish]
// Create a client, and connect to the Google MQTT bridge.
MqttClient client = new MqttClient(mqttServerAddress, mqttClientId, new MemoryPersistence());

// Both connect and publish operations may fail. If they do, allow retries but with an
// exponential backoff time period.
long initialConnectIntervalMillis = 500L;
long maxConnectIntervalMillis = 6000L;
long maxConnectRetryTimeElapsedMillis = 900000L;
float intervalMultiplier = 1.5f;

long retryIntervalMs = initialConnectIntervalMillis;
long totalRetryTimeMs = 0;

while (!client.isConnected() && totalRetryTimeMs < maxConnectRetryTimeElapsedMillis) {
try {
client.connect(connectOptions);
} catch (MqttException e) {
int reason = e.getReasonCode();

// If the connection is lost or if the server cannot be connected, allow retries, but with
// exponential backoff.
System.out.println("An error occurred: " + e.getMessage());
if (reason == MqttException.REASON_CODE_CONNECTION_LOST
|| reason == MqttException.REASON_CODE_SERVER_CONNECT_ERROR) {
System.out.println("Retrying in " + retryIntervalMs / 1000.0 + " seconds.");
Thread.sleep(retryIntervalMs);
totalRetryTimeMs += retryIntervalMs;
retryIntervalMs *= intervalMultiplier;
if (retryIntervalMs > maxConnectIntervalMillis) {
retryIntervalMs = maxConnectIntervalMillis;
}
} else {
throw e;
}
}
}

attachCallback(client, options.deviceId);

// Publish to the events or state topic based on the flag.
String subTopic = options.messageType.equals("event") ? "events" : options.messageType;

// The MQTT topic that this device will publish telemetry data to. The MQTT topic name is
// required to be in the format below. Note that this is not the same as the device registry's
// Cloud Pub/Sub topic.
String mqttTopic = String.format("/devices/%s/%s", options.deviceId, subTopic);

// Publish numMessages messages to the MQTT bridge, at a rate of 1 per second.
for (int i = 1; i <= options.numMessages; ++i) {
String payload = String.format("%s/%s-payload-%d %s", options.registryId, options.deviceId, i,"hi");
System.out.format(
"Publishing %s message %d/%d: '%s'\n",
options.messageType, i, options.numMessages, payload);

// Refresh the connection credentials before the JWT expires.
// [START iot_mqtt_jwt_refresh]
long secsSinceRefresh = ((new DateTime()).getMillis() - iat.getMillis()) / 1000;
if (secsSinceRefresh > (options.tokenExpMins * 60)) {
System.out.format("\tRefreshing token after: %d seconds\n", secsSinceRefresh);
iat = new DateTime();
if (options.algorithm.equals("RS256")) {
connectOptions.setPassword(
createJwtRsa(options.projectId, options.privateKeyFile).toCharArray());
} else if (options.algorithm.equals("ES256")) {
connectOptions.setPassword(
createJwtEs(options.projectId, options.privateKeyFile).toCharArray());
} else {
throw new IllegalArgumentException(
"Invalid algorithm " + options.algorithm
+ ". Should be one of 'RS256' or 'ES256'.");
}
client.disconnect();
client.connect();
attachCallback(client, options.deviceId);
}
// [END iot_mqtt_jwt_refresh]

// Publish "payload" to the MQTT topic. qos=1 means at least once delivery. Cloud IoT Core
// also supports qos=0 for at most once delivery.
String a="hi";
MqttMessage message = new MqttMessage(payload.getBytes());
message.setQos(1);
client.publish(mqttTopic, message);

if (options.messageType.equals("event")) {
// Send telemetry events every second
Thread.sleep(5000);
} else {
// Note: Update Device state less frequently than with telemetry events
Thread.sleep(5000);
}
}

// Disconnect the client if still connected, and finish the run.
if (client.isConnected()) {
client.disconnect();
}

System.out.println("Finished loop successfully. Goodbye!");
// [END iot_mqtt_publish]
}


following attachment consists of binding structure.

Note:If I run MqttExample.java alone in java application I am able publish the event message.

This java class embedded in a binding to the ESH framework is successfully run by "standalone" but I am not able to run this java class through binding.

please help me to resolve this issue.
Re: ESH Google IoT core binding [message #1791049 is a reply to message #1790992] Fri, 22 June 2018 07:49 Go to previous messageGo to next message
Stefan Triller is currently offline Stefan TrillerFriend
Messages: 29
Registered: April 2017
Junior Member
Hi Paramesh,

please put code into the "code" tags from the formatting tools of this forum, so the source is easier to read.

Reading from your screenshot your example contains a "main" method and thus you are able to "run it standalone" as a java program. Just copying over this class into a binding does not make it run as Henning said.

Are you familiar with (Java) programming? Please have a look at the documentation https://www.eclipse.org/smarthome/documentation/development/bindings/how-to.html

Basically you have to create a ThingHandler plus a xml description file, which has to embed parts of the code that your example contains.

Regards,

Stefan
Re: ESH Google IoT core binding [message #1791163 is a reply to message #1791049] Mon, 25 June 2018 11:31 Go to previous messageGo to next message
Paramesh  Surakod is currently offline Paramesh SurakodFriend
Messages: 15
Registered: January 2018
Junior Member
Hi Stefan thanks for the reply,

As you said my example contains a "main" method and thus I am able to "run it standalone" as a java program.

I just want to compile and get the output (Eg:print "hellowrold" in the console) from that newly created java class when the "binding is running".

I would like to know how the controlflow works in ESH binding to execute that newly created java class(through Eclipse IDE).


please help me out to resolve this issue
Re: ESH Google IoT core binding [message #1791635 is a reply to message #1791163] Tue, 03 July 2018 08:32 Go to previous message
Stefan Triller is currently offline Stefan TrillerFriend
Messages: 29
Registered: April 2017
Junior Member
Hello Paramesh,

you can have a look at the ThingHandler documentation: https://www.eclipse.org/smarthome/documentation/development/bindings/thing-handler.html where you can see what is executed when.

To have a simple "hello world" printed to the console just put it into the "handleCommand" method, bind an item to a channel of your thing and change the status of the item (i.e. via entering smarthome update MyItem "newState" into the console of your IDE).

Regards,

Stefan
Previous Topic:Parameters on Channel
Next Topic:change states of a channel
Goto Forum:
  


Current Time: Sat Dec 14 19:46:24 GMT 2024

Powered by FUDForum. Page generated in 0.04383 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top