Advertisement
Guest User

Untitled

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