diff --git a/modules/distribution/src/samples/firealarm/sketch/RaspberryAgent.zip b/modules/distribution/src/samples/firealarm/sketch/RaspberryAgent.zip index 3823a6c8..7c529b58 100644 Binary files a/modules/distribution/src/samples/firealarm/sketch/RaspberryAgent.zip and b/modules/distribution/src/samples/firealarm/sketch/RaspberryAgent.zip differ diff --git a/modules/distribution/src/samples/firealarm/src/org.wso2.carbon.device.mgt.iot.sample.firealarm.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/sample/firealarm/service/impl/FireAlarmControllerService.java b/modules/distribution/src/samples/firealarm/src/org.wso2.carbon.device.mgt.iot.sample.firealarm.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/sample/firealarm/service/impl/FireAlarmControllerService.java index ca09f4ff..21132285 100644 --- a/modules/distribution/src/samples/firealarm/src/org.wso2.carbon.device.mgt.iot.sample.firealarm.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/sample/firealarm/service/impl/FireAlarmControllerService.java +++ b/modules/distribution/src/samples/firealarm/src/org.wso2.carbon.device.mgt.iot.sample.firealarm.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/sample/firealarm/service/impl/FireAlarmControllerService.java @@ -28,11 +28,12 @@ import org.wso2.carbon.device.mgt.common.DeviceIdentifier; import org.wso2.carbon.device.mgt.common.DeviceManagementException; import org.wso2.carbon.device.mgt.iot.common.DeviceController; import org.wso2.carbon.device.mgt.iot.common.DeviceValidator; +import org.wso2.carbon.device.mgt.iot.common.controlqueue.xmpp.XmppConfig; import org.wso2.carbon.device.mgt.iot.common.datastore.impl.DataStreamDefinitions; import org.wso2.carbon.device.mgt.iot.common.exception.DeviceControllerException; import org.wso2.carbon.device.mgt.iot.common.exception.UnauthorizedException; -import org.wso2.carbon.device.mgt.iot.sample.firealarm.service.impl.util.DeviceJSON; import org.wso2.carbon.device.mgt.iot.sample.firealarm.plugin.constants.FireAlarmConstants; +import org.wso2.carbon.device.mgt.iot.sample.firealarm.service.impl.util.DeviceJSON; import org.wso2.carbon.utils.CarbonUtils; import javax.servlet.http.HttpServletResponse; @@ -63,8 +64,8 @@ public class FireAlarmControllerService { private static final String URL_PREFIX = "http://"; private static final String BULB_CONTEXT = "/BULB/"; - private static final String FAN_CONTEXT = "/FAN/"; - private static final String TEMPERATURE_CONTEXT = "/TEMP/"; + private static final String SONAR_CONTEXT = "/SONAR/"; + private static final String TEMPERATURE_CONTEXT = "/TEMPERATURE/"; public static final String XMPP_PROTOCOL = "XMPP"; public static final String HTTP_PROTOCOL = "HTTP"; @@ -149,8 +150,12 @@ public class FireAlarmControllerService { sendCommandViaHTTP(deviceIP, 80, callUrlPattern, true); break; case MQTT_PROTOCOL: - callUrlPattern = BULB_CONTEXT.replace("/", ""); - sendCommandViaMQTT(owner, deviceId, callUrlPattern, switchToState); + sendCommandViaMQTT(owner, deviceId, BULB_CONTEXT.replace("/", ""), + switchToState); + break; + case XMPP_PROTOCOL: +// requestBulbChangeViaXMPP(switchToState, response); + sendCommandViaXMPP(owner, deviceId, BULB_CONTEXT, switchToState); break; default: if (protocolString == null) { @@ -172,76 +177,74 @@ public class FireAlarmControllerService { } - @Path("/fan/{state}") - @POST - public void switchFan(@HeaderParam("owner") String owner, - @HeaderParam("deviceId") String deviceId, - @HeaderParam("protocol") String protocol, - @PathParam("state") String state, - @Context HttpServletResponse response) { + @Path("/readsonar") + @GET + public String requestSonarReading(@HeaderParam("owner") String owner, + @HeaderParam("deviceId") String deviceId, + @HeaderParam("protocol") String protocol, + @Context HttpServletResponse response) { + String replyMsg = ""; + DeviceValidator deviceValidator = new DeviceValidator(); try { - DeviceValidator deviceValidator = new DeviceValidator(); if (!deviceValidator.isExist(owner, new DeviceIdentifier(deviceId, FireAlarmConstants .DEVICE_TYPE))) { response.setStatus(HttpStatus.SC_UNAUTHORIZED); - return; + return "Unauthorized Access"; } } catch (DeviceManagementException e) { - log.error("DeviceValidation Failed for deviceId: " + deviceId + " of user: " + owner); + replyMsg = e.getErrorMessage(); response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR); - return; - } - - String switchToState = state.toUpperCase(); - - if (!switchToState.equals(FireAlarmConstants.STATE_ON) && !switchToState.equals( - FireAlarmConstants.STATE_OFF)) { - log.error("The requested state change shoud be either - 'ON' or 'OFF'"); - response.setStatus(HttpStatus.SC_BAD_REQUEST); - return; + return replyMsg; } - String deviceIP = deviceToIpMap.get(deviceId); + String deviceIp = deviceToIpMap.get(deviceId); - if (deviceIP == null) { + if (deviceIp == null) { + replyMsg = "IP not registered for device: " + deviceId + " of owner: " + owner; response.setStatus(HttpStatus.SC_PRECONDITION_FAILED); - return; + return replyMsg; } - String protocolString = protocol.toUpperCase(); - String callUrlPattern = FAN_CONTEXT + switchToState; - - log.info("Sending command: '" + callUrlPattern + "' to firealarm at: " + deviceIP + " " + - "via" + " " + protocol); - try { - switch (protocolString) { + switch (protocol) { case HTTP_PROTOCOL: - sendCommandViaHTTP(deviceIP, 80, callUrlPattern, true); + log.info("Sending request to read sonar value at : " + deviceIp + + " via " + HTTP_PROTOCOL); + + replyMsg = sendCommandViaHTTP(deviceIp, 80, SONAR_CONTEXT, false); break; - case MQTT_PROTOCOL: - callUrlPattern = FAN_CONTEXT.replace("/", ""); - sendCommandViaMQTT(owner, deviceId, callUrlPattern, switchToState); + + case XMPP_PROTOCOL: + log.info("Sending request to read sonar value at : " + deviceIp + + " via " + + XMPP_PROTOCOL); + replyMsg = sendCommandViaXMPP(owner, deviceId, SONAR_CONTEXT, "."); break; + default: - if (protocolString == null) { - sendCommandViaHTTP(deviceIP, 80, callUrlPattern, true); + if (protocol == null) { + log.info("Sending request to read sonar value at : " + deviceIp + + " via " + HTTP_PROTOCOL); + + replyMsg = sendCommandViaHTTP(deviceIp, 80, SONAR_CONTEXT, false); } else { + replyMsg = "Requested protocol '" + protocol + "' is not supported"; response.setStatus(HttpStatus.SC_NOT_IMPLEMENTED); - return; + return replyMsg; } break; } } catch (DeviceManagementException e) { - log.error("Failed to send command '" + callUrlPattern + "' to: " + deviceIP + " via" + - " " + protocol); + replyMsg = e.getErrorMessage(); response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR); - return; + return replyMsg; } response.setStatus(HttpStatus.SC_OK); + replyMsg = "The current sonar reading of the device is " + replyMsg; + return replyMsg; } @@ -288,7 +291,8 @@ public class FireAlarmControllerService { log.info("Sending request to read firealarm-temperature at : " + deviceIp + " via " + XMPP_PROTOCOL); - replyMsg = requestTemperatureViaXMPP(deviceIp, response); + replyMsg = sendCommandViaXMPP(owner, deviceId, TEMPERATURE_CONTEXT, "."); +// replyMsg = requestTemperatureViaXMPP(response); break; default: @@ -316,46 +320,53 @@ public class FireAlarmControllerService { } - public String requestTemperatureViaXMPP(String deviceIp, - @Context HttpServletResponse response) { - String replyMsg = ""; - - String sep = File.separator; - String scriptsFolder = "repository" + sep + "resources" + sep + "scripts"; - String scriptPath = CarbonUtils.getCarbonHome() + sep + scriptsFolder + sep - + "xmpp_client.py"; - String command = "python " + scriptPath; - - replyMsg = executeCommand(command); - - response.setStatus(HttpStatus.SC_OK); - return replyMsg; - } - - - private String executeCommand(String command) { - StringBuffer output = new StringBuffer(); - - Process p; - try { - p = Runtime.getRuntime().exec(command); - p.waitFor(); - BufferedReader reader = - new BufferedReader(new InputStreamReader(p.getInputStream())); - - String line = ""; - while ((line = reader.readLine()) != null) { - output.append(line + "\n"); - } - - } catch (Exception e) { - log.info(e.getMessage(), e); - } - - return output.toString(); - - } - +// public String requestTemperatureViaXMPP(@Context HttpServletResponse response) { +// String replyMsg = ""; +// +// String sep = File.separator; +// String scriptsFolder = "repository" + sep + "resources" + sep + "scripts"; +// String scriptPath = CarbonUtils.getCarbonHome() + sep + scriptsFolder + sep +// + "xmpp_client.py -r Temperature"; +// String command = "python " + scriptPath; +// +// replyMsg = executeCommand(command); +// +// response.setStatus(HttpStatus.SC_OK); +// return replyMsg; +// } + + +// public String requestSonarViaXMPP(@Context HttpServletResponse response) { +// String replyMsg = ""; +// +// String sep = File.separator; +// String scriptsFolder = "repository" + sep + "resources" + sep + "scripts"; +// String scriptPath = CarbonUtils.getCarbonHome() + sep + scriptsFolder + sep +// + "xmpp_client.py -r Sonar"; +// String command = "python " + scriptPath; +// +// replyMsg = executeCommand(command); +// +// response.setStatus(HttpStatus.SC_OK); +// return replyMsg; +// } + + +// public String requestBulbChangeViaXMPP(String state, +// @Context HttpServletResponse response) { +// String replyMsg = ""; +// +// String sep = File.separator; +// String scriptsFolder = "repository" + sep + "resources" + sep + "scripts"; +// String scriptPath = CarbonUtils.getCarbonHome() + sep + scriptsFolder + sep +// + "xmpp_client.py -r Bulb -s " + state; +// String command = "python " + scriptPath; +// +// replyMsg = executeCommand(command); +// +// response.setStatus(HttpStatus.SC_OK); +// return replyMsg; +// } @Path("/push_temperature") @POST @@ -441,10 +452,10 @@ public class FireAlarmControllerService { if (sensors.length == 3) { String temperature = sensors[0]; String bulb = sensors[1]; - String fan = sensors[2]; + String sonar = sensors[2]; sensorValues = "Temperature:" + temperature + "C\tBulb Status:" + bulb + - "\t\tFan Status:" + fan; + "\t\tSonar Status:" + sonar; log.info(sensorValues); DeviceController deviceController = new DeviceController(); result = deviceController.pushBamData(dataMsg.owner, FireAlarmConstants @@ -476,12 +487,12 @@ public class FireAlarmControllerService { .DEVICE_TYPE, dataMsg.deviceId, System.currentTimeMillis(), "DeviceData", - fan, - "FAN"); + sonar, + "SONAR"); if (!result) { response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR); - log.error("Error whilst pushing Fan data: " + sensorValues); + log.error("Error whilst pushing Sonar data: " + sensorValues); } } else { @@ -504,6 +515,89 @@ public class FireAlarmControllerService { } + private String sendCommandViaXMPP(String deviceOwner, String deviceId, String resource, + String state) throws DeviceManagementException { + + String replyMsg = ""; + String scriptArguments = ""; + String command = ""; + + String seperator = File.separator; + String xmppServerURL = XmppConfig.getInstance().getXmppEndpoint(); + int indexOfChar = xmppServerURL.lastIndexOf(seperator); + if (indexOfChar != -1) { + xmppServerURL = xmppServerURL.substring((indexOfChar + 1), xmppServerURL.length()); + } + + indexOfChar = xmppServerURL.indexOf(":"); + if (indexOfChar != -1) { + xmppServerURL = xmppServerURL.substring(0, indexOfChar); + } + + String xmppAdminUName = XmppConfig.getInstance().getXmppUsername(); + String xmppAdminPass = XmppConfig.getInstance().getXmppPassword(); + + String xmppAdminUserLogin = xmppAdminUName + "@" + xmppServerURL + seperator + deviceOwner; + String clientToConnect = deviceId + "@" + xmppServerURL + seperator + deviceOwner; + + String scriptsFolder = "repository" + seperator + "resources" + seperator + "scripts"; + String scriptPath = CarbonUtils.getCarbonHome() + seperator + scriptsFolder + seperator + + "xmpp_client.py "; + + scriptArguments = "-j " + xmppAdminUserLogin + " -p " + xmppAdminPass + " -c " + clientToConnect + " -r " + resource + " -s " + state; + command = "python " + scriptPath + scriptArguments; + + if (log.isDebugEnabled()){ + log.debug("Connecting to XMPP Server via Admin credentials: " + xmppAdminUserLogin); + log.debug("Trying to contact xmpp device account: " + clientToConnect); + log.debug("Arguments used for the scripts: '" + scriptArguments + "'"); + log.debug("Command exceuted: '" + command + "'"); + } + +// switch (resource) { +// case BULB_CONTEXT: +// scriptArguments = "-r Bulb -s " + state; +// command = "python " + scriptPath + scriptArguments; +// break; +// case SONAR_CONTEXT: +// scriptArguments = "-r Sonar"; +// command = "python " + scriptPath + scriptArguments; +// break; +// case TEMPERATURE_CONTEXT: +// scriptArguments = "-r Temperature"; +// command = "python " + scriptPath + scriptArguments; +// break; +// } + + replyMsg = executeCommand(command); + return replyMsg; + } + + + private String executeCommand(String command) { + StringBuffer output = new StringBuffer(); + + Process p; + try { + p = Runtime.getRuntime().exec(command); + p.waitFor(); + BufferedReader reader = + new BufferedReader(new InputStreamReader(p.getInputStream())); + + String line = ""; + while ((line = reader.readLine()) != null) { + output.append(line + "\n"); + } + + } catch (Exception e) { + log.info(e.getMessage(), e); + } + + return output.toString(); + + } + + private boolean sendCommandViaMQTT(String deviceOwner, String deviceId, String resource, String state) throws DeviceManagementException { diff --git a/modules/distribution/src/scripts/xmpp_client.py b/modules/distribution/src/scripts/xmpp_client.py index e53b94b1..c9814cd6 100755 --- a/modules/distribution/src/scripts/xmpp_client.py +++ b/modules/distribution/src/scripts/xmpp_client.py @@ -18,7 +18,6 @@ * limitations under the License. */ """ -import getpass import logging import sys from optparse import OptionParser @@ -34,6 +33,7 @@ from sleekxmpp.exceptions import IqError, IqTimeout # ourselves to UTF-8. if sys.version_info < (3, 0): from sleekxmpp.util.misc_ops import setdefaultencoding + setdefaultencoding('utf8') else: raw_input = input @@ -41,6 +41,7 @@ else: # from sleekxmpp.plugins.xep_0323.device import Device PRINT_HEADER_LENGTH = 40 + class IoT_TestDevice(sleekxmpp.ClientXMPP): """ A simple IoT device that can act as client @@ -53,15 +54,17 @@ class IoT_TestDevice(sleekxmpp.ClientXMPP): python xmpp_client.py -j "bob@yourdomain.com" -p "password" -c "alice@yourdomain.com/device1" {--[debug|quiet]} python xmpp_client.py -j "bob@127.0.0.1" -p "password" -c "alice@127.0.0.1/device1" {--[debug|quiet]} """ - def __init__(self, jid, password, sensorjid): + + def __init__(self, jid, password, sensorjid, sensorType): sleekxmpp.ClientXMPP.__init__(self, jid, password) self.add_event_handler("session_start", self.session_start) self.add_event_handler("message", self.message) - self.device=None - self.releaseMe=False + self.device = None + self.releaseMe = False self.target_jid = sensorjid - #self.beServer=True - #self.clientJID=None + self.requestType = sensorType + # self.beServer=True + # self.clientJID=None def datacallback(self, from_jid, result, nodeId=None, timestamp=None, fields=None, error_msg=None): @@ -70,24 +73,28 @@ class IoT_TestDevice(sleekxmpp.ClientXMPP): se script below for the registration of the callback """ logging.debug("we got data %s from %s", str(result), from_jid) - if(result=="fields"): + if (result == "fields"): header = 'XEP 302 Sensor Data' logging.info('-' * PRINT_HEADER_LENGTH) - gap = ' '* ((PRINT_HEADER_LENGTH - len(header)) / 2) + gap = ' ' * ((PRINT_HEADER_LENGTH - len(header)) / 2) logging.info(gap + header) logging.info('-' * PRINT_HEADER_LENGTH) - logging.debug("RECV:"+str(fields)) + logging.debug("RECV:" + str(fields)) if len(fields) > 0: logging.info("Name\t\tType\tValue\tUnit") for field in fields: - logging.info(" - " + field["name"] + "\t" + field["typename"] + "\t" + field["value"] + "\t" + field["unit"]) + logging.info(" - " + field["name"] + "\t" + field["typename"] + "\t" + field[ + "value"] + "\t" + field["unit"]) + + if self.requestType in ("/" + field["name"].upper() + "/."): + print field["value"] + logging.info('-' * PRINT_HEADER_LENGTH) self.disconnect() - print field["value"] def testForRelease(self): # todo thread safe @@ -95,20 +102,20 @@ class IoT_TestDevice(sleekxmpp.ClientXMPP): def doReleaseMe(self): # todo thread safe - self.releaseMe=True + self.releaseMe = True def addDevice(self, device): - self.device=device + self.device = device def session_start(self, event): self.send_presence() self.get_roster() # tell your preffered friend that you are alive using generic xmpp chat protocol - #self.send_message(mto='jocke@jabber.sust.se', mbody=self.boundjid.bare +' is now online use xep_323 stanza to talk to me') + # self.send_message(mto='jocke@jabber.sust.se', mbody=self.boundjid.bare +' is now online use xep_323 stanza to talk to me') - #------------------------------------------------------------------------------------------- + # ------------------------------------------------------------------------------------------- # Service Discovery - #------------------------------------------------------------------------------------------- + # ------------------------------------------------------------------------------------------- try: # By using block=True, the result stanza will be # returned. Execution will block until the reply is @@ -125,7 +132,7 @@ class IoT_TestDevice(sleekxmpp.ClientXMPP): else: header = 'XMPP Service Discovery' logging.info('-' * PRINT_HEADER_LENGTH) - gap = ' '* ((PRINT_HEADER_LENGTH - len(header)) / 2) + gap = ' ' * ((PRINT_HEADER_LENGTH - len(header)) / 2) logging.info(gap + header) logging.info('-' * PRINT_HEADER_LENGTH) @@ -134,41 +141,35 @@ class IoT_TestDevice(sleekxmpp.ClientXMPP): for feature in info['disco_info']['features']: logging.info(' - %s' % feature) - #------------------------------------------------------------------------------------------- + # ------------------------------------------------------------------------------------------- # Requesting data through XEP0323 - #------------------------------------------------------------------------------------------- - session = self['xep_0323'].request_data(self.boundjid.full, self.target_jid, - self.datacallback, flags={"momentary": "true"}) + # ------------------------------------------------------------------------------------------- + + logging.info('-' * PRINT_HEADER_LENGTH) + logging.info("Sending Request: %s to %s", self.requestType, self.target_jid) + + if self.requestType in ('/TEMPERATURE/.', '/SONAR/.'): + session = self['xep_0323'].request_data(self.boundjid.full, self.target_jid, + self.datacallback, flags={"momentary": "true"}) + else: + self.send_message(mto=self.target_jid, + mbody=self.requestType, + mtype='chat') + + # Using wait=True ensures that the send queue will be + # emptied before ending the session. + self.disconnect(wait=True) + print ("Bulb state switched - " + self.requestType) def message(self, msg): if msg['type'] in ('chat', 'normal'): - logging.debug("got normal chat message" + str(msg)) + logging.info("got normal chat message" + str(msg)) ipPublic = urlopen('http://icanhazip.com').read() ipSocket = socket.gethostbyname(socket.gethostname()) - msg.reply("Hi I am " + self.boundjid.full + " and I am on IP " + ipSocket + " use xep_323 stanza to talk to me").send() + msg.reply( + "Hi I am " + self.boundjid.full + " and I am on IP " + ipSocket + " use xep_323 stanza to talk to me").send() else: - logging.debug("got unknown message type %s", str(msg['type'])) - -# class TheDevice(Device): -# """ -# This is the actual device object that you will use to get information from your real hardware -# You will be called in the refresh method when someone is requesting information from you -# """ -# def __init__(self,nodeId): -# Device.__init__(self,nodeId) -# self.counter=0 -# -# def refresh(self,fields): -# """ -# the implementation of the refresh method -# """ -# #self._set_momentary_timestamp(self._get_timestamp()) -# self.counter+=1 -# #self._add_field_momentary_data(self, "Temperature", self.counter) -# -# self._add_field(name="Temperature", typename="numeric", unit="C") -# self._set_momentary_timestamp(self._get_timestamp()) -# self._add_field_momentary_data("Temperature", str(self.counter), flags={"automaticReadout": "true"}) + logging.info("got unknown message type %s", str(msg['type'])) if __name__ == '__main__': @@ -206,36 +207,42 @@ if __name__ == '__main__': optp.add_option("-c", "--sensorjid", dest="sensorjid", help="Another device to call for data on", default=None) + optp.add_option("-r", "--sensorType", dest="sensorType", + help="The type of the sensor info requested", default="/TEMPERATURE/") + + optp.add_option("-s", "--sensorState", dest="sensorState", + help="The state of the sensor to switch to", default="") + opts, args = optp.parse_args() - # Setup logging. + # Setup logging. logging.basicConfig(level=opts.loglevel, format='%(levelname)-8s %(message)s') if opts.jid is None: - #opts.jid = raw_input("Username: ") - opts.jid = "admin@204.232.188.215/raspi" + opts.jid = "admin@204.232.188.215/admin" if opts.password is None: - opts.password = "wso2iot123" - #opts.password = getpass.getpass("Password: ") - if opts.sensorjid is None: - opts.sensorjid = "1hrdqr4r2ymhy@204.232.188.215/raspi" - #opts.sensorjid = getpass.getpass("Sensor JID: ") + opts.password = "admin" + # if opts.sensorjid is None: + # opts.sensorjid = "t4ibkqs8t7ox@204.232.188.215/admin" - #------------------------------------------------------------------------------------------- + # ------------------------------------------------------------------------------------------- # Starting XMPP with XEP0030, XEP0323, XEP0325 - #------------------------------------------------------------------------------------------- - xmpp = IoT_TestDevice(opts.jid, opts.password, opts.sensorjid) + # ------------------------------------------------------------------------------------------- + + requestState = opts.sensorType + opts.sensorState + + xmpp = IoT_TestDevice(opts.jid, opts.password, opts.sensorjid, requestState) xmpp.register_plugin('xep_0030') xmpp.register_plugin('xep_0323') xmpp.register_plugin('xep_0325') if opts.sensorjid: - logging.debug("will try to call another device for data") + logging.debug("Will try to call another device for data") # xmpp.beClientOrServer(server=False,clientJID=opts.sensorjid) xmpp.connect() xmpp.process(block=True) logging.debug("ready ending") else: - print "noopp didn't happen" + print "ID of the client to communicate-to not given..."