Java tutorial
/** * Copyright 2016 IBM Corp. All Rights Reserved. * <p> * Licensed under the IBM License, a copy of which may be obtained at: * <p> * http://www14.software.ibm.com/cgi-bin/weblap/lap.pl?li_formnum=L-DDIN-AHKPKY&popup=n&title=IBM%20IoT%20for%20Automotive%20Sample%20Starter%20Apps%20%28Android-Mobile%20and%20Server-all%29 * <p> * You may not use this file except in compliance with the license. */ package obdii.starter.automotive.iot.ibm.com.iot4a_obdii; import android.support.annotation.NonNull; import android.util.Base64; import android.util.Log; import com.google.gson.JsonObject; import com.ibm.iotf.client.device.DeviceClient; import org.eclipse.paho.client.mqttv3.MqttException; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.Properties; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; /* IoT Platform Device Client */ public class IoTPlatformDevice { // Platform parameters static final String defaultOrganizationId = "Set Your IoT Platform Organization ID"; static final String defaultApiKey = "Set Your IoT Platform API Key"; static final String defaultApiToken = "Set Your IoT Platform API Token"; private static final String typeId = "OBDII"; @NonNull private static final String getIoTPAPIURL(final String organizationId) { return "https://" + organizationId + ".internetofthings.ibmcloud.com/api/v0002"; } @NonNull private static final String getIoTPAddDevicesEndPoint(final String organizationId) { return getIoTPAPIURL(organizationId) + "/bulk/devices/add"; } @NonNull private static String getIoTPGetDeviceEndpoint(final String organizationId, final String device_id) { return getIoTPAPIURL(organizationId) + "/device/types/" + typeId + "/devices/" + device_id; } static interface ProbeDataGenerator { public JsonObject generateData(); public void notifyPostResult(boolean success, JsonObject event); } public static abstract class ResponseListener implements API.doRequest.TaskListener { @Override public void postExecute(JSONArray result) throws JSONException { final JSONObject serverResponse = result.getJSONObject(result.length() - 1); final int statusCode = serverResponse.getInt("statusCode"); response(statusCode, result); } protected abstract void response(int statusCode, JSONArray result); } private String organizationId = null; private String apiKey = null; private String apiToken = null; private DeviceClient deviceClient = null; private JSONObject currentDevice; private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); private ScheduledFuture<?> uploadHandler = null; private final Home home; IoTPlatformDevice(final Home home) { this.home = home; } void clean() { stopPublishing(); scheduler.shutdown(); } public boolean hasDeviceToken(final String deviceId) { return !"".equals(getDeviceToken(deviceId)); } public String getDeviceToken(final String deviceId) { final String sharedPrefsKey = "iota-obdii-auth-" + deviceId; return home.getPreference(sharedPrefsKey, ""); } public void setDeviceToken(final String deviceId, final String authToken) { home.setPreference("iota-obdii-auth-" + deviceId, authToken); } private String getCredentialsBase64() { final String credentials = apiKey + ":" + apiToken; final String credentialsBase64 = Base64.encodeToString(credentials.getBytes(), Base64.DEFAULT).replace("\n", ""); return credentialsBase64; } public boolean hasValidOrganization() { return organizationId != null && !"".equals(organizationId); } public synchronized boolean createDeviceClient(final JSONObject deviceDefinition) throws Exception { if (deviceDefinition != null) { if (deviceClient != null) { disconnectDevice(); } currentDevice = deviceDefinition; } if (deviceClient != null) { return true; } if (currentDevice == null) { throw new NoDeviceDefinitionException(); } if (!hasValidOrganization()) { throw new NoIoTPOrganizationException(); } final Properties options = new Properties(); options.setProperty("org", organizationId); options.setProperty("type", typeId); final String deviceId = currentDevice.getString("deviceId"); options.setProperty("id", deviceId); options.setProperty("auth-method", "token"); final String token = getDeviceToken(deviceId); options.setProperty("auth-token", token); deviceClient = new DeviceClient(options); System.out.println("IOTP DEVICE CLIENT CREATED: " + options.toString()); return true; } public void checkDeviceRegistration(final ResponseListener listener, final String device_id, final String uuid) throws InterruptedException, ExecutionException, NoIoTPOrganizationException { if (!hasValidOrganization()) { throw new NoIoTPOrganizationException(); } final API.doRequest task = new API.doRequest(listener, uuid); final String url = getIoTPGetDeviceEndpoint(organizationId, device_id); task.execute(url, "GET", null, null, getCredentialsBase64()).get(); System.out.println("CHECKING DEVICE REGISTRATION SUCCESSFULLY DONE......"); Log.d("Got", url); } public void requestDeviceRegistration(final ResponseListener listener, final String device_id, final String uuid) throws InterruptedException, ExecutionException, NoIoTPOrganizationException { if (!hasValidOrganization()) { throw new NoIoTPOrganizationException(); } final API.doRequest task = new API.doRequest(listener, uuid); try { final String url = getIoTPAddDevicesEndPoint(organizationId); final JSONArray bodyArray = new JSONArray(); final JSONObject bodyObject = new JSONObject(); bodyObject.put("typeId", typeId).put("deviceId", device_id); bodyArray.put(bodyObject); final String payload = bodyArray.toString(); task.execute(url, "POST", null, payload, getCredentialsBase64()).get(); System.out.println("REGISTER DEVICE REQUEST SUCCESSFULLY POSTED......"); Log.d("Posted", payload); } catch (JSONException e) { e.printStackTrace(); } } public synchronized void connectDevice() throws MqttException { if (deviceClient != null && !deviceClient.isConnected()) { deviceClient.connect(); } } public synchronized void disconnectDevice() { if (deviceClient != null && deviceClient.isConnected()) { deviceClient.disconnect(); } deviceClient = null; } public synchronized boolean isConnected() { return deviceClient != null && deviceClient.isConnected(); } public synchronized void startPublishing(final ProbeDataGenerator eventGenerator, final int uploadDelayMS, final int uploadIntervalMS) { stopPublishing(); uploadHandler = scheduler.scheduleAtFixedRate(new Runnable() { @Override public void run() { try { final JsonObject event = eventGenerator.generateData(); if (event != null) { eventGenerator.notifyPostResult(publishEvent(event), event); } } catch (MqttException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } }, uploadDelayMS, uploadIntervalMS, TimeUnit.MILLISECONDS); } public synchronized void stopPublishing() { if (uploadHandler != null) { uploadHandler.cancel(true); uploadHandler = null; } } private boolean publishEvent(final JsonObject event) throws MqttException { // Normally, the connection is kept alive, but it is closed when interval is long. Reconnect in this case. connectDevice(); if (deviceClient != null) { deviceClient.publishEvent("carprobe", event, 0); return true; } else { return false; } } public final boolean isCurrentOrganizationSameAs(final String newId) { return organizationId != null && organizationId.equals(newId); } public void changeOrganization(final String newOrdId, final String newApiKey, final String newApiToken) { if (isCurrentOrganizationSameAs(newOrdId)) { return; } stopPublishing(); disconnectDevice(); this.organizationId = newOrdId; this.apiKey = newApiKey; this.apiToken = newApiToken; } public String getOrganizationId() { return organizationId; } public String getApiKey() { return apiKey; } public String getApiToken() { return apiToken; } }