Merge pull request #76 from GPrathap/IoTS-1.0.0-M1

added Raspberry Pi agent
Ruwan 9 years ago
commit 71ed5edce4

@ -0,0 +1,98 @@
#"""
#/**
#* 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.
#**/
#"""
#!/bin/sh
### BEGIN INIT INFO
# Provides: RaspberryService
# Required-Start: $remote_fs $syslog $network
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: WSO2-IOT RPi Service
# Description: RPi Service used to Publish RPi Stats to the WSO2 Device Cloud
### END INIT INFO
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
# Change the next 3 lines to suit where you install your script and what you want to call it
DESC="This service is used to publish events from the Raspberry Pi to the WSO2 Device Cloud"
NAME=RaspberryStats
DIR=/usr/local/src/RaspberryAgent
DAEMON=$DIR/RaspberryAgent.py
DAEMON_NAME=$NAME
SCRIPTNAME=RaspberryService.sh
# The process ID of the script when it runs is stored here:
PIDFILE=/var/run/$DAEMON_NAME.pid
# Add any command line options for your daemon here
DAEMON_OPTS="-l /usr/local/src/RaspberryAgent/RaspberryStats.log -m N -i 56"
# This next line determines what user the script runs as.
# Root generally not recommended but necessary if you are using the Raspberry Pi GPIO from Python.
DAEMON_USER=root #pi
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions
do_start () {
log_daemon_msg "Starting system $DAEMON_NAME daemon"
start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --user $DAEMON_USER --chuid $DAEMON_USER --startas $DAEMON -- $DAEMON_OPTS
log_end_msg $?
}
do_stop () {
log_daemon_msg "Stopping system $DAEMON_NAME daemon"
start-stop-daemon --stop --pidfile $PIDFILE --retry 10
log_end_msg $?
}
case "$1" in
start|stop)
do_${1}
;;
restart|reload|force-reload)
do_stop
do_start
;;
status)
status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit $?
;;
getdeviceid)
$DIR/getMac.sh && exit 0 || exit $?
;;
*)
#echo Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"
echo "Usage: /etc/init.d/$SCRIPTNAME {start|stop|restart|status}"
exit 1
;;
esac
exit 0

@ -0,0 +1,32 @@
#
# Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
[Device-Configurations]
owner=${DEVICE_OWNER}
deviceId=${DEVICE_ID}
device-name=${DEVICE_NAME}
controller-context=/drone_analyzer/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

@ -1,14 +0,0 @@
[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

@ -16,5 +16,5 @@
# under the License.
#
templates=RaspberryPi.deb
templates=deviceConfig.properties
zipfilename=RaspberryPi.zip

@ -0,0 +1,338 @@
#!/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()

@ -20,46 +20,27 @@
**/
"""
import logging, logging.handlers
import sys, os, signal, argparse
import httplib, time
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
import datetime
import running_mode
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'
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PUSH_INTERVAL = 5000 # time interval between successive data pushes in seconds
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Logger defaults
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LOG_FILENAME = "/usr/local/src/RaspberryAgent/logs/RaspberryStats.log"
#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
@ -67,30 +48,60 @@ LOG_LEVEL = logging.INFO # Could be e.g. "DEBUG" or "WARNING"
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)
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
LOG_FILENAME = args.log
if args.interval:
PUSH_INTERVAL = 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())
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())
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -100,17 +111,18 @@ class IOTLogger(object):
# 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
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
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -118,86 +130,68 @@ def configureLogger(loggerName):
# 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 '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
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)
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()
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()
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -205,36 +199,38 @@ def connectAndPushData():
# This is a Thread object for reading temperature continuously
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class TemperatureReaderThread(object):
def __init__(self, interval=3):
self.interval = interval
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
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 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)
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -246,9 +242,9 @@ class TemperatureReaderThread(object):
class UtilsThread(object):
def __init__(self):
thread = threading.Thread(target=self.run, args=())
thread.daemon = True # Daemonize thread
thread.start() # Start the execution
thread.daemon = True # Daemonize thread
thread.start() # Start the execution
def run(self):
iotUtils.main()
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -262,13 +258,22 @@ class UtilsThread(object):
class ListenHTTPServerThread(object):
def __init__(self):
thread = threading.Thread(target=self.run, args=())
thread.daemon = True # Daemonize thread
thread.start() # Start the execution
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)
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -277,11 +282,12 @@ class ListenHTTPServerThread(object):
class ListenXMPPServerThread(object):
def __init__(self):
thread = threading.Thread(target=self.run, args=())
thread.daemon = True # Daemonize thread
thread.start() # Start the execution
thread.daemon = True # Daemonize thread
thread.start() # Start the execution
def run(self):
xmppServer.main()
pass
#xmppServer.main()
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -292,41 +298,41 @@ class ListenXMPPServerThread(object):
class ListenMQTTThread(object):
def __init__(self):
thread = threading.Thread(target=self.run, args=())
thread.daemon = True # Daemonize thread
thread.start() # Start the execution
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")
# iotUtils.setUpGPIOPins()
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()
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)
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()
main()

@ -0,0 +1,32 @@
#
# Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
[Device-Configurations]
owner=admin
deviceId=1iv9uchjd5lq0
device-name=teddr_1iv9uchjd5lq0
controller-context=/raspberrypi/RaspberryPiDeviceManager/controller
https-ep=https://192.168.237.1:9443
http-ep=http://192.168.237.1:9763
apim-ep=http://localhost:8280
mqtt-ep=tcp://204.232.188.214:1883
xmpp-ep=http://204.232.188.215:5222
auth-method=token
auth-token=1f8fcefa0bb80aac9ae92e0497b19b94
refresh-token=d83c134e2038f4ef37d545c23b3be768
push-interval=15

@ -23,81 +23,66 @@
import time
import BaseHTTPServer
import iotUtils
import running_mode
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# HOST and PORT info of the HTTP Server that gets started
# HOST_NAME is initialised in the main() method
# Class that handles HTTP GET requests for operations on the RPi
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#global HOST_NAME
#HOST_NAME = "0.0.0.0"
class OnRequestListener(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(request):
# """Respond to a GET request."""
SERVER_PORT = 80 # Maybe set this to 9000.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if not processURLPath(request.path):
return
print request.path.split("/")[1].upper()
resource = request.path.split("/")[1].upper()
state = request.path.split("/")[2].upper()
print "HTTP_SERVER: Resource - " + resource
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 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 '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 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
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
try:
return a.upper() == b.upper()
except AttributeError:
return a == b
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -106,29 +91,29 @@ def iequal(a, b):
# 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
HOST_NAME = iotUtils.getDeviceIP()
HTTP_SERVER_PORT = iotUtils.getHTTPServerPort()
server_class = BaseHTTPServer.HTTPServer
while True:
try:
httpd = server_class((HOST_NAME, HTTP_SERVER_PORT), OnRequestListener)
print "HTTP_SERVER: " + time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, HTTP_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))
if running_mode.RUNNING_MODE == "N":
iotUtils.switchBulb("OFF")
else :
iotUtils.switchBulb("OFF")
httpd.server_close()
print "HTTP_SERVER: " + time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, HTTP_SERVER_PORT)
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
pass
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if __name__ == '__main__':
main()
main()

@ -21,8 +21,9 @@
"""
import time, commands
import RPi.GPIO as GPIO
import ConfigParser
import ConfigParser, os
import random
import running_mode
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# HOST_NAME(IP) of the Device
@ -31,25 +32,25 @@ 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
global LAST_TEMP
LAST_TEMP = 25 # The Last read temperature value from the DHT sensor. Kept globally
# Updated by the temperature reading thread
# Associate pin 23 to TRIG
TEMPERATURE_READING_INTERVAL_REAL_MODE = 3
TEMPERATURE_READING_INTERVAL_VIRTUAL_MODE = 60
TEMP_PIN = 4
TEMP_SENSOR_TYPE = 11
BULB_PIN = 11 # The GPIO Pin# in RPi to which the LED is connected
HTTP_SERVER_PORT = 80 # http server port which is listning on
global GPIO
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Device specific info when pushing data to server
# Read from a file "deviceConfigs.cfg" in the same folder level
# Read from a file "deviceConfig.properties" in the same folder level
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
configParser = ConfigParser.RawConfigParser()
configFilePath = r'./deviceConfigs.cfg'
configFilePath = os.path.join(os.path.dirname(__file__), './deviceConfig.properties')
configParser.read(configFilePath)
DEVICE_OWNER = configParser.get('Device-Configurations', 'owner')
@ -57,10 +58,14 @@ 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":'
CONTROLLER_CONTEXT = configParser.get('Device-Configurations', 'controller-context')
DEVICE_INFO = '{"owner":"' + DEVICE_OWNER + '","deviceId":"' + DEVICE_ID + '","reply":'
HTTPS_EP = configParser.get('Device-Configurations', 'https-ep')
HTTP_EP = configParser.get('Device-Configurations', 'http-ep')
DEVICE_IP = '"{ip}","value":'
DEVICE_DATA = '"{temperature}"' # '"{temperature}:{load}:OFF"'
DEVICE_DATA = '"{temperature}"' # '"{temperature}:{load}:OFF"'
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -70,17 +75,39 @@ DEVICE_DATA = '"{temperature}"'
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"
if running_mode.RUNNING_MODE == "N":
import RPi.GPIO as GPIO
if state == "ON":
GPIO.output(BULB_PIN, True)
print "BULB Switched ON"
elif state == "OFF":
GPIO.output(BULB_PIN, False)
print "BULB Switched OFF"
else:
if state == "ON":
print "BULB Switched ON"
elif state == "OFF":
print "BULB Switched OFF"
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# This method generate a random temperature value
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def generateRandomTemperatureAndHumidityValues():
return [random.randint(15, 40),random.randint(15, 40)]
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# If an agent runs on a real setup GPIO needs to be imported
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def initGPIOModule():
if running_mode.RUNNING_MODE == 'N':
import RPi.GPIO as GPIO
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Get the wlan0 interface via which the RPi is connected
@ -88,99 +115,39 @@ def switchBulb(state):
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
if len(rPi_IP) <= 16:
print "------------------------------------------------------------------------------------"
print "IOT_UTILS: IP Address of RaspberryPi: " + rPi_IP
print "------------------------------------------------------------------------------------"
return rPi_IP
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Get the port which http server is listening on
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def getHTTPServerPort():
return HTTP_SERVER_PORT
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Set the GPIO pin modes for the ones to be read
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def setUpGPIOPins():
import RPi.GPIO as GPIO
try:
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
except Exception as e:
print "IOT_UTILS: Exception at 'GPIO.setmode'"
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
pass
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
@ -188,13 +155,11 @@ def readSonarDistance():
def main():
global HOST_NAME
HOST_NAME = getDeviceIP()
setUpGPIOPins()
if running_mode.RUNNING_MODE == 'N':
setUpGPIOPins()
while True:
readSonarDistance()
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if __name__ == '__main__':
main()
main()

@ -22,7 +22,6 @@
import time
import iotUtils
#import RPi.GPIO as GPIO
import paho.mqtt.client as mqtt
@ -54,7 +53,7 @@ def on_message(client, userdata, msg):
#request.send_header("Content-type", "text/plain")
#request.end_headers()
#request.wfile.write(LAST_TEMP)
# return
# return
elif resource == "BULB":
iotUtils.switchBulb(state)
@ -66,8 +65,8 @@ def on_message(client, userdata, msg):
def main():
MQTT_ENDPOINT = iotUtils.MQTT_EP.split(":")
MQTT_IP = MQTT_ENDPOINT[0]
MQTT_PORT = MQTT_ENDPOINT[1]
MQTT_IP = MQTT_ENDPOINT[1].replace('//','')
MQTT_PORT = int(MQTT_ENDPOINT[2])
DEV_OWNER = iotUtils.DEVICE_OWNER
DEV_ID = iotUtils.DEVICE_ID

@ -25,33 +25,35 @@ import ssl, pyasn1
from urllib import urlopen
import iotUtils
import running_mode
# 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
def initSleekXMPP():
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
self.device = None
self.releaseMe = False
self.beServer = True
def beClientOrServer(self,server=True,clientJID=None ):
self.beServer=True
def beClientOrServer(self, server=True, clientJID=None):
self.beServer = True
def testForRelease(self):
# todo thread safe
@ -59,16 +61,16 @@ class IoT_TestDevice(sleekxmpp.ClientXMPP):
def doReleaseMe(self):
# todo thread safe
self.releaseMe=True
self.releaseMe = True
def addDevice(self, device):
self.device=device
self.device = device
def session_start(self, event):
self.send_presence()
self.get_roster()
# tell your preffered friend that you are alive
#self.send_message(mto='jocke@jabber.sust.se', mbody=self.boundjid.bare +' is now online use xep_323 stanza to talk to me')
# self.send_message(mto='jocke@jabber.sust.se', mbody=self.boundjid.bare +' is now online use xep_323 stanza to talk to me')
def message(self, msg):
if msg['type'] in ('chat', 'normal'):
@ -78,40 +80,47 @@ class IoT_TestDevice(sleekxmpp.ClientXMPP):
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):
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)
# 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_ENDPOINT = iotUtils.XMPP_EP.split(":")
XMPP_IP = XMPP_ENDPOINT[1].replace('//', '')
XMPP_PORT = int(XMPP_ENDPOINT[2])
XMPP_OWN = iotUtils.DEVICE_OWNER
XMPP_JID = iotUtils.DEVICE_ID + "@" + XMPP_ENDP + "/raspi"
XMPP_JID = iotUtils.DEVICE_ID + "@" + XMPP_IP + "/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 = IoT_TestDevice(XMPP_JID, XMPP_PWD)
xmpp.ssl_version = ssl.PROTOCOL_SSLv3
xmpp.register_plugin('xep_0030')
@ -131,15 +140,17 @@ def main():
xmpp['xep_0323'].register_node(nodeId=XMPP_OWN, device=myDevice, commTimeout=10)
xmpp.beClientOrServer(server=True)
while not(xmpp.testForRelease()):
while not (xmpp.testForRelease()):
try:
xmpp.connect()
xmpp.process(block=True)
print ("XMPP_SERVER: Lost Connection")
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__':
initSleekXMPP()
main()

@ -0,0 +1,35 @@
#"""
#/**
#* 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.
#**/
#"""
#!/usr/bin/env bash
destination="/usr/local/src/RaspberryAgent"
currentDir=$PWD
if [ ! -d "$destination" ]
then
mkdir $destination
fi
sudo cp $currentDir/deviceConfig.properties $currentDir/src
sudo cp -r $currentDir/src $destination
sudo chmod +x $destination/RaspberryAgent.py
sudo update-rc.d -f RaspberryService.sh remove
sudo cp $currentDir/RaspberryService.sh /etc/init.d
sudo chmod +x /etc/init.d/RaspberryService.sh
sudo update-rc.d RaspberryService.sh defaults

@ -1,18 +1,34 @@
#"""
#/**
#* 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.
#**/
#"""
#!/bin/bash
echo "----------------------------------------------------------------"
echo "| WSO2 IOT Sample "
echo "| RaspiAlarm "
echo "| RaspiAgent "
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
@ -31,23 +47,21 @@ if [ $? -ne 0 ]; then
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 "dpkg --remove --force-remove-reinstreq wso2-raspi-agent"
echo "exit"
echo "----------------------------------------------------------------"
echo "Retry Installation...."
break;
fi
for f in ./deviceConfigs.cfg; do
for f in ./deviceConfig.properties; 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...";
echo "'deviceConfig.properties' 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
@ -61,27 +75,36 @@ sudo python setup.py install
cd $currentDir
#sudo apt-get install python-pip
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
read -p "Are you want to run this as a virtual agent? (Yes/No) " mode
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
case $mode in
[Yy]* ) mode="Y"
echo "----------------------------------------------------------"
echo " This will run as a virtual agent "
echo "----------------------------------------------------------"
break;;
[Nn]* ) mode="N"
echo "----------------------------------------------------------"
echo " This will run as a real agent "
echo "----------------------------------------------------------"
break;;
* ) echo "Please answer yes or no.";
esac
done
sudo nohup ./RaspberryStats.py -i $input > /dev/null 2>&1 &
./src/RaspberryStats.py -i $input -m $mode
if [ $? -ne 0 ]; then
echo "Could not start the service..."
@ -91,4 +114,4 @@ fi
echo "--------------------------------------------------------------------------"
echo "| Successfully Started "
echo "---------------------------------------------------------------------------"
echo "| -------------------------- "
Loading…
Cancel
Save