Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python3 -B
- # -*- coding: utf-8 -*-
- from psycopg2 import connect,extras
- from time import mktime,sleep,time
- from secrets import dbpass,nagios
- from requests import get,post
- from datetime import datetime
- from json import dumps,loads
- from re import finditer,match
- from sys import stdout
- def check_polling(atm):
- cursor.execute("SELECT EXTRACT(EPOCH FROM created) FROM machine_pings WHERE device_id='"+atm['device_id']+"' ORDER BY created DESC LIMIT 1")
- ping = int(time()-cursor.fetchone()[0])
- if ping > 1200: pingstatus = 2
- elif ping > 420: pingstatus = 1
- else: pingstatus = 0
- post(nagios+'/submit_result',headers={'content-type':'application/json'},timeout=10,data=dumps({'host':atm['name'],'status':pingstatus,'output':str(ping)+' s'}))
- def check_cash_in_balance(atm):
- comments = nagios_status['content'][atm['name']]['services']['Säiliö']['comments']
- emptied = None
- balance = 0
- while not emptied:
- last = str(max(map(int,comments.keys())))
- data = match('(\d+)€( +\d+-\d+-\d+ \d+:\d+(?:\d+))?',comments[last]['comment_data'])
- if data and data.group(1):
- balance += int(data.group(1))
- if data.group(2): emptied = data.group(2)
- else: emptied = datetime.fromtimestamp(float(comments[last]['entry_time'])).strftime('%Y-%m-%d %H:%M:%S')
- else: del comments[last]
- 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")
- billcounts = {'total':0}
- for r in cursor.fetchall():
- billcounts['total'] += r['count']
- if r['fiat'] in (20,50,100,200,500): billcounts[r['fiat']] = r['count']
- balance += r['fiat']*r['count']
- output = str(balance)+' € ('+str(billcounts['total'])+' kpl)'
- if len(billcounts) > 1:
- outputdetail = []
- for d in [20,50,100,200,500]:
- if d in billcounts.keys(): outputdetail.append(str(billcounts[d])+'×'+str(d)+'€')
- output += ' ('+' '.join(outputdetail)+')'
- if billcounts['total'] > 440 or balance > 30000: status=2
- elif billcounts['total'] > 350 or balance > 20000: status=1
- else: status = 0
- post(nagios+'/submit_result',headers={'content-type':'application/json'},timeout=10,data=dumps({'host':atm['name'],'service':'Säiliö','status':status,'output':output}))
- def check_cash_out_balance(atm):
- update_cash_out_balance(atm)
- denoms = {'top':atm_denominations[atm['name']][0],'bottom':atm_denominations[atm['name']][1]}
- cash = atm['cassette1']*denoms['top'] + atm['cassette2']*denoms['bottom']
- if cash < 3000 or cash > 30000: status = 2
- elif cash < 5000 or cash > 20000: status = 1
- else: status = 0
- if cash:
- bills = []
- if atm['cassette1']: bills.append(str(atm['cassette1'])+'×'+str(denoms['top'])+'€')
- if atm['cassette2']: bills.append(str(atm['cassette2'])+'×'+str(denoms['bottom'])+'€')
- output = str(cash)+' € ('+' '.join(bills)+')'
- else: output = 'OUT OF CASH'
- post(nagios+'/submit_result',headers={'content-type':'application/json'},timeout=10,data=dumps({'host':atm['name'],'service':'Myynti','status':status,'output':output}))
- def check_dispense_errors(atm):
- 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 %')");
- response = cursor.fetchone()
- errors = {}
- status = 0
- if response['dispense_errors_1']:
- errors['Top'] = response['dispense_errors_1']
- status += 1
- if response['dispense_errors_2']:
- errors['Bottom'] = response['dispense_errors_2']
- status += 1
- if errors:
- output = 'Dispense failed '+str(response['last_error_time'])+' ago ('+' '.join(errors)+')'
- else:
- output = 'OK'
- post(nagios+'/submit_result',headers={'content-type':'application/json'},timeout=10,data=dumps({'host':atm['name'],'service':'Virhetilanne','status':status,'output':output}))
- def update_cash_out_balance(atm):
- comments = nagios_status['content'][atm['name']]['services']['Myynti']['comments']
- last = str(max(map(int,comments.keys())))
- lastfile = open('Myynti-CommentID-'+atm['name'],'r')
- if last > lastfile.read():
- lastfile = open('Myynti-CommentID-'+atm['name'],'w')
- lastfile.write(last+'\n')
- for match in finditer('(-?\d+)x(\d+)€',comments[last]['comment_data']):
- matched_amount = int(match.group(1))
- matched_denom = int(match.group(2))
- if matched_denom == atm_denominations[atm['name']][0]:
- print(atm['name']+': '+str(matched_amount)+'x'+str(matched_denom)+'€')
- cursor.execute("UPDATE devices SET cassette1="+str(matched_amount)+"+cassette1 WHERE device_id='"+atm['device_id']+"'")
- database.commit()
- elif matched_denom == atm_denominations[atm['name']][1]:
- print(atm['name']+': '+str(matched_amount)+'x'+str(matched_denom)+'€')
- cursor.execute("UPDATE devices SET cassette2="+str(matched_amount)+"+cassette2 WHERE device_id='"+atm['device_id']+"'")
- database.commit()
- atm_denominations = {
- 'Finnvape':[20,50],
- 'Turku':[20,50] ,
- 'Oulu':[20,50] ,
- }
- database = connect("host='127.0.0.1' dbname='lamassu' user='lamassu_pg' password='"+dbpass+"'")
- cursor = database.cursor(cursor_factory=extras.DictCursor)
- while True:
- nagios_status = loads(get(nagios+'/state',timeout=10).text)
- cursor.execute('SELECT * FROM devices WHERE paired')
- for atm in cursor.fetchall():
- check_polling(atm)
- check_cash_in_balance(atm)
- check_cash_out_balance(atm)
- check_dispense_errors(atm)
- database.commit()
- stdout.flush()
- sleep(20)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement