diff --git a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiServiceImpl.java b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiServiceImpl.java index 93999db63..3e9c00ba1 100644 --- a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiServiceImpl.java +++ b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiServiceImpl.java @@ -110,8 +110,8 @@ public class RaspberryPiServiceImpl implements RaspberryPiService { @Produces("application/json") public Response getRaspberryPiTemperatureStats(@PathParam("deviceId") String deviceId, @QueryParam("from") long from, @QueryParam("to") long to) { - String fromDate = String.valueOf(from); - String toDate = String.valueOf(to); + String fromDate = String.valueOf(from*1000); + String toDate = String.valueOf(to*1000); String query = "meta_deviceId:" + deviceId + " AND meta_deviceType:" + RaspberrypiConstants.DEVICE_TYPE + " AND meta_time : [" + fromDate + " TO " + toDate + "]"; String sensorTableName = RaspberrypiConstants.TEMPERATURE_EVENT_TABLE; @@ -121,7 +121,7 @@ public class RaspberryPiServiceImpl implements RaspberryPiService { return Response.status(Response.Status.UNAUTHORIZED.getStatusCode()).build(); } List sortByFields = new ArrayList<>(); - SortByField sortByField = new SortByField("time", SortType.ASC); + SortByField sortByField = new SortByField("meta_time", SortType.ASC); sortByFields.add(sortByField); List sensorRecords = APIUtil.getAllEventsForDevice(sensorTableName, query, sortByFields); return Response.status(Response.Status.OK.getStatusCode()).entity(sensorRecords).build(); @@ -221,7 +221,7 @@ public class RaspberryPiServiceImpl implements RaspberryPiService { String refreshToken = accessTokenInfo.getRefreshToken(); ZipUtil ziputil = new ZipUtil(); return ziputil.createZipFile(owner, APIUtil.getTenantDomainOftheUser(), sketchType, - deviceId, deviceName, accessToken, refreshToken); + deviceId, deviceName, accessToken, refreshToken, apiApplicationKey.toString()); } private static String shortUUID() { diff --git a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipUtil.java b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipUtil.java index bb2a92b85..220de83a2 100644 --- a/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipUtil.java +++ b/components/device-types/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/util/ZipUtil.java @@ -18,9 +18,12 @@ package org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util; +import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.json.JSONObject; +import org.wso2.carbon.apimgt.application.extension.constants.ApiApplicationConstants; import org.wso2.carbon.core.util.Utils; import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry; @@ -61,7 +64,7 @@ public class ZipUtil { public ZipArchive createZipFile(String owner, String tenantDomain, String deviceType, String deviceId, String deviceName, String token, - String refreshToken) throws DeviceManagementException { + String refreshToken, String apiApplicationKey) throws DeviceManagementException { String sketchFolder = "repository" + File.separator + "resources" + File.separator + "sketches"; String templateSketchPath = sketchFolder + File.separator + deviceType; @@ -96,6 +99,7 @@ public class ZipUtil { } } } + String base64EncodedApplicationKey = getBase64EncodedAPIAppKey(apiApplicationKey); Map contextParams = new HashMap<>(); contextParams.put("SERVER_NAME", APIUtil.getTenantDomainOftheUser()); @@ -106,6 +110,7 @@ public class ZipUtil { contextParams.put("HTTP_EP", httpServerEP); contextParams.put("APIM_EP", httpsServerEP); contextParams.put("MQTT_EP", mqttEndpoint); + contextParams.put("API_APPLICATION_KEY", base64EncodedApplicationKey); contextParams.put("DEVICE_TOKEN", token); contextParams.put("DEVICE_REFRESH_TOKEN", refreshToken); @@ -119,6 +124,15 @@ public class ZipUtil { } } + private String getBase64EncodedAPIAppKey(String apiAppCredentialsAsJSONString) { + + JSONObject jsonObject = new JSONObject(apiAppCredentialsAsJSONString); + String consumerKey = jsonObject.get(ApiApplicationConstants.OAUTH_CLIENT_ID).toString(); + String consumerSecret = jsonObject.get(ApiApplicationConstants.OAUTH_CLIENT_SECRET).toString(); + String stringToEncode = consumerKey + ":" + consumerSecret; + return Base64.encodeBase64String(stringToEncode.getBytes()); + } + private static String getServerUrl() { try { return org.apache.axis2.util.Utils.getIpAddress(); diff --git a/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.backend.feature/src/main/resources/agent/deviceConfig.properties b/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.backend.feature/src/main/resources/agent/deviceConfig.properties index 133429198..4d15b3006 100644 --- a/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.backend.feature/src/main/resources/agent/deviceConfig.properties +++ b/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.backend.feature/src/main/resources/agent/deviceConfig.properties @@ -20,14 +20,12 @@ owner=${DEVICE_OWNER} deviceId=${DEVICE_ID} device-name=${DEVICE_NAME} controller-context=/raspberrypi/controller -mqtt-sub-topic=${SERVER_NAME}/{owner}/raspberrypi/{deviceId} -mqtt-pub-topic=${SERVER_NAME}/{owner}/raspberrypi/{deviceId}/publisher https-ep=${HTTPS_EP} http-ep=${HTTP_EP} apim-ep=${APIM_EP} mqtt-ep=${MQTT_EP} -xmpp-ep=${XMPP_EP} auth-method=token +application-key=${API_APPLICATION_KEY} auth-token=${DEVICE_TOKEN} refresh-token=${DEVICE_REFRESH_TOKEN} push-interval=15 diff --git a/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.backend.feature/src/main/resources/agent/src/RaspberryAgent.py b/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.backend.feature/src/main/resources/agent/src/RaspberryAgent.py index 5ab04be85..80b140755 100644 --- a/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.backend.feature/src/main/resources/agent/src/RaspberryAgent.py +++ b/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.backend.feature/src/main/resources/agent/src/RaspberryAgent.py @@ -181,10 +181,7 @@ def connectAndPushData(): currentTime = calendar.timegm(time.gmtime()) rPiTemperature = iotUtils.LAST_TEMP # Push the last read temperature value PUSH_DATA = iotUtils.DEVICE_INFO.format(currentTime, rPiTemperature) - - print '~~~~~~~~~~~~~~~~~~~~~~~~ Publishing Device-Data ~~~~~~~~~~~~~~~~~~~~~~~~~' - print ('PUBLISHED DATA: ' + PUSH_DATA) - print ('PUBLISHED TOPIC: ' + mqttConnector.TOPIC_TO_PUBLISH) + mqttConnector.publish(PUSH_DATA) # print '~~~~~~~~~~~~~~~~~~~~~~~~ End Of Publishing ~~~~~~~~~~~~~~~~~~~~~~~~~' diff --git a/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.backend.feature/src/main/resources/agent/src/iotUtils.py b/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.backend.feature/src/main/resources/agent/src/iotUtils.py index 3bf0cd6e0..76f47b527 100644 --- a/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.backend.feature/src/main/resources/agent/src/iotUtils.py +++ b/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.backend.feature/src/main/resources/agent/src/iotUtils.py @@ -56,11 +56,10 @@ SERVER_NAME = configParser.get('Device-Configurations', 'server-name') DEVICE_OWNER = configParser.get('Device-Configurations', 'owner') DEVICE_ID = configParser.get('Device-Configurations', 'deviceId') MQTT_EP = configParser.get('Device-Configurations', 'mqtt-ep') -XMPP_EP = configParser.get('Device-Configurations', 'xmpp-ep') AUTH_TOKEN = configParser.get('Device-Configurations', 'auth-token') +REFRESH_TOKEN = configParser.get('Device-Configurations', 'refresh-token') +APPLICATION_KEY = configParser.get('Device-Configurations', 'application-key') CONTROLLER_CONTEXT = configParser.get('Device-Configurations', 'controller-context') -MQTT_SUB_TOPIC = configParser.get('Device-Configurations', 'mqtt-sub-topic').format(owner = DEVICE_OWNER, deviceId = DEVICE_ID) -MQTT_PUB_TOPIC = configParser.get('Device-Configurations', 'mqtt-pub-topic').format(owner = DEVICE_OWNER, deviceId = DEVICE_ID) DEVICE_INFO = '{{"event":{{"metaData":{{"owner":"' + DEVICE_OWNER + '","type":"raspberrypi","deviceId":"' + DEVICE_ID + '","time":{}}},"payloadData":{{"temperature":{:.2f}}}}}}}' # '{"owner":"' + DEVICE_OWNER + '","deviceId":"' + DEVICE_ID + '","temperature":' diff --git a/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.backend.feature/src/main/resources/agent/src/mqttConnector.py b/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.backend.feature/src/main/resources/agent/src/mqttConnector.py index f05d8e018..795765619 100644 --- a/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.backend.feature/src/main/resources/agent/src/mqttConnector.py +++ b/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.backend.feature/src/main/resources/agent/src/mqttConnector.py @@ -23,16 +23,29 @@ import time import iotUtils import paho.mqtt.client as mqtt +from token_updater import RefreshToken +agent_connected = False # The callback for when the client receives a CONNACK response from the server. def on_connect(client, userdata, flags, rc): - print("MQTT_LISTENER: Connected with result code " + str(rc)) + if rc == 0: + global agent_connected + agent_connected = True + # Subscribing in on_connect() means that if we lose the connection and + # reconnect then subscriptions will be renewed. + print ("MQTT_LISTENER: Subscribing with topic " + TOPIC_TO_SUBSCRIBE) + client.subscribe(TOPIC_TO_SUBSCRIBE) + elif rc == 4: + token = RefreshToken() + response = token.updateTokens() + newAccessToken = response['access_token'] + client.username_pw_set(newAccessToken, password="") + else: + global agent_connected + agent_connected = False - # Subscribing in on_connect() means that if we lose the connection and - # reconnect then subscriptions will be renewed. - print ("MQTT_LISTENER: Subscribing with topic " + TOPIC_TO_SUBSCRIBE) - client.subscribe(TOPIC_TO_SUBSCRIBE) + print("MQTT_LISTENER: Connected with result code " + str(rc)) @@ -72,12 +85,28 @@ def on_publish(client, userdata, mid): # The callback for when a PUBLISH message to the server when door is open or close # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def publish(msg): - global mqttClient - mqttClient.publish(TOPIC_TO_PUBLISH, msg) + if agent_connected: + print '~~~~~~~~~~~~~~~~~~~~~~~~ Publishing Device-Data ~~~~~~~~~~~~~~~~~~~~~~~~~' + print ('PUBLISHED DATA: ' + msg) + print ('PUBLISHED TOPIC: ' + TOPIC_TO_PUBLISH) + global mqttClient + mqttClient.publish(TOPIC_TO_PUBLISH, msg) def on_subscribe(client, userdata, mid, granted_qos): print "Successfully subscribed to " + TOPIC_TO_SUBSCRIBE +def on_disconnect(client, userdata, rc): + global agent_connected + agent_connected = False + print ("Agent disconnected from broker") + + print("Obtaining new access token") + token = RefreshToken() + response = token.updateTokens() + newAccessToken = response['access_token'] + client.username_pw_set(newAccessToken, password="") + + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # The Main method of the server script # This method is invoked from RaspberryStats.py on a new thread @@ -106,6 +135,7 @@ def main(): mqttClient.on_message = on_message mqttClient.on_publish = on_publish mqttClient.on_subscribe = on_subscribe + mqttClient.on_disconnect = on_disconnect mqttClient.username_pw_set(iotUtils.AUTH_TOKEN, password = "") while True: @@ -131,5 +161,4 @@ def main(): if __name__ == '__main__': iotUtils.setUpGPIOPins() - main() - + main() \ No newline at end of file diff --git a/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.backend.feature/src/main/resources/agent/src/token_updater.py b/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.backend.feature/src/main/resources/agent/src/token_updater.py new file mode 100644 index 000000000..bd08ce266 --- /dev/null +++ b/features/device-types-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.backend.feature/src/main/resources/agent/src/token_updater.py @@ -0,0 +1,53 @@ +import json +import urllib +import iotUtils +import requests + + +applicationKey = None +refreshToken = None +filename = "deviceConfig.properties" + + +class RefreshToken(): + + def post(self, url, payload, appKey): + headers = { 'Authorization' : 'Basic ' + appKey, 'Content-Type' : 'application/x-www-form-urlencoded' } + baseUrl = iotUtils.HTTP_EP + url + response = requests.post(baseUrl, params=payload, headers=headers); + return response + + def read_server_conf(self): + with open(filename, 'r') as outfile: + conf_file = outfile.readlines() + + return conf_file + + def updateFile(self, response): + newRefreshToken = response['refresh_token'] + newAccessToken = response['access_token'] + + with open(filename, 'r+') as f: + lines = f.readlines() + f.seek(0) + f.truncate() + for line in lines: + if line.__contains__("auth-token="): + line = "auth-token=" + newAccessToken + "\n" + if line.__contains__("refresh-token="): + line = "refresh-token=" + newRefreshToken + "\n" + f.write(line) + + + def updateTokens(self,): + global applicationKey + global refreshToken + refreshToken = iotUtils.REFRESH_TOKEN + applicationKey = iotUtils.APPLICATION_KEY + + params = urllib.urlencode({"grant_type": "refresh_token", "refresh_token": refreshToken, + "scope": "Enroll device"}) + data = self.post("/token", params, applicationKey) + response = json.loads(data) + self.updateFile(response) + return response \ No newline at end of file