Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Version: 1
- # Author: Joachim Olsson
- # Email: joachim.olsson@gcf-consulting.com
- # Date: 2016-10-05
- #
- # This file detects hardware pulses from energy meter and logs them
- # The default input pin is GPIO24 on raspberry pi
- # Each tick on this pin is worth 10 Wh
- # This is stored in memory, and written to file by default once every minute
- import RPi.GPIO as GPIO
- import datetime
- import time
- import os
- import sys
- import linecache
- import requests
- import json
- import threading
- from random import randint
- def LogException(Info):
- print 'Enter LogException()'
- f = None
- try:
- LoggingLock.acquire()
- f = open(os.getcwd() + LogFile, "a+")
- dateTime = datetime.datetime.utcnow()
- data = f.read()
- f.seek(0)
- f.truncate()
- jsonData = json.loads(data)
- jsonData['ExceptionEntries'].append({'Time': dateTime.isoformat(), 'ExceptionInfo': Info})
- f.write(json.dumps(jsonData))
- except ValueError as ex:
- #Error in data, input valid sequence in file
- print 'Decoding JSON failed! Document:'
- print data
- jsonData = {
- 'LogEntries': [],
- 'DeviceEntries': [],
- 'ExceptionEntries': [{'Time': dateTime.isoformat(), 'ExceptionInfo': Info}]
- }
- f.write(json.dumps(jsonData))
- print '\nJSON Data Restored!'
- except Exception as ex:
- f.close()
- LoggingLock.release()
- LogExceptionInfo()
- LoggingLock.acquire()
- f = open(os.getcwd() + LogFile, "a+")
- LogExceptionInfo()
- finally:
- if(f and not f.closed):
- f.close()
- LoggingLock.release()
- print 'Exit LogException()'
- def LogExceptionInfo():
- print 'Enter LogExceptionInfo()'
- try:
- exc_type, exc_obj, tb = sys.exc_info()
- f = tb.tb_frame
- lineno = tb.tb_lineno
- filename = f.f_code.co_filename
- linecache.checkcache(filename)
- line = linecache.getline(filename, lineno, f.f_globals)
- dateTime = datetime.datetime.utcnow()
- text = '[{}] EXCEPTION OCCURRED IN ({}, LINE {} "{}"): {}'.format(dateTime, filename, lineno, line.strip(), exc_obj)
- print text
- LogException(text)
- except ValueError as ex:
- LogExceptionInfo()
- except Exception as ex:
- LogExceptionInfo()
- print 'Exit LogExceptionInfo()'
- def GetAuthorizationToken():
- print 'Enter GetAuthorizationToken()'
- try:
- print "Lock - Token"
- AuthorizationLock.acquire()
- global AuthorizationType, AuthorizationCredentials, AuthorizationExpires, Authorized
- data = {
- 'username': LoginAccountUsername,
- 'password': LoginAccountPassword,
- 'grant_type': 'password'
- }
- response = requests.post(BaseAuth, data = data)
- data = response.json()
- if(response.status_code == 200):
- AuthorizationExpires = datetime.datetime.utcnow() + datetime.timedelta(seconds=data['expires_in']) - datetime.timedelta(hours=1)
- AuthorizationCredentials = data['access_token']
- AuthorizationType = "Bearer "
- Authorized = True
- print "Authorization Expires at: " + str(AuthorizationExpires)
- print "Authorization Type: " + str(AuthorizationType)
- print "Authorization Credentials: " + str(AuthorizationCredentials)
- else:
- Authorized = False
- LogAction("LOGIN FAIL")
- except:
- LogExceptionInfo()
- finally:
- print "Release - Token"
- AuthorizationLock.release()
- print 'Exit GetAuthorizationToken()'
- def GetUpdates():
- f = None
- try:
- AuthorizationLock.acquire()
- headers = { "Authorization" : AuthorizationType + AuthorizationCredentials, "Accept": "text/*", "Accept-Encoding": "gzip;q=1.0, deflate;q=0.8, *;q=0" }
- response = requests.get(BaseAPI + "/Logging/GetUpdater", headers = headers)
- print str(response.content)
- f = open(os.getcwd() + UpdaterFile, "a+")
- f.seek(0)
- f.truncate()
- f.write(unicode(response.content, "UTF-8"))
- except:
- LogExceptionInfo()
- finally:
- AuthorizationLock.release()
- if(f and not f.closed):
- f.close()
- try:
- RunScript(os.getcwd() + UpdaterFile)
- os._exit(1)
- except:
- LogExceptionInfo()
- def GetConfig():
- print 'Enter GetConfig()'
- global Authorized, HardwareLogInterval, PostInterval
- LatestBuild = CurrentBuild
- try:
- AuthorizationLock.acquire()
- authorized = Authorized
- except:
- LogExceptionInfo()
- finally:
- AuthorizationLock.release()
- try:
- if(not authorized):
- GetAuthorizationToken()
- except:
- LogExceptionInfo()
- try:
- AuthorizationLock.acquire()
- headers = { "Authorization" : AuthorizationType + AuthorizationCredentials, "Accept": "application/json", "Accept-Encoding": "gzip;q=1.0, deflate;q=0.8, *;q=0" }
- response = requests.get(BaseAPI + "/Logging/GetConfig", headers = headers)
- data = response.json()
- if(response.status_code == 200):
- try:
- ConfigLock.acquire()
- Status = data['Status']
- HardwareLogInterval = datetime.timedelta(seconds=data['LogInterval'])
- PostInterval = datetime.timedelta(seconds=data['PostInterval'])
- NextLogTime = datetime.datetime.utcnow() + HardwareLogInterval
- NextPostTime = datetime.datetime.utcnow() + PostInterval
- LatestBuild = data['LatestBuild']
- '''print "Retrieved config"
- print "Status: " + str(Status)
- print "LogInterval: " + str(HardwareLogInterval)
- print "PostInterval: " + str(PostInterval)'''
- LogAction("GET CONFIG")
- except:
- LogExceptionInfo()
- finally:
- ConfigLock.release()
- else:
- authorized = False
- LogAction("GET CONFIG FAIL")
- except:
- LogExceptionInfo()
- finally:
- AuthorizationLock.release()
- try:
- if(not authorized):
- GetAuthorizationToken()
- except:
- LogExceptionInfo()
- if(LatestBuild != CurrentBuild):
- GetUpdates()
- print 'Exit GetConfig()'
- def GetCPUSerial():
- print 'Enter GetCPUSerial()'
- cpuSerial = '0000000000000000'
- try:
- f = open('/proc/cpuinfo','r') #RPi Serial location
- for line in f:
- if line[0:6]=='Serial':
- cpuSerial = line[10:26]
- return int(str(cpuSerial), 16)
- except Exception as ex:
- LogExceptionInfo()
- finally:
- f.close()
- print 'Exit GetCPUSerial()'
- def StartHardwareLogger():
- print 'Enter StartHardwareLogger()'
- try:
- print "StartHardwareLogger"
- GPIO.setwarnings(False)
- GPIO.setmode(GPIO.BCM)
- GPIO.setup(HardwarePin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
- GPIO.add_event_detect(HardwarePin, GPIO.RISING, callback=HardwareLoggerCallback, bouncetime=BounceIntervalMs)
- except:
- LogExceptionInfo()
- print 'Exit StartHardwareLogger()'
- def HardwareLoggerCallback(ch):
- print 'Enter HardwareLoggerCallback(ch)'
- try:
- global CurrentEnergyLevel,CountEnergyTicks,DateTime,NextLogTime
- print "HardwareLoggerCallback"
- CurrentEnergyLevel += 10
- CountEnergyTicks += 1
- DateTime = datetime.datetime.utcnow()
- if(DateTime >= NextLogTime and CurrentEnergyLevel > 0):
- NextLogTime = DateTime + HardwareLogInterval
- LogEntry(CurrentEnergyLevel)
- CurrentEnergyLevel = 0
- '''if (CountEnergyTicks >= 3):
- print "HardwareLoggerCallback 3"
- GPIO.remove_event_detect(HardwarePin)
- GPIO.cleanup()
- StartHardwareLogger()'''
- except:
- #GPIO.cleanup()
- LogExceptionInfo()
- #StartHardwareLogger()
- print 'Exit HardwareLoggerCallback(ch)'
- def LogEntry(EnergyLevel):
- print 'Enter LogEntry(EnergyLevel)'
- f = None
- try:
- LoggingLock.acquire()
- f = open(os.getcwd() + LogFile, "a+")
- dateTime = datetime.datetime.utcnow()
- data = f.read()
- f.seek(0)
- f.truncate()
- jsonData = json.loads(data)
- jsonData['LogEntries'].append({
- 'Time': dateTime.isoformat(),
- 'EnergyAmount': EnergyLevel,
- })
- f.write(json.dumps(jsonData))
- except ValueError as ex:
- print ex
- #Error in data, input valid sequence in file
- print 'Decoding JSON failed!\nDocument:\n'
- print data
- jsonData = {
- 'LogEntries': [{
- 'Time': dateTime.isoformat(),
- 'EnergyAmount': EnergyLevel
- }],
- 'DeviceEntries': [],
- 'ExceptionEntries': []
- }
- f.write(json.dumps(jsonData))
- print 'JSON Data Restored!'
- except Exception as ex:
- if(f and not f.closed):
- f.close()
- LoggingLock.release()
- LogExceptionInfo()
- LoggingLock.acquire()
- f = open(os.getcwd() + LogFile, "a+")
- finally:
- if(f and not f.closed):
- f.close()
- LoggingLock.release()
- print 'Exit LogEntry(EnergyLevel)'
- def LogAction(Info):
- print 'Enter LogAction(Info)'
- f = None
- try:
- LoggingLock.acquire()
- f = open(os.getcwd() + LogFile, "a+")
- dateTime = datetime.datetime.utcnow()
- data = f.read()
- f.seek(0)
- f.truncate()
- jsonData = json.loads(data)
- jsonData['DeviceEntries'].append({'Time': dateTime.isoformat(), 'Action': Info})
- f.write(json.dumps(jsonData))
- except ValueError as ex:
- #Error in data, input valid sequence in file
- print 'Decoding JSON failed! Document:'
- print data
- jsonData = {
- 'LogEntries': [],
- 'DeviceEntries': [{'Time': dateTime.isoformat(), 'Action': Info}],
- 'ExceptionEntries': []
- }
- f.write(json.dumps(jsonData))
- print 'JSON Data Restored!'
- except Exception as ex:
- if(f and not f.closed):
- f.close()
- LoggingLock.release()
- LogExceptionInfo()
- LoggingLock.acquire()
- f = open(os.getcwd() + LogFile, "a+")
- LogExceptionInfo()
- finally:
- if(f and not f.closed):
- f.close()
- LoggingLock.release()
- print 'Exit LogAction(Info)'
- def CheckPostLog():
- print 'Enter CheckPostLog()'
- global NextPostTime, PostInterval, HardwareLogInterval, NextLogTime, Status
- f = None
- LatestBuild = CurrentBuild
- print "Time is " + str(datetime.datetime.utcnow().isoformat()) + " and next post will occur after " + str(NextPostTime.isoformat())
- if(datetime.datetime.utcnow() >= NextPostTime):
- try:
- LoggingLock.acquire()
- NextPostTime = datetime.datetime.utcnow() + PostInterval
- f = open(os.getcwd() + LogFile, "a+")
- jsonData = json.loads(f.read())
- jsonData['Time'] = datetime.datetime.utcnow().isoformat()
- headers = { "Authorization" : AuthorizationType + AuthorizationCredentials, "Accept": "application/json", "Content-Type": "application/json" }
- response = requests.post(BaseAPI + "/Logging/Log", headers = headers, json=jsonData)
- data = response.json()
- if(response.status_code == 200):
- print "Posted Log - Current Log was cleared"
- f.seek(0)
- f.truncate()
- jsonData = {
- 'LogEntries': [],
- 'DeviceEntries': [],
- 'ExceptionEntries': []
- }
- f.write(json.dumps(jsonData))
- try:
- ConfigLock.acquire()
- Status = data['Status']
- HardwareLogInterval = datetime.timedelta(seconds=data['LogInterval'])
- PostInterval = datetime.timedelta(seconds=data['PostInterval'])
- NextLogTime = datetime.datetime.utcnow() + HardwareLogInterval
- NextPostTime = datetime.datetime.utcnow() + PostInterval
- LatestBuild = data['LatestBuild']
- finally:
- ConfigLock.release()
- else:
- print "Error Sending Log: "
- print data
- except ValueError as ex:
- if(f and not f.closed):
- f.seek(0)
- f.truncate()
- jsonData = {
- 'LogEntries': [],
- 'DeviceEntries': [],
- 'ExceptionEntries': []
- }
- f.write(json.dumps(jsonData))
- except:
- if(f and not f.closed):
- f.close()
- LoggingLock.release()
- LogExceptionInfo()
- LoggingLock.acquire()
- f = open(os.getcwd() + LogFile, "a+")
- finally:
- if(f and not f.closed):
- f.close()
- LoggingLock.release()
- try:
- if(LatestBuild != CurrentBuild):
- GetUpdates()
- except:
- LogExceptionInfo()
- print 'Exit CheckPostLog()'
- ########-----Global Variables-----########
- ConfigLock = threading.Lock()
- Status = 0
- PostInterval = datetime.timedelta(seconds=3)
- HardwareLogInterval = datetime.timedelta(seconds=5) #How often to log to file
- DateTime = datetime.datetime.utcnow()
- NextLogTime = DateTime + HardwareLogInterval
- NextPostTime = DateTime + PostInterval
- BounceIntervalMs = 50 #Note, anything logged in this interval won't be counted
- HardwarePin = 24 #GPIO24
- AuthorizationLock = threading.Lock()
- BaseAPI = "http://192.168.1.16:8080/API/"
- BaseAuth = "http://192.168.1.16:8080/oauth/token"
- AuthorizationType = ""
- AuthorizationCredentials = ""
- AuthorizationExpires = datetime.datetime.utcnow()
- Authorized = False
- LoginAccountUsername = "Device@AndrewPeters"
- LoginAccountPassword = "p4ssw0rd"
- LoggingLock = threading.Lock()
- CurrentEnergyLevel = 0
- CountEnergyTicks = 0
- #CPUSerial = GetCPUSerial()
- LogFile = "/Log.json"
- UpdaterFile = "/Updater.py"
- CurrentBuild = 1
- ########-----Main Program-----########
- print "\n==================="
- print "PowerCoins Logger - Running"
- print "===================\n"
- while True:
- try:
- LogAction("BOOT")
- StartHardwareLogger()
- while(True):
- GetAuthorizationToken()
- if(Authorized):
- break
- else:
- time.sleep(30)
- GetConfig()
- while True:
- time.sleep(3)
- if(randint(0,15) > 14):
- LogEntry(randint(30,120))
- CheckPostLog()
- except Exception as e:
- print e
- LogAction("EXIT(AUTORESTART)")
- GPIO.cleanup()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement