FabLabKasse.cashPayment.client package

Subpackages

Submodules

FabLabKasse.cashPayment.client.PaymentDeviceClient module

Client for accessing a cash device driver.

class FabLabKasse.cashPayment.client.PaymentDeviceClient.PaymentDeviceClient(cmd, options)[source]

Bases: object

Client for accessing a cash device driver. It starts a new python process (“server”) for the specified device driver. It uses non-blocking communication and talks to the server process using stdin/stdout.

accept(maximumPayin)[source]

accept up to maximumPayin money, until stopAccepting() is called

poll() must be called before other actions are taken

canAccept()[source]

does the device support accept commands?

(If this function has not returned True/False once before, it may only be called while no operation is in progress and will raise an Exception otherwise. )

return values and usage:

  • None: please call the function again later. The answer has not yet been received from the device. No other actions (dispense/accept/possibleDispense) may be called until a non-None value was returned! call poll() repeatedly until canAccept() != None
  • True/False: Does (not) support accepting. (Now the answer is cached and may the function may be called again
    always)
Return type:boolean | None
dispense(amount)[source]

Dispense up to the requested amount of money (as much as possible)

  • Wait until hasStopped() is true, then retrieve the paid out value with getFinalAmountAndReset()
  • An intermediate value (as a progess report) can be retrieved with getCurrentAmount, but the operation cannot
    be aborted.
  • If you want to make sure that enough is available, see possibleDispense()
empty()[source]

start service-mode emptying

The implementation of this modes is device specific:

  • If the device has an inaccessible storage, it should move the contents to the cashbox so that it can be taken out for counting.
  • If available, manual payout buttons are enabled.

usage:

  • call empty()
  • sleep, do something else, whatever you want…
  • call poll() at least once before the next step:
  • as soon as you want to stop, call stopEmptying()
  • call hasStopped() until it returns True
  • then call getFinalAmountAndReset()
getCurrentAmount()[source]

how much has currently been paid in? (value is not always up-to-date, but will not be higher than the actual value)

getFinalAmountAndReset()[source]

call this as soon as hasStopped() is true. this returns the final amount paid in/out (negative for payout)

hasStopped()[source]

returns True as soon as the operation (accept/dispense) has finished

poll()[source]

update internal status

call this regularly

Raise:Exception if the device crashed - do not try to recover from this exception, or the result of any following calls will be undefined
possibleDispense()[source]

how much can be paid out?

(function may only be called while no operation is in progress, will raise Exception otherwise)

return value:

  • None: request in progress, please call the function again until it does not return None. No other actions (dispense/accept/canPayout) may be called until a non-None value was returned! Call poll() repeatedly until possibleDispense()!=None.
  • [maximumAmount, remainingAmount]: This one non-None response is not cached, another call will send return None again and send a new query to the device
    • maximumAmount (int): the device has enough money to pay out any amount up to maximumAmount
    • remainingAmount (int): How much money could be remaining at worst, if canBePaid==True? This is usually a per-device constant. remainingAmount will be == 0 for a small-coins dispenser that includes 1ct.

Important

it can be still possible to payout more, but not any value above maximumAmount!

For example a banknote dispenser filled with 2*10€ and 5*100€ bills will return:

possibleDispense() == [2999, 999] which means “can payout any value in 0…29,99€ with an unpaid rest of <= 9,99€”

But it can still fulfill a request of exactly 500€!

Return type:None | [int, int]
stopAccepting()[source]

stop accepting (does not work immediately - some payins may be possible!)

Return type:None
stopEmptying()[source]

end the mode that was started by empty()

usage: see empty()

updateAcceptValue(maximumPayin)[source]

lower the amount of money that is accepted at maximum

this can be called while accept is active

example use case:
  • Two payment devices should accept 50€ in total.
  • 10€ were inserted into the first device -> update the second device to a maximum of 40€.

FabLabKasse.cashPayment.client.PaymentDevicesManager module

class FabLabKasse.cashPayment.client.PaymentDevicesManager.PaymentDevicesManager(cfg)[source]

Bases: object

abortPayin()[source]
canPayout()[source]

returns values [totalMaximumRequest, totalRemaining]:

every requested amount <= totalMaximumRequest can be paid out, with an unpaid rest <= totalRemaining (the return value is only a conservative estimate, not the theoretical optimum)

Please warn the user if totalMaximumRequest is too low for the possible change

if this function returns None, the value is still being fetched. In this case, sleep some time, then call poll() and then call the function again.

empty()[source]

start service-empty mode

see PaymentDeviceClient.empty

Return type:None
getCurrentAmount()[source]

get intermediate amount, how much was paid in or out

getFinalAmount()[source]

if stopped, return the final amount and reset to idle state

else, return None

payin(requested, maximum)[source]
payout(value)[source]
poll()[source]

call repeatedly to update status

Return type:None
startingUp()[source]

return True if devices are still being started

No action methods may be called until this returns False

statusText()[source]
stopEmptying()[source]

exit service-empty mode

use getFinalAmount() afterwards

Return type:None
class FabLabKasse.cashPayment.client.PaymentDevicesManager.PaymentDevicesManagerTest(methodName='runTest')[source]

Bases: unittest.case.TestCase

Test PaymentDevicesManager

test_canPayout_with_one_random_datapoint_on_example_server()[source]

test the _canPayout_total() function with 10 random datapoints and the exampleserver (from example config)

FabLabKasse.cashPayment.client.PaymentDevicesManager.demo()[source]

Simple demonstration using two exampleServer devices

Module contents