Advertisement
Guest User

Untitled

a guest
Jul 6th, 2018
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.87 KB | None | 0 0
  1. #!/usr/bin/python3 -B
  2. # -*- coding: utf-8 -*-
  3. from psycopg2 import connect,extras
  4. from time import mktime,sleep,time
  5. from secrets import dbpass,nagios
  6. from requests import get,post
  7. from datetime import datetime
  8. from json import dumps,loads
  9. from re import finditer,match
  10. from sys import stdout
  11.  
  12. def check_polling(atm):
  13. cursor.execute("SELECT EXTRACT(EPOCH FROM created) FROM machine_pings WHERE device_id='"+atm['device_id']+"' ORDER BY created DESC LIMIT 1")
  14. ping = int(time()-cursor.fetchone()[0])
  15. if ping > 1200: pingstatus = 2
  16. elif ping > 420: pingstatus = 1
  17. else: pingstatus = 0
  18. post(nagios+'/submit_result',headers={'content-type':'application/json'},timeout=10,data=dumps({'host':atm['name'],'status':pingstatus,'output':str(ping)+' s'}))
  19.  
  20. def check_cash_in_balance(atm):
  21. comments = nagios_status['content'][atm['name']]['services']['Säiliö']['comments']
  22. emptied = None
  23. balance = 0
  24. while not emptied:
  25. last = str(max(map(int,comments.keys())))
  26. data = match('(\d+)€( +\d+-\d+-\d+ \d+:\d+(?:\d+))?',comments[last]['comment_data'])
  27. if data and data.group(1):
  28. balance += int(data.group(1))
  29. if data.group(2): emptied = data.group(2)
  30. else: emptied = datetime.fromtimestamp(float(comments[last]['entry_time'])).strftime('%Y-%m-%d %H:%M:%S')
  31. else: del comments[last]
  32. cursor.execute("SELECT b.fiat,count(*) FROM bills AS b JOIN cash_in_txs AS c ON b.cash_in_txs_id=c.id JOIN devices AS d ON c.device_id=d.device_id WHERE d.name='"+atm['name']+"' AND b.created>'"+emptied+"' GROUP BY b.fiat,d.name")
  33. billcounts = {'total':0}
  34. for r in cursor.fetchall():
  35. billcounts['total'] += r['count']
  36. if r['fiat'] in (20,50,100,200,500): billcounts[r['fiat']] = r['count']
  37. balance += r['fiat']*r['count']
  38. output = str(balance)+' € ('+str(billcounts['total'])+' kpl)'
  39. if len(billcounts) > 1:
  40. outputdetail = []
  41. for d in [20,50,100,200,500]:
  42. if d in billcounts.keys(): outputdetail.append(str(billcounts[d])+'×'+str(d)+'€')
  43. output += ' ('+' '.join(outputdetail)+')'
  44. if billcounts['total'] > 440 or balance > 30000: status=2
  45. elif billcounts['total'] > 350 or balance > 20000: status=1
  46. else: status = 0
  47. post(nagios+'/submit_result',headers={'content-type':'application/json'},timeout=10,data=dumps({'host':atm['name'],'service':'Säiliö','status':status,'output':output}))
  48.  
  49. def check_cash_out_balance(atm):
  50. update_cash_out_balance(atm)
  51. denoms = {'top':atm_denominations[atm['name']][0],'bottom':atm_denominations[atm['name']][1]}
  52. cash = atm['cassette1']*denoms['top'] + atm['cassette2']*denoms['bottom']
  53. if cash < 3000 or cash > 30000: status = 2
  54. elif cash < 5000 or cash > 20000: status = 1
  55. else: status = 0
  56. if cash:
  57. bills = []
  58. if atm['cassette1']: bills.append(str(atm['cassette1'])+'×'+str(denoms['top'])+'€')
  59. if atm['cassette2']: bills.append(str(atm['cassette2'])+'×'+str(denoms['bottom'])+'€')
  60. output = str(cash)+' € ('+' '.join(bills)+')'
  61. else: output = 'OUT OF CASH'
  62. post(nagios+'/submit_result',headers={'content-type':'application/json'},timeout=10,data=dumps({'host':atm['name'],'service':'Myynti','status':status,'output':output}))
  63.  
  64. def check_dispense_errors(atm):
  65. cursor.execute("SELECT NOW()-MAX(a.created) AS last_error_time, SUM(a.provisioned_1-a.dispensed_1) AS dispense_errors_1, SUM(a.provisioned_2-a.dispensed_2) AS dispense_errors_2 FROM cash_out_actions AS a JOIN cash_out_txs AS t ON a.tx_id=t.id JOIN devices AS d ON t.device_id=d.device_id WHERE d.name='"+atm['name']+"' AND (a.dispensed_1!=a.provisioned_1 OR a.dispensed_2!=a.provisioned_2) AND (a.error IS NULL OR a.error NOT LIKE 'refund txid %')");
  66. response = cursor.fetchone()
  67. errors = {}
  68. status = 0
  69. if response['dispense_errors_1']:
  70. errors['Top'] = response['dispense_errors_1']
  71. status += 1
  72. if response['dispense_errors_2']:
  73. errors['Bottom'] = response['dispense_errors_2']
  74. status += 1
  75. if errors:
  76. output = 'Dispense failed '+str(response['last_error_time'])+' ago ('+' '.join(errors)+')'
  77. else:
  78. output = 'OK'
  79. post(nagios+'/submit_result',headers={'content-type':'application/json'},timeout=10,data=dumps({'host':atm['name'],'service':'Virhetilanne','status':status,'output':output}))
  80.  
  81. def update_cash_out_balance(atm):
  82. comments = nagios_status['content'][atm['name']]['services']['Myynti']['comments']
  83. last = str(max(map(int,comments.keys())))
  84. lastfile = open('Myynti-CommentID-'+atm['name'],'r')
  85. if last > lastfile.read():
  86. lastfile = open('Myynti-CommentID-'+atm['name'],'w')
  87. lastfile.write(last+'\n')
  88. for match in finditer('(-?\d+)x(\d+)€',comments[last]['comment_data']):
  89. matched_amount = int(match.group(1))
  90. matched_denom = int(match.group(2))
  91. if matched_denom == atm_denominations[atm['name']][0]:
  92. print(atm['name']+': '+str(matched_amount)+'x'+str(matched_denom)+'€')
  93. cursor.execute("UPDATE devices SET cassette1="+str(matched_amount)+"+cassette1 WHERE device_id='"+atm['device_id']+"'")
  94. database.commit()
  95. elif matched_denom == atm_denominations[atm['name']][1]:
  96. print(atm['name']+': '+str(matched_amount)+'x'+str(matched_denom)+'€')
  97. cursor.execute("UPDATE devices SET cassette2="+str(matched_amount)+"+cassette2 WHERE device_id='"+atm['device_id']+"'")
  98. database.commit()
  99.  
  100. atm_denominations = {
  101. 'Finnvape':[20,50],
  102. 'Turku':[20,50] ,
  103. 'Oulu':[20,50] ,
  104. }
  105.  
  106. database = connect("host='127.0.0.1' dbname='lamassu' user='lamassu_pg' password='"+dbpass+"'")
  107. cursor = database.cursor(cursor_factory=extras.DictCursor)
  108. while True:
  109. nagios_status = loads(get(nagios+'/state',timeout=10).text)
  110. cursor.execute('SELECT * FROM devices WHERE paired')
  111. for atm in cursor.fetchall():
  112. check_polling(atm)
  113. check_cash_in_balance(atm)
  114. check_cash_out_balance(atm)
  115. check_dispense_errors(atm)
  116. database.commit()
  117. stdout.flush()
  118. sleep(20)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement