diff --git a/components/iot-plugins/iot-analytics/org.wso2.carbon.device.mgt.iot.analytics/src/main/resources/carbonapps/Temperature/Eventreceiver_mqtt_temperature_1.0.0/EventReceiver_mqtt_temperature.xml b/components/iot-plugins/iot-analytics/org.wso2.carbon.device.mgt.iot.analytics/src/main/resources/carbonapps/Temperature/Eventreceiver_mqtt_temperature_1.0.0/EventReceiver_mqtt_temperature.xml index 1166733c4..1de2653af 100644 --- a/components/iot-plugins/iot-analytics/org.wso2.carbon.device.mgt.iot.analytics/src/main/resources/carbonapps/Temperature/Eventreceiver_mqtt_temperature_1.0.0/EventReceiver_mqtt_temperature.xml +++ b/components/iot-plugins/iot-analytics/org.wso2.carbon.device.mgt.iot.analytics/src/main/resources/carbonapps/Temperature/Eventreceiver_mqtt_temperature_1.0.0/EventReceiver_mqtt_temperature.xml @@ -19,7 +19,7 @@ - wso2/carbon.super/+/temperature + wso2/carbon.super/+/+/temperature admin device_id_json_path:event.metaData.deviceId,device_id_topic_hierarchy_index:3 default diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiManagerServiceImpl.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiManagerServiceImpl.java index dcf7ec6c3..d0c90e9f8 100644 --- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiManagerServiceImpl.java +++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/RaspberryPiManagerServiceImpl.java @@ -157,7 +157,7 @@ public class RaspberryPiManagerServiceImpl implements RaspberryPiManagerService @Path("devices/download") @GET @Produces("application/zip") - public Response downloadSketch(@QueryParam("deviceName") String deviceName, @QueryParam("sketch_type") String sketchType) { + public Response downloadSketch(@QueryParam("deviceName") String deviceName, @QueryParam("sketchType") String sketchType) { try { ZipArchive zipFile = createDownloadFile(APIUtil.getAuthenticatedUser(), deviceName, sketchType); Response.ResponseBuilder response = Response.ok(FileUtils.readFileToByteArray(zipFile.getZipFile())); diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/transport/RaspberryPiMQTTConnector.java b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/transport/RaspberryPiMQTTConnector.java index 16e43f950..48c874fc4 100644 --- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/transport/RaspberryPiMQTTConnector.java +++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.api/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/impl/transport/RaspberryPiMQTTConnector.java @@ -22,11 +22,17 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.json.JSONObject; import org.wso2.carbon.apimgt.application.extension.APIManagementProviderService; import org.wso2.carbon.apimgt.application.extension.dto.ApiApplicationKey; import org.wso2.carbon.apimgt.application.extension.exception.APIManagerException; import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig; +import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.exception.RaspberrypiException; import org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl.util.APIUtil; import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants; import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException; @@ -37,11 +43,13 @@ import org.wso2.carbon.identity.jwt.client.extension.exception.JWTClientExceptio import org.wso2.carbon.user.api.UserStoreException; import java.nio.charset.StandardCharsets; +import java.security.PublicKey; import java.util.UUID; public class RaspberryPiMQTTConnector extends MQTTTransportHandler { private static Log log = LogFactory.getLog(RaspberryPiMQTTConnector.class); - private static final String subscribeTopic = "wso2/" + RaspberrypiConstants.DEVICE_TYPE + "/+/publisher"; +// subscribeTopic is not used for the RaspberryPi sample since the DAS device directly publishes to DAS MQTT receiver + private static final String subscribeTopic = "wso2/+/"+ RaspberrypiConstants.DEVICE_TYPE + "/+/publisher"; private static final String KEY_TYPE = "PRODUCTION"; private static final String EMPTY_STRING = ""; @@ -104,7 +112,26 @@ public class RaspberryPiMQTTConnector extends MQTTTransportHandler { } @Override - public void processIncomingMessage(MqttMessage message, String... messageParams) throws TransportHandlerException { + public void publishDeviceData(String... publishData) throws TransportHandlerException { + if (publishData.length != 3) { + String errorMsg = "Incorrect number of arguments received to SEND-MQTT Message. " + + "Need to be [owner, deviceId, resource{BULB/TEMP}, state{ON/OFF or null}]"; + log.error(errorMsg); + throw new TransportHandlerException(errorMsg); + } + + String deviceId = publishData[0]; + String resource = publishData[1]; + String state = publishData[2]; + + MqttMessage pushMessage = new MqttMessage(); + String publishTopic = "wso2/" + APIUtil.getTenantDomainOftheUser() + "/" + + RaspberrypiConstants.DEVICE_TYPE + "/" + deviceId; + String actualMessage = resource + ":" + state; + pushMessage.setPayload(actualMessage.getBytes(StandardCharsets.UTF_8)); + pushMessage.setQos(DEFAULT_MQTT_QUALITY_OF_SERVICE); + pushMessage.setRetained(false); + publishToQueue(publishTopic, pushMessage); } @Override @@ -135,6 +162,10 @@ public class RaspberryPiMQTTConnector extends MQTTTransportHandler { terminatorThread.start(); } + @Override + public void processIncomingMessage(MqttMessage mqttMessage, String... messageParams) throws TransportHandlerException { + } + @Override public void processIncomingMessage() throws TransportHandlerException { @@ -154,28 +185,5 @@ public class RaspberryPiMQTTConnector extends MQTTTransportHandler { public void publishDeviceData(MqttMessage publishData) throws TransportHandlerException { } - - @Override - public void publishDeviceData(String... publishData) throws TransportHandlerException { - if (publishData.length != 3) { - String errorMsg = "Incorrect number of arguments received to SEND-MQTT Message. " + - "Need to be [owner, deviceId, resource{BULB/TEMP}, state{ON/OFF or null}]"; - log.error(errorMsg); - throw new TransportHandlerException(errorMsg); - } - - String deviceId = publishData[0]; - String resource = publishData[1]; - String state = publishData[2]; - - MqttMessage pushMessage = new MqttMessage(); - String publishTopic = "wso2/" + APIUtil.getTenantDomainOftheUser() + "/" - + RaspberrypiConstants.DEVICE_TYPE + "/" + deviceId; - String actualMessage = resource + ":" + state; - pushMessage.setPayload(actualMessage.getBytes(StandardCharsets.UTF_8)); - pushMessage.setQos(DEFAULT_MQTT_QUALITY_OF_SERVICE); - pushMessage.setRetained(false); - publishToQueue(publishTopic, pushMessage); - } } diff --git a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.type-view/type-view.hbs b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.type-view/type-view.hbs index 67e4d0225..7ecbf7056 100644 --- a/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.type-view/type-view.hbs +++ b/components/iot-plugins/raspberrypi-plugin/org.wso2.carbon.device.mgt.iot.raspberrypi.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.type-view/type-view.hbs @@ -65,7 +65,7 @@

/+/virtual_firealarm/+/publisher // wildcard (+) is in place for device_owner & device_id - private static String subscribeTopic = "wso2/+/"+ VirtualFireAlarmConstants.DEVICE_TYPE + "/+/publisher"; + private static final String subscribeTopic = "wso2/+/"+ VirtualFireAlarmConstants.DEVICE_TYPE + "/+/publisher"; private static String iotServerSubscriber = UUID.randomUUID().toString().substring(0, 5); private static final String KEY_TYPE = "PRODUCTION"; private static final String EMPTY_STRING = ""; diff --git a/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/deviceConfig.properties b/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/deviceConfig.properties index 489af7042..06de853d8 100644 --- a/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/deviceConfig.properties +++ b/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/deviceConfig.properties @@ -20,6 +20,8 @@ owner=${DEVICE_OWNER} deviceId=${DEVICE_ID} device-name=${DEVICE_NAME} controller-context=/raspberrypi/controller +mqtt-sub-topic=wso2/{owner}/raspberrypi/{deviceId} +mqtt-pub-topic=wso2/{owner}/raspberrypi/{deviceId}/publisher https-ep=${HTTPS_EP} http-ep=${HTTP_EP} apim-ep=${APIM_EP} diff --git a/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/org.eclipse.paho.mqtt.python.tar b/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/org.eclipse.paho.mqtt.python.tar new file mode 100644 index 000000000..5f65105b8 Binary files /dev/null and b/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/org.eclipse.paho.mqtt.python.tar differ diff --git a/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/RaspberryAgent.py b/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/RaspberryAgent.py index 188eca451..7b4afed5b 100644 --- a/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/RaspberryAgent.py +++ b/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/RaspberryAgent.py @@ -22,22 +22,22 @@ import logging, logging.handlers import sys, os, signal, argparse import running_mode -import time, threading, datetime +import time, threading, datetime, calendar -import httplib, ssl -from functools import wraps +# import httplib, ssl +# from functools import wraps # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Overriding the default SSL version used in some of the Python (2.7.x) versions # This is a known issue in earlier Python releases # But was fixed in later versions. Ex-2.7.11 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -def sslwrap(func): - @wraps(func) - def bar(*args, **kw): - kw['ssl_version'] = ssl.PROTOCOL_TLSv1 - return func(*args, **kw) - return bar +# def sslwrap(func): +# @wraps(func) +# def bar(*args, **kw): +# kw['ssl_version'] = ssl.PROTOCOL_TLSv1 +# return func(*args, **kw) +# return bar # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PUSH_INTERVAL = 5000 # time interval between successive data pushes in seconds @@ -81,7 +81,8 @@ if args.interval: if args.mode: running_mode.RUNNING_MODE = args.mode iotUtils = __import__('iotUtils') - httpServer = __import__('httpServer') # python script used to start a http-server to listen for operations + mqttConnector = __import__('mqttConnector') + # httpServer = __import__('httpServer') # python script used to start a http-server to listen for operations # (includes the TEMPERATURE global variable) if running_mode.RUNNING_MODE == 'N': @@ -92,16 +93,16 @@ if args.mode: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Endpoint specific settings to which the data is pushed # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -DC_ENDPOINT = iotUtils.HTTPS_EP.split(":") -DC_IP = DC_ENDPOINT[1].replace('//', '') -DC_PORT = int(DC_ENDPOINT[2]) -DC_ENDPOINT_CONTEXT = iotUtils.CONTROLLER_CONTEXT -PUSH_ENDPOINT = str(DC_ENDPOINT_CONTEXT) + '/push_temperature/' -REGISTER_ENDPOINT = str(DC_ENDPOINT_CONTEXT) + '/register' - -HOST = iotUtils.getDeviceIP() -HOST_HTTP_SERVER_PORT = iotUtils.getHTTPServerPort() -HOST_AND_PORT = str(HOST)+ ":" + str(HOST_HTTP_SERVER_PORT) +# DC_ENDPOINT = iotUtils.HTTPS_EP.split(":") +# DC_IP = DC_ENDPOINT[1].replace('//', '') +# DC_PORT = int(DC_ENDPOINT[2]) +# DC_ENDPOINT_CONTEXT = iotUtils.CONTROLLER_CONTEXT +# PUSH_ENDPOINT = str(DC_ENDPOINT_CONTEXT) + '/push_temperature/' +# REGISTER_ENDPOINT = str(DC_ENDPOINT_CONTEXT) + '/register' + +# HOST = iotUtils.getDeviceIP() +# HOST_HTTP_SERVER_PORT = iotUtils.getHTTPServerPort() +# HOST_AND_PORT = str(HOST)+ ":" + str(HOST_HTTP_SERVER_PORT) ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -142,32 +143,32 @@ def configureLogger(loggerName): # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # This method registers the DevieIP in the Device-Cloud # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -def registerDeviceIP(): - ssl.wrap_socket = sslwrap(ssl.wrap_socket) # using the overridden sslwrap that uses TLSv1 - if sys.version_info<(2,7,9): - dcConncection = httplib.HTTPSConnection(host=DC_IP, port=DC_PORT) - else: - dcConncection = httplib.HTTPSConnection(host=DC_IP, port=DC_PORT, context=ssl._create_unverified_context()) - #TODO need to get server certificate when initializing https connection - dcConncection.set_debuglevel(1) - dcConncection.connect() - - registerURL = str(REGISTER_ENDPOINT) + '/' + str(iotUtils.DEVICE_OWNER) + '/' + str(iotUtils.DEVICE_ID) + '/' + \ - str(HOST) + '/' + str(HOST_HTTP_SERVER_PORT) + '/' - dcConncection.putrequest('POST', registerURL) - dcConncection.putheader('Authorization', 'Bearer ' + iotUtils.AUTH_TOKEN) - dcConncection.endheaders() - dcResponse = dcConncection.getresponse() - - print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' - print ('RASPBERRY_STATS: ' + str(registerURL)) - print ('RASPBERRY_STATS: ' + str(dcResponse.status)) - print ('RASPBERRY_STATS: ' + str(dcResponse.reason)) - print ('RASPBERRY_STATS: Response Message') - print str(dcResponse.msg) - - dcConncection.close() - print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' +# def registerDeviceIP(): +# ssl.wrap_socket = sslwrap(ssl.wrap_socket) # using the overridden sslwrap that uses TLSv1 +# if sys.version_info<(2,7,9): +# dcConncection = httplib.HTTPSConnection(host=DC_IP, port=DC_PORT) +# else: +# dcConncection = httplib.HTTPSConnection(host=DC_IP, port=DC_PORT, context=ssl._create_unverified_context()) +# #TODO need to get server certificate when initializing https connection +# dcConncection.set_debuglevel(1) +# dcConncection.connect() +# +# registerURL = str(REGISTER_ENDPOINT) + '/' + str(iotUtils.DEVICE_OWNER) + '/' + str(iotUtils.DEVICE_ID) + '/' + \ +# str(HOST) + '/' + str(HOST_HTTP_SERVER_PORT) + '/' +# dcConncection.putrequest('POST', registerURL) +# dcConncection.putheader('Authorization', 'Bearer ' + iotUtils.AUTH_TOKEN) +# dcConncection.endheaders() +# dcResponse = dcConncection.getresponse() +# +# print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' +# print ('RASPBERRY_STATS: ' + str(registerURL)) +# print ('RASPBERRY_STATS: ' + str(dcResponse.status)) +# print ('RASPBERRY_STATS: ' + str(dcResponse.reason)) +# print ('RASPBERRY_STATS: Response Message') +# print str(dcResponse.msg) +# +# dcConncection.close() +# print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -175,44 +176,54 @@ def registerDeviceIP(): # This method connects to the Device-Cloud and pushes data # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def connectAndPushData(): - if sys.version_info<(2,7,9): - dcConnection = httplib.HTTPSConnection(host=DC_IP, port=DC_PORT) - else: - dcConnection = httplib.HTTPSConnection(host=DC_IP, port=DC_PORT, context=ssl._create_unverified_context()) - - dcConnection.set_debuglevel(1) - dcConnection.connect() - request = dcConnection.putrequest('POST', PUSH_ENDPOINT) - dcConnection.putheader('Authorization', 'Bearer ' + iotUtils.AUTH_TOKEN) - dcConnection.putheader('Content-Type', 'application/json') - ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ### Read the Temperature and Load info of RPi and construct payload - ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - + currentTime = calendar.timegm(time.gmtime()) rPiTemperature = iotUtils.LAST_TEMP # Push the last read temperature value - PUSH_DATA = iotUtils.DEVICE_INFO + iotUtils.DEVICE_IP.format(ip=HOST_AND_PORT) + iotUtils.DEVICE_DATA.format( - temperature=rPiTemperature) - PUSH_DATA += '}' - dcConnection.putheader('Content-Length', len(PUSH_DATA)) - dcConnection.endheaders() - - print PUSH_DATA - print '~~~~~~~~~~~~~~~~~~~~~~~~ Pushing Device-Data ~~~~~~~~~~~~~~~~~~~~~~~~~' - - dcConnection.send(PUSH_DATA) # Push the data - dcResponse = dcConnection.getresponse() - - print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' - print ('RASPBERRY_STATS: ' + str(dcResponse.status)) - print ('RASPBERRY_STATS: ' + str(dcResponse.reason)) - print ('RASPBERRY_STATS: Response Message') - print str(dcResponse.msg) - print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' - dcConnection.close() - - if (dcResponse.status == 409 or dcResponse.status == 412): - print 'RASPBERRY_STATS: Re-registering Device IP' - registerDeviceIP() + 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 ~~~~~~~~~~~~~~~~~~~~~~~~~' + + # if sys.version_info<(2,7,9): + # dcConnection = httplib.HTTPSConnection(host=DC_IP, port=DC_PORT) + # else: + # dcConnection = httplib.HTTPSConnection(host=DC_IP, port=DC_PORT, context=ssl._create_unverified_context()) + + # dcConnection.set_debuglevel(1) + # dcConnection.connect() + # request = dcConnection.putrequest('POST', PUSH_ENDPOINT) + # dcConnection.putheader('Authorization', 'Bearer ' + iotUtils.AUTH_TOKEN) + # dcConnection.putheader('Content-Type', 'application/json') + # ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + # ### Read the Temperature and Load info of RPi and construct payload + # ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + # rPiTemperature = iotUtils.LAST_TEMP # Push the last read temperature value + # PUSH_DATA = iotUtils.DEVICE_INFO + iotUtils.DEVICE_IP.format(ip=HOST_AND_PORT) + iotUtils.DEVICE_DATA.format( + # temperature=rPiTemperature) + # PUSH_DATA += '}' + # dcConnection.putheader('Content-Length', len(PUSH_DATA)) + # dcConnection.endheaders() + + # print PUSH_DATA + # print '~~~~~~~~~~~~~~~~~~~~~~~~ Pushing Device-Data ~~~~~~~~~~~~~~~~~~~~~~~~~' + + # dcConnection.send(PUSH_DATA) # Push the data + # dcResponse = dcConnection.getresponse() + + # print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' + # print ('RASPBERRY_STATS: ' + str(dcResponse.status)) + # print ('RASPBERRY_STATS: ' + str(dcResponse.reason)) + # print ('RASPBERRY_STATS: Response Message') + # print str(dcResponse.msg) + # print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' + # dcConnection.close() + + # if (dcResponse.status == 409 or dcResponse.status == 412): + # print 'RASPBERRY_STATS: Re-registering Device IP' + # registerDeviceIP() ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -249,9 +260,9 @@ class TemperatureReaderThread(object): print 'RASPBERRY_STATS: Temp={0:0.1f}*C Humidity={1:0.1f}%'.format(temperature, humidity) except Exception, e: - print "RASPBERRY_STATS: Exception in TempReaderThread: Could not successfully read Temperature" - print ("RASPBERRY_STATS: " + str(e)) print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' + print "RASPBERRY_STATS: Exception in TempReaderThread: Could not successfully read Temperature" + print ("RASPBERRY_STATS: " + str(e)) pass time.sleep(self.interval) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -282,6 +293,19 @@ class ListenHTTPServerThread(object): httpServer.main() # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# This is a Thread object for connecting and subscribing to an MQTT Queue +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class SubscribeToMQTTQueue(object): + def __init__(self): + thread = threading.Thread(target=self.run, args=()) + thread.daemon = True # Daemonize thread + thread.start() # Start the execution + + def run(self): + mqttConnector.main() +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # When sysvinit sends the TERM signal, cleanup before exiting @@ -300,12 +324,11 @@ signal.signal(signal.SIGTERM, sigterm_handler) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def main(): configureLogger("WSO2IOT_RPiStats") - if running_mode.RUNNING_MODE == 'N': - iotUtils.setUpGPIOPins() UtilsThread() - registerDeviceIP() # Call the register endpoint and register Device IP + # registerDeviceIP() # Call the register endpoint and register Device IP + # ListenHTTPServerThread() # starts an HTTP Server that listens for operational commands to switch ON/OFF Led + SubscribeToMQTTQueue() # connects and subscribes to an MQTT Queue that receives MQTT commands from the server TemperatureReaderThread() # initiates and runs the thread to continuously read temperature from DHT Sensor - ListenHTTPServerThread() # starts an HTTP Server that listens for operational commands to switch ON/OFF Led while True: try: if iotUtils.LAST_TEMP > 0: # Push data only if there had been a successful temperature read diff --git a/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/deviceConfig.properties b/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/deviceConfig.properties deleted file mode 100644 index 489af7042..000000000 --- a/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/deviceConfig.properties +++ /dev/null @@ -1,33 +0,0 @@ -# -# Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -[Device-Configurations] -server-name=${SERVER_NAME} -owner=${DEVICE_OWNER} -deviceId=${DEVICE_ID} -device-name=${DEVICE_NAME} -controller-context=/raspberrypi/controller -https-ep=${HTTPS_EP} -http-ep=${HTTP_EP} -apim-ep=${APIM_EP} -mqtt-ep=${MQTT_EP} -xmpp-ep=${XMPP_EP} -auth-method=token -auth-token=${DEVICE_TOKEN} -refresh-token=${DEVICE_REFRESH_TOKEN} -push-interval=15 - - diff --git a/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/iotUtils.py b/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/iotUtils.py index 1419f91d6..323cf5ea5 100644 --- a/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/iotUtils.py +++ b/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/iotUtils.py @@ -26,7 +26,7 @@ import random import running_mode # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# HOST_NAME(IP) of the Device +# HOST_NAME(IP) of the Device # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ global HOST_NAME HOST_NAME = "0.0.0.0" @@ -52,18 +52,27 @@ configParser = ConfigParser.RawConfigParser() configFilePath = os.path.join(os.path.dirname(__file__), './deviceConfig.properties') configParser.read(configFilePath) +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') CONTROLLER_CONTEXT = configParser.get('Device-Configurations', 'controller-context') -DEVICE_INFO = '{"owner":"' + DEVICE_OWNER + '","deviceId":"' + DEVICE_ID + '","reply":' +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":{:.2f}}},"payloadData":{{"temperature":{:.2f}}}}}}}' + +# '{"owner":"' + DEVICE_OWNER + '","deviceId":"' + DEVICE_ID + '","temperature":' HTTPS_EP = configParser.get('Device-Configurations', 'https-ep') HTTP_EP = configParser.get('Device-Configurations', 'http-ep') APIM_EP = configParser.get('Device-Configurations', 'apim-ep') -DEVICE_IP = '"{ip}","value":' -DEVICE_DATA = '"{temperature}"' # '"{temperature}:{load}:OFF"' +# DEVICE_IP = '"{ip}","value":' +# DEVICE_DATA = '"{temperature}"' # '"{temperature}:{load}:OFF"' + + +# {"event": {"metaData": {"owner": "admin", "type": "arduino","deviceId": "s15kdwf34vue","time": 0},"payloadData": { "temperature": 22} }} + ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -73,6 +82,7 @@ DEVICE_DATA = '"{temperature}"' # '"{temperature}:{load}:OFF"' # Method used to switch ON/OFF the LED attached to RPi # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def switchBulb(state): + print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' print "Requested Switch State: " + state if running_mode.RUNNING_MODE == "N": @@ -88,7 +98,6 @@ def switchBulb(state): print "BULB Switched ON" elif state == "OFF": print "BULB Switched OFF" - print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -174,7 +183,7 @@ def setUpGPIOPins(): # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def main(): global HOST_NAME - HOST_NAME = getDeviceIP() + # HOST_NAME = getDeviceIP() if running_mode.RUNNING_MODE == 'N': setUpGPIOPins() @@ -182,4 +191,4 @@ def main(): # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/mqttConnector.py b/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/mqttConnector.py new file mode 100644 index 000000000..f0da9154c --- /dev/null +++ b/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/mqttConnector.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python + +""" +/** +* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you under the Apache License, +* Version 2.0 (the "License"); you may not use this file except +* in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +**/ +""" + +import time +import iotUtils +import paho.mqtt.client as mqtt + + +# 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)) + + # 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) + + + +# The callback for when a PUBLISH message is received from the server. +def on_message(client, userdata, msg): + print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' + print 'MQTT_LISTENER: Message Received by Device' + print( "MQTT_LISTENER: " + msg.topic + " --> " + str(msg.payload) ) + + request = str(msg.payload) + + resource = request.split(":")[0].upper() + state = request.split(":")[1].upper() + + print "MQTT_LISTENER: Resource- " + resource + + if resource == "TEMP": + pass + #request.send_response(200) + #request.send_header("Content-type", "text/plain") + #request.end_headers() + #request.wfile.write(LAST_TEMP) + # return + + elif resource == "BULB": + iotUtils.switchBulb(state) + + +def on_publish(client, userdata, mid): + print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' + print 'Temperature Data Published Succesfully' + # print (client) + # print (userdata) + # print (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) + + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# The Main method of the server script +# This method is invoked from RaspberryStats.py on a new thread +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +def main(): + MQTT_ENDPOINT = iotUtils.MQTT_EP.split(":") + MQTT_IP = MQTT_ENDPOINT[1].replace('//','') + MQTT_PORT = int(MQTT_ENDPOINT[2]) + + SERVER_NAME = iotUtils.SERVER_NAME + DEV_ID = iotUtils.DEVICE_ID + + global TOPIC_TO_SUBSCRIBE + # TOPIC_TO_SUBSCRIBE = SERVER_NAME + "/raspberrypi/" + DEV_ID + TOPIC_TO_SUBSCRIBE = SERVER_NAME + "/raspberrypi/" + DEV_ID + global TOPIC_TO_PUBLISH + # TOPIC_TO_PUBLISH = SERVER_NAME + "/raspberrypi/" + DEV_ID + "/publisher" + TOPIC_TO_PUBLISH = SERVER_NAME + "/raspberrypi/" + DEV_ID + "/temperature" + + print ("MQTT_LISTENER: MQTT_ENDPOINT is " + str(MQTT_ENDPOINT)) + print ("MQTT_LISTENER: MQTT_TOPIC is " + TOPIC_TO_SUBSCRIBE) + + global mqttClient + mqttClient = mqtt.Client() + mqttClient.on_connect = on_connect + mqttClient.on_message = on_message + mqttClient.on_publish = on_publish + mqttClient.username_pw_set(iotUtils.AUTH_TOKEN, password = "") + + while True: + try: + mqttClient.connect(MQTT_IP, MQTT_PORT, 180) + print "MQTT_LISTENER: " + time.asctime(), "Connected to MQTT Broker - %s:%s" % (MQTT_IP, MQTT_PORT) + + # Blocking call that processes network traffic, dispatches callbacks and + # handles reconnecting. + # Other loop*() functions are available that give a threaded interface and a + # manual interface. + mqttClient.loop_forever() + + except (KeyboardInterrupt, Exception) as e: + print "MQTT_LISTENER: Exception in MQTTServerThread (either KeyboardInterrupt or Other)" + print ("MQTT_LISTENER: " + str(e)) + + mqttClient.disconnect() + print "MQTT_LISTENER: " + time.asctime(), "Connection to Broker closed - %s:%s" % (MQTT_IP, MQTT_PORT) + print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' + pass + + +if __name__ == '__main__': + iotUtils.setUpGPIOPins() + main() + diff --git a/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/running_mode.py b/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/running_mode.py index 1b28e4aa3..748b0eb23 100644 --- a/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/running_mode.py +++ b/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/running_mode.py @@ -1,2 +1,3 @@ -global RUNNING_MODE \ No newline at end of file +global RUNNING_MODE +RUNNING_MODE = 'N' \ No newline at end of file diff --git a/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/testAgent.sh b/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/testAgent.sh index ea9e4bee1..4ac9112c0 100644 --- a/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/testAgent.sh +++ b/features/iot-plugins-feature/raspberrypi-plugin-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/testAgent.sh @@ -97,14 +97,26 @@ done cp deviceConfig.properties ./src if [ "$mode" = "N" ]; then + # Install RPi.GPIO Library for Accessing RPi GPIO Pins sudo apt-get install rpi.gpio + # ----------------------------------------------------- + # Install Adafruit_Python_DHT Library for reading DHT Sensor git clone https://github.com/adafruit/Adafruit_Python_DHT.git sudo apt-get install build-essential python-dev python-openssl - sudo python ./Adafruit_Python_DHT/setup.py install + cd ./Adafruit_Python_DHT + sudo python setup.py install + cd .. + # ----------------------------------------------------- + # Install Paho-MQTT-Library for MQTT Communication + git clone https://github.com/eclipse/paho.mqtt.python.git + cd ./paho.mqtt.python + sudo python setup.py install + cd .. + # ----------------------------------------------------- fi chmod +x ./src/RaspberryAgent.py -./src/RaspberryAgent.py -i $input -m $mode +sudo python ./src/RaspberryAgent.py -i $input -m $mode if [ $? -ne 0 ]; then echo "Could not start the service..."