parent
aac8923fa2
commit
128791af39
@ -0,0 +1,325 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||||
|
* Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
**/
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
import logging, logging.handlers
|
||||||
|
import sys, os, signal, argparse
|
||||||
|
import httplib, time
|
||||||
|
import threading
|
||||||
|
import Adafruit_DHT # Adafruit library required for temperature sensing
|
||||||
|
|
||||||
|
import iotUtils
|
||||||
|
import httpServer # python script used to start a http-server to listen for operations (includes the TEMPERATURE global variable)
|
||||||
|
import xmppServer # python script used to communicate with xmpp server
|
||||||
|
import mqttListener # python script used to accept messages via mqtt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PUSH_INTERVAL = 300 # time interval between successive data pushes in seconds
|
||||||
|
logging_enabled = True
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# Endpoint specific settings to which the data is pushed
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
DC_IP = '204.232.188.214' #'192.168.57.128'
|
||||||
|
DC_PORT = 8281
|
||||||
|
HOST = DC_IP + ':' + `DC_PORT`
|
||||||
|
|
||||||
|
DC_ENDPOINT = '/firealarm/1.0/controller' #'/firealarm/1.0/'
|
||||||
|
PUSH_ENDPOINT = DC_ENDPOINT + '/push_temperature'
|
||||||
|
REGISTER_ENDPOINT = DC_ENDPOINT + '/register'
|
||||||
|
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# Logger defaults
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
LOG_FILENAME = "/usr/local/src/RaspberryAgent/logs/RaspberryStats.log"
|
||||||
|
LOG_LEVEL = logging.INFO # Could be e.g. "DEBUG" or "WARNING"
|
||||||
|
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# Define and parse command line arguments
|
||||||
|
# If the log file is specified on the command line then override the default
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
parser = argparse.ArgumentParser(description="Python service to push RPi info to the Device Cloud")
|
||||||
|
parser.add_argument("-l", "--log", help="file to write log to (default '" + LOG_FILENAME + "')")
|
||||||
|
|
||||||
|
help_string = "time interval between successive data pushes (default '" + str(PUSH_INTERVAL) + "')"
|
||||||
|
parser.add_argument("-i", "--interval", type=int, help=help_string)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
if args.log:
|
||||||
|
LOG_FILENAME = args.log
|
||||||
|
|
||||||
|
if args.interval:
|
||||||
|
PUSH_INTERVAL = args.interval
|
||||||
|
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# A class we can use to capture stdout and sterr in the log
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
class IOTLogger(object):
|
||||||
|
def __init__(self, logger, level):
|
||||||
|
"""Needs a logger and a logger level."""
|
||||||
|
self.logger = logger
|
||||||
|
self.level = level
|
||||||
|
|
||||||
|
def write(self, message):
|
||||||
|
if message.rstrip() != "": # Only log if there is a message (not just a new line)
|
||||||
|
self.logger.log(self.level, message.rstrip())
|
||||||
|
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# Configure logging to log to a file,
|
||||||
|
# making a new file at midnight and keeping the last 3 day's data
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
def configureLogger(loggerName):
|
||||||
|
logger = logging.getLogger(loggerName)
|
||||||
|
logger.setLevel(LOG_LEVEL) # Set the log level to LOG_LEVEL
|
||||||
|
handler = logging.handlers.TimedRotatingFileHandler(LOG_FILENAME, when="midnight", backupCount=3) # Handler that writes to a file,
|
||||||
|
# ~~~make new file at midnight and keep 3 backups
|
||||||
|
formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(message)s') # Format each log message like this
|
||||||
|
handler.setFormatter(formatter) # Attach the formatter to the handler
|
||||||
|
logger.addHandler(handler) # Attach the handler to the logger
|
||||||
|
|
||||||
|
if(logging_enabled):
|
||||||
|
sys.stdout = IOTLogger(logger, logging.INFO) # Replace stdout with logging to file at INFO level
|
||||||
|
sys.stderr = IOTLogger(logger, logging.ERROR) # Replace stderr with logging to file at ERROR level
|
||||||
|
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# This method registers the DevieIP in the Device-Cloud
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
def registerDeviceIP():
|
||||||
|
dcConncection = httplib.HTTPConnection(DC_IP, DC_PORT)
|
||||||
|
dcConncection.set_debuglevel(1)
|
||||||
|
dcConncection.connect()
|
||||||
|
|
||||||
|
registerURL = REGISTER_ENDPOINT + '/' + iotUtils.DEVICE_OWNER + '/' + iotUtils.DEVICE_ID + '/' + iotUtils.HOST_NAME
|
||||||
|
|
||||||
|
dcConncection.putrequest('POST', registerURL)
|
||||||
|
dcConncection.putheader('Authorization', 'Bearer ' + iotUtils.AUTH_TOKEN)
|
||||||
|
dcConncection.endheaders()
|
||||||
|
|
||||||
|
dcConncection.send('')
|
||||||
|
dcResponse = dcConncection.getresponse()
|
||||||
|
|
||||||
|
print '~~~~~~~~~~~~~~~~~~~~~~~~ Device Registration ~~~~~~~~~~~~~~~~~~~~~~~~~'
|
||||||
|
print registerURL
|
||||||
|
print dcResponse.status, dcResponse.reason
|
||||||
|
print dcResponse.msg
|
||||||
|
|
||||||
|
dcConncection.close()
|
||||||
|
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
|
||||||
|
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# This method connects to the Device-Cloud and pushes data
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
def connectAndPushData():
|
||||||
|
dcConncection = httplib.HTTPConnection(DC_IP, DC_PORT)
|
||||||
|
dcConncection.set_debuglevel(1)
|
||||||
|
|
||||||
|
dcConncection.connect()
|
||||||
|
|
||||||
|
request = dcConncection.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)
|
||||||
|
|
||||||
|
for k in headers:
|
||||||
|
dcConncection.putheader(k, headers[k])
|
||||||
|
dcConncection.endheaders()
|
||||||
|
|
||||||
|
dcConncection.send(PUSH_DATA) # Push the data
|
||||||
|
dcResponse = dcConncection.getresponse()
|
||||||
|
|
||||||
|
print dcResponse.status, dcResponse.reason
|
||||||
|
print dcResponse.msg
|
||||||
|
|
||||||
|
dcConncection.close()
|
||||||
|
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
|
||||||
|
|
||||||
|
if (dcResponse.status == 409 or dcResponse.status == 412):
|
||||||
|
print 'Re-registering Device IP'
|
||||||
|
registerDeviceIP()
|
||||||
|
|
||||||
|
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# This is a Thread object for reading temperature continuously
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
class TemperatureReaderThread(object):
|
||||||
|
def __init__(self, interval=3):
|
||||||
|
self.interval = interval
|
||||||
|
|
||||||
|
thread = threading.Thread(target=self.run, args=())
|
||||||
|
thread.daemon = True # Daemonize thread
|
||||||
|
thread.start() # Start the execution
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
TEMP_PIN = 4
|
||||||
|
TEMP_SENSOR_TYPE = 11
|
||||||
|
|
||||||
|
# Try to grab a sensor reading. Use the read_retry method which will retry up
|
||||||
|
# to 15 times to get a sensor reading (waiting 2 seconds between each retry).
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
humidity, temperature = Adafruit_DHT.read_retry(TEMP_SENSOR_TYPE, TEMP_PIN)
|
||||||
|
|
||||||
|
if temperature != iotUtils.LAST_TEMP:
|
||||||
|
iotUtils.LAST_TEMP = temperature
|
||||||
|
connectAndPushData()
|
||||||
|
|
||||||
|
iotUtils.LAST_TEMP = temperature
|
||||||
|
print 'Temp={0:0.1f}*C Humidity={1:0.1f}%'.format(temperature, humidity)
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
print "Exception in TempReaderThread: Could not successfully read Temperature"
|
||||||
|
print str(e)
|
||||||
|
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
|
||||||
|
pass
|
||||||
|
|
||||||
|
time.sleep(self.interval)
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# This is a Thread object for listening for MQTT Messages
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
class UtilsThread(object):
|
||||||
|
def __init__(self):
|
||||||
|
thread = threading.Thread(target=self.run, args=())
|
||||||
|
thread.daemon = True # Daemonize thread
|
||||||
|
thread.start() # Start the execution
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
iotUtils.main()
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# This is a Thread object for HTTP-Server that listens for operations on RPi
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
class ListenHTTPServerThread(object):
|
||||||
|
def __init__(self):
|
||||||
|
thread = threading.Thread(target=self.run, args=())
|
||||||
|
thread.daemon = True # Daemonize thread
|
||||||
|
thread.start() # Start the execution
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
httpServer.main()
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# This is a Thread object for Server that listens for XMPP Messages
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
class ListenXMPPServerThread(object):
|
||||||
|
def __init__(self):
|
||||||
|
thread = threading.Thread(target=self.run, args=())
|
||||||
|
thread.daemon = True # Daemonize thread
|
||||||
|
thread.start() # Start the execution
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
xmppServer.main()
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# This is a Thread object for listening for MQTT Messages
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
class ListenMQTTThread(object):
|
||||||
|
def __init__(self):
|
||||||
|
thread = threading.Thread(target=self.run, args=())
|
||||||
|
thread.daemon = True # Daemonize thread
|
||||||
|
thread.start() # Start the execution
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
mqttListener.main()
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# The Main method of the RPi Agent
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
def main():
|
||||||
|
configureLogger("WSO2IOT_RPiStats")
|
||||||
|
# iotUtils.setUpGPIOPins()
|
||||||
|
|
||||||
|
UtilsThread()
|
||||||
|
registerDeviceIP() # Call the register endpoint and register Device IP
|
||||||
|
TemperatureReaderThread() # initiates and runs the thread to continuously read temperature from DHT Sensor
|
||||||
|
ListenHTTPServerThread() # starts an HTTP Server that listens for operational commands to switch ON/OFF Led
|
||||||
|
ListenXMPPServerThread()
|
||||||
|
ListenMQTTThread()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
if iotUtils.LAST_TEMP > 0: # Push data only if there had been a successful temperature read
|
||||||
|
connectAndPushData() # Push Sensor (Temperature) data to WSO2 BAM
|
||||||
|
time.sleep(PUSH_INTERVAL)
|
||||||
|
except (KeyboardInterrupt, Exception) as e:
|
||||||
|
print "Exception in RaspberryAgentThread (either KeyboardInterrupt or Other):"
|
||||||
|
print str(e)
|
||||||
|
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
|
||||||
|
pass
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@ -0,0 +1,135 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||||
|
* Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
**/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import time
|
||||||
|
import BaseHTTPServer
|
||||||
|
import iotUtils
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# HOST and PORT info of the HTTP Server that gets started
|
||||||
|
# HOST_NAME is initialised in the main() method
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
#global HOST_NAME
|
||||||
|
#HOST_NAME = "0.0.0.0"
|
||||||
|
|
||||||
|
SERVER_PORT = 80 # Maybe set this to 9000.
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# Class that handles HTTP GET requests for operations on the RPi
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||||
|
def do_GET(request):
|
||||||
|
# """Respond to a GET request."""
|
||||||
|
|
||||||
|
if not processURLPath(request.path):
|
||||||
|
return
|
||||||
|
|
||||||
|
resource = request.path.split("/")[1].upper()
|
||||||
|
state = request.path.split("/")[2].upper()
|
||||||
|
print "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 "Requested Switch State: " + state
|
||||||
|
|
||||||
|
elif resource == "SONAR":
|
||||||
|
request.send_response(200)
|
||||||
|
request.send_header("Content-type", "text/plain")
|
||||||
|
request.end_headers()
|
||||||
|
request.wfile.write(iotUtils.LAST_DISTANCE)
|
||||||
|
|
||||||
|
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# Check the URL string of the request and validate
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
def processURLPath(path):
|
||||||
|
if path.count("/") != 2 and not "favicon" in path:
|
||||||
|
print "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 "Invalid resource: " + resource + " to execute operation"
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# Case-Insensitive check on whether two string are similar
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
def iequal(a, b):
|
||||||
|
try:
|
||||||
|
return a.upper() == b.upper()
|
||||||
|
except AttributeError:
|
||||||
|
return a == b
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# The Main method of the server script
|
||||||
|
# This method is invoked from RaspberryStats.py on a new thread
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
def main():
|
||||||
|
HOST_NAME = iotUtils.getDeviceIP()
|
||||||
|
server_class = BaseHTTPServer.HTTPServer
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
httpd = server_class((HOST_NAME, SERVER_PORT), MyHandler)
|
||||||
|
print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, SERVER_PORT)
|
||||||
|
|
||||||
|
httpd.serve_forever()
|
||||||
|
except (KeyboardInterrupt, Exception) as e:
|
||||||
|
print "Exception in ServerThread (either KeyboardInterrupt or Other):"
|
||||||
|
print str(e)
|
||||||
|
|
||||||
|
# GPIO.output(BULB_PIN, False)
|
||||||
|
iotUtils.switchBulb("OFF")
|
||||||
|
httpd.server_close()
|
||||||
|
print time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, SERVER_PORT)
|
||||||
|
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
|
||||||
|
pass
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
@ -0,0 +1,244 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||||
|
* Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
**/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import time, commands
|
||||||
|
# import threading
|
||||||
|
import RPi.GPIO as GPIO
|
||||||
|
import ConfigParser
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# HOST_NAME(IP) of the Device
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
global HOST_NAME
|
||||||
|
HOST_NAME = "0.0.0.0"
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
global LAST_TEMP
|
||||||
|
LAST_TEMP = 25 # The Last read temperature value from the DHT sensor. Kept globally
|
||||||
|
# Updated by the temperature reading thread
|
||||||
|
|
||||||
|
global LAST_DISTANCE
|
||||||
|
LAST_DISTANCE = 100
|
||||||
|
|
||||||
|
SONAR_TRIG_PIN = 16 #Associate pin 23 to TRIG
|
||||||
|
SONAR_ECHO_PIN = 18
|
||||||
|
BULB_PIN = 11 # The GPIO Pin# in RPi to which the LED is connected
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# Device specific info when pushing data to server
|
||||||
|
# Read from a file "deviceConfigs.cfg" in the same folder level
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
configParser = ConfigParser.RawConfigParser()
|
||||||
|
configFilePath = r'./deviceConfigs.cfg'
|
||||||
|
configParser.read(configFilePath)
|
||||||
|
|
||||||
|
DEVICE_OWNER = configParser.get('Device-Configurations', 'owner')
|
||||||
|
DEVICE_ID = configParser.get('Device-Configurations', 'deviceId')
|
||||||
|
MQTT_EP = configParser.get('Device-Configurations', 'mqtt-ep')
|
||||||
|
XMPP_EP = configParser.get('Device-Configurations', 'xmpp-ep')
|
||||||
|
AUTH_TOKEN = configParser.get('Device-Configurations', 'auth-token')
|
||||||
|
|
||||||
|
DEVICE_INFO = '{"owner":"'+ DEVICE_OWNER + '","deviceId":"' + DEVICE_ID + '","reply":'
|
||||||
|
DEVICE_IP = '"{ip}","value":'
|
||||||
|
DEVICE_DATA = '"{temperature}"' # '"{temperature}:{load}:OFF"'
|
||||||
|
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# Method used to switch ON/OFF the LED attached to RPi
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
def switchBulb(state):
|
||||||
|
print "Requested Switch State: " + state
|
||||||
|
|
||||||
|
if state == "ON":
|
||||||
|
GPIO.output(BULB_PIN, True)
|
||||||
|
print "BULB Switched ON"
|
||||||
|
elif state == "OFF":
|
||||||
|
GPIO.output(BULB_PIN, False)
|
||||||
|
print "BULB Switched OFF"
|
||||||
|
|
||||||
|
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# Get the wlan0 interface via which the RPi is connected
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
def getDeviceIP():
|
||||||
|
rPi_IP = commands.getoutput("ip route list | grep 'src '").split()
|
||||||
|
rPi_IP = rPi_IP[rPi_IP.index('src') + 1]
|
||||||
|
|
||||||
|
if len(rPi_IP)<=16:
|
||||||
|
print "------------------------------------------------------------------------------------"
|
||||||
|
print "IP Address of RaspberryPi: " + rPi_IP
|
||||||
|
print "------------------------------------------------------------------------------------"
|
||||||
|
return rPi_IP
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# Set the GPIO pin modes for the ones to be read
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
def setUpGPIOPins():
|
||||||
|
try:
|
||||||
|
GPIO.setwarnings(False)
|
||||||
|
GPIO.setmode(GPIO.BOARD)
|
||||||
|
except Exception as e:
|
||||||
|
print "Exception at 'GPIO.setmode'"
|
||||||
|
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
|
||||||
|
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# This is a Thread object for reading sonar values continuously
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# class SonarReaderThread(object):
|
||||||
|
# def __init__(self, interval=3):
|
||||||
|
# self.interval = interval
|
||||||
|
# thread = threading.Thread(target=self.run, args=())
|
||||||
|
# thread.daemon = True # Daemonize thread
|
||||||
|
# thread.start() # Start the execution
|
||||||
|
|
||||||
|
# def run(self):
|
||||||
|
# while True:
|
||||||
|
# try:
|
||||||
|
# GPIO.output(SONAR_TRIG_PIN, False) #Set TRIG as LOW
|
||||||
|
# print "SONAR: 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 "SONAR: Distance: ", distance - 0.5,"cm" #Print distance with 0.5 cm calibration
|
||||||
|
# else:
|
||||||
|
# print "SONAR: Out Of Range" #display out of range
|
||||||
|
|
||||||
|
# except Exception, e:
|
||||||
|
# print "SONAR: Exception in SonarReaderThread: Could not successfully read Sonar"
|
||||||
|
# print str(e)
|
||||||
|
# print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
|
||||||
|
# pass
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
def readSonarDistance():
|
||||||
|
global LAST_DISTANCE
|
||||||
|
try:
|
||||||
|
GPIO.output(SONAR_TRIG_PIN, False) #Set TRIG as LOW
|
||||||
|
print "SONAR: 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 "SONAR: Distance: ", distance - 0.5,"cm" #Print distance with 0.5 cm calibration
|
||||||
|
LAST_DISTANCE = distance
|
||||||
|
else:
|
||||||
|
print "SONAR: Out Of Range" #display out of range
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
print "SONAR: Exception in SonarReaderThread: Could not successfully read Sonar"
|
||||||
|
print str(e)
|
||||||
|
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# The Main method of the server script
|
||||||
|
# This method is invoked from RaspberryStats.py on a new thread
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
def main():
|
||||||
|
HOST_NAME = getDeviceIP()
|
||||||
|
setUpGPIOPins()
|
||||||
|
# SonarReaderThread()
|
||||||
|
while True:
|
||||||
|
readSonarDistance()
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
@ -0,0 +1,116 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* WSO2 Inc. licenses this file to you under the Apache License,
|
||||||
|
* Version 2.0 (the "License"); you may not use this file except
|
||||||
|
* in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
**/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import time
|
||||||
|
import iotUtils
|
||||||
|
#import RPi.GPIO as GPIO
|
||||||
|
import paho.mqtt.client as mqtt
|
||||||
|
|
||||||
|
|
||||||
|
# The callback for when the client receives a CONNACK response from the server.
|
||||||
|
def on_connect(client, userdata, flags, rc):
|
||||||
|
print("Connected with result code "+str(rc))
|
||||||
|
|
||||||
|
# Subscribing in on_connect() means that if we lose the connection and
|
||||||
|
# reconnect then subscriptions will be renewed.
|
||||||
|
print ("Subscribing with topic " + TOPIC)
|
||||||
|
client.subscribe(TOPIC)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# The callback for when a PUBLISH message is received from the server.
|
||||||
|
def on_message(client, userdata, msg):
|
||||||
|
print(msg.topic+" "+str(msg.payload))
|
||||||
|
|
||||||
|
request = str(msg.payload)
|
||||||
|
|
||||||
|
resource = request.split(":")[0].upper()
|
||||||
|
state = request.split(":")[1].upper()
|
||||||
|
|
||||||
|
print "Resource: " + resource
|
||||||
|
|
||||||
|
if resource == "TEMP":
|
||||||
|
pass
|
||||||
|
#request.send_response(200)
|
||||||
|
#request.send_header("Content-type", "text/plain")
|
||||||
|
#request.end_headers()
|
||||||
|
#request.wfile.write(LAST_TEMP)
|
||||||
|
# return
|
||||||
|
|
||||||
|
elif resource == "BULB":
|
||||||
|
iotUtils.switchBulb(state)
|
||||||
|
# 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"
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# The Main method of the server script
|
||||||
|
# This method is invoked from RaspberryStats.py on a new thread
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
def main():
|
||||||
|
|
||||||
|
MQTT_ENDPOINT = iotUtils.MQTT_EP.split(":")
|
||||||
|
MQTT_IP = MQTT_ENDPOINT[0]
|
||||||
|
MQTT_PORT = MQTT_ENDPOINT[1]
|
||||||
|
|
||||||
|
DEV_OWNER = iotUtils.DEVICE_OWNER
|
||||||
|
DEV_ID = iotUtils.DEVICE_ID
|
||||||
|
|
||||||
|
global TOPIC
|
||||||
|
TOPIC = "wso2/iot/" + DEV_OWNER + "/firealarm/" + DEV_ID
|
||||||
|
|
||||||
|
print ("MQTT_ENDPOINT: " + str(MQTT_ENDPOINT))
|
||||||
|
print ("MQTT_TOPIC: " + TOPIC)
|
||||||
|
|
||||||
|
mqttClient = mqtt.Client()
|
||||||
|
mqttClient.on_connect = on_connect
|
||||||
|
mqttClient.on_message = on_message
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
mqttClient.connect(MQTT_IP, MQTT_PORT, 60)
|
||||||
|
print time.asctime(), "Connected to MQTT Broker - %s:%s" % (MQTT_IP, MQTT_PORT)
|
||||||
|
|
||||||
|
# Blocking call that processes network traffic, dispatches callbacks and
|
||||||
|
# handles reconnecting.
|
||||||
|
# Other loop*() functions are available that give a threaded interface and a
|
||||||
|
# manual interface.
|
||||||
|
mqttClient.loop_forever()
|
||||||
|
|
||||||
|
except (KeyboardInterrupt, Exception) as e:
|
||||||
|
print "Exception in MQTTServerThread (either KeyboardInterrupt or Other):"
|
||||||
|
print str(e)
|
||||||
|
|
||||||
|
mqttClient.disconnect()
|
||||||
|
print time.asctime(), "Connection to Broker closed - %s:%s" % (MQTT_IP, MQTT_PORT)
|
||||||
|
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
iotUtils.setUpGPIOPins()
|
||||||
|
main()
|
||||||
|
|
@ -0,0 +1,144 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sleekxmpp
|
||||||
|
import getpass
|
||||||
|
import sys
|
||||||
|
import ssl, pyasn1
|
||||||
|
|
||||||
|
from urllib import urlopen
|
||||||
|
import iotUtils
|
||||||
|
|
||||||
|
# Python versions before 3.0 do not use UTF-8 encoding
|
||||||
|
# by default. To ensure that Unicode is handled properly
|
||||||
|
# throughout SleekXMPP, we will set the default encoding
|
||||||
|
# ourselves to UTF-8.
|
||||||
|
if sys.version_info < (3, 0):
|
||||||
|
from sleekxmpp.util.misc_ops import setdefaultencoding
|
||||||
|
setdefaultencoding('utf8')
|
||||||
|
else:
|
||||||
|
raw_input = input
|
||||||
|
|
||||||
|
from sleekxmpp.plugins.xep_0323.device import Device
|
||||||
|
|
||||||
|
class IoT_TestDevice(sleekxmpp.ClientXMPP):
|
||||||
|
"""
|
||||||
|
A simple IoT device that can act as server or client
|
||||||
|
"""
|
||||||
|
def __init__(self, jid, password):
|
||||||
|
sleekxmpp.ClientXMPP.__init__(self, jid, password)
|
||||||
|
self.add_event_handler("session_start", self.session_start)
|
||||||
|
self.add_event_handler("message", self.message)
|
||||||
|
self.device=None
|
||||||
|
self.releaseMe=False
|
||||||
|
self.beServer=True
|
||||||
|
|
||||||
|
def beClientOrServer(self,server=True,clientJID=None ):
|
||||||
|
self.beServer=True
|
||||||
|
|
||||||
|
def testForRelease(self):
|
||||||
|
# todo thread safe
|
||||||
|
return self.releaseMe
|
||||||
|
|
||||||
|
def doReleaseMe(self):
|
||||||
|
# todo thread safe
|
||||||
|
self.releaseMe=True
|
||||||
|
|
||||||
|
def addDevice(self, device):
|
||||||
|
self.device=device
|
||||||
|
|
||||||
|
def session_start(self, event):
|
||||||
|
self.send_presence()
|
||||||
|
self.get_roster()
|
||||||
|
# tell your preffered friend that you are alive
|
||||||
|
#self.send_message(mto='jocke@jabber.sust.se', mbody=self.boundjid.bare +' is now online use xep_323 stanza to talk to me')
|
||||||
|
|
||||||
|
def message(self, msg):
|
||||||
|
if msg['type'] in ('chat', 'normal'):
|
||||||
|
print ("got normal chat message" + str(msg))
|
||||||
|
ip=urlopen('http://icanhazip.com').read()
|
||||||
|
msg.reply("Hi I am " + self.boundjid.full + " and I am on IP " + ip).send()
|
||||||
|
else:
|
||||||
|
print ("got unknown message type %s", str(msg['type']))
|
||||||
|
|
||||||
|
class TheDevice(Device):
|
||||||
|
"""
|
||||||
|
This is the actual device object that you will use to get information from your real hardware
|
||||||
|
You will be called in the refresh method when someone is requesting information from you
|
||||||
|
"""
|
||||||
|
def __init__(self,nodeId):
|
||||||
|
Device.__init__(self,nodeId)
|
||||||
|
|
||||||
|
def refresh(self,fields):
|
||||||
|
"""
|
||||||
|
the implementation of the refresh method
|
||||||
|
"""
|
||||||
|
# global LAST_TEMP
|
||||||
|
#self._set_momentary_timestamp(self._get_timestamp())
|
||||||
|
#self._add_field_momentary_data(self, "Temperature", self.counter)
|
||||||
|
|
||||||
|
self._add_field(name="Temperature", typename="numeric", unit="C")
|
||||||
|
self._set_momentary_timestamp(self._get_timestamp())
|
||||||
|
self._add_field_momentary_data("Temperature", str(iotUtils.LAST_TEMP), flags={"automaticReadout": "true"})
|
||||||
|
|
||||||
|
def main():
|
||||||
|
XMPP_ENDP = iotUtils.XMPP_EP.split(":")[0]
|
||||||
|
|
||||||
|
XMPP_OWN = iotUtils.DEVICE_OWNER
|
||||||
|
XMPP_JID = iotUtils.DEVICE_ID + "@" + XMPP_ENDP + "/raspi"
|
||||||
|
XMPP_PWD = iotUtils.AUTH_TOKEN
|
||||||
|
|
||||||
|
print XMPP_OWN
|
||||||
|
print XMPP_JID
|
||||||
|
print XMPP_PWD
|
||||||
|
xmpp = IoT_TestDevice(XMPP_JID,XMPP_PWD)
|
||||||
|
|
||||||
|
xmpp.ssl_version = ssl.PROTOCOL_SSLv3
|
||||||
|
|
||||||
|
xmpp.register_plugin('xep_0030')
|
||||||
|
xmpp.register_plugin('xep_0323')
|
||||||
|
xmpp.register_plugin('xep_0325')
|
||||||
|
|
||||||
|
if XMPP_OWN:
|
||||||
|
# xmpp['xep_0030'].add_feature(feature='urn:xmpp:sn',
|
||||||
|
# node=opts.nodeid,
|
||||||
|
# jid=xmpp.boundjid.full)
|
||||||
|
|
||||||
|
myDevice = TheDevice(XMPP_OWN)
|
||||||
|
# myDevice._add_field(name="Relay", typename="numeric", unit="Bool");
|
||||||
|
myDevice._add_field(name="Temperature", typename="numeric", unit="C")
|
||||||
|
myDevice._set_momentary_timestamp("2013-03-07T16:24:30")
|
||||||
|
myDevice._add_field_momentary_data("Temperature", "23.4", flags={"automaticReadout": "true"})
|
||||||
|
|
||||||
|
xmpp['xep_0323'].register_node(nodeId=XMPP_OWN, device=myDevice, commTimeout=10)
|
||||||
|
xmpp.beClientOrServer(server=True)
|
||||||
|
|
||||||
|
while not(xmpp.testForRelease()):
|
||||||
|
try:
|
||||||
|
xmpp.connect()
|
||||||
|
xmpp.process(block=True)
|
||||||
|
print ("lost connection")
|
||||||
|
except Exception as e:
|
||||||
|
print "Exception in XMPPServerThread (either KeyboardInterrupt or Other):"
|
||||||
|
print str(e)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
Loading…
Reference in new issue