forked from community/device-mgt-plugins
Merge pull request #76 from GPrathap/IoTS-1.0.0-M1
added Raspberry Pi agent
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
|
|
@ -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()
|
@ -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
|
||||||
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
global RUNNING_MODE
|
@ -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
|
Loading…
Reference in new issue