Smart cassette fallback on dispenser pickup errors #27
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Currently, when a bill dispenser encounters a pickup error (e.g., cassette fails to grab a bill), the machine shows "Out of money" to the customer — even when other cassettes are full and working. This happens because the current lamassu-machine error handling treats any dispense error as terminal: close the serial port, mark as uninitialized, show "out of cash".
This is a poor UX. A customer who just deposited cash sees "out of money" when the ATM could have fulfilled their withdrawal from a different cassette.
Current behavior (lamassu-machine)
puloonrs232.jsdispatches a single dispense command with[count_cassette1, count_cassette2, ...]puloon-dispenser.jscallsthis.close()— serial port closed,initialized = falsebrain.jssees the error, stores it in the transaction log, shows "Out of cash" screenNo retry or fallback logic exists.
Proposed behavior
On a recoverable dispense error (pickup error, bill-end on one cassette), the dispenser should attempt to fulfill the remaining amount from other cassettes before giving up.
How it works
The Puloon dispense response already tells us per-cassette
dispensedandrejectedcounts. So on error we know:Retry strategy:
requested - already_dispensedRecoverable vs terminal errors
Recoverable (worth retrying from another cassette):
Terminal (don't retry, hardware needs attention):
Scope
BillDispenser.dispense()interface already returns per-cassette results, so the retry logic can live in a shared layer above the driverWhere it fits
The retry logic should live in the state machine / ATM store layer (not inside the driver), since:
Example scenario (Tejo, 4 cassettes)
Config: Cassette 1 = $5, Cassette 2 = $20, Cassette 3 = $50, Cassette 4 = $100
Customer requests $120 cash-out. Optimal combo: 1x$100 + 1x$20.
[0, 1, 0, 1](1 from cassette 2, 1 from cassette 4)[0, 0, 2, 0]Without this feature, step 2 would show "Out of money" despite cassettes 1, 2, 3 all being full.