mdb: support vend success/failure/completion, checksum cleanup

master
informatic 2023-07-15 21:58:03 +02:00
parent fc4e256acb
commit 3db2cfb7f8
2 changed files with 37 additions and 28 deletions

View File

@ -39,12 +39,19 @@ class BitvendCashlessMDBDevice(CashlessMDBDevice):
db.session.commit()
self.current_tx_id = None
cashless_purchase_counter.inc()
return True
def vend_failure(self):
with self.app.app_context():
self.logger.info("Reverting transaction {}...".format(self.current_tx_id))
Transaction.query.filter(Transaction.id == self.current_tx_id).delete()
db.session.commit()
def vend_complete(self):
self.logger.info("Vend complete!")
self.current_tx_id = None
cashless_purchase_counter.inc()
last_purchase = 0
def process_request(self, req):

View File

@ -9,6 +9,7 @@ except ImportError:
try:
import cygpio
from cygpio import CythonRaspiBackend
except ImportError:
cygpio = None
@ -33,17 +34,18 @@ class MDBRequest(object):
self.data = bytearray()
def validate_checksum(self):
if not self.data:
return False
try:
if self.ack:
if len(self.data) == 1 and self.processed:
return True # Only ACK
return self.data[-2] == compute_checksum(self.command, self.data[:-2])
return len(self.data) >= 2 and self.data[-2] == compute_checksum(
self.command, self.data[:-2]
)
else:
return self.data[-1] == compute_checksum(self.command, self.data[:-1])
return len(self.data) >= 1 and self.data[-1] == compute_checksum(
self.command, self.data[:-1]
)
except KeyboardInterrupt:
raise
except:
@ -184,23 +186,6 @@ class CashlessMDBDevice(MDBDevice):
lockup_counter = 0
def process_request(self, req):
# FIXME this shouldn't be required...
# if req.command == 0x30 and req.validate_checksum():
# self.lockup_counter += 1
# if self.lockup_counter % 50 == 0:
# self.logger.info('YOLO')
# return []
# return
# if req.command == 0x31 and req.validate_checksum():
# return []
# if req.command == 0x37 and req.validate_checksum():
# return []
# if req.command == 0x36 and req.validate_checksum():
# return []
# if req.command == 0x34 and req.validate_checksum():
# return []
if (req.command & self.base_address) != self.base_address:
# Target mismatch
return
@ -254,15 +239,18 @@ class CashlessMDBDevice(MDBDevice):
elif req.data[0] == 0x02: # vend succ
self.logger.info("VEND: success %r", req)
self.vend_success()
return []
elif req.data[0] == 0x03:
self.logger.info("VEND: failure")
self.vend_failure()
return []
elif req.data[0] == 0x04:
self.logger.info("VEND: session complete %r", req)
self.state = "OK"
self.vend_complete()
return [0x07]
elif req.data[0] == 0x05:
@ -311,8 +299,9 @@ class CashlessMDBDevice(MDBDevice):
return []
def begin_session(self, amount):
self.logger.info("Beginning session for %d", amount)
# Begins new session with balance provided
self.logger.info("Beginning session for %d", amount)
if amount > 10000:
amount = 10000
@ -323,9 +312,22 @@ class CashlessMDBDevice(MDBDevice):
self.poll_queue.put([0x04])
def vend_request(self, product, value):
# Called when user selects a product
# Called when user selects a product - funds shall be locked here
return True
def vend_success(self):
# Called when product has been released to user - funds shall be
# deducted here
pass
def vend_failure(self):
# Called when product release has failed - funds shall be reverted here
pass
def vend_complete(self):
# Called after vend request/success/failure
pass
@property
def online(self):
return time.time() - self.last_poll < 5