SHARE
TWEET

new.py

a guest Mar 20th, 2017 71 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # Version: 1
  2. # Author: Joachim Olsson
  3. # Email: joachim.olsson@gcf-consulting.com
  4. # Date: 2016-10-05
  5. #
  6. # This file detects hardware pulses from energy meter and logs them
  7. # The default input pin is GPIO24 on raspberry pi
  8. # Each tick on this pin is worth 10 Wh
  9. # This is stored in memory, and written to file by default once every minute
  10.  
  11. import RPi.GPIO as GPIO
  12. import datetime
  13. import time
  14. import os
  15. import sys
  16. import linecache
  17. import requests
  18. import json
  19. import threading
  20. from random import randint
  21.  
  22. def LogException(Info):
  23.     print 'Enter LogException()'
  24.     f = None
  25.     try:
  26.         LoggingLock.acquire()
  27.         f = open(os.getcwd() + LogFile, "a+")
  28.         dateTime = datetime.datetime.utcnow()
  29.         data = f.read()
  30.         f.seek(0)
  31.         f.truncate()
  32.         jsonData = json.loads(data)
  33.         jsonData['ExceptionEntries'].append({'Time': dateTime.isoformat(), 'ExceptionInfo': Info})
  34.         f.write(json.dumps(jsonData))
  35.     except ValueError as ex:
  36.         #Error in data, input valid sequence in file
  37.         print 'Decoding JSON failed! Document:'
  38.         print data
  39.         jsonData = {
  40.                 'LogEntries': [],
  41.                 'DeviceEntries': [],
  42.                 'ExceptionEntries': [{'Time': dateTime.isoformat(), 'ExceptionInfo': Info}]
  43.         }
  44.        
  45.         f.write(json.dumps(jsonData))
  46.         print '\nJSON Data Restored!'
  47.     except Exception as ex:
  48.         f.close()
  49.         LoggingLock.release()
  50.         LogExceptionInfo()
  51.         LoggingLock.acquire()
  52.         f = open(os.getcwd() + LogFile, "a+")
  53.         LogExceptionInfo()
  54.     finally:
  55.         if(f and not f.closed):
  56.             f.close()
  57.         LoggingLock.release()
  58.     print 'Exit LogException()'
  59.  
  60. def LogExceptionInfo():
  61.     print 'Enter LogExceptionInfo()'
  62.     try:            
  63.         exc_type, exc_obj, tb = sys.exc_info()
  64.         f = tb.tb_frame
  65.         lineno = tb.tb_lineno
  66.         filename = f.f_code.co_filename
  67.         linecache.checkcache(filename)
  68.         line = linecache.getline(filename, lineno, f.f_globals)
  69.         dateTime = datetime.datetime.utcnow()
  70.         text = '[{}] EXCEPTION OCCURRED IN ({}, LINE {} "{}"): {}'.format(dateTime, filename, lineno, line.strip(), exc_obj)
  71.         print text
  72.         LogException(text)
  73.     except ValueError as ex:
  74.         LogExceptionInfo()
  75.     except Exception as ex:
  76.         LogExceptionInfo()
  77.     print 'Exit LogExceptionInfo()'
  78.  
  79. def GetAuthorizationToken():
  80.     print 'Enter GetAuthorizationToken()'
  81.     try:
  82.         print "Lock - Token"
  83.         AuthorizationLock.acquire()
  84.         global AuthorizationType, AuthorizationCredentials, AuthorizationExpires, Authorized
  85.         data = {
  86.             'username': LoginAccountUsername,
  87.             'password': LoginAccountPassword,
  88.             'grant_type': 'password'
  89.         }
  90.         response = requests.post(BaseAuth, data = data)
  91.         data = response.json()
  92.        
  93.         if(response.status_code == 200):
  94.             AuthorizationExpires = datetime.datetime.utcnow() + datetime.timedelta(seconds=data['expires_in']) - datetime.timedelta(hours=1)
  95.             AuthorizationCredentials = data['access_token']
  96.             AuthorizationType = "Bearer "
  97.             Authorized = True
  98.             print "Authorization Expires at: " + str(AuthorizationExpires)
  99.             print "Authorization Type: " + str(AuthorizationType)
  100.             print "Authorization Credentials: " + str(AuthorizationCredentials)
  101.         else:
  102.             Authorized = False
  103.             LogAction("LOGIN FAIL")
  104.     except:
  105.         LogExceptionInfo()
  106.     finally:
  107.         print "Release - Token"
  108.         AuthorizationLock.release()
  109.     print 'Exit GetAuthorizationToken()'
  110.  
  111. def GetUpdates():
  112.     f = None
  113.     try:
  114.         AuthorizationLock.acquire()
  115.         headers = { "Authorization" : AuthorizationType + AuthorizationCredentials, "Accept": "text/*", "Accept-Encoding": "gzip;q=1.0, deflate;q=0.8, *;q=0" }
  116.         response = requests.get(BaseAPI + "/Logging/GetUpdater", headers = headers)
  117.         print str(response.content)
  118.         f = open(os.getcwd() + UpdaterFile, "a+")
  119.         f.seek(0)
  120.         f.truncate()
  121.         f.write(unicode(response.content, "UTF-8"))
  122.     except:
  123.         LogExceptionInfo()
  124.     finally:
  125.         AuthorizationLock.release()
  126.         if(f and not f.closed):
  127.             f.close()
  128.     try:
  129.         RunScript(os.getcwd() + UpdaterFile)
  130.         os._exit(1)
  131.     except:
  132.         LogExceptionInfo()      
  133.        
  134.    
  135. def GetConfig():
  136.     print 'Enter GetConfig()'
  137.     global Authorized, HardwareLogInterval, PostInterval
  138.     LatestBuild = CurrentBuild
  139.     try:
  140.         AuthorizationLock.acquire()
  141.         authorized = Authorized
  142.     except:
  143.         LogExceptionInfo()
  144.     finally:
  145.         AuthorizationLock.release()
  146.     try:
  147.         if(not authorized):
  148.             GetAuthorizationToken()
  149.     except:
  150.         LogExceptionInfo()
  151.        
  152.     try:
  153.         AuthorizationLock.acquire()
  154.         headers = { "Authorization" : AuthorizationType + AuthorizationCredentials, "Accept": "application/json", "Accept-Encoding": "gzip;q=1.0, deflate;q=0.8, *;q=0" }
  155.         response = requests.get(BaseAPI + "/Logging/GetConfig", headers = headers)
  156.         data = response.json()
  157.         if(response.status_code == 200):
  158.             try:
  159.                 ConfigLock.acquire()
  160.                 Status = data['Status']
  161.                 HardwareLogInterval = datetime.timedelta(seconds=data['LogInterval'])
  162.                 PostInterval = datetime.timedelta(seconds=data['PostInterval'])
  163.                 NextLogTime = datetime.datetime.utcnow() + HardwareLogInterval
  164.                 NextPostTime = datetime.datetime.utcnow() + PostInterval
  165.                 LatestBuild = data['LatestBuild']
  166.                 '''print "Retrieved config"
  167.                 print "Status: " + str(Status)
  168.                 print "LogInterval: " + str(HardwareLogInterval)
  169.                 print "PostInterval: " + str(PostInterval)'''
  170.                 LogAction("GET CONFIG")
  171.             except:
  172.                 LogExceptionInfo()
  173.             finally:
  174.                 ConfigLock.release()
  175.         else:
  176.             authorized = False
  177.             LogAction("GET CONFIG FAIL")      
  178.     except:
  179.         LogExceptionInfo()
  180.     finally:
  181.         AuthorizationLock.release()        
  182.    
  183.     try:
  184.         if(not authorized):
  185.             GetAuthorizationToken()
  186.     except:
  187.         LogExceptionInfo()
  188.  
  189.     if(LatestBuild != CurrentBuild):
  190.         GetUpdates()
  191.        
  192.     print 'Exit GetConfig()'
  193.        
  194. def GetCPUSerial():
  195.     print 'Enter GetCPUSerial()'
  196.     cpuSerial = '0000000000000000'
  197.     try:
  198.         f = open('/proc/cpuinfo','r') #RPi Serial location
  199.         for line in f:
  200.             if line[0:6]=='Serial':
  201.                 cpuSerial = line[10:26]
  202.         return int(str(cpuSerial), 16)
  203.     except Exception as ex:
  204.         LogExceptionInfo()
  205.     finally:
  206.         f.close()
  207.     print 'Exit GetCPUSerial()'
  208.  
  209. def StartHardwareLogger():
  210.     print 'Enter StartHardwareLogger()'
  211.     try:
  212.         print "StartHardwareLogger"
  213.         GPIO.setwarnings(False)
  214.         GPIO.setmode(GPIO.BCM)
  215.         GPIO.setup(HardwarePin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
  216.         GPIO.add_event_detect(HardwarePin, GPIO.RISING, callback=HardwareLoggerCallback, bouncetime=BounceIntervalMs)
  217.     except:
  218.         LogExceptionInfo()
  219.     print 'Exit StartHardwareLogger()'
  220.  
  221. def HardwareLoggerCallback(ch):
  222.     print 'Enter HardwareLoggerCallback(ch)'
  223.     try:
  224.         global CurrentEnergyLevel,CountEnergyTicks,DateTime,NextLogTime
  225.         print "HardwareLoggerCallback"
  226.         CurrentEnergyLevel += 10
  227.         CountEnergyTicks += 1
  228.         DateTime = datetime.datetime.utcnow()
  229.         if(DateTime >= NextLogTime and CurrentEnergyLevel > 0):
  230.             NextLogTime = DateTime + HardwareLogInterval
  231.             LogEntry(CurrentEnergyLevel)
  232.             CurrentEnergyLevel = 0
  233.         '''if (CountEnergyTicks >= 3):
  234.             print "HardwareLoggerCallback 3"
  235.             GPIO.remove_event_detect(HardwarePin)
  236.             GPIO.cleanup()
  237.             StartHardwareLogger()'''
  238.     except:
  239.         #GPIO.cleanup()
  240.         LogExceptionInfo()
  241.         #StartHardwareLogger()
  242.     print 'Exit HardwareLoggerCallback(ch)'
  243.  
  244. def LogEntry(EnergyLevel):
  245.     print 'Enter LogEntry(EnergyLevel)'
  246.     f = None
  247.     try:
  248.         LoggingLock.acquire()
  249.         f = open(os.getcwd() + LogFile, "a+")
  250.         dateTime = datetime.datetime.utcnow()
  251.         data = f.read()
  252.         f.seek(0)
  253.         f.truncate()
  254.         jsonData = json.loads(data)
  255.         jsonData['LogEntries'].append({
  256.                 'Time': dateTime.isoformat(),
  257.                 'EnergyAmount': EnergyLevel,
  258.                 })
  259.         f.write(json.dumps(jsonData))
  260.     except ValueError as ex:
  261.         print ex
  262.         #Error in data, input valid sequence in file
  263.         print 'Decoding JSON failed!\nDocument:\n'
  264.         print data
  265.         jsonData = {
  266.                 'LogEntries': [{
  267.                         'Time': dateTime.isoformat(),
  268.                         'EnergyAmount': EnergyLevel
  269.                         }],
  270.                 'DeviceEntries': [],
  271.                 'ExceptionEntries': []
  272.         }
  273.         f.write(json.dumps(jsonData))
  274.         print 'JSON Data Restored!'
  275.     except Exception as ex:
  276.         if(f and not f.closed):
  277.             f.close()
  278.         LoggingLock.release()
  279.         LogExceptionInfo()
  280.         LoggingLock.acquire()
  281.         f = open(os.getcwd() + LogFile, "a+")
  282.     finally:
  283.         if(f and not f.closed):
  284.             f.close()
  285.         LoggingLock.release()
  286.     print 'Exit LogEntry(EnergyLevel)'
  287.  
  288. def LogAction(Info):
  289.     print 'Enter LogAction(Info)'
  290.     f = None
  291.     try:
  292.         LoggingLock.acquire()
  293.         f = open(os.getcwd() + LogFile, "a+")
  294.         dateTime = datetime.datetime.utcnow()
  295.         data = f.read()
  296.         f.seek(0)
  297.         f.truncate()
  298.         jsonData = json.loads(data)
  299.         jsonData['DeviceEntries'].append({'Time': dateTime.isoformat(), 'Action': Info})
  300.         f.write(json.dumps(jsonData))
  301.     except ValueError as ex:
  302.         #Error in data, input valid sequence in file
  303.         print 'Decoding JSON failed! Document:'
  304.         print data
  305.         jsonData = {
  306.                 'LogEntries': [],
  307.                 'DeviceEntries': [{'Time': dateTime.isoformat(), 'Action': Info}],
  308.                 'ExceptionEntries': []
  309.         }
  310.         f.write(json.dumps(jsonData))
  311.         print 'JSON Data Restored!'
  312.     except Exception as ex:
  313.         if(f and not f.closed):
  314.             f.close()
  315.         LoggingLock.release()
  316.         LogExceptionInfo()
  317.         LoggingLock.acquire()
  318.         f = open(os.getcwd() + LogFile, "a+")
  319.         LogExceptionInfo()
  320.     finally:
  321.         if(f and not f.closed):
  322.             f.close()
  323.         LoggingLock.release()
  324.     print 'Exit LogAction(Info)'
  325.  
  326. def CheckPostLog():
  327.     print 'Enter CheckPostLog()'
  328.     global NextPostTime, PostInterval, HardwareLogInterval, NextLogTime, Status
  329.     f = None
  330.     LatestBuild = CurrentBuild
  331.     print "Time is " + str(datetime.datetime.utcnow().isoformat()) + " and next post will occur after " + str(NextPostTime.isoformat())
  332.     if(datetime.datetime.utcnow() >= NextPostTime):
  333.         try:
  334.             LoggingLock.acquire()
  335.             NextPostTime = datetime.datetime.utcnow() + PostInterval
  336.             f = open(os.getcwd() + LogFile, "a+")
  337.             jsonData = json.loads(f.read())
  338.             jsonData['Time'] = datetime.datetime.utcnow().isoformat()
  339.             headers = { "Authorization" : AuthorizationType + AuthorizationCredentials, "Accept": "application/json", "Content-Type": "application/json" }
  340.             response = requests.post(BaseAPI + "/Logging/Log", headers = headers, json=jsonData)
  341.             data = response.json()
  342.             if(response.status_code == 200):
  343.                 print "Posted Log - Current Log was cleared"
  344.                 f.seek(0)
  345.                 f.truncate()
  346.                 jsonData = {
  347.                         'LogEntries': [],
  348.                         'DeviceEntries': [],
  349.                         'ExceptionEntries': []
  350.                 }
  351.                 f.write(json.dumps(jsonData))
  352.                 try:
  353.                     ConfigLock.acquire()
  354.                     Status = data['Status']
  355.                     HardwareLogInterval = datetime.timedelta(seconds=data['LogInterval'])
  356.                     PostInterval = datetime.timedelta(seconds=data['PostInterval'])
  357.                     NextLogTime = datetime.datetime.utcnow() + HardwareLogInterval
  358.                     NextPostTime = datetime.datetime.utcnow() + PostInterval
  359.                     LatestBuild = data['LatestBuild']
  360.                 finally:
  361.                     ConfigLock.release()
  362.             else:
  363.                 print "Error Sending Log: "
  364.                 print data
  365.         except ValueError as ex:
  366.             if(f and not f.closed):
  367.                 f.seek(0)
  368.                 f.truncate()
  369.                 jsonData = {
  370.                     'LogEntries': [],
  371.                     'DeviceEntries': [],
  372.                     'ExceptionEntries': []
  373.                 }
  374.                 f.write(json.dumps(jsonData))
  375.         except:
  376.             if(f and not f.closed):
  377.                 f.close()
  378.             LoggingLock.release()
  379.             LogExceptionInfo()
  380.             LoggingLock.acquire()
  381.             f = open(os.getcwd() + LogFile, "a+")
  382.         finally:
  383.             if(f and not f.closed):
  384.                 f.close()
  385.             LoggingLock.release()
  386.  
  387.         try:
  388.             if(LatestBuild != CurrentBuild):
  389.                 GetUpdates()
  390.         except:
  391.             LogExceptionInfo()
  392.     print 'Exit CheckPostLog()'
  393.  
  394.  
  395.  
  396.  
  397. ########-----Global Variables-----########
  398. ConfigLock = threading.Lock()
  399.  
  400. Status = 0
  401. PostInterval = datetime.timedelta(seconds=3)
  402. HardwareLogInterval = datetime.timedelta(seconds=5) #How often to log to file
  403. DateTime = datetime.datetime.utcnow()
  404. NextLogTime = DateTime + HardwareLogInterval
  405. NextPostTime = DateTime + PostInterval
  406. BounceIntervalMs = 50 #Note, anything logged in this interval won't be counted
  407. HardwarePin = 24 #GPIO24
  408.  
  409.  
  410. AuthorizationLock = threading.Lock()
  411.  
  412. BaseAPI = "http://192.168.1.16:8080/API/"
  413. BaseAuth = "http://192.168.1.16:8080/oauth/token"
  414. AuthorizationType = ""
  415. AuthorizationCredentials = ""
  416. AuthorizationExpires = datetime.datetime.utcnow()
  417. Authorized = False
  418. LoginAccountUsername = "Device@AndrewPeters"
  419. LoginAccountPassword = "p4ssw0rd"
  420.  
  421.  
  422. LoggingLock = threading.Lock()
  423.  
  424. CurrentEnergyLevel = 0
  425. CountEnergyTicks = 0
  426. #CPUSerial = GetCPUSerial()
  427. LogFile = "/Log.json"
  428. UpdaterFile = "/Updater.py"
  429. CurrentBuild = 1
  430.  
  431. ########-----Main Program-----########
  432. print "\n==================="
  433. print "PowerCoins Logger - Running"
  434. print "===================\n"
  435.  
  436. while True:
  437.     try:
  438.  
  439.        
  440.         LogAction("BOOT")
  441.         StartHardwareLogger()
  442.         while(True):
  443.             GetAuthorizationToken()
  444.             if(Authorized):
  445.                 break
  446.             else:
  447.                 time.sleep(30)
  448.         GetConfig()
  449.         while True:
  450.             time.sleep(3)
  451.             if(randint(0,15) > 14):
  452.                 LogEntry(randint(30,120))
  453.             CheckPostLog()
  454.        
  455.     except Exception as e:
  456.         print e
  457.         LogAction("EXIT(AUTORESTART)")
  458.         GPIO.cleanup()
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top