forked from community/device-mgt-plugins
Merge pull request #92 from GPrathap/IoTS-1.0.0-M1
updated Raspberry Pi agent: enable secure HTTPS communication
commit
e2bbb47b59
@ -1,192 +0,0 @@
|
||||
/*
|
||||
* 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.droneanalyzer.service.transport;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jivesoftware.smack.*;
|
||||
import org.jivesoftware.smack.filter.AndFilter;
|
||||
import org.jivesoftware.smack.filter.PacketFilter;
|
||||
import org.jivesoftware.smack.filter.PacketTypeFilter;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
|
||||
import org.wso2.carbon.device.mgt.iot.droneanalyzer.service.trasformer.MessageTransformer;
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Created by geesara on 12/7/15.
|
||||
*/
|
||||
public class DroneXMPPConnector {
|
||||
|
||||
private static Log log = LogFactory.getLog(DroneXMPPConnector.class);
|
||||
|
||||
// XmppManager xmppManager;
|
||||
|
||||
private MessageTransformer messageController;
|
||||
private static String xmppServerIP;
|
||||
private static int xmppServerPort;
|
||||
private static String xmppAdminUsername;
|
||||
private static String xmppAdminPassword;
|
||||
private static String xmppAdminAccountJID;
|
||||
|
||||
public DroneXMPPConnector(MessageTransformer messageController) {
|
||||
this.messageController = messageController;
|
||||
initConnector();
|
||||
}
|
||||
|
||||
|
||||
public void initConnector() {
|
||||
/* xmppServerIP = XmppConfig.getInstance().getXmppServerIP();
|
||||
xmppAdminUsername = XmppConfig.getInstance().getXmppUsername();
|
||||
xmppAdminPassword = XmppConfig.getInstance().getXmppPassword();
|
||||
xmppAdminAccountJID = xmppAdminUsername + "@" + xmppServerIP;*/
|
||||
xmppServerPort = 5222;
|
||||
xmppServerIP = "localhost";
|
||||
xmppAdminUsername = "admin";
|
||||
xmppAdminPassword = "admin";
|
||||
xmppAdminAccountJID = xmppAdminUsername + "@" + xmppServerIP;
|
||||
}
|
||||
|
||||
/*public void connectAndLogin() {
|
||||
try {
|
||||
super.connectAndLogin(xmppAdminUsername, xmppAdminPassword, null);
|
||||
super.setMessageFilterOnReceiver(xmppAdminAccountJID);
|
||||
} catch (DeviceManagementException e) {
|
||||
log.error("Connect/Login attempt to XMPP Server at: " + xmppServerIP + " failed");
|
||||
retryXMPPConnection();
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
private XMPPConnection xmppConnection;
|
||||
|
||||
public void connect(String server, int port) throws Exception {
|
||||
if(xmppConnection == null){
|
||||
xmppConnection = new XMPPConnection(new ConnectionConfiguration(server, port));
|
||||
xmppConnection.connect();
|
||||
}else{
|
||||
System.out.println("Already user is connected");
|
||||
}
|
||||
/*xmppConnection = new XMPPConnection(new ConnectionConfiguration(server, port));
|
||||
xmppConnection.connect();*/
|
||||
}
|
||||
|
||||
public void disconnect(){
|
||||
if(xmppConnection != null){
|
||||
xmppConnection.disconnect();
|
||||
//interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public void login(String username, String password) throws Exception{
|
||||
printRoster();
|
||||
connect( xmppServerIP, xmppServerPort);
|
||||
xmppConnection.login(username, password);
|
||||
}
|
||||
|
||||
public void run(){
|
||||
try {
|
||||
System.out.println(xmppAdminAccountJID+xmppAdminPassword);
|
||||
login(xmppAdminAccountJID, xmppAdminPassword);
|
||||
System.out.println("Login successful");
|
||||
listeningForMessages();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void listeningForMessages() {
|
||||
PacketFilter filter = new AndFilter(new PacketTypeFilter(Message.class));
|
||||
PacketCollector collector = xmppConnection.createPacketCollector(filter);
|
||||
while (true) {
|
||||
System.out.println("waiting ...");
|
||||
Packet packet = collector.nextResult();
|
||||
if (packet instanceof Message) {
|
||||
Message inbound_message = (Message) packet;
|
||||
if (inbound_message != null && inbound_message.getBody() != null){
|
||||
System.out.println(inbound_message.getBody());
|
||||
messageController.messageTranslater(inbound_message.getBody());
|
||||
}
|
||||
|
||||
} else {
|
||||
log.error("Message has been corrupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void printRoster() throws Exception {
|
||||
if(xmppConnection != null){
|
||||
Roster roster = xmppConnection.getRoster();
|
||||
if(roster !=null && roster.getEntries() != null){
|
||||
Collection<RosterEntry> entries = roster.getEntries();
|
||||
for (RosterEntry entry : entries) {
|
||||
System.out.println(String.format("Buddy:%1$s - Status:%2$s",
|
||||
entry.getName(), entry.getStatus()));
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
System.out.println("There are no users");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* private void retryXMPPConnection() {
|
||||
Thread retryToConnect = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
while (true) {
|
||||
if (!isConnected()) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Re-trying to reach XMPP Server....");
|
||||
}
|
||||
|
||||
try {
|
||||
VirtualFireAlarmXMPPConnector.super.connectAndLogin(xmppAdminUsername,
|
||||
xmppAdminPassword,
|
||||
null);
|
||||
VirtualFireAlarmXMPPConnector.super.setMessageFilterOnReceiver(
|
||||
xmppAdminAccountJID);
|
||||
} catch (DeviceManagementException e1) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Attempt to re-connect to XMPP-Server failed");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e1) {
|
||||
log.error("XMPP: Thread Sleep Interrupt Exception");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
retryToConnect.setDaemon(true);
|
||||
retryToConnect.start();
|
||||
}*/
|
||||
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
package org.wso2.carbon.device.mgt.iot.droneanalyzer.service;
|
||||
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.cxf.jaxrs.client.WebClient;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import org.wso2.carbon.device.mgt.common.Device;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class DroneServiceTest {
|
||||
|
||||
private static org.apache.commons.logging.Log log = LogFactory.getLog(DroneServiceTest.class);
|
||||
ApplicationContext context;
|
||||
WebClient client;
|
||||
|
||||
@Before
|
||||
public void init(){
|
||||
context = new ClassPathXmlApplicationContext("spring-cxf-client.xml");
|
||||
client = context.getBean("droneClient", WebClient.class);
|
||||
}
|
||||
//@Test
|
||||
public void registerDevice(){
|
||||
client.path("manager/device/register").accept(MediaType.APPLICATION_JSON_TYPE);
|
||||
client.query("deviceId", "device7");
|
||||
client.query("name", "dronetypeOne");
|
||||
client.query("owner", "DroneOwner");
|
||||
Response res = client.put(null);
|
||||
log.info("Response status :"+ res.getStatus());
|
||||
System.out.println("Response status :"+ res.getStatus());
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void removeDevice(){
|
||||
client.path("manager/device/remove/").accept(MediaType.APPLICATION_JSON_TYPE);
|
||||
client.path("device7");
|
||||
Response res = client.delete();
|
||||
log.info("Response status :"+ res.getStatus());
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void updateDevice(){
|
||||
client.path("manager/device/update/").accept(MediaType.APPLICATION_JSON_TYPE);
|
||||
client.path("device2");
|
||||
client.query("name", "ARDrone");
|
||||
Response res = client.post(null);
|
||||
log.info("Response status :"+ res.getStatus());
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void getDevice(){
|
||||
client.path("manager/device/").accept(MediaType.APPLICATION_JSON_TYPE);
|
||||
client.path("device2");
|
||||
Device res = client.get(Device.class);
|
||||
log.info("Device name :"+ res.getName());
|
||||
log.info("Device type :"+ res.getType());
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void getDroneDevices(){
|
||||
client.path("manager/devices/").accept(MediaType.APPLICATION_JSON_TYPE);
|
||||
client.path("DroneOwner");
|
||||
Collection<? extends Device> res = client.getCollection(Device.class);
|
||||
Iterator<? extends Device> iterator = res.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Device device = iterator.next();
|
||||
log.info("Device name :" + device.getName());
|
||||
log.info("Device type :"+ device.getType());
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void downloadSketch(){
|
||||
client.path("manager/devices/");
|
||||
client.path("type1");
|
||||
client.path("download").accept(MediaType.APPLICATION_OCTET_STREAM);
|
||||
Response res = client.get();
|
||||
log.info(res.getStatus());
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void droneController(){
|
||||
client.path("controller/send_command");
|
||||
client.query("owner", "DroneOwner");
|
||||
client.query("deviceId", "device2");
|
||||
client.query("action", "takeoff");
|
||||
client.query("speed", 5);
|
||||
client.query("duration", 56);
|
||||
client.accept(MediaType.APPLICATION_JSON);
|
||||
Response res = client.post(null);
|
||||
System.out.println(res.getStatus());
|
||||
}
|
||||
|
||||
public void generateSketchLink(){
|
||||
client.path("manager/devices/");
|
||||
client.path("type1");
|
||||
client.path("download").accept(MediaType.APPLICATION_OCTET_STREAM);
|
||||
Response res = client.get();
|
||||
log.info(res.getStatus());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package org.wso2.carbon.device.mgt.iot.droneanalyzer.service.transport;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
import org.wso2.carbon.device.mgt.iot.controlqueue.xmpp.XmppConfig;
|
||||
import org.wso2.carbon.utils.CarbonUtils;
|
||||
|
||||
/**
|
||||
* Created by geesara on 12/10/15.
|
||||
*/
|
||||
public class DroneAnalyzerXMPPConnectorTest {
|
||||
private static Log log = LogFactory.getLog(DroneAnalyzerXMPPConnectorTest.class);
|
||||
public DroneAnalyzerXMPPConnector droneAnalyzerXMPPConnector;
|
||||
|
||||
@BeforeClass
|
||||
public void setup(){
|
||||
//droneAnalyzerXMPPConnector = new DroneAnalyzerXMPPConnector();
|
||||
//droneAnalyzerXMPPConnector.initConnector();
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void login(){
|
||||
// droneAnalyzerXMPPConnector.connectAndLogin();
|
||||
// log.info("ip address "+XmppConfig.getInstance().getXmppServerIP());
|
||||
//log.info("path "+ CarbonUtils.getCarbonConfigDirPath());
|
||||
// log.info("path "+ CarbonUtils.getCarbonHome());
|
||||
//System.out.println(System.getProperty("carbon.home"));
|
||||
System.out.println(System.getenv("CARBON_HOME"));
|
||||
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
|
||||
|
||||
|
||||
<bean id="jacksonJsonProvider" class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"></bean>
|
||||
|
||||
<util:list id="webClientProviders">
|
||||
<ref bean="jacksonJsonProvider"/>
|
||||
</util:list>
|
||||
|
||||
<bean id="droneClient" class="org.apache.cxf.jaxrs.client.WebClient"
|
||||
factory-method="create">
|
||||
<constructor-arg type="java.lang.String" value="http://localhost:9763/drone_analyzer/DroneAnalyzerServiceUnitManager/"/>
|
||||
<constructor-arg ref="webClientProviders" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
@ -0,0 +1,38 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
--------------
|
||||
testRun.sh
|
||||
--------------
|
||||
This script is used to run this service in a testing environment. It can be run on a real Raspberry Pi device or
|
||||
a virtual environment.
|
||||
To run: sudo ./testRun.sh and follow the instructions.
|
||||
|
||||
-------------------
|
||||
startService.sh
|
||||
-------------------
|
||||
After testing, this script can be used to deploy this application as a service on Raspberry Pi which will get loaded
|
||||
during boot up process.
|
||||
To run: sudo ./startService.sh
|
||||
Note: You should have to provide following arguments in RaspberryService.sh as shown below.
|
||||
|
||||
DAEMON_OPTS="-l /usr/local/src/RaspberryAgent/RaspberryStats.log -m N -i 56"
|
||||
|
||||
-l ----> file to write log
|
||||
-i ----> time interval between successive data pushes to the wso2 IoT Server
|
||||
-m ----> weather is going to run on the real device or not
|
@ -1,20 +0,0 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
templates=deviceConfig.properties
|
||||
zipfilename=RaspberryPi.zip
|
@ -1,338 +0,0 @@
|
||||
#!/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 datetime
|
||||
|
||||
import running_mode
|
||||
|
||||
PUSH_INTERVAL = 5000 # time interval between successive data pushes in seconds
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# Logger defaults
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#LOG_FILENAME = "/usr/local/src/RaspberryAgent/logs/RaspberryStats.log"
|
||||
LOG_FILENAME = "RaspberryStats.log"
|
||||
logging_enabled = False
|
||||
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_for_data_push_interval = "time interval between successive data pushes (default '" + str(PUSH_INTERVAL) + "')"
|
||||
help_string_for_running_mode = "time interval between successive data pushes (default '" + str(PUSH_INTERVAL) + "')"
|
||||
parser.add_argument("-i", "--interval", type=int, help=help_string_for_data_push_interval)
|
||||
parser.add_argument("-m", "--mode", type=str, help=help_string_for_running_mode)
|
||||
|
||||
args = parser.parse_args()
|
||||
if args.log:
|
||||
LOG_FILENAME = args.log
|
||||
|
||||
if args.interval:
|
||||
PUSH_INTERVAL = args.interval
|
||||
|
||||
if args.mode:
|
||||
running_mode.RUNNING_MODE = args.mode
|
||||
iotUtils = __import__('iotUtils')
|
||||
httpServer = __import__('httpServer') # python script used to start a http-server to listen for operations
|
||||
# (includes the TEMPERATURE global variable)
|
||||
mqttListener = __import__('mqttListener') # python script used to accept messages via mqtt
|
||||
#xmppServer = __import__('xmppServer') # python script used to communicate with xmpp server
|
||||
|
||||
if running_mode.RUNNING_MODE == 'N':
|
||||
Adafruit_DHT = __import__('Adafruit_DHT') # Adafruit library required for temperature sensing
|
||||
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# Endpoint specific settings to which the data is pushed
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
DC_ENDPOINT = iotUtils.HTTP_EP.split(":")
|
||||
DC_IP = DC_ENDPOINT[1].replace('//', '')
|
||||
DC_PORT = int(DC_ENDPOINT[2])
|
||||
DC_ENDPOINT_CONTEXT = iotUtils.CONTROLLER_CONTEXT
|
||||
PUSH_ENDPOINT = str(DC_ENDPOINT_CONTEXT) + '/push_temperature/'
|
||||
REGISTER_ENDPOINT = str(DC_ENDPOINT_CONTEXT) + '/register'
|
||||
|
||||
HOST = iotUtils.getDeviceIP()
|
||||
HOST_HTTP_SERVER_PORT = iotUtils.getHTTPServerPort()
|
||||
HOST_AND_PORT = str(HOST)+ ":" + str(HOST_HTTP_SERVER_PORT)
|
||||
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# 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 = str(REGISTER_ENDPOINT) + '/' + str(iotUtils.DEVICE_OWNER) + '/' + str(iotUtils.DEVICE_ID) + '/' + \
|
||||
str(HOST) + '/' + str(HOST_HTTP_SERVER_PORT) + '/'
|
||||
dcConncection.putrequest('POST', registerURL)
|
||||
dcConncection.putheader('Authorization', 'Bearer ' + iotUtils.AUTH_TOKEN)
|
||||
dcConncection.endheaders()
|
||||
dcResponse = dcConncection.getresponse()
|
||||
|
||||
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
|
||||
print ('RASPBERRY_STATS: ' + str(registerURL))
|
||||
print ('RASPBERRY_STATS: ' + str(dcResponse.status))
|
||||
print ('RASPBERRY_STATS: ' + str(dcResponse.reason))
|
||||
print ('RASPBERRY_STATS: Response Message')
|
||||
print str(dcResponse.msg)
|
||||
|
||||
dcConncection.close()
|
||||
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
|
||||
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# 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)
|
||||
dcConnection.putheader('Authorization', 'Bearer ' + iotUtils.AUTH_TOKEN)
|
||||
dcConnection.putheader('Content-Type', 'application/json')
|
||||
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
### Read the Temperature and Load info of RPi and construct payload
|
||||
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
rPiTemperature = iotUtils.LAST_TEMP # Push the last read temperature value
|
||||
PUSH_DATA = iotUtils.DEVICE_INFO + iotUtils.DEVICE_IP.format(ip=HOST_AND_PORT) + iotUtils.DEVICE_DATA.format(
|
||||
temperature=rPiTemperature)
|
||||
PUSH_DATA += '}'
|
||||
dcConnection.putheader('Content-Length', len(PUSH_DATA))
|
||||
dcConnection.endheaders()
|
||||
|
||||
print PUSH_DATA
|
||||
print '~~~~~~~~~~~~~~~~~~~~~~~~ Pushing Device-Data ~~~~~~~~~~~~~~~~~~~~~~~~~'
|
||||
|
||||
dcConnection.send(PUSH_DATA) # Push the data
|
||||
dcResponse = dcConnection.getresponse()
|
||||
|
||||
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
|
||||
print ('RASPBERRY_STATS: ' + str(dcResponse.status))
|
||||
print ('RASPBERRY_STATS: ' + str(dcResponse.reason))
|
||||
print ('RASPBERRY_STATS: Response Message')
|
||||
print str(dcResponse.msg)
|
||||
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
|
||||
dcConnection.close()
|
||||
|
||||
if (dcResponse.status == 409 or dcResponse.status == 412):
|
||||
print 'RASPBERRY_STATS: Re-registering Device IP'
|
||||
registerDeviceIP()
|
||||
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# This is a Thread object for reading temperature continuously
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class TemperatureReaderThread(object):
|
||||
def __init__(self):
|
||||
if running_mode.RUNNING_MODE == 'N':
|
||||
self.interval = iotUtils.TEMPERATURE_READING_INTERVAL_REAL_MODE
|
||||
else:
|
||||
self.interval = iotUtils.TEMPERATURE_READING_INTERVAL_VIRTUAL_MODE
|
||||
thread = threading.Thread(target=self.run, args=())
|
||||
thread.daemon = True # Daemonize thread
|
||||
thread.start() # Start the execution
|
||||
|
||||
def run(self):
|
||||
|
||||
# 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:
|
||||
if running_mode.RUNNING_MODE == 'N':
|
||||
humidity, temperature = Adafruit_DHT.read_retry(iotUtils.TEMP_SENSOR_TYPE, iotUtils.TEMP_PIN)
|
||||
else:
|
||||
humidity, temperature = iotUtils.generateRandomTemperatureAndHumidityValues()
|
||||
|
||||
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()
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
def get_now():
|
||||
"get the current date and time as a string"
|
||||
return datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||
|
||||
|
||||
def sigterm_handler(_signo, _stack_frame):
|
||||
"When sysvinit sends the TERM signal, cleanup before exiting."
|
||||
print("[] received signal {}, exiting...".format(_signo))
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# 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):
|
||||
pass
|
||||
#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()
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
signal.signal(signal.SIGTERM, sigterm_handler)
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# The Main method of the RPi Agent
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
def main():
|
||||
configureLogger("WSO2IOT_RPiStats")
|
||||
if running_mode.RUNNING_MODE == 'N':
|
||||
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,32 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
Loading…
Reference in new issue