diff --git a/components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/ArduinoService.java b/components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/ArduinoService.java
index 03acf76276..a0bc3be694 100644
--- a/components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/ArduinoService.java
+++ b/components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/arduino/service/ArduinoService.java
@@ -39,6 +39,7 @@ import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager;
import org.wso2.carbon.device.mgt.iot.util.ZipArchive;
import org.wso2.carbon.device.mgt.iot.util.ZipUtil;
+import javax.jws.WebService;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
@@ -459,8 +460,8 @@ public class ArduinoService {
String deviceHttpEndpoint = deviceIP + ":" + devicePort;
deviceToIpMap.put(deviceId, deviceHttpEndpoint);
- result = "Device-IP Registered";
+ result = "Device-IP Registered";
response.setStatus(Response.Status.OK.getStatusCode());
if (log.isDebugEnabled()) {
@@ -689,7 +690,5 @@ public class ArduinoService {
String errorMsg = "Validation attempt for deviceId [" + deviceId + "] of owner [" + owner + "] failed.\n";
log.error(errorMsg + Response.Status.INTERNAL_SERVER_ERROR.getReasonPhrase() + "\n" + e.getErrorMessage());
}
-
-
}
}
diff --git a/components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.service.impl/src/main/webapp/WEB-INF/web.xml b/components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.service.impl/src/main/webapp/WEB-INF/web.xml
index 2175bbda26..87f9c84601 100644
--- a/components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.service.impl/src/main/webapp/WEB-INF/web.xml
+++ b/components/device-mgt-iot-arduino/org.wso2.carbon.device.mgt.iot.arduino.service.impl/src/main/webapp/WEB-INF/web.xml
@@ -19,5 +19,52 @@
/*
+
+ isAdminService
+ false
+
+
+ doAuthentication
+ false
+
+
+
+
+ managed-api-enabled
+ true
+
+
+ managed-api-owner
+ admin
+
+
+ managed-api-name
+ arduino
+
+
+ managed-api-endpoint
+ http://localhost:9763/arduino
+
+
+ managed-api-version
+ 1.0.0
+
+
+ managed-api-context
+ /arduino
+
+
+ managed-api-context-template
+ /arduino/{version}
+
+
+ managed-api-application
+ arduino
+
+
+ managed-api-isSecured
+ true
+
+
diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/constants/RaspberrypiConstants.java b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/constants/RaspberrypiConstants.java
index 8a8841d0a1..1c419f0b5c 100644
--- a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/constants/RaspberrypiConstants.java
+++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/plugin/constants/RaspberrypiConstants.java
@@ -23,5 +23,13 @@ public class RaspberrypiConstants {
public final static String DEVICE_TYPE = "raspberrypi";
public final static String DEVICE_PLUGIN_DEVICE_NAME = "DEVICE_NAME";
public final static String DEVICE_PLUGIN_DEVICE_ID = "RASPBERRYPI_DEVICE_ID";
+ public final static String STATE_ON = "ON";
+ public final static String STATE_OFF = "OFF";
+
+ public static final String URL_PREFIX = "http://";
+ public static final String BULB_CONTEXT = "/BULB/";
+ public static final String TEMPERATURE_CONTEXT = "/TEMPERATURE/";
+
+ public static final String SENSOR_TEMPERATURE = "temperature";
}
diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/pom.xml b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/pom.xml
new file mode 100644
index 0000000000..146e472712
--- /dev/null
+++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/pom.xml
@@ -0,0 +1,149 @@
+
+
+
+
+
+ device-mgt-iot-raspberrypi
+ org.wso2.carbon.devicemgt-plugins
+ 1.9.2-SNAPSHOT
+ ../pom.xml
+
+
+
+ 4.0.0
+ org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl
+ 1.9.2-SNAPSHOT
+ war
+ WSO2 Carbon - IoT Server RaspberryPi API
+ WSO2 Carbon - RaspberryPi Service API Implementation
+ http://wso2.org
+
+
+
+
+ org.wso2.carbon.devicemgt
+ org.wso2.carbon.device.mgt.common
+ provided
+
+
+ org.wso2.carbon.devicemgt
+ org.wso2.carbon.device.mgt.core
+ provided
+
+
+ org.apache.axis2.wso2
+ axis2-client
+
+
+
+
+
+
+ org.apache.cxf
+ cxf-rt-frontend-jaxws
+ provided
+
+
+ org.apache.cxf
+ cxf-rt-frontend-jaxrs
+ provided
+
+
+ org.apache.cxf
+ cxf-rt-transports-http
+ provided
+
+
+
+
+ org.eclipse.paho
+ mqtt-client
+ provided
+
+
+
+
+ org.apache.httpcomponents
+ httpasyncclient
+ 4.1
+ provided
+
+
+ org.wso2.carbon.devicemgt-plugins
+ org.wso2.carbon.device.mgt.iot
+ provided
+
+
+ org.wso2.carbon.devicemgt-plugins
+ org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl
+ provided
+
+
+
+
+ org.codehaus.jackson
+ jackson-core-asl
+
+
+ org.codehaus.jackson
+ jackson-jaxrs
+
+
+ javax
+ javaee-web-api
+ provided
+
+
+ javax.ws.rs
+ jsr311-api
+ provided
+
+
+
+ org.wso2.carbon.devicemgt
+ org.wso2.carbon.device.mgt.analytics
+ provided
+
+
+
+
+
+
+
+
+
+ maven-compiler-plugin
+
+ UTF-8
+
+ ${wso2.maven.compiler.target}
+
+
+
+ maven-war-plugin
+
+ raspberrypi
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/RaspberryPiService.java b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/RaspberryPiService.java
new file mode 100644
index 0000000000..f4805d274a
--- /dev/null
+++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/RaspberryPiService.java
@@ -0,0 +1,624 @@
+/*
+ * 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.
+ */
+
+package org.wso2.carbon.device.mgt.iot.raspberrypi.service;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+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.common.EnrolmentInfo;
+import org.wso2.carbon.device.mgt.iot.DeviceManagement;
+import org.wso2.carbon.device.mgt.iot.DeviceValidator;
+import org.wso2.carbon.device.mgt.iot.apimgt.AccessTokenInfo;
+import org.wso2.carbon.device.mgt.iot.apimgt.TokenClient;
+import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppAccount;
+import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppConfig;
+import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppServerClient;
+import org.wso2.carbon.device.mgt.iot.exception.AccessTokenException;
+import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
+import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants;
+import org.wso2.carbon.device.mgt.iot.raspberrypi.service.dto.DeviceJSON;
+import org.wso2.carbon.device.mgt.iot.raspberrypi.service.transport.RaspberryPiMQTTSubscriber;
+import org.wso2.carbon.device.mgt.iot.raspberrypi.service.util.RaspberrypiServiceUtils;
+import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager;
+import org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord;
+import org.wso2.carbon.device.mgt.iot.util.ZipArchive;
+import org.wso2.carbon.device.mgt.iot.util.ZipUtil;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Path("/RaspberryPiDeviceManager")
+public class RaspberryPiService {
+
+ private static Log log = LogFactory.getLog(RaspberryPiService.class);
+
+ //TODO; replace this tenant domain
+ private static final String SUPER_TENANT = "carbon.super";
+
+ @Context //injected response proxy supporting multiple thread
+ private HttpServletResponse response;
+
+ public static final String HTTP_PROTOCOL = "HTTP";
+ public static final String MQTT_PROTOCOL = "MQTT";
+
+ private ConcurrentHashMap deviceToIpMap = new ConcurrentHashMap<>();
+ private RaspberryPiMQTTSubscriber raspberryPiMQTTSubscriber;
+
+ /**
+ * @param raspberryPiMQTTSubscriber
+ */
+ public void setRaspberryPiMQTTSubscriber(
+ final RaspberryPiMQTTSubscriber raspberryPiMQTTSubscriber) {
+ this.raspberryPiMQTTSubscriber = raspberryPiMQTTSubscriber;
+
+ Runnable xmppStarter = new Runnable() {
+ @Override
+ public void run() {
+ raspberryPiMQTTSubscriber.initConnector();
+ raspberryPiMQTTSubscriber.connectAndSubscribe();
+ }
+ };
+
+ Thread xmppStarterThread = new Thread(xmppStarter);
+ xmppStarterThread.setDaemon(true);
+ xmppStarterThread.start();
+ }
+
+ /**
+ * @return
+ */
+ public RaspberryPiMQTTSubscriber getRaspberryPiMQTTSubscriber() {
+ return raspberryPiMQTTSubscriber;
+ }
+
+ /* ---------------------------------------------------------------------------------------
+ Device management specific APIs
+ Also contains utility methods required for the execution of these APIs
+ --------------------------------------------------------------------------------------- */
+ @Path("manager/device/register")
+ @PUT
+ public boolean register(@QueryParam("deviceId") String deviceId,
+ @QueryParam("name") String name, @QueryParam("owner") String owner) {
+
+ DeviceManagement deviceManagement = new DeviceManagement(SUPER_TENANT);
+
+ DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
+ deviceIdentifier.setId(deviceId);
+ deviceIdentifier.setType(RaspberrypiConstants.DEVICE_TYPE);
+ try {
+ if (deviceManagement.getDeviceManagementService().isEnrolled(deviceIdentifier)) {
+ response.setStatus(Response.Status.CONFLICT.getStatusCode());
+ return false;
+ }
+
+ Device device = new Device();
+ device.setDeviceIdentifier(deviceId);
+ EnrolmentInfo enrolmentInfo = new EnrolmentInfo();
+ enrolmentInfo.setDateOfEnrolment(new Date().getTime());
+ enrolmentInfo.setDateOfLastUpdate(new Date().getTime());
+ enrolmentInfo.setStatus(EnrolmentInfo.Status.ACTIVE);
+ enrolmentInfo.setOwnership(EnrolmentInfo.OwnerShip.BYOD);
+ device.setName(name);
+ device.setType(RaspberrypiConstants.DEVICE_TYPE);
+ enrolmentInfo.setOwner(owner);
+ device.setEnrolmentInfo(enrolmentInfo);
+ boolean added = deviceManagement.getDeviceManagementService().enrollDevice(device);
+ if (added) {
+ response.setStatus(Response.Status.OK.getStatusCode());
+ } else {
+ response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode());
+ }
+
+ return added;
+ } catch (DeviceManagementException e) {
+ response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+ return false;
+ } finally {
+ deviceManagement.endTenantFlow();
+ }
+ }
+
+ @Path("manager/device/remove/{device_id}")
+ @DELETE
+ public void removeDevice(@PathParam("device_id") String deviceId,
+ @Context HttpServletResponse response) {
+
+ DeviceManagement deviceManagement = new DeviceManagement(SUPER_TENANT);
+ DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
+ deviceIdentifier.setId(deviceId);
+ deviceIdentifier.setType(RaspberrypiConstants.DEVICE_TYPE);
+ try {
+ boolean removed = deviceManagement.getDeviceManagementService().disenrollDevice(
+ deviceIdentifier);
+ if (removed) {
+ response.setStatus(Response.Status.OK.getStatusCode());
+ } else {
+ response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode());
+ }
+ } catch (DeviceManagementException e) {
+ response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+ } finally {
+ deviceManagement.endTenantFlow();
+ }
+
+
+ }
+
+ @Path("manager/device/update/{device_id}")
+ @POST
+ public boolean updateDevice(@PathParam("device_id") String deviceId,
+ @QueryParam("name") String name,
+ @Context HttpServletResponse response) {
+
+ DeviceManagement deviceManagement = new DeviceManagement(SUPER_TENANT);
+
+ DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
+ deviceIdentifier.setId(deviceId);
+ deviceIdentifier.setType(RaspberrypiConstants.DEVICE_TYPE);
+ try {
+ Device device = deviceManagement.getDeviceManagementService().getDevice(deviceIdentifier);
+ device.setDeviceIdentifier(deviceId);
+
+ // device.setDeviceTypeId(deviceTypeId);
+ device.getEnrolmentInfo().setDateOfLastUpdate(new Date().getTime());
+
+ device.setName(name);
+ device.setType(RaspberrypiConstants.DEVICE_TYPE);
+
+ boolean updated = deviceManagement.getDeviceManagementService().modifyEnrollment(device);
+
+ if (updated) {
+ response.setStatus(Response.Status.OK.getStatusCode());
+
+ } else {
+ response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode());
+ }
+ return updated;
+ } catch (DeviceManagementException e) {
+ log.error(e.getErrorMessage());
+ return false;
+ } finally {
+ deviceManagement.endTenantFlow();
+ }
+
+ }
+
+ @Path("manager/device/{device_id}")
+ @GET
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Device getDevice(@PathParam("device_id") String deviceId) {
+
+ DeviceManagement deviceManagement = new DeviceManagement(SUPER_TENANT);
+ DeviceIdentifier deviceIdentifier = new DeviceIdentifier();
+ deviceIdentifier.setId(deviceId);
+ deviceIdentifier.setType(RaspberrypiConstants.DEVICE_TYPE);
+
+ try {
+ return deviceManagement.getDeviceManagementService().getDevice(deviceIdentifier);
+ } catch (DeviceManagementException ex) {
+ log.error("Error occurred while retrieving device with Id " + deviceId + "\n" + ex);
+ return null;
+ } finally {
+ deviceManagement.endTenantFlow();
+ }
+
+ }
+
+ @Path("manager/devices/{username}")
+ @GET
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Device[] getRaspberrypiDevices(@PathParam("username") String username) {
+
+ DeviceManagement deviceManagement = new DeviceManagement(SUPER_TENANT);
+
+ try {
+ List userDevices = deviceManagement.getDeviceManagementService().getDevicesOfUser(username);
+ ArrayList usersRaspberrypiDevices = new ArrayList<>();
+ for (Device device : userDevices) {
+ if (device.getType().equals(RaspberrypiConstants.DEVICE_TYPE) &&
+ device.getEnrolmentInfo().getStatus().equals(EnrolmentInfo.Status.ACTIVE)) {
+ usersRaspberrypiDevices.add(device);
+ }
+ }
+ return usersRaspberrypiDevices.toArray(new Device[]{});
+
+ } catch (DeviceManagementException e) {
+ response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+ return null;
+ } finally {
+ deviceManagement.endTenantFlow();
+ }
+ }
+
+ @Path("manager/device/{sketch_type}/download")
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response downloadSketch(@QueryParam("owner") String owner,
+ @QueryParam("deviceName") String customDeviceName,
+ @PathParam("sketch_type") String
+ sketchType) {
+
+ try {
+ ZipArchive zipFile = createDownloadFile(owner, customDeviceName, sketchType);
+ Response.ResponseBuilder response = Response.ok(FileUtils.readFileToByteArray(zipFile.getZipFile()));
+ response.type("application/zip");
+ response.header("Content-Disposition", "attachment; filename=\"" + zipFile.getFileName() + "\"");
+ return response.build();
+
+ } catch (IllegalArgumentException ex) {
+ return Response.status(400).entity(ex.getMessage()).build();//bad request
+ } catch (DeviceManagementException ex) {
+ return Response.status(500).entity(ex.getMessage()).build();
+ } catch (AccessTokenException ex) {
+ return Response.status(500).entity(ex.getMessage()).build();
+ } catch (DeviceControllerException ex) {
+ return Response.status(500).entity(ex.getMessage()).build();
+ } catch (IOException ex) {
+ return Response.status(500).entity(ex.getMessage()).build();
+ }
+ }
+
+
+ @Path("manager/device/{sketch_type}/generate_link")
+ @GET
+ public Response generateSketchLink(@QueryParam("owner") String owner,
+ @QueryParam("deviceName") String customDeviceName,
+ @PathParam("sketch_type") String sketchType) {
+
+ try {
+ ZipArchive zipFile = createDownloadFile(owner, customDeviceName, sketchType);
+ Response.ResponseBuilder rb = Response.ok(zipFile.getDeviceId());
+ return rb.build();
+ } catch (IllegalArgumentException ex) {
+ return Response.status(400).entity(ex.getMessage()).build();//bad request
+ } catch (DeviceManagementException ex) {
+ return Response.status(500).entity(ex.getMessage()).build();
+ } catch (AccessTokenException ex) {
+ return Response.status(500).entity(ex.getMessage()).build();
+ } catch (DeviceControllerException ex) {
+ return Response.status(500).entity(ex.getMessage()).build();
+ }
+ }
+
+
+ private ZipArchive createDownloadFile(String owner, String customDeviceName, String sketchType)
+ throws DeviceManagementException, AccessTokenException, DeviceControllerException {
+ if (owner == null) {
+ throw new IllegalArgumentException("Error on createDownloadFile() Owner is null!");
+ }
+
+ //create new device id
+ String deviceId = shortUUID();
+
+ TokenClient accessTokenClient = new TokenClient(RaspberrypiConstants.DEVICE_TYPE);
+ AccessTokenInfo accessTokenInfo = accessTokenClient.getAccessToken(owner, deviceId);
+
+ //create token
+ String accessToken = accessTokenInfo.getAccess_token();
+ String refreshToken = accessTokenInfo.getRefresh_token();
+ //adding registering data
+
+ XmppAccount newXmppAccount = new XmppAccount();
+ newXmppAccount.setAccountName(owner + "_" + deviceId);
+ newXmppAccount.setUsername(deviceId);
+ newXmppAccount.setPassword(accessToken);
+ newXmppAccount.setEmail(deviceId + "@wso2.com");
+
+ XmppServerClient xmppServerClient = new XmppServerClient();
+ xmppServerClient.initControlQueue();
+ boolean status;
+
+ if (XmppConfig.getInstance().isEnabled()) {
+ status = xmppServerClient.createXMPPAccount(newXmppAccount);
+ if (!status) {
+ String msg =
+ "XMPP Account was not created for device - " + deviceId + " of owner - " + owner +
+ ".XMPP might have been disabled in org.wso2.carbon.device.mgt.iot.common.config" +
+ ".server.configs";
+ log.warn(msg);
+ throw new DeviceManagementException(msg);
+ }
+ }
+
+ //Register the device with CDMF
+ String deviceName = customDeviceName + "_" + deviceId;
+ status = register(deviceId, deviceName, owner);
+
+ if (!status) {
+ String msg = "Error occurred while registering the device with " + "id: " + deviceId + " owner:" + owner;
+ throw new DeviceManagementException(msg);
+ }
+
+ ZipUtil ziputil = new ZipUtil();
+ ZipArchive zipFile = ziputil.downloadSketch(owner, SUPER_TENANT, sketchType, deviceId, deviceName, accessToken,
+ refreshToken);
+ zipFile.setDeviceId(deviceId);
+ return zipFile;
+ }
+
+ private static String shortUUID() {
+ UUID uuid = UUID.randomUUID();
+ long l = ByteBuffer.wrap(uuid.toString().getBytes(StandardCharsets.UTF_8)).getLong();
+ return Long.toString(l, Character.MAX_RADIX);
+ }
+
+ /* ---------------------------------------------------------------------------------------
+ Device specific APIs - Control APIs + Data-Publishing APIs
+ --------------------------------------------------------------------------------------- */
+
+ @Path("controller/register/{owner}/{deviceId}/{ip}/{port}")
+ @POST
+ public String registerDeviceIP(@PathParam("owner") String owner,
+ @PathParam("deviceId") String deviceId,
+ @PathParam("ip") String deviceIP,
+ @PathParam("port") String devicePort,
+ @Context HttpServletResponse response,
+ @Context HttpServletRequest request) {
+
+ //TODO:: Need to get IP from the request itself
+ String result;
+
+ if (log.isDebugEnabled()) {
+ log.debug("Got register call from IP: " + deviceIP + " for Device ID: " + deviceId + " of owner: " + owner);
+ }
+
+ String deviceHttpEndpoint = deviceIP + ":" + devicePort;
+ deviceToIpMap.put(deviceId, deviceHttpEndpoint);
+
+ result = "Device-IP Registered";
+ response.setStatus(Response.Status.OK.getStatusCode());
+
+ if (log.isDebugEnabled()) {
+ log.debug(result);
+ }
+
+ return result;
+ }
+
+
+ /**
+ * @param owner
+ * @param deviceId
+ * @param protocol
+ * @param state
+ * @param response
+ */
+ @Path("controller/bulb/{state}")
+ @POST
+ public void switchBulb(@HeaderParam("owner") String owner,
+ @HeaderParam("deviceId") String deviceId,
+ @HeaderParam("protocol") String protocol,
+ @PathParam("state") String state,
+ @Context HttpServletResponse response) {
+
+ try {
+ DeviceValidator deviceValidator = new DeviceValidator();
+ if (!deviceValidator.isExist(owner, SUPER_TENANT, new DeviceIdentifier(deviceId,
+ RaspberrypiConstants.DEVICE_TYPE))) {
+ response.setStatus(Response.Status.UNAUTHORIZED.getStatusCode());
+ return;
+ }
+ } catch (DeviceManagementException e) {
+ log.error("DeviceValidation Failed for deviceId: " + deviceId + " of user: " + owner);
+ response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+ return;
+ }
+
+ String switchToState = state.toUpperCase();
+
+ if (!switchToState.equals(RaspberrypiConstants.STATE_ON) && !switchToState.equals(
+ RaspberrypiConstants.STATE_OFF)) {
+ log.error("The requested state change shoud be either - 'ON' or 'OFF'");
+ response.setStatus(Response.Status.BAD_REQUEST.getStatusCode());
+ return;
+ }
+
+ String protocolString = protocol.toUpperCase();
+ String callUrlPattern = RaspberrypiConstants.BULB_CONTEXT + switchToState;
+
+ if (log.isDebugEnabled()) {
+ log.debug("Sending request to switch-bulb of device [" + deviceId + "] via " + protocolString);
+ }
+
+ try {
+ switch (protocolString) {
+ case HTTP_PROTOCOL:
+ String deviceHTTPEndpoint = deviceToIpMap.get(deviceId);
+ if (deviceHTTPEndpoint == null) {
+ response.setStatus(Response.Status.PRECONDITION_FAILED.getStatusCode());
+ return;
+ }
+
+ RaspberrypiServiceUtils.sendCommandViaHTTP(deviceHTTPEndpoint, callUrlPattern, true);
+ break;
+
+ case MQTT_PROTOCOL:
+ String mqttMessage = RaspberrypiConstants.BULB_CONTEXT.replace("/", "");
+ RaspberrypiServiceUtils.sendCommandViaMQTT(owner, deviceId, mqttMessage, switchToState);
+ break;
+
+ default:
+ response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode());
+ return;
+ }
+ } catch (DeviceManagementException e) {
+ log.error("Failed to send switch-bulb request to device [" + deviceId + "] via " + protocolString);
+ response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+ return;
+ }
+
+ response.setStatus(Response.Status.OK.getStatusCode());
+ }
+
+
+ /**
+ * @param owner
+ * @param deviceId
+ * @param protocol
+ * @param response
+ * @return
+ */
+ @Path("controller/readtemperature")
+ @GET
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public SensorRecord requestTemperature(@HeaderParam("owner") String owner,
+ @HeaderParam("deviceId") String deviceId,
+ @HeaderParam("protocol") String protocol,
+ @Context HttpServletResponse response) {
+ SensorRecord sensorRecord = null;
+
+ DeviceValidator deviceValidator = new DeviceValidator();
+ try {
+ if (!deviceValidator.isExist(owner, SUPER_TENANT, new DeviceIdentifier(deviceId,
+ RaspberrypiConstants.DEVICE_TYPE))) {
+ response.setStatus(Response.Status.UNAUTHORIZED.getStatusCode());
+ }
+ } catch (DeviceManagementException e) {
+ response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+ }
+
+ String protocolString = protocol.toUpperCase();
+
+ if (log.isDebugEnabled()) {
+ log.debug(
+ "Sending request to read raspberrypi-temperature of device [" + deviceId + "] via " +
+ protocolString);
+ }
+
+ try {
+ switch (protocolString) {
+ case HTTP_PROTOCOL:
+ String deviceHTTPEndpoint = deviceToIpMap.get(deviceId);
+ if (deviceHTTPEndpoint == null) {
+ response.setStatus(Response.Status.PRECONDITION_FAILED.getStatusCode());
+ }
+
+ String temperatureValue = RaspberrypiServiceUtils.sendCommandViaHTTP(deviceHTTPEndpoint,
+ RaspberrypiConstants
+ .TEMPERATURE_CONTEXT,
+ false);
+ SensorDataManager.getInstance().setSensorRecord(deviceId, RaspberrypiConstants.SENSOR_TEMPERATURE,
+ temperatureValue,
+ Calendar.getInstance().getTimeInMillis());
+ break;
+
+ case MQTT_PROTOCOL:
+ String mqttMessage = RaspberrypiConstants.BULB_CONTEXT.replace("/", "");
+ RaspberrypiServiceUtils.sendCommandViaMQTT(owner, deviceId, mqttMessage, "");
+ break;
+ default:
+ response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode());
+ }
+ sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId,
+ RaspberrypiConstants.SENSOR_TEMPERATURE);
+ } catch (DeviceManagementException | DeviceControllerException e) {
+ response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+ }
+
+ response.setStatus(Response.Status.OK.getStatusCode());
+ return sensorRecord;
+ }
+
+ /**
+ * @param dataMsg
+ * @param response
+ */
+ @Path("controller/push_temperature")
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ public void pushTemperatureData(final DeviceJSON dataMsg,
+ @Context HttpServletResponse response,
+ @Context HttpServletRequest request) {
+ String owner = dataMsg.owner;
+ String deviceId = dataMsg.deviceId;
+ String deviceIp = dataMsg.reply; //TODO:: Get IP from request
+ float temperature = dataMsg.value;
+
+ try {
+ DeviceValidator deviceValidator = new DeviceValidator();
+ if (!deviceValidator.isExist(owner, SUPER_TENANT, new DeviceIdentifier(deviceId,
+ RaspberrypiConstants.DEVICE_TYPE))) {
+ response.setStatus(Response.Status.UNAUTHORIZED.getStatusCode());
+ log.warn("Temperature data Received from unregistered raspberrypi device [" + deviceId +
+ "] for owner [" + owner + "]");
+ return;
+ }
+
+ String registeredIp = deviceToIpMap.get(deviceId);
+
+ if (registeredIp == null) {
+ log.warn("Unregistered IP: Temperature Data Received from an un-registered IP " + deviceIp +
+ " for device ID - " + deviceId);
+ response.setStatus(Response.Status.PRECONDITION_FAILED.getStatusCode());
+ return;
+ } else if (!registeredIp.equals(deviceIp)) {
+ log.warn("Conflicting IP: Received IP is " + deviceIp + ". Device with ID " + deviceId +
+ " is already registered under some other IP. Re-registration required");
+ response.setStatus(Response.Status.CONFLICT.getStatusCode());
+ return;
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("Received Pin Data Value: " + temperature + " degrees C");
+ }
+ SensorDataManager.getInstance().setSensorRecord(deviceId, RaspberrypiConstants.SENSOR_TEMPERATURE,
+ String.valueOf(temperature),
+ Calendar.getInstance().getTimeInMillis());
+
+ if (!RaspberrypiServiceUtils.publishToDAS(dataMsg.owner, dataMsg.deviceId, dataMsg.value)) {
+ response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+ log.warn("An error occured whilst trying to publish temperature data of raspberrypi with ID [" +
+ deviceId + "] of owner [" + owner + "]");
+ }
+
+ } catch (DeviceManagementException e) {
+ String errorMsg = "Validation attempt for deviceId [" + deviceId + "] of owner [" + owner + "] failed.\n";
+ log.error(errorMsg + Response.Status.INTERNAL_SERVER_ERROR.getReasonPhrase() + "\n" + e.getErrorMessage());
+ }
+ }
+
+}
diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/dto/DeviceJSON.java b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/dto/DeviceJSON.java
new file mode 100644
index 0000000000..c8695d707d
--- /dev/null
+++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/dto/DeviceJSON.java
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+package org.wso2.carbon.device.mgt.iot.raspberrypi.service.dto;
+
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class DeviceJSON {
+ @XmlElement(required = true) public String owner;
+ @XmlElement(required = true) public String deviceId;
+ @XmlElement(required = true) public String reply;
+ @XmlElement public Long time;
+ @XmlElement public String key;
+ @XmlElement public float value;
+}
diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/exception/RaspberrypiException.java b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/exception/RaspberrypiException.java
new file mode 100644
index 0000000000..d3fd75860b
--- /dev/null
+++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/exception/RaspberrypiException.java
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+package org.wso2.carbon.device.mgt.iot.raspberrypi.service.exception;
+
+public class RaspberryPiException extends Exception {
+ private static final long serialVersionUID = 118512086957330189L;
+
+ public RaspberryPiException(String errorMessage) {
+ super(errorMessage);
+ }
+
+ public RaspberryPiException(String errorMessage, Throwable throwable) {
+ super(errorMessage, throwable);
+ }
+}
diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/transport/RaspberrypiMQTTSubscriber.java b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/transport/RaspberrypiMQTTSubscriber.java
new file mode 100644
index 0000000000..2de9b9a257
--- /dev/null
+++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/transport/RaspberrypiMQTTSubscriber.java
@@ -0,0 +1,134 @@
+/*
+ * 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.
+ */
+
+package org.wso2.carbon.device.mgt.iot.raspberrypi.service.transport;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.eclipse.paho.client.mqttv3.MqttMessage;
+import org.wso2.carbon.device.mgt.common.DeviceManagementException;
+import org.wso2.carbon.device.mgt.iot.config.server.DeviceManagementConfigurationManager;
+import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig;
+import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttSubscriber;
+import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants;
+import org.wso2.carbon.device.mgt.iot.raspberrypi.service.util.RaspberrypiServiceUtils;
+import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager;
+
+import java.io.File;
+import java.util.Calendar;
+import java.util.UUID;
+
+public class RaspberryPiMQTTSubscriber extends MqttSubscriber {
+ private static Log log = LogFactory.getLog(RaspberryPiMQTTSubscriber.class);
+
+ private static final String serverName =
+ DeviceManagementConfigurationManager.getInstance().getDeviceManagementServerInfo().getName();
+ private static final String subscribeTopic =
+ serverName + File.separator + "+" + File.separator + RaspberrypiConstants.DEVICE_TYPE +
+ File.separator + "+" + File.separator + "publisher";
+
+ private static final String iotServerSubscriber = UUID.randomUUID().toString().substring(0, 5);
+ private String mqttEndpoint;
+
+ private RaspberryPiMQTTSubscriber() {
+ super(iotServerSubscriber, RaspberrypiConstants.DEVICE_TYPE,
+ MqttConfig.getInstance().getMqttQueueEndpoint(), subscribeTopic);
+ }
+
+ public void initConnector() {
+ mqttEndpoint = MqttConfig.getInstance().getMqttQueueEndpoint();
+ }
+
+ public void connectAndSubscribe() {
+ try {
+ super.connectAndSubscribe();
+ } catch (DeviceManagementException e) {
+ log.error("Subscription to MQTT Broker at: " + mqttEndpoint + " failed");
+ retryMQTTSubscription();
+ }
+ }
+
+ @Override
+ protected void postMessageArrived(String topic, MqttMessage mqttMessage) {
+ String ownerAndId = topic.replace("wso2" + File.separator + "iot" + File.separator, "");
+ ownerAndId = ownerAndId.replace(File.separator + RaspberrypiConstants.DEVICE_TYPE + File.separator, ":");
+ ownerAndId = ownerAndId.replace(File.separator + "publisher", "");
+
+ String owner = ownerAndId.split(":")[0];
+ String deviceId = ownerAndId.split(":")[1];
+ String receivedMessage = mqttMessage.toString();
+
+ if (log.isDebugEnabled()) {
+ log.debug("Received MQTT message for: {OWNER-" + owner + "} & {DEVICE.ID-" + deviceId + "}");
+ log.debug("MQTT: Received Message [" + receivedMessage + "] topic: [" + topic + "]");
+ }
+
+ if (receivedMessage.contains("PUBLISHER")) {
+ float temperature = Float.parseFloat(receivedMessage.split(":")[2]);
+
+ if (!RaspberrypiServiceUtils.publishToDAS(owner, deviceId, temperature)) {
+ log.error("MQTT Subscriber: Publishing data to DAS failed.");
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("MQTT Subscriber: Published data to DAS successfully.");
+ }
+
+ } else if (receivedMessage.contains("TEMPERATURE")) {
+ String temperatureValue = receivedMessage.split(":")[1];
+ SensorDataManager.getInstance().setSensorRecord(deviceId, RaspberrypiConstants.SENSOR_TEMPERATURE,
+ temperatureValue,
+ Calendar.getInstance().getTimeInMillis());
+ }
+ }
+
+ private void retryMQTTSubscription() {
+ Thread retryToSubscribe = new Thread() {
+ @Override
+ public void run() {
+ while (true) {
+ if (!isConnected()) {
+ if (log.isDebugEnabled()) {
+ log.debug("Subscriber re-trying to reach MQTT queue....");
+ }
+
+ try {
+ RaspberryPiMQTTSubscriber.super.connectAndSubscribe();
+ } catch (DeviceManagementException e1) {
+ if (log.isDebugEnabled()) {
+ log.debug("Attempt to re-connect to MQTT-Queue failed");
+ }
+ }
+ } else {
+ break;
+ }
+
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e1) {
+ log.error("MQTT: Thread S;eep Interrupt Exception");
+ }
+ }
+ }
+ };
+
+ retryToSubscribe.setDaemon(true);
+ retryToSubscribe.start();
+ }
+}
+
diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/util/RaspberrypiServiceUtils.java b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/util/RaspberrypiServiceUtils.java
new file mode 100644
index 0000000000..56fe46dabb
--- /dev/null
+++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/raspberrypi/service/util/RaspberrypiServiceUtils.java
@@ -0,0 +1,234 @@
+/*
+ * 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.
+ */
+
+package org.wso2.carbon.device.mgt.iot.raspberrypi.service.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.concurrent.FutureCallback;
+import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
+import org.apache.http.impl.nio.client.HttpAsyncClients;
+import org.wso2.carbon.context.PrivilegedCarbonContext;
+import org.wso2.carbon.device.mgt.analytics.exception.DataPublisherConfigurationException;
+import org.wso2.carbon.device.mgt.analytics.service.DeviceAnalyticsService;
+import org.wso2.carbon.device.mgt.common.DeviceManagementException;
+import org.wso2.carbon.device.mgt.iot.DeviceController;
+import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException;
+import org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.constants.RaspberrypiConstants;
+
+import javax.ws.rs.HttpMethod;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.ProtocolException;
+import java.net.URL;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Future;
+
+public class RaspberrypiServiceUtils {
+ private static final Log log = LogFactory.getLog(RaspberrypiServiceUtils.class);
+
+ //TODO; replace this tenant domain
+ private static final String SUPER_TENANT = "carbon.super";
+ private static final String TEMPERATURE_STREAM_DEFINITION = "org.wso2.iot.devices.temperature";
+
+ public static String sendCommandViaHTTP(final String deviceHTTPEndpoint, String urlContext,
+ boolean fireAndForgot) throws DeviceManagementException {
+
+ String responseMsg = "";
+ String urlString = RaspberrypiConstants.URL_PREFIX + deviceHTTPEndpoint + urlContext;
+
+ if (log.isDebugEnabled()) {
+ log.debug(urlString);
+ }
+
+ if (!fireAndForgot) {
+ HttpURLConnection httpConnection = getHttpConnection(urlString);
+
+ try {
+ httpConnection.setRequestMethod(HttpMethod.GET);
+ } catch (ProtocolException e) {
+ String errorMsg =
+ "Protocol specific error occurred when trying to set method to GET" +
+ " for:" + urlString;
+ log.error(errorMsg);
+ throw new DeviceManagementException(errorMsg, e);
+ }
+
+ responseMsg = readResponseFromGetRequest(httpConnection);
+
+ } else {
+ CloseableHttpAsyncClient httpclient = null;
+ try {
+
+ httpclient = HttpAsyncClients.createDefault();
+ httpclient.start();
+ HttpGet request = new HttpGet(urlString);
+ final CountDownLatch latch = new CountDownLatch(1);
+ Future future = httpclient.execute(
+ request, new FutureCallback() {
+ @Override
+ public void completed(HttpResponse httpResponse) {
+ latch.countDown();
+ }
+
+ @Override
+ public void failed(Exception e) {
+ latch.countDown();
+ }
+
+ @Override
+ public void cancelled() {
+ latch.countDown();
+ }
+ });
+
+ latch.await();
+
+ } catch (InterruptedException e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Sync Interrupted");
+ }
+ } finally {
+ try {
+ if (httpclient != null) {
+ httpclient.close();
+
+ }
+ } catch (IOException e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Failed on close");
+ }
+ }
+ }
+ }
+
+ return responseMsg;
+ }
+
+
+ public static boolean sendCommandViaMQTT(String deviceOwner, String deviceId, String resource,
+ String state) throws DeviceManagementException {
+
+ boolean result;
+ DeviceController deviceController = new DeviceController();
+
+ try {
+ result = deviceController.publishMqttControl(deviceOwner, RaspberrypiConstants.DEVICE_TYPE, deviceId, resource, state);
+ } catch (DeviceControllerException e) {
+ String errorMsg = "Error whilst trying to publish to MQTT Queue";
+ log.error(errorMsg);
+ throw new DeviceManagementException(errorMsg, e);
+ }
+ return result;
+ }
+
+ /* ---------------------------------------------------------------------------------------
+ Utility methods relevant to creating and sending http requests
+ --------------------------------------------------------------------------------------- */
+
+ /* This methods creates and returns a http connection object */
+
+ public static HttpURLConnection getHttpConnection(String urlString) throws
+ DeviceManagementException {
+
+ URL connectionUrl = null;
+ HttpURLConnection httpConnection;
+
+ try {
+ connectionUrl = new URL(urlString);
+ httpConnection = (HttpURLConnection) connectionUrl.openConnection();
+ } catch (MalformedURLException e) {
+ String errorMsg =
+ "Error occured whilst trying to form HTTP-URL from string: " + urlString;
+ log.error(errorMsg);
+ throw new DeviceManagementException(errorMsg, e);
+ } catch (IOException e) {
+ String errorMsg = "Error occured whilst trying to open a connection to: " +
+ connectionUrl.toString();
+ log.error(errorMsg);
+ throw new DeviceManagementException(errorMsg, e);
+ }
+
+ return httpConnection;
+ }
+
+ /* This methods reads and returns the response from the connection */
+
+ public static String readResponseFromGetRequest(HttpURLConnection httpConnection)
+ throws DeviceManagementException {
+ BufferedReader bufferedReader;
+ try {
+ bufferedReader = new BufferedReader(new InputStreamReader(
+ httpConnection.getInputStream()));
+ } catch (IOException e) {
+ String errorMsg =
+ "There is an issue with connecting the reader to the input stream at: " +
+ httpConnection.getURL();
+ log.error(errorMsg);
+ throw new DeviceManagementException(errorMsg, e);
+ }
+
+ String responseLine;
+ StringBuilder completeResponse = new StringBuilder();
+
+ try {
+ while ((responseLine = bufferedReader.readLine()) != null) {
+ completeResponse.append(responseLine);
+ }
+ } catch (IOException e) {
+ String errorMsg =
+ "Error occured whilst trying read from the connection stream at: " +
+ httpConnection.getURL();
+ log.error(errorMsg);
+ throw new DeviceManagementException(errorMsg, e);
+ }
+ try {
+ bufferedReader.close();
+ } catch (IOException e) {
+ log.error(
+ "Could not succesfully close the bufferedReader to the connection at: " +
+ httpConnection.getURL());
+ }
+
+ return completeResponse.toString();
+ }
+
+ public static boolean publishToDAS(String owner, String deviceId, float temperature) {
+ PrivilegedCarbonContext.startTenantFlow();
+ PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext();
+ ctx.setTenantDomain(SUPER_TENANT, true);
+ DeviceAnalyticsService deviceAnalyticsService = (DeviceAnalyticsService) ctx.getOSGiService(
+ DeviceAnalyticsService.class, null);
+ Object metdaData[] = {owner, RaspberrypiConstants.DEVICE_TYPE, deviceId, System.currentTimeMillis()};
+ Object payloadData[] = {temperature};
+
+ try {
+ deviceAnalyticsService.publishEvent(TEMPERATURE_STREAM_DEFINITION, "1.0.0", metdaData, new Object[0], payloadData);
+ } catch (DataPublisherConfigurationException e) {
+ return false;
+ } finally {
+ PrivilegedCarbonContext.endTenantFlow();
+ }
+ return true;
+ }
+}
diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/webapp/META-INF/webapp-classloading.xml b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/webapp/META-INF/webapp-classloading.xml
new file mode 100644
index 0000000000..fa44619195
--- /dev/null
+++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/webapp/META-INF/webapp-classloading.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+ false
+
+
+ CXF,Carbon
+
diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/webapp/WEB-INF/cxf-servlet.xml
new file mode 100644
index 0000000000..78b5061a0b
--- /dev/null
+++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/webapp/WEB-INF/cxf-servlet.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/webapp/WEB-INF/web.xml b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..6518ec4e2e
--- /dev/null
+++ b/components/device-mgt-iot-raspberrypi/org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,70 @@
+
+
+ RaspberryPi
+ RaspberryPi
+
+
+ CXFServlet
+ org.apache.cxf.transport.servlet.CXFServlet
+ 1
+
+
+
+
+ CXFServlet
+ /*
+
+
+
+ isAdminService
+ false
+
+
+ doAuthentication
+ false
+
+
+
+
+ managed-api-enabled
+ true
+
+
+ managed-api-owner
+ admin
+
+
+ managed-api-name
+ raspberrypi
+
+
+ managed-api-endpoint
+ http://localhost:9763/raspberrypi
+
+
+ managed-api-version
+ 1.0.0
+
+
+ managed-api-context
+ /raspberrypi
+
+
+ managed-api-context-template
+ /raspberrypi/{version}
+
+
+ managed-api-application
+ raspberrypi
+
+
+ managed-api-isSecured
+ true
+
+
+
+
diff --git a/components/device-mgt-iot-raspberrypi/pom.xml b/components/device-mgt-iot-raspberrypi/pom.xml
index 80de139dd2..b765b22f9c 100644
--- a/components/device-mgt-iot-raspberrypi/pom.xml
+++ b/components/device-mgt-iot-raspberrypi/pom.xml
@@ -37,7 +37,7 @@
org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl
-
+ org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl
diff --git a/components/device-mgt-iot-virtualfirealarm/org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/VirtualFireAlarmService.java b/components/device-mgt-iot-virtualfirealarm/org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/VirtualFireAlarmService.java
index 6548530823..a0f41b1164 100644
--- a/components/device-mgt-iot-virtualfirealarm/org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/VirtualFireAlarmService.java
+++ b/components/device-mgt-iot-virtualfirealarm/org.wso2.carbon.device.mgt.iot.virtualfirealarm.service.impl/src/main/java/org/wso2/carbon/device/mgt/iot/virtualfirealarm/service/VirtualFireAlarmService.java
@@ -21,9 +21,6 @@ package org.wso2.carbon.device.mgt.iot.virtualfirealarm.service;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.cxf.helpers.IOUtils;
-import org.apache.http.Header;
-import org.apache.woden.wsdl20.extensions.http.HTTPHeader;
import org.wso2.carbon.certificate.mgt.core.dto.SCEPResponse;
import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException;
import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementService;
@@ -69,11 +66,8 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@@ -104,12 +98,20 @@ public class VirtualFireAlarmService {
private ConcurrentHashMap deviceToIpMap = new ConcurrentHashMap<>();
+ /**
+ *
+ * @param verificationManager
+ */
public void setVerificationManager(
VerificationManager verificationManager) {
this.verificationManager = verificationManager;
verificationManager.initVerificationManager();
}
+ /**
+ *
+ * @param virtualFireAlarmXMPPConnector
+ */
public void setVirtualFireAlarmXMPPConnector(
final VirtualFireAlarmXMPPConnector virtualFireAlarmXMPPConnector) {
this.virtualFireAlarmXMPPConnector = virtualFireAlarmXMPPConnector;
@@ -127,6 +129,10 @@ public class VirtualFireAlarmService {
mqttStarterThread.start();
}
+ /**
+ *
+ * @param virtualFireAlarmMQTTSubscriber
+ */
public void setVirtualFireAlarmMQTTSubscriber(
final VirtualFireAlarmMQTTSubscriber virtualFireAlarmMQTTSubscriber) {
this.virtualFireAlarmMQTTSubscriber = virtualFireAlarmMQTTSubscriber;
@@ -144,22 +150,42 @@ public class VirtualFireAlarmService {
xmppStarterThread.start();
}
+ /**
+ *
+ * @return
+ */
public VerificationManager getVerificationManager() {
return verificationManager;
}
+ /**
+ *
+ * @return
+ */
public VirtualFireAlarmXMPPConnector getVirtualFireAlarmXMPPConnector() {
return virtualFireAlarmXMPPConnector;
}
+ /**
+ *
+ * @return
+ */
public VirtualFireAlarmMQTTSubscriber getVirtualFireAlarmMQTTSubscriber() {
return virtualFireAlarmMQTTSubscriber;
}
/* ---------------------------------------------------------------------------------------
Device management specific APIs
- Also contains utility methods required for the execution of these APIs
- --------------------------------------------------------------------------------------- */
+ Also contains utility methods required for the execution of these APIs
+ --------------------------------------------------------------------------------------- */
+
+ /**
+ *
+ * @param deviceId
+ * @param name
+ * @param owner
+ * @return
+ */
@Path("manager/device/register")
@PUT
public boolean register(@QueryParam("deviceId") String deviceId,
@@ -205,6 +231,11 @@ public class VirtualFireAlarmService {
}
}
+ /**
+ *
+ * @param deviceId
+ * @param response
+ */
@Path("manager/device/remove/{device_id}")
@DELETE
public void removeDevice(@PathParam("device_id") String deviceId, @Context HttpServletResponse response) {
@@ -218,10 +249,8 @@ public class VirtualFireAlarmService {
deviceIdentifier);
if (removed) {
response.setStatus(Response.Status.OK.getStatusCode());
-
} else {
response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode());
-
}
} catch (DeviceManagementException e) {
response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode());
@@ -231,6 +260,13 @@ public class VirtualFireAlarmService {
}
+ /**
+ *
+ * @param deviceId
+ * @param name
+ * @param response
+ * @return
+ */
@Path("manager/device/update/{device_id}")
@POST
public boolean updateDevice(@PathParam("device_id") String deviceId,
@@ -256,10 +292,8 @@ public class VirtualFireAlarmService {
if (updated) {
response.setStatus(Response.Status.OK.getStatusCode());
-
} else {
response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode());
-
}
return updated;
} catch (DeviceManagementException e) {
@@ -271,6 +305,11 @@ public class VirtualFireAlarmService {
}
+ /**
+ *
+ * @param deviceId
+ * @return
+ */
@Path("manager/device/{device_id}")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@@ -294,6 +333,11 @@ public class VirtualFireAlarmService {
}
+ /**
+ *
+ * @param username
+ * @return
+ */
@Path("manager/devices/{username}")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@@ -324,9 +368,15 @@ public class VirtualFireAlarmService {
} finally {
deviceManagement.endTenantFlow();
}
-
}
+ /**
+ *
+ * @param owner
+ * @param customDeviceName
+ * @param sketchType
+ * @return
+ */
@Path("manager/device/{sketch_type}/download")
@GET
@Produces(MediaType.APPLICATION_JSON)
@@ -353,6 +403,13 @@ public class VirtualFireAlarmService {
}
}
+ /**
+ *
+ * @param owner
+ * @param customDeviceName
+ * @param sketchType
+ * @return
+ */
@Path("manager/device/{sketch_type}/generate_link")
@GET
public Response generateSketchLink(@QueryParam("owner") String owner,
@@ -372,9 +429,18 @@ public class VirtualFireAlarmService {
} catch (DeviceControllerException ex) {
return Response.status(500).entity(ex.getMessage()).build();
}
-
}
+ /**
+ *
+ * @param owner
+ * @param customDeviceName
+ * @param sketchType
+ * @return
+ * @throws DeviceManagementException
+ * @throws AccessTokenException
+ * @throws DeviceControllerException
+ */
private ZipArchive createDownloadFile(String owner, String customDeviceName, String sketchType)
throws DeviceManagementException, AccessTokenException, DeviceControllerException {
if (owner == null) {
@@ -406,8 +472,7 @@ public class VirtualFireAlarmService {
status = xmppServerClient.createXMPPAccount(newXmppAccount);
if (!status) {
String msg =
- "XMPP Account was not created for device - " + deviceId + " of owner - " +
- owner +
+ "XMPP Account was not created for device - " + deviceId + " of owner - " + owner +
".XMPP might have been disabled in org.wso2.carbon.device.mgt.iot" +
".common.config.server.configs";
log.warn(msg);
@@ -420,8 +485,7 @@ public class VirtualFireAlarmService {
status = register(deviceId, deviceName, owner);
if (!status) {
- String msg = "Error occurred while registering the device with " + "id: " + deviceId
- + " owner:" + owner;
+ String msg = "Error occurred while registering the device with " + "id: " + deviceId + " owner:" + owner;
throw new DeviceManagementException(msg);
}
@@ -433,6 +497,10 @@ public class VirtualFireAlarmService {
return zipFile;
}
+ /**
+ *
+ * @return
+ */
private static String shortUUID() {
UUID uuid = UUID.randomUUID();
long l = ByteBuffer.wrap(uuid.toString().getBytes(StandardCharsets.UTF_8)).getLong();
@@ -443,6 +511,17 @@ public class VirtualFireAlarmService {
Device specific APIs - Control APIs + Data-Publishing APIs
Also contains utility methods required for the execution of these APIs
--------------------------------------------------------------------------------------- */
+
+ /**
+ *
+ * @param owner
+ * @param deviceId
+ * @param deviceIP
+ * @param devicePort
+ * @param response
+ * @param request
+ * @return
+ */
@Path("controller/register/{owner}/{deviceId}/{ip}/{port}")
@POST
public String registerDeviceIP(@PathParam("owner") String owner,
@@ -473,6 +552,15 @@ public class VirtualFireAlarmService {
/* Service to switch "ON" and "OFF" the Virtual FireAlarm bulb
Called by an external client intended to control the Virtual FireAlarm bulb */
+
+ /**
+ *
+ * @param owner
+ * @param deviceId
+ * @param protocol
+ * @param state
+ * @param response
+ */
@Path("controller/bulb/{state}")
@POST
public void switchBulb(@HeaderParam("owner") String owner,
@@ -546,6 +634,14 @@ public class VirtualFireAlarmService {
}
+ /**
+ *
+ * @param owner
+ * @param deviceId
+ * @param protocol
+ * @param response
+ * @return
+ */
@Path("controller/readsonar")
@GET
public String requestSonarReading(@HeaderParam("owner") String owner,
@@ -619,6 +715,14 @@ public class VirtualFireAlarmService {
}
+ /**
+ *
+ * @param owner
+ * @param deviceId
+ * @param protocol
+ * @param response
+ * @return
+ */
@Path("controller/readtemperature")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@@ -691,6 +795,11 @@ public class VirtualFireAlarmService {
return sensorRecord;
}
+ /**
+ *
+ * @param dataMsg
+ * @param response
+ */
@Path("controller/push_temperature")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@@ -726,6 +835,12 @@ public class VirtualFireAlarmService {
}
+ /**
+ *
+ * @param operation
+ * @param message
+ * @return
+ */
@GET
@Path("controller/scep")
public Response scepRequest(@QueryParam("operation") String operation, @QueryParam("message") String message) {
@@ -803,6 +918,12 @@ public class VirtualFireAlarmService {
return Response.serverError().build();
}
+ /**
+ *
+ * @param operation
+ * @param inputStream
+ * @return
+ */
@POST
@Path("controller/scep")
public Response scepRequestPost(@QueryParam("operation") String operation, InputStream inputStream) {
diff --git a/components/device-mgt-iot/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/apimgt/TokenClient.java b/components/device-mgt-iot/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/apimgt/TokenClient.java
index 58f4fc0b23..4450707214 100644
--- a/components/device-mgt-iot/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/apimgt/TokenClient.java
+++ b/components/device-mgt-iot/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/apimgt/TokenClient.java
@@ -116,16 +116,27 @@ public class TokenClient {
HttpResponse httpResponse = httpClient.execute(postMethod);
String response = IoTUtil.getResponseString(httpResponse);
+
if(log.isDebugEnabled()) {
log.debug(response);
}
- JSONObject jsonObject = new JSONObject(response);
+ JSONObject jsonObject = new JSONObject(response);
AccessTokenInfo accessTokenInfo = new AccessTokenInfo();
- accessTokenInfo.setAccess_token(jsonObject.getString("access_token"));
- accessTokenInfo.setRefresh_token(jsonObject.getString("refresh_token"));
- accessTokenInfo.setExpires_in(jsonObject.getInt("expires_in"));
- accessTokenInfo.setToken_type(jsonObject.getString("token_type"));
+
+ if (!jsonObject.get("access_token").equals(null)) {
+ accessTokenInfo.setAccess_token(jsonObject.getString("access_token"));
+ }
+ if (!jsonObject.get("refresh_token").equals(null)) {
+ accessTokenInfo.setRefresh_token(jsonObject.getString("refresh_token"));
+ }
+ if (!jsonObject.get("expires_in").equals(null)) {
+ accessTokenInfo.setExpires_in(jsonObject.getInt("expires_in"));
+ }
+ if (!jsonObject.get("token_type").equals(null)) {
+ accessTokenInfo.setToken_type(jsonObject.getString("token_type"));
+ }
+
return accessTokenInfo;
} catch ( IOException | JSONException | IoTException e) {
diff --git a/components/device-mgt-iot/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/util/ZipUtil.java b/components/device-mgt-iot/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/util/ZipUtil.java
index 03ff7d539f..4b18d6e648 100644
--- a/components/device-mgt-iot/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/util/ZipUtil.java
+++ b/components/device-mgt-iot/org.wso2.carbon.device.mgt.iot/src/main/java/org/wso2/carbon/device/mgt/iot/util/ZipUtil.java
@@ -48,8 +48,7 @@ public class ZipUtil {
+ sep + deviceId;
String templateSketchPath = sketchFolder + sep + deviceType;
-// String iotServerIP = System.getProperty("bind.address");
- String iotServerIP = System.getProperty("server.host");
+ String iotServerIP = System.getProperty("carbon.local.ip"); // bind.address
String httpsServerPort = System.getProperty("httpsPort");
String httpServerPort = System.getProperty("httpPort");
@@ -60,28 +59,13 @@ public class ZipUtil {
DeviceManagementConfigurationManager.getInstance().getDeviceCloudMgtConfig().getApiManager()
.getServerURL();
-// int indexOfChar = apimIP.lastIndexOf(File.separator);
-// if (indexOfChar != -1) {
-// apimIP = apimIP.substring((indexOfChar + 1), apimIP.length());
-// }
-
String apimGatewayPort =
DeviceManagementConfigurationManager.getInstance().getDeviceCloudMgtConfig().getApiManager()
.getGatewayPort();
String apimEndpoint = apimHost + ":" + apimGatewayPort;
-
String mqttEndpoint = MqttConfig.getInstance().getMqttQueueEndpoint();
-// indexOfChar = mqttEndpoint.lastIndexOf(File.separator);
-// if (indexOfChar != -1) {
-// mqttEndpoint = mqttEndpoint.substring((indexOfChar + 1), mqttEndpoint.length());
-// }
-
String xmppEndpoint = XmppConfig.getInstance().getXmppEndpoint();
-// indexOfChar = xmppEndpoint.lastIndexOf(File.separator);
-// if (indexOfChar != -1) {
-// xmppEndpoint = xmppEndpoint.substring((indexOfChar + 1), xmppEndpoint.length());
-// }
int indexOfChar = xmppEndpoint.lastIndexOf(":");
if (indexOfChar != -1) {
@@ -104,8 +88,7 @@ public class ZipUtil {
ZipArchive zipFile;
try {
- zipFile = IotDeviceManagementUtil.getSketchArchive(archivesPath, templateSketchPath,
- contextParams);
+ zipFile = IotDeviceManagementUtil.getSketchArchive(archivesPath, templateSketchPath, contextParams);
} catch (IOException e) {
throw new DeviceManagementException("Zip File Creation Failed", e);
}
diff --git a/features/device-mgt-iot-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/conf/devicetype-config.xml b/features/device-mgt-iot-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/conf/devicetype-config.xml
index e546b8263e..da47f1a34e 100644
--- a/features/device-mgt-iot-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/conf/devicetype-config.xml
+++ b/features/device-mgt-iot-feature/org.wso2.carbon.device.mgt.iot.feature/src/main/resources/conf/devicetype-config.xml
@@ -3,18 +3,18 @@
jdbc/AndroidSenseDM_DB
-
-
-
+
+ jdbc/ArduinoDM_DB
+
jdbc/DigitalDisplayDM_DB
jdbc/DroneAnalyzerDM_DB
-
-
-
+
+ jdbc/RaspberryPiDM_DB
+
jdbc/VirtualFireAlarmDM_DB
diff --git a/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/GuideToPi b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/GuideToPi
new file mode 100644
index 0000000000..9c23d9eea6
--- /dev/null
+++ b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/GuideToPi
@@ -0,0 +1,17 @@
+Install Rpi.GPIO
+Install sh
+ sudo easy_install pip
+ sudo pip install sh
+
+
+wget http://67.192.60.197/mikem/bcm2835/bcm2835-1.8.tar.gz
+tar xvfz bcm2835-1.8.tar.gz;
+cd bcm2835-1.8;
+./configure;
+make;
+sudo make install
+
+sudo apt-get update
+sudo apt-get install python-dev
+
+nohup command >/dev/null 2>&1 &
\ No newline at end of file
diff --git a/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/deviceConfigs.cfg b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/deviceConfigs.cfg
new file mode 100644
index 0000000000..2638fa9094
--- /dev/null
+++ b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/deviceConfigs.cfg
@@ -0,0 +1,14 @@
+[Device-Configurations]
+owner=${DEVICE_OWNER}
+deviceId=${DEVICE_ID}
+device-name=${DEVICE_NAME}
+controller-context=/RaspberryPiDeviceManager/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/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/raspberrypi.deb b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/raspberrypi.deb
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/Adafruit_Python_DHT.zip b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/Adafruit_Python_DHT.zip
new file mode 100644
index 0000000000..889117c3f7
Binary files /dev/null and b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/Adafruit_Python_DHT.zip differ
diff --git a/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/RaspberryStats.py b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/RaspberryStats.py
new file mode 100755
index 0000000000..34d0a172b0
--- /dev/null
+++ b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/RaspberryStats.py
@@ -0,0 +1,332 @@
+#!/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 logging, logging.handlers
+import sys, os, signal, argparse
+import httplib, time
+import threading
+import Adafruit_DHT # Adafruit library required for temperature sensing
+
+import iotUtils
+import httpServer # python script used to start a http-server to listen for operations (includes the TEMPERATURE global variable)
+import xmppServer # python script used to communicate with xmpp server
+import mqttListener # python script used to accept messages via mqtt
+
+
+
+PUSH_INTERVAL = 300 # time interval between successive data pushes in seconds
+logging_enabled = False
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Endpoint specific settings to which the data is pushed
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+DC_IP = '204.232.188.214' #'192.168.57.128'
+DC_PORT = 8281
+HOST = DC_IP + ':' + `DC_PORT`
+
+DC_ENDPOINT = '/firealarm/1.0/controller' #'/firealarm/1.0/'
+PUSH_ENDPOINT = DC_ENDPOINT + '/push_temperature'
+REGISTER_ENDPOINT = DC_ENDPOINT + '/register'
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Logger defaults
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LOG_FILENAME = "/usr/local/src/RaspberryAgent/logs/RaspberryStats.log"
+LOG_LEVEL = logging.INFO # Could be e.g. "DEBUG" or "WARNING"
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Define and parse command line arguments
+# If the log file is specified on the command line then override the default
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+parser = argparse.ArgumentParser(description="Python service to push RPi info to the Device Cloud")
+parser.add_argument("-l", "--log", help="file to write log to (default '" + LOG_FILENAME + "')")
+
+help_string = "time interval between successive data pushes (default '" + str(PUSH_INTERVAL) + "')"
+parser.add_argument("-i", "--interval", type=int, help=help_string)
+
+args = parser.parse_args()
+if args.log:
+ LOG_FILENAME = args.log
+
+if args.interval:
+ PUSH_INTERVAL = args.interval
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# A class we can use to capture stdout and sterr in the log
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class IOTLogger(object):
+ def __init__(self, logger, level):
+ """Needs a logger and a logger level."""
+ self.logger = logger
+ self.level = level
+
+ def write(self, message):
+ if message.rstrip() != "": # Only log if there is a message (not just a new line)
+ self.logger.log(self.level, message.rstrip())
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Configure logging to log to a file,
+# making a new file at midnight and keeping the last 3 day's data
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+def configureLogger(loggerName):
+ logger = logging.getLogger(loggerName)
+ logger.setLevel(LOG_LEVEL) # Set the log level to LOG_LEVEL
+ handler = logging.handlers.TimedRotatingFileHandler(LOG_FILENAME, when="midnight", backupCount=3) # Handler that writes to a file,
+ # ~~~make new file at midnight and keep 3 backups
+ formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(message)s') # Format each log message like this
+ handler.setFormatter(formatter) # Attach the formatter to the handler
+ logger.addHandler(handler) # Attach the handler to the logger
+
+ if(logging_enabled):
+ sys.stdout = IOTLogger(logger, logging.INFO) # Replace stdout with logging to file at INFO level
+ sys.stderr = IOTLogger(logger, logging.ERROR) # Replace stderr with logging to file at ERROR level
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# This method registers the DevieIP in the Device-Cloud
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+def registerDeviceIP():
+ dcConncection = httplib.HTTPConnection(DC_IP, DC_PORT)
+ dcConncection.set_debuglevel(1)
+ dcConncection.connect()
+
+ registerURL = REGISTER_ENDPOINT + '/' + iotUtils.DEVICE_OWNER + '/' + iotUtils.DEVICE_ID + '/' + iotUtils.HOST_NAME
+
+ dcConncection.putrequest('POST', registerURL)
+ dcConncection.putheader('Authorization', 'Bearer ' + iotUtils.AUTH_TOKEN)
+ dcConncection.endheaders()
+
+ print '~~~~~~~~~~~~~~~~~~~~~~~~ Device Registration ~~~~~~~~~~~~~~~~~~~~~~~~~'
+ 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 '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# This method connects to the Device-Cloud and pushes data
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+def connectAndPushData():
+ dcConnection = httplib.HTTPConnection(DC_IP, DC_PORT)
+ dcConnection.set_debuglevel(1)
+
+ dcConnection.connect()
+
+ request = dcConnection.putrequest('POST', PUSH_ENDPOINT)
+
+ headers = {}
+ headers['Authorization'] = 'Bearer ' + iotUtils.AUTH_TOKEN
+ headers['Content-Type'] = 'application/json'
+
+ ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ### Read the Temperature and Load info of RPi and construct payload
+ ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ # rPiTemperature=getCPUTemp() # Can be used if required to push CPU Temperature
+ # rPiLoad = getCPULoad() # Can be used if required to push CPU Load
+
+ ### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ rPiTemperature = iotUtils.LAST_TEMP # Push the last read temperature value
+ PUSH_DATA = iotUtils.DEVICE_INFO + iotUtils.DEVICE_IP.format(ip=iotUtils.HOST_NAME) + iotUtils.DEVICE_DATA.format(temperature=rPiTemperature)
+ PUSH_DATA += '}'
+
+ # print PUSH_DATA
+
+ headers['Content-Length'] = len(PUSH_DATA)
+ print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
+
+ for k in headers:
+ dcConnection.putheader(k, headers[k])
+ dcConnection.endheaders()
+
+ 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()
+
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# This is a Thread object for reading temperature continuously
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class TemperatureReaderThread(object):
+ def __init__(self, interval=3):
+ self.interval = interval
+
+ thread = threading.Thread(target=self.run, args=())
+ thread.daemon = True # Daemonize thread
+ thread.start() # Start the execution
+
+ def run(self):
+ TEMP_PIN = 4
+ TEMP_SENSOR_TYPE = 11
+
+ # Try to grab a sensor reading. Use the read_retry method which will retry up
+ # to 15 times to get a sensor reading (waiting 2 seconds between each retry).
+ while True:
+ try:
+ humidity, temperature = Adafruit_DHT.read_retry(TEMP_SENSOR_TYPE, TEMP_PIN)
+
+ if temperature != iotUtils.LAST_TEMP:
+ iotUtils.LAST_TEMP = temperature
+ connectAndPushData()
+
+ iotUtils.LAST_TEMP = temperature
+ 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 '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
+ pass
+
+ time.sleep(self.interval)
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# This is a Thread object for listening for MQTT Messages
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class UtilsThread(object):
+ def __init__(self):
+ thread = threading.Thread(target=self.run, args=())
+ thread.daemon = True # Daemonize thread
+ thread.start() # Start the execution
+
+ def run(self):
+ iotUtils.main()
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# This is a Thread object for HTTP-Server that listens for operations on RPi
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class ListenHTTPServerThread(object):
+ def __init__(self):
+ thread = threading.Thread(target=self.run, args=())
+ thread.daemon = True # Daemonize thread
+ thread.start() # Start the execution
+
+ def run(self):
+ httpServer.main()
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# This is a Thread object for Server that listens for XMPP Messages
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class ListenXMPPServerThread(object):
+ def __init__(self):
+ thread = threading.Thread(target=self.run, args=())
+ thread.daemon = True # Daemonize thread
+ thread.start() # Start the execution
+
+ def run(self):
+ xmppServer.main()
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# This is a Thread object for listening for MQTT Messages
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class ListenMQTTThread(object):
+ def __init__(self):
+ thread = threading.Thread(target=self.run, args=())
+ thread.daemon = True # Daemonize thread
+ thread.start() # Start the execution
+
+ def run(self):
+ mqttListener.main()
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# The Main method of the RPi Agent
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+def main():
+ configureLogger("WSO2IOT_RPiStats")
+# iotUtils.setUpGPIOPins()
+
+ UtilsThread()
+ registerDeviceIP() # Call the register endpoint and register Device IP
+ 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
+ ListenXMPPServerThread()
+ ListenMQTTThread()
+
+ while True:
+ try:
+ if iotUtils.LAST_TEMP > 0: # Push data only if there had been a successful temperature read
+ connectAndPushData() # Push Sensor (Temperature) data to WSO2 BAM
+ time.sleep(PUSH_INTERVAL)
+ except (KeyboardInterrupt, Exception) as e:
+ print "RASPBERRY_STATS: Exception in RaspberryAgentThread (either KeyboardInterrupt or Other)"
+ print ("RASPBERRY_STATS: " + str(e))
+ print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
+ pass
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+if __name__ == "__main__":
+ main()
diff --git a/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/getMac.sh b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/getMac.sh
new file mode 100755
index 0000000000..0b35872df2
--- /dev/null
+++ b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/getMac.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+"""
+/**
+* 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.
+**/
+"""
+
+piMac=`/sbin/ifconfig | grep 'wlan0' | tr -s ' ' | cut -d ' ' -f5 | tr -d ':'`
+echo The device ID is $piMac
diff --git a/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/httpServer.py b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/httpServer.py
new file mode 100755
index 0000000000..c31a7bb8a0
--- /dev/null
+++ b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/httpServer.py
@@ -0,0 +1,134 @@
+#!/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 BaseHTTPServer
+import iotUtils
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# HOST and PORT info of the HTTP Server that gets started
+# HOST_NAME is initialised in the main() method
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#global HOST_NAME
+#HOST_NAME = "0.0.0.0"
+
+SERVER_PORT = 80 # Maybe set this to 9000.
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Class that handles HTTP GET requests for operations on the RPi
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+ def do_GET(request):
+ # """Respond to a GET request."""
+
+ if not processURLPath(request.path):
+ return
+
+ resource = request.path.split("/")[1].upper()
+ state = request.path.split("/")[2].upper()
+ print "HTTP_SERVER: Resource - " + resource
+
+ if resource == "TEMP":
+ request.send_response(200)
+ request.send_header("Content-type", "text/plain")
+ request.end_headers()
+ request.wfile.write(iotUtils.LAST_TEMP)
+
+ elif resource == "BULB":
+ iotUtils.switchBulb(state)
+ print "HTTP_SERVER: Requested Switch State - " + state
+
+ elif resource == "SONAR":
+ request.send_response(200)
+ request.send_header("Content-type", "text/plain")
+ request.end_headers()
+ request.wfile.write(iotUtils.LAST_DISTANCE)
+
+ print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Check the URL string of the request and validate
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+def processURLPath(path):
+ if path.count("/") != 2 and not "favicon" in path:
+ print "HTTP_SERVER: Invalid URL String: " + path
+ return False
+
+ resource = path.split("/")[1]
+
+ if not iequal("BULB", resource) and not iequal("TEMP", resource) and not iequal("FAN", resource) and not iequal("SONAR", resource):
+ if not "favicon" in resource:
+ print "HTTP_SERVER: Invalid resource - " + resource + " to execute operation"
+ return False
+
+ return True
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Case-Insensitive check on whether two string are similar
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+def iequal(a, b):
+ try:
+ return a.upper() == b.upper()
+ except AttributeError:
+ return a == b
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# The Main method of the server script
+# This method is invoked from RaspberryStats.py on a new thread
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+def main():
+ HOST_NAME = iotUtils.getDeviceIP()
+ server_class = BaseHTTPServer.HTTPServer
+
+ while True:
+ try:
+ httpd = server_class((HOST_NAME, SERVER_PORT), MyHandler)
+ print "HTTP_SERVER: " + time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, SERVER_PORT)
+
+ httpd.serve_forever()
+ except (KeyboardInterrupt, Exception) as e:
+ print "HTTP_SERVER: Exception in HttpServerThread (either KeyboardInterrupt or Other)"
+ print ("HTTP_SERVER: " + str(e))
+
+ iotUtils.switchBulb("OFF")
+ httpd.server_close()
+ print "HTTP_SERVER: " + time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, SERVER_PORT)
+ print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
+ pass
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+if __name__ == '__main__':
+ main()
+
diff --git a/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/iotUtils.py b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/iotUtils.py
new file mode 100755
index 0000000000..bd9faea404
--- /dev/null
+++ b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/iotUtils.py
@@ -0,0 +1,200 @@
+#!/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, commands
+import RPi.GPIO as GPIO
+import ConfigParser
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# HOST_NAME(IP) of the Device
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+global HOST_NAME
+HOST_NAME = "0.0.0.0"
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+global LAST_TEMP
+LAST_TEMP = 25 # The Last read temperature value from the DHT sensor. Kept globally
+ # Updated by the temperature reading thread
+
+global LAST_DISTANCE
+LAST_DISTANCE = 100
+
+SONAR_TRIG_PIN = 16 #Associate pin 23 to TRIG
+SONAR_ECHO_PIN = 18
+BULB_PIN = 11 # The GPIO Pin# in RPi to which the LED is connected
+
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Device specific info when pushing data to server
+# Read from a file "deviceConfigs.cfg" in the same folder level
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+configParser = ConfigParser.RawConfigParser()
+configFilePath = r'./deviceConfigs.cfg'
+configParser.read(configFilePath)
+
+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')
+
+DEVICE_INFO = '{"owner":"'+ DEVICE_OWNER + '","deviceId":"' + DEVICE_ID + '","reply":'
+DEVICE_IP = '"{ip}","value":'
+DEVICE_DATA = '"{temperature}"' # '"{temperature}:{load}:OFF"'
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Method used to switch ON/OFF the LED attached to RPi
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+def switchBulb(state):
+ print "Requested Switch State: " + state
+
+ if state == "ON":
+ GPIO.output(BULB_PIN, True)
+ print "BULB Switched ON"
+ elif state == "OFF":
+ GPIO.output(BULB_PIN, False)
+ print "BULB Switched OFF"
+
+ print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Get the wlan0 interface via which the RPi is connected
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+def getDeviceIP():
+ rPi_IP = commands.getoutput("ip route list | grep 'src '").split()
+ rPi_IP = rPi_IP[rPi_IP.index('src') + 1]
+
+ if len(rPi_IP)<=16:
+ print "------------------------------------------------------------------------------------"
+ print "IOT_UTILS: IP Address of RaspberryPi: " + rPi_IP
+ print "------------------------------------------------------------------------------------"
+ return rPi_IP
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Set the GPIO pin modes for the ones to be read
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+def setUpGPIOPins():
+ try:
+ GPIO.setwarnings(False)
+ GPIO.setmode(GPIO.BOARD)
+ except Exception as e:
+ print "IOT_UTILS: Exception at 'GPIO.setmode'"
+ print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
+ pass
+
+ GPIO.setup(SONAR_TRIG_PIN,GPIO.OUT) #Set pin as GPIO out
+ GPIO.setup(SONAR_ECHO_PIN,GPIO.IN) #Set pin as GPIO in
+ GPIO.setup(BULB_PIN, GPIO.OUT)
+ GPIO.output(BULB_PIN, False)
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# This method get the CPU Temperature of the Raspberry Pi
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+def getCPUTemp():
+ CPU_TEMP_LOC = "/sys/class/thermal/thermal_zone0/temp" # RaspberryPi file location to get CPU TEMP info
+ tempFile = open(CPU_TEMP_LOC)
+ cpuTemp = tempFile.read()
+ cpuTemp = long(float(cpuTemp))
+ cpuTemp = cpuTemp * 1.0 / 1000.0
+ print "The CPU temperature is: %.2f" % cpuTemp
+ return cpuTemp
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# This method get the CPU Load of the Raspberry Pi
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+def getCPULoad():
+ CPU_LOAD_LOC = "/proc/loadavg" # RaspberryPi file location to get CPU LOAD info
+ loadFile = open(CPU_LOAD_LOC)
+ cpuLoad = loadFile.read()
+ cpuLoad = cpuLoad.split()[0]
+ cpuLoad = long(float(cpuLoad))
+ print "The CPU temperature is: %.2f" % cpuLoad
+ return cpuLoad
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+def readSonarDistance():
+ global LAST_DISTANCE
+ try:
+ GPIO.output(SONAR_TRIG_PIN, False) #Set TRIG as LOW
+ print "IOT_UTILS: Waitng For Sonar Sensor To Settle"
+ time.sleep(0.5) #Delay of 2 seconds
+
+ GPIO.output(SONAR_TRIG_PIN, True) #Set TRIG as HIGH
+ time.sleep(0.00001) #Delay of 0.00001 seconds
+ GPIO.output(SONAR_TRIG_PIN, False) #Set TRIG as LOW
+
+ while GPIO.input(SONAR_ECHO_PIN)==0: #Check whether the ECHO is LOW
+ pulse_start = time.time() #Saves the last known time of LOW pulse
+
+ while GPIO.input(SONAR_ECHO_PIN)==1: #Check whether the ECHO is HIGH
+ pulse_end = time.time() #Saves the last known time of HIGH pulse
+
+ pulse_duration = pulse_end - pulse_start #Get pulse duration to a variable
+
+ distance = pulse_duration * 17150 #Multiply pulse duration by 17150 to get distance
+ distance = round(distance, 2) #Round to two decimal points
+
+ if distance > 2 and distance < 400: #Check whether the distance is within range
+ print "IOT_UTILS: Distance: ", distance - 0.5,"cm" #Print distance with 0.5 cm calibration
+ LAST_DISTANCE = distance
+ else:
+ print "IOT_UTILS: Out Of Range" #display out of range
+
+ except Exception, e:
+ print "IOT_UTILS: Exception in SonarReaderThread: Could not successfully read Sonar"
+ print ("IOT_UTILS: " + str(e))
+ print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
+
+
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# The Main method of the server script
+# This method is invoked from RaspberryStats.py on a new thread
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+def main():
+ global HOST_NAME
+ HOST_NAME = getDeviceIP()
+ setUpGPIOPins()
+
+ while True:
+ readSonarDistance()
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+if __name__ == '__main__':
+ main()
+
diff --git a/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/mqttListener.py b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/mqttListener.py
new file mode 100755
index 0000000000..e36d0eee79
--- /dev/null
+++ b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/mqttListener.py
@@ -0,0 +1,109 @@
+#!/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 RPi.GPIO as GPIO
+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)
+ client.subscribe(TOPIC)
+
+
+
+# The callback for when a PUBLISH message is received from the server.
+def on_message(client, userdata, msg):
+ 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)
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# 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[0]
+ MQTT_PORT = MQTT_ENDPOINT[1]
+
+ DEV_OWNER = iotUtils.DEVICE_OWNER
+ DEV_ID = iotUtils.DEVICE_ID
+
+ global TOPIC
+ TOPIC = "wso2/iot/" + DEV_OWNER + "/firealarm/" + DEV_ID
+
+ print ("MQTT_LISTENER: MQTT_ENDPOINT is " + str(MQTT_ENDPOINT))
+ print ("MQTT_LISTENER: MQTT_TOPIC is " + TOPIC)
+
+ mqttClient = mqtt.Client()
+ mqttClient.on_connect = on_connect
+ mqttClient.on_message = on_message
+
+ while True:
+ try:
+ mqttClient.connect(MQTT_IP, MQTT_PORT, 60)
+ 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/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/org.eclipse.paho.mqtt.python.tar b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/org.eclipse.paho.mqtt.python.tar
new file mode 100644
index 0000000000..5f65105b8f
Binary files /dev/null and b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/org.eclipse.paho.mqtt.python.tar differ
diff --git a/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/xmppServer.py b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/xmppServer.py
new file mode 100755
index 0000000000..199d145734
--- /dev/null
+++ b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/src/xmppServer.py
@@ -0,0 +1,145 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+/*
+ * Copyright (c) 2014, 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.
+ */
+"""
+
+import sleekxmpp
+import getpass
+import sys
+import ssl, pyasn1
+
+from urllib import urlopen
+import iotUtils
+
+# Python versions before 3.0 do not use UTF-8 encoding
+# by default. To ensure that Unicode is handled properly
+# throughout SleekXMPP, we will set the default encoding
+# ourselves to UTF-8.
+if sys.version_info < (3, 0):
+ from sleekxmpp.util.misc_ops import setdefaultencoding
+ setdefaultencoding('utf8')
+else:
+ raw_input = input
+
+from sleekxmpp.plugins.xep_0323.device import Device
+
+class IoT_TestDevice(sleekxmpp.ClientXMPP):
+ """
+ A simple IoT device that can act as server or client
+ """
+ def __init__(self, jid, password):
+ 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.beServer=True
+
+ def beClientOrServer(self,server=True,clientJID=None ):
+ self.beServer=True
+
+ def testForRelease(self):
+ # todo thread safe
+ return self.releaseMe
+
+ def doReleaseMe(self):
+ # todo thread safe
+ self.releaseMe=True
+
+ def addDevice(self, device):
+ self.device=device
+
+ def session_start(self, event):
+ self.send_presence()
+ self.get_roster()
+ # tell your preffered friend that you are alive
+ #self.send_message(mto='jocke@jabber.sust.se', mbody=self.boundjid.bare +' is now online use xep_323 stanza to talk to me')
+
+ def message(self, msg):
+ if msg['type'] in ('chat', 'normal'):
+ print ("XMPP_SERVER: Got normal chat message" + str(msg))
+ ip = urlopen('http://icanhazip.com').read()
+ msg.reply("XMPP_SERVER: Hi I am " + self.boundjid.full + " and I am on IP " + ip).send()
+ else:
+ print ("XMPP_SERVER: 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)
+
+ def refresh(self,fields):
+ """
+ the implementation of the refresh method
+ """
+# global LAST_TEMP
+ #self._set_momentary_timestamp(self._get_timestamp())
+ #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(iotUtils.LAST_TEMP), flags={"automaticReadout": "true"})
+
+def main():
+ XMPP_ENDP = iotUtils.XMPP_EP.split(":")[0]
+
+ XMPP_OWN = iotUtils.DEVICE_OWNER
+ XMPP_JID = iotUtils.DEVICE_ID + "@" + XMPP_ENDP + "/raspi"
+ XMPP_PWD = iotUtils.AUTH_TOKEN
+
+ print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
+ print "XMPP_SERVER: Owner - " + XMPP_OWN
+ print "XMPP_SERVER: AccountID - " + XMPP_JID
+ print "XMPP_SERVER: AccountPass - " + XMPP_PWD
+ print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
+
+ xmpp = IoT_TestDevice(XMPP_JID,XMPP_PWD)
+ xmpp.ssl_version = ssl.PROTOCOL_SSLv3
+
+ xmpp.register_plugin('xep_0030')
+ xmpp.register_plugin('xep_0323')
+ xmpp.register_plugin('xep_0325')
+
+ if XMPP_OWN:
+ # xmpp['xep_0030'].add_feature(feature='urn:xmpp:sn',
+ # node=opts.nodeid,
+ # jid=xmpp.boundjid.full)
+
+ myDevice = TheDevice(XMPP_OWN)
+ # myDevice._add_field(name="Relay", typename="numeric", unit="Bool");
+ myDevice._add_field(name="Temperature", typename="numeric", unit="C")
+ myDevice._set_momentary_timestamp("2013-03-07T16:24:30")
+ myDevice._add_field_momentary_data("Temperature", "23.4", flags={"automaticReadout": "true"})
+
+ xmpp['xep_0323'].register_node(nodeId=XMPP_OWN, device=myDevice, commTimeout=10)
+ xmpp.beClientOrServer(server=True)
+
+ while not(xmpp.testForRelease()):
+ try:
+ xmpp.connect()
+ xmpp.process(block=True)
+ print ("XMPP_SERVER: Lost Connection")
+ except Exception as e:
+ print "XMPP_SERVER: Exception in XMPPServerThread (either KeyboardInterrupt or Other)"
+ print ("XMPP_SERVER: " + str(e))
+
+if __name__ == '__main__':
+ main()
diff --git a/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/startservice.sh b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/startservice.sh
new file mode 100755
index 0000000000..321e973c9f
--- /dev/null
+++ b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/agent/startservice.sh
@@ -0,0 +1,94 @@
+#!/bin/bash
+
+echo "----------------------------------------------------------------"
+echo "| WSO2 IOT Sample "
+echo "| RaspiAlarm "
+echo "| ---------------- "
+echo "| ....initializing startup-script "
+echo "----------------------------------------------------------------"
+
+currentDir=$PWD
+
+cd /var/lib/dpkg/info
+sudo rm -rf wso2-raspi-alarm*
+dpkg --remove --force-remove-reinstreq wso2-raspi-alarm
+
+while true; do
+ read -p "Do you wish to run 'apt-get update' and continue? [Yes/No] " yn
+ case $yn in
+ [Yy]* ) sudo apt-get update;
+ break;;
+ [Nn]* ) echo "Continuing without apt-get update...";
+ break;;
+ * ) echo "Please answer yes or no.";
+ esac
+done
+
+if [ $? -ne 0 ]; then
+ echo "apt-get update failed.... Some dependencies may not get installed"
+ echo "If an already installed version of the package exists, try running:"
+ echo "----------------------------------------------------------------"
+ echo "sudo -i"
+ echo "cd /var/lib/dpkg/info"
+ echo "rm -rf wso2-raspi-alarm*"
+ echo "dpkg --remove --force-remove-reinstreq wso2-raspi-alarm"
+ echo "exit"
+ echo "----------------------------------------------------------------"
+ echo "Retry Installation...."
+ break;
+fi
+
+
+for f in ./deviceConfigs.cfg; do
+ ## Check if the glob gets expanded to existing files.
+ ## If not, f here will be exactly the pattern above
+ ## and the exists test will evaluate to false.
+ # [ -e "$f" ] && echo "'wso2-raspi-alarm_1.0_armhf.deb' file found and installing" || echo "'wso2-raspi-alarm_1.0_armhf.deb' file does not exist in current path"; exit;
+ if [ -e "$f" ]; then
+ echo "Configuration file found......"
+ else
+ echo "'deviceConfigs.cfg' file does not exist in current path. \nExiting installation...";
+ exit;
+ fi
+ ## This is all we needed to know, so we can break after the first iteration
+ break
+done
+
+cd $currentDir
+git clone git://git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.python.git
+cd org.eclipse.paho.mqtt.python
+sudo python setup.py install
+
+cd $currentDir
+
+#sudo apt-get install python-pip
+sudo pip install sleekxmpp
+sudo pip install pyasn1 pyasn1-modules
+
+
+echo "Running the RaspberryAgent service...."
+# sudo service RaspberryService.sh start
+
+while true; do
+ read -p "Whats the time-interval (in seconds) between successive Data-Pushes to the WSO2-DC (ex: '60' indicates 1 minute) > " input
+
+ if [ $input -eq $input 2>/dev/null ]
+ then
+ echo "Setting data-push interval to $input seconds."
+ break;
+ else
+ echo "Input needs to be an integer indicating the number seconds between successive data-pushes."
+ fi
+done
+
+sudo nohup ./RaspberryStats.py -i $input > /dev/null 2>&1 &
+
+if [ $? -ne 0 ]; then
+ echo "Could not start the service..."
+ exit;
+fi
+
+
+echo "--------------------------------------------------------------------------"
+echo "| Successfully Started "
+echo "---------------------------------------------------------------------------"
diff --git a/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.type-view/private/conf/device-type.json b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.type-view/private/conf/device-type.json
index d7662e6a6d..5811e89ef5 100644
--- a/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.type-view/private/conf/device-type.json
+++ b/features/device-mgt-iot-raspberrypi-feature/org.wso2.carbon.device.mgt.iot.raspberrypi.feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.raspberrypi.type-view/private/conf/device-type.json
@@ -2,7 +2,7 @@
"deviceType": {
"label": "RaspberryPi",
"category": "iot",
- "downloadAgentUri": "https://localhost:9443/raspberrypi/RaspberryPiDeviceManager/manager/device/raspberrypi/download",
- "downloadAgentLinkGenUri" : "https://localhost:9443/raspberrypi/RaspberryPiDeviceManager/manager/device/raspberrypi/generate_link"
+ "downloadAgentUri": "RaspberryPiDeviceManager/manager/device/raspberrypi/download",
+ "downloadAgentLinkGenUri" : "RaspberryPiDeviceManager/manager/device/raspberrypi/generate_link"
}
}
\ No newline at end of file
diff --git a/features/device-mgt-iot-virtualfirealarm-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/advanced_agent/deviceConfig.properties b/features/device-mgt-iot-virtualfirealarm-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/advanced_agent/deviceConfig.properties
index 0e2be4403e..f76a969f72 100644
--- a/features/device-mgt-iot-virtualfirealarm-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/advanced_agent/deviceConfig.properties
+++ b/features/device-mgt-iot-virtualfirealarm-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/advanced_agent/deviceConfig.properties
@@ -19,7 +19,7 @@
owner=${DEVICE_OWNER}
deviceId=${DEVICE_ID}
device-name=${DEVICE_NAME}
-controller-context=/virtual_firealarm/controller
+controller-context=/virtual_firealarm/VirtualFireAlarmDeviceManager/controller
https-ep=${HTTPS_EP}
http-ep=${HTTP_EP}
apim-ep=${APIM_EP}
diff --git a/features/device-mgt-iot-virtualfirealarm-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/agent/deviceConfig.properties b/features/device-mgt-iot-virtualfirealarm-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/agent/deviceConfig.properties
index 0e2be4403e..f76a969f72 100644
--- a/features/device-mgt-iot-virtualfirealarm-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/agent/deviceConfig.properties
+++ b/features/device-mgt-iot-virtualfirealarm-feature/org.wso2.carbon.device.mgt.iot.virtualfirealarm.feature/src/main/resources/agent/deviceConfig.properties
@@ -19,7 +19,7 @@
owner=${DEVICE_OWNER}
deviceId=${DEVICE_ID}
device-name=${DEVICE_NAME}
-controller-context=/virtual_firealarm/controller
+controller-context=/virtual_firealarm/VirtualFireAlarmDeviceManager/controller
https-ep=${HTTPS_EP}
http-ep=${HTTP_EP}
apim-ep=${APIM_EP}
diff --git a/pom.xml b/pom.xml
index a4cbec451a..f3dbe262a3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -48,10 +48,10 @@
components/device-mgt-iot-androidsense
-
+ components/device-mgt-iot-arduino
components/device-mgt-iot-digitaldisplay
components/device-mgt-iot-droneanalyzer
-
+ components/device-mgt-iot-raspberrypi
components/device-mgt-iot-virtualfirealarm
@@ -64,10 +64,10 @@
features/device-mgt-iot-androidsense-feature
-
+ features/device-mgt-iot-arduino-feature
features/device-mgt-iot-digitaldisplay-feature
features/device-mgt-iot-droneanalyzer-feature
-
+ features/device-mgt-iot-raspberrypi-feature
features/device-mgt-iot-virtualfirealarm-feature