forked from community/device-mgt-plugins
Merge pull request #60 from Shabirmean/IoTS-1.0.0-M1
Added complete RaspberryPi Component and Feature
commit
561d46a377
@ -0,0 +1,149 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>device-mgt-iot-raspberrypi</artifactId>
|
||||
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
|
||||
<version>1.9.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>org.wso2.carbon.device.mgt.iot.raspberrypi.service.impl</artifactId>
|
||||
<version>1.9.2-SNAPSHOT</version>
|
||||
<packaging>war</packaging>
|
||||
<name>WSO2 Carbon - IoT Server RaspberryPi API</name>
|
||||
<description>WSO2 Carbon - RaspberryPi Service API Implementation</description>
|
||||
<url>http://wso2.org</url>
|
||||
|
||||
<dependencies>
|
||||
<!-- CDM -->
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.device.mgt.core</artifactId>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.apache.axis2.wso2</groupId>
|
||||
<artifactId>axis2-client</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!--CXF -->
|
||||
<dependency>
|
||||
<groupId>org.apache.cxf</groupId>
|
||||
<artifactId>cxf-rt-frontend-jaxws</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cxf</groupId>
|
||||
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cxf</groupId>
|
||||
<artifactId>cxf-rt-transports-http</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!--MQTT -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.paho</groupId>
|
||||
<artifactId>mqtt-client</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!--IOT -->
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpasyncclient</artifactId>
|
||||
<version>4.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
|
||||
<artifactId>org.wso2.carbon.device.mgt.iot</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt-plugins</groupId>
|
||||
<artifactId>org.wso2.carbon.device.mgt.iot.raspberrypi.plugin.impl</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!--JAX-RS -->
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-core-asl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-jaxrs</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax</groupId>
|
||||
<artifactId>javaee-web-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>jsr311-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.device.mgt.analytics</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<encoding>UTF-8</encoding>
|
||||
<source>${wso2.maven.compiler.source}</source>
|
||||
<target>${wso2.maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<warName>raspberrypi</warName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -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<String, String> 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<Device> userDevices = deviceManagement.getDeviceManagementService().getDevicesOfUser(username);
|
||||
ArrayList<Device> 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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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<HttpResponse> future = httpclient.execute(
|
||||
request, new FutureCallback<HttpResponse>() {
|
||||
@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;
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
|
||||
<!--
|
||||
~ Copyright 2005-2013 WSO2, Inc. (http://wso2.com)
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<!--
|
||||
This file defines class loading policy of the whole container. But this behaviour can be overridden by individual webapps by putting this file into the META-INF/ directory.
|
||||
-->
|
||||
<Classloading xmlns="http://wso2.org/projects/as/classloading">
|
||||
|
||||
<!-- Parent-first or child-first. Default behaviour is child-first.-->
|
||||
<ParentFirst>false</ParentFirst>
|
||||
|
||||
<!--
|
||||
Default environments that contains provides to all the webapps. This can be overridden by individual webapps by specifing required environments
|
||||
Tomcat environment is the default and every webapps gets it even if they didn't specify it.
|
||||
e.g. If a webapps requires CXF, they will get both Tomcat and CXF.
|
||||
-->
|
||||
<Environments>CXF,Carbon</Environments>
|
||||
</Classloading>
|
@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">
|
||||
|
||||
|
||||
|
||||
|
||||
<jaxrs:server id="RaspberryPi" address="/">
|
||||
<jaxrs:serviceBeans>
|
||||
<bean id="RaspberryPiService"
|
||||
class="org.wso2.carbon.device.mgt.iot.raspberrypi.service.RaspberryPiService">
|
||||
<property name="raspberryPiMQTTSubscriber" ref="mqttSubscriberBean"/>
|
||||
</bean>
|
||||
</jaxrs:serviceBeans>
|
||||
<jaxrs:providers>
|
||||
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
|
||||
</jaxrs:providers>
|
||||
</jaxrs:server>
|
||||
|
||||
<bean id="mqttSubscriberBean"
|
||||
class="org.wso2.carbon.device.mgt.iot.raspberrypi.service.transport.RaspberryPiMQTTSubscriber">
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<web-app version="2.5"
|
||||
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
||||
metadata-complete="true">
|
||||
<display-name>RaspberryPi</display-name>
|
||||
<description>RaspberryPi</description>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>CXFServlet</servlet-name>
|
||||
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>CXFServlet</servlet-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<context-param>
|
||||
<param-name>isAdminService</param-name>
|
||||
<param-value>false</param-value>
|
||||
</context-param>
|
||||
<context-param>
|
||||
<param-name>doAuthentication</param-name>
|
||||
<param-value>false</param-value>
|
||||
</context-param>
|
||||
|
||||
<!--publish to apim-->
|
||||
<context-param>
|
||||
<param-name>managed-api-enabled</param-name>
|
||||
<param-value>true</param-value>
|
||||
</context-param>
|
||||
<context-param>
|
||||
<param-name>managed-api-owner</param-name>
|
||||
<param-value>admin</param-value>
|
||||
</context-param>
|
||||
<context-param>
|
||||
<param-name>managed-api-name</param-name>
|
||||
<param-value>raspberrypi</param-value>
|
||||
</context-param>
|
||||
<context-param>
|
||||
<param-name>managed-api-endpoint</param-name>
|
||||
<param-value>http://localhost:9763/raspberrypi</param-value>
|
||||
</context-param>
|
||||
<context-param>
|
||||
<param-name>managed-api-version</param-name>
|
||||
<param-value>1.0.0</param-value>
|
||||
</context-param>
|
||||
<context-param>
|
||||
<param-name>managed-api-context</param-name>
|
||||
<param-value>/raspberrypi</param-value>
|
||||
</context-param>
|
||||
<context-param>
|
||||
<param-name>managed-api-context-template</param-name>
|
||||
<param-value>/raspberrypi/{version}</param-value>
|
||||
</context-param>
|
||||
<context-param>
|
||||
<param-name>managed-api-application</param-name>
|
||||
<param-value>raspberrypi</param-value>
|
||||
</context-param>
|
||||
<context-param>
|
||||
<param-name>managed-api-isSecured</param-name>
|
||||
<param-value>true</param-value>
|
||||
</context-param>
|
||||
|
||||
|
||||
</web-app>
|
@ -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 &
|
@ -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
|
Binary file not shown.
@ -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()
|
@ -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
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
Binary file not shown.
@ -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()
|
@ -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 "---------------------------------------------------------------------------"
|
Loading…
Reference in new issue