2023-04-19 16:26:12 +02:00
# include "src/ATBAPP/ATBDeviceControllerPlugin.h"
# include "src/ATBAPP/ATBHealthEvent.h"
2023-06-21 10:55:12 +02:00
# include "src/ATBAPP/ATBMachineEvent.h"
2023-06-19 16:26:33 +02:00
# include "src/ATBAPP/Utils.h"
2023-07-05 18:47:45 +02:00
# include "src/ATBAPP/support/JSON.h"
2023-07-20 08:15:03 +02:00
# include "src/ATBAPP/support/DBusControllerInterface.h"
2023-08-03 09:10:44 +02:00
# include "src/ATBAPP/support/PTUSystem.h"
2023-11-30 18:15:07 +01:00
# include "src/ATBAPP/support/CashUtils.h"
2023-04-19 16:26:12 +02:00
2023-05-03 11:56:36 +02:00
# include <QTimer>
2023-07-10 16:09:16 +02:00
# include <QThread>
2023-05-04 13:21:14 +02:00
# include <QTextCodec>
2023-06-05 12:49:20 +02:00
# include <QDebug>
# include <QPluginLoader>
# include <QDateTime>
2023-06-15 14:15:13 +02:00
# include <QFileInfo>
2023-06-22 08:50:10 +02:00
# include <QCoreApplication>
# include <QUuid>
2023-05-03 11:56:36 +02:00
2023-06-19 16:26:33 +02:00
# include <cstdlib>
2023-04-19 16:26:12 +02:00
2023-06-22 08:50:10 +02:00
ATBDeviceControllerPlugin : : ATBDeviceControllerPlugin ( QObject * parent )
2023-11-21 11:21:28 +01:00
: isMaster ( false )
, pluginState ( PLUGIN_STATE : : NOT_INITIALIZED )
2023-06-22 08:50:10 +02:00
, eventReceiver ( nullptr )
2023-04-19 16:26:12 +02:00
{
2023-06-20 13:11:40 +02:00
this - > setParent ( parent ) ;
2023-04-19 16:26:12 +02:00
this - > pluginInfo = QString : : fromUtf8 ( pluginInfoString . c_str ( ) ) ;
2023-06-05 12:49:20 +02:00
if ( ! this - > private_loadCashAgentLib ( " " ) ) {
return ;
}
2023-07-20 08:15:03 +02:00
this - > init_sc_dbus ( ) ;
2023-06-16 11:21:24 +02:00
//connect(dynamic_cast<QObject*>(hw), SIGNAL(hwapi_templatePrintFinished_OK()), this, SLOT(onPrintFinishedOK()), Qt::QueuedConnection);
//connect(dynamic_cast<QObject*>(hw), SIGNAL(hwapi_templatePrintFinished_Err()), this, SLOT(onPrintFinishedERR()), Qt::QueuedConnection);
2023-11-23 17:59:49 +01:00
connect ( dynamic_cast < QObject * > ( hw ) , SIGNAL ( hwapi_gotNewCoin ( ) ) , this , SLOT ( onCashGotCoin ( ) ) , Qt : : QueuedConnection ) ;
connect ( dynamic_cast < QObject * > ( hw ) , SIGNAL ( hwapi_payStopByMax ( ) ) , this , SLOT ( onCashPayStopByMax ( ) ) , Qt : : QueuedConnection ) ;
connect ( dynamic_cast < QObject * > ( hw ) , SIGNAL ( hwapi_payStopByPushbutton ( ) ) , this , SLOT ( onCashPayStopByPushbutton ( ) ) , Qt : : QueuedConnection ) ;
connect ( dynamic_cast < QObject * > ( hw ) , SIGNAL ( hwapi_payStopByEscrow ( ) ) , this , SLOT ( onCashPayStopByEscrow ( ) ) , Qt : : QueuedConnection ) ;
connect ( dynamic_cast < QObject * > ( hw ) , SIGNAL ( hwapi_payStopByError ( ) ) , this , SLOT ( onCashPayStopByError ( ) ) , Qt : : QueuedConnection ) ;
connect ( dynamic_cast < QObject * > ( hw ) , SIGNAL ( hwapi_payStopByTimeout ( ) ) , this , SLOT ( onCashPayStopByTimeout ( ) ) , Qt : : QueuedConnection ) ;
2023-06-16 11:21:24 +02:00
connect ( dynamic_cast < QObject * > ( hw ) , SIGNAL ( hwapi_doorServiceDoorOpened ( ) ) , this , SLOT ( onServiceDoorOpened ( ) ) , Qt : : QueuedConnection ) ; // switch to ModeSERVICE
connect ( dynamic_cast < QObject * > ( hw ) , SIGNAL ( hwapi_doorVaultDoorOpened ( ) ) , this , SLOT ( onVaultDoorOpened ( ) ) , Qt : : QueuedConnection ) ; // Screen?? with message
connect ( dynamic_cast < QObject * > ( hw ) , SIGNAL ( hwapi_doorCoinBoxRemoved ( ) ) , this , SLOT ( onCoinBoxRemoved ( ) ) , Qt : : QueuedConnection ) ; // Create/Send Account
connect ( dynamic_cast < QObject * > ( hw ) , SIGNAL ( hwapi_doorCoinBoxInserted ( ) ) , this , SLOT ( onCoinBoxInserted ( ) ) , Qt : : QueuedConnection ) ;
2023-06-20 13:23:36 +02:00
connect ( dynamic_cast < QObject * > ( hw ) , SIGNAL ( hwapi_doorCBinAndAllDoorsClosed ( ) ) , this , SLOT ( onCBinAndAllDoorsClosed ( ) ) , Qt : : QueuedConnection ) ;
2023-06-16 11:21:24 +02:00
connect ( dynamic_cast < QObject * > ( hw ) , SIGNAL ( hwapi_doorAllDoorsClosed ( ) ) , this , SLOT ( onAllDoorsClosed ( ) ) , Qt : : QueuedConnection ) ; // check for errors, switch to mode IDLE
2023-06-13 17:00:17 +02:00
2023-07-10 16:09:16 +02:00
// move hw object to separate thread:
auto hwThread = new QThread ;
dynamic_cast < QObject * > ( hw ) - > moveToThread ( hwThread ) ;
hwThread - > start ( ) ;
2023-06-13 17:00:17 +02:00
2023-06-22 08:50:10 +02:00
this - > diag = new DeviceControllerDiag ( this ) ;
2023-07-05 18:47:45 +02:00
connect ( this - > diag , & DeviceControllerDiag : : newVoltage , this , & ATBDeviceControllerPlugin : : onNewVoltage ) ;
2023-06-22 08:50:10 +02:00
2023-06-09 11:18:39 +02:00
this - > currentSelectedTicketType = 0 ;
2023-06-16 15:50:25 +02:00
this - > currentCashState = CASH_STATE : : CACHE_EMPTY ;
2023-11-30 18:16:45 +01:00
this - > cashStartAmountInt = 0 ;
2023-04-19 16:26:12 +02:00
}
ATBDeviceControllerPlugin : : ~ ATBDeviceControllerPlugin ( ) { }
2023-06-21 10:55:12 +02:00
PLUGIN_STATE ATBDeviceControllerPlugin : : initDCPlugin ( QObject * eventReceiver , const QSettings & settings )
2023-04-19 16:26:12 +02:00
{
2023-06-21 10:55:12 +02:00
this - > eventReceiver = eventReceiver ;
2023-04-19 16:26:12 +02:00
2023-05-02 17:39:38 +02:00
// read variables from setting
2023-11-24 09:30:05 +01:00
this - > serialPortName = settings . value ( " ATBDeviceControllerPlugin/serialPort " , " ttymxc2 " ) . toString ( ) ;
QByteArray printerEncoding = settings . value ( " ATBDeviceControllerPlugin/printerEncoding " , " ISO 8859-2 " ) . toString ( ) . toLatin1 ( ) ;
2023-12-01 15:07:29 +01:00
QString printerLocaleString = settings . value ( " ATBDeviceControllerPlugin/printerLocale " , " de_DE " ) . toString ( ) . toLatin1 ( ) ;
this - > printerLocale = QLocale ( printerLocaleString ) ;
2023-04-19 16:26:12 +02:00
2023-11-21 11:21:28 +01:00
if ( this - > isMaster ) {
// open serial port
hw - > dc_openSerial ( 5 , " 115200 " , this - > serialPortName , 1 ) ;
hw - > dc_autoRequest ( true ) ;
}
2023-06-15 09:48:25 +02:00
2023-08-03 09:10:44 +02:00
hw - > dc_setNewCustomerNumber ( PTUSystem : : readCustomerNumber ( ) ) ;
hw - > dc_setNewMachineNumber ( PTUSystem : : readMachineNumber ( ) ) ;
hw - > dc_setNewZone ( PTUSystem : : readZoneNumber ( ) ) ;
hw - > dc_setNewBorough ( PTUSystem : : readGroupNumber ( ) ) ;
2023-06-12 09:51:34 +02:00
hw - > rtc_setDateTime ( ) ;
2023-06-15 14:18:32 +02:00
// this is necessary to init the CashAgentLib (!)
hw - > vend_failed ( ) ;
2023-05-04 13:21:14 +02:00
// text encoding for printer
this - > codec = QTextCodec : : codecForName ( printerEncoding ) ;
2023-11-24 09:32:00 +01:00
if ( this - > codec = = nullptr ) {
printerEncoding = " ISO 8859-1 " ;
qCritical ( ) < < " ATBDeviceControllerPlugin: ERROR: printer encoding \" " < < printerEncoding < < " \" is not supported! " ;
qCritical ( ) < < " ... use default encoding: " < < printerEncoding ;
this - > codec = QTextCodec : : codecForName ( printerEncoding ) ;
}
else {
qCritical ( ) < < " ATBDeviceControllerPlugin: Set printer encoding to " < < printerEncoding ;
}
2023-06-22 08:50:10 +02:00
this - > diag - > init ( this - > hw , this - > eventReceiver ) ;
2023-05-04 13:21:14 +02:00
2023-04-19 16:26:12 +02:00
this - > pluginState = PLUGIN_STATE : : INITIALIZED ;
return pluginState ;
}
2023-06-30 10:40:14 +02:00
void ATBDeviceControllerPlugin : : startPhysicalLayer ( )
{
2023-11-21 11:21:28 +01:00
if ( ! this - > isMaster ) return ;
2023-06-30 10:40:14 +02:00
if ( this - > pluginState = = PLUGIN_STATE : : NOT_INITIALIZED )
{
qCritical ( ) < < " ATBDeviceControllerPlugin::startPhysicalLayer(): plugin is not initialized " ;
return ;
}
// open serial port
hw - > dc_openSerial ( 5 , " 115200 " , this - > serialPortName , 1 ) ;
hw - > dc_autoRequest ( true ) ;
}
void ATBDeviceControllerPlugin : : stopPhysicalLayer ( )
{
2023-11-21 11:21:28 +01:00
if ( ! this - > isMaster ) return ;
2023-06-30 10:40:14 +02:00
if ( this - > pluginState = = PLUGIN_STATE : : NOT_INITIALIZED )
{
qCritical ( ) < < " ATBDeviceControllerPlugin::startPhysicalLayer(): plugin is not initialized " ;
return ;
}
hw - > dc_autoRequest ( false ) ;
hw - > dc_closeSerial ( ) ;
}
2023-07-05 12:44:45 +02:00
void ATBDeviceControllerPlugin : : reboot ( )
{
// note:
// - dc reset lasts about ~5s !
// - makes a power cycle to certain components, e.g. card terminal
hw - > bl_rebootDC ( ) ;
}
2023-06-30 10:40:14 +02:00
2023-07-05 10:22:41 +02:00
void ATBDeviceControllerPlugin : : reset ( )
{
2023-07-05 12:44:45 +02:00
// note:
// - dc reset lasts about ~5s !
// - makes a power cycle to certain components, e.g. card terminal
2023-07-05 10:22:41 +02:00
hw - > dc_OrderToReset ( ) ;
}
2023-06-30 10:40:14 +02:00
2023-06-12 08:31:17 +02:00
// Handle Mode-Changes --------------------------------------------------------
void ATBDeviceControllerPlugin : : onChangedProgramModeToSELL ( )
{
2023-07-03 12:24:59 +02:00
hw - > rtc_setDateTime ( ) ;
2023-11-30 09:27:57 +01:00
hw - > mdb_switchWake ( 0 ) ; // wakeup MDB components
2023-06-12 08:31:17 +02:00
}
2023-06-13 17:00:17 +02:00
void ATBDeviceControllerPlugin : : onChangedProgramModeToSERVICE ( )
2023-06-12 08:31:17 +02:00
{
2023-06-15 09:48:25 +02:00
//hw->dc_autoRequest(true);
2023-11-30 09:27:57 +01:00
hw - > mdb_switchWake ( 0 ) ; // wakeup MDB components
2023-06-12 08:31:17 +02:00
}
2023-06-13 17:00:17 +02:00
void ATBDeviceControllerPlugin : : onChangedProgramModeToIDLE ( )
2023-06-12 08:31:17 +02:00
{
2023-06-15 09:48:25 +02:00
//hw->dc_autoRequest(false); // <-- TODO: ???
2023-06-22 14:50:56 +02:00
this - > diag - > diagRequest ( ) ;
2023-11-30 09:27:57 +01:00
hw - > mdb_switchWake ( 1 ) ;
2023-06-22 14:50:56 +02:00
2023-06-12 08:31:17 +02:00
}
2023-06-13 17:00:17 +02:00
void ATBDeviceControllerPlugin : : onChangedProgramModeToOOO ( )
2023-06-12 08:31:17 +02:00
{
}
2023-04-19 16:26:12 +02:00
// TASKS: Cash handling -------------------------------------------------------
void ATBDeviceControllerPlugin : : requestStartCashInput ( const QString & amount )
{
2023-05-04 14:28:38 +02:00
qCritical ( ) < < " Start Cash vending with amount = " < < amount ;
2023-04-19 16:26:12 +02:00
2023-11-30 18:16:45 +01:00
this - > cashStartAmountInt = static_cast < uint32_t > ( amount . toUInt ( ) ) ;
2023-05-19 15:33:52 +02:00
2023-11-30 18:16:45 +01:00
if ( this - > cashStartAmountInt = = 0 ) this - > cashStartAmountInt = UINT_MAX ;
2023-05-23 10:21:00 +02:00
2023-11-30 18:16:45 +01:00
hw - > cash_startPayment ( this - > cashStartAmountInt ) ;
2023-04-19 16:26:12 +02:00
}
void ATBDeviceControllerPlugin : : requestStopCashInput ( )
{
2023-05-04 14:28:38 +02:00
hw - > cash_stopPayment ( ) ;
2023-06-05 18:04:34 +02:00
// we need new cash value in application...
2023-06-28 10:55:49 +02:00
QTimer : : singleShot ( 2500 , this , SLOT ( onCashPayStopedSuccess ( ) ) ) ;
2023-04-19 16:26:12 +02:00
}
void ATBDeviceControllerPlugin : : cashCollect ( )
{
2023-05-04 14:28:38 +02:00
hw - > vend_success ( ) ;
2023-12-08 12:41:57 +01:00
// inserted amount
uint32_t amountInt = this - > hw - > getInsertedAmount ( ) ;
QString amountString = QString : : number ( amountInt ) ;
// inserted coins
uint32_t amountCoinsInt = CashUtils : : getAmountOfInsertedCoins ( this - > hw ) ;
QString amountCoinsString = QString : : number ( amountCoinsInt ) ;
// inserted notes
uint32_t amountNotesInt = CashUtils : : getAmountOfInsertedNotes ( this - > hw ) ;
QString amountNotesString = QString : : number ( amountNotesInt ) ;
if ( this - > coinProcessor ( ) = = nsDeviceControllerInterface : : COIN_PROCESSOR : : CHANGER ) {
QTimer : : singleShot ( 1000 , this , & ATBDeviceControllerPlugin : : onCashChangerState ) ;
}
else {
emit this - > cashPaymentFinished ( nsDeviceControllerInterface : : RESULT_STATE : : SUCCESS ,
amountString ,
amountCoinsString , // coins
amountNotesString , // notes
0 , // proposed change
" " ,
" " ) ;
this - > currentCashState = CASH_STATE : : CACHE_EMPTY ;
}
2023-04-19 16:26:12 +02:00
}
void ATBDeviceControllerPlugin : : cashAbort ( )
{
2023-05-04 14:28:38 +02:00
hw - > vend_failed ( ) ;
2023-06-16 15:50:25 +02:00
this - > currentCashState = CASH_STATE : : CACHE_EMPTY ;
2023-04-19 16:26:12 +02:00
}
2023-11-23 17:58:36 +01:00
// Coin/Cash processing variants ----------------------------------------------
nsDeviceControllerInterface : : COIN_PROCESSOR ATBDeviceControllerPlugin : : coinProcessor ( )
{
return this - > diag - > coinProcessorType ;
}
nsDeviceControllerInterface : : BILL_ACCEPTOR ATBDeviceControllerPlugin : : billAcceptor ( )
{
return this - > diag - > billAcceptor ;
}
2023-06-01 16:30:50 +02:00
// TASKS: Account -------------------------------------------------------------
2023-06-13 17:00:17 +02:00
// for an external account request, e.g. by an ui-button:
2023-06-01 16:30:50 +02:00
void ATBDeviceControllerPlugin : : requestAccount ( )
{
2023-06-19 16:26:33 +02:00
qCritical ( ) < < " ATBDeviceControllerPlugin::requestAccount() " ;
this - > private_startAccount ( ) ;
}
void ATBDeviceControllerPlugin : : private_startAccount ( )
{
uint16_t backupedAccNumbers [ 8 ] ; // array of account numbers
uint8_t nrOfVals ; // number of saved accounts
// it is not defined which one is the latest account
hw - > log_getHoldAccountNumbers ( & nrOfVals , backupedAccNumbers ) ;
2023-06-19 16:27:20 +02:00
// DEBUG
qCritical ( ) < < " Start account: " ;
qCritical ( ) < < " nrOfVals = " < < nrOfVals ;
for ( int i = 0 ; i < nrOfVals ; + + i ) {
2023-07-19 20:43:48 +02:00
qCritical ( ) < < " backupedAccNumbers[ " < < i < < " ] = " < < backupedAccNumbers [ i ] ;
2023-06-19 16:27:20 +02:00
}
2023-06-19 16:26:33 +02:00
qsort ( backupedAccNumbers , nrOfVals , sizeof ( uint16_t ) , Utils : : compare ) ;
uint16_t latestAccountNumber = backupedAccNumbers [ nrOfVals - 1 ] ;
2023-06-19 16:27:20 +02:00
// DEBUG
qCritical ( ) < < " latestAccountNumber = " < < latestAccountNumber ;
2023-07-27 09:59:20 +02:00
hw - > log_selectVaultRecord ( latestAccountNumber ) ;
2023-06-19 16:26:33 +02:00
this - > accountCheckCounter = 0 ;
QTimer : : singleShot ( 500 , this , SLOT ( private_checkAccountData ( ) ) ) ;
}
void ATBDeviceControllerPlugin : : private_checkAccountData ( )
{
2023-06-19 16:27:20 +02:00
// DEBUG
qCritical ( ) < < " --> private_checkAccountData() " ;
2023-06-19 16:26:33 +02:00
if ( hw - > log_chkIfVaultRecordAvailable ( ) ) {
this - > private_getAccountData ( ) ;
}
else {
if ( this - > accountCheckCounter < 10 ) {
this - > accountCheckCounter + + ;
QTimer : : singleShot ( 500 , this , SLOT ( private_checkAccountData ( ) ) ) ;
}
else {
// cannot get accountData within ~10*500ms
qCritical ( ) < < " checkAccountData() failed " ;
2023-06-22 14:54:54 +02:00
// simulate:
this - > private_getAccountData ( ) ;
2023-06-19 16:26:33 +02:00
// TODO: create and send an HealthEvent...
}
}
}
void ATBDeviceControllerPlugin : : private_getAccountData ( )
{
2023-06-19 16:27:20 +02:00
// DEBUG
qCritical ( ) < < " --> private_getAccountData() " ;
2023-06-19 16:26:33 +02:00
struct T_vaultRecord retVR ;
hw - > log_getVaultRecord ( & retVR ) ;
QHash < QString , QVariant > accountData ;
accountData . insert ( " AccountingNumber " , QString : : number ( retVR . AccountingNumber ) ) ;
2023-07-19 20:46:38 +02:00
// build dateTime: -------------------------------------------------------
// Example: "2023-07-19T18:24:01.063+02:00"
QString startDateTimeString ;
QString formatString = " yyyy-MM-ddThh:mm:ss " ;
uint year = retVR . year + 2000 ;
startDateTimeString . append ( QString : : number ( year ) ) . append ( " - " ) ;
uint month = retVR . month ;
startDateTimeString . append ( QString : : number ( month ) . rightJustified ( 2 , ' 0 ' ) ) . append ( " - " ) ;
uint day = retVR . dom ;
startDateTimeString . append ( QString : : number ( day ) . rightJustified ( 2 , ' 0 ' ) ) . append ( " T " ) ;
uint hour = retVR . hour ;
startDateTimeString . append ( QString : : number ( hour ) . rightJustified ( 2 , ' 0 ' ) ) . append ( " : " ) ;
uint minute = retVR . min ;
startDateTimeString . append ( QString : : number ( minute ) . rightJustified ( 2 , ' 0 ' ) ) . append ( " : " ) ;
uint seconds = retVR . sec ;
startDateTimeString . append ( QString : : number ( seconds ) . rightJustified ( 2 , ' 0 ' ) ) ;
qCritical ( ) < < " startDateTimeString = " < < startDateTimeString ;
QDateTime startDateTime = QDateTime : : fromString ( startDateTimeString , formatString ) ;
accountData . insert ( " accountStartTime " , startDateTime ) ;
//-------------------------------------------------------------------------
2023-11-29 12:31:05 +01:00
// COINS in Vault: --------------------------------------------------------
2023-07-19 20:46:38 +02:00
2023-11-29 16:10:38 +01:00
int numberOfCoinVariants = sizeof ( retVR . coinsInVault ) / sizeof ( retVR . coinsInVault [ 0 ] ) ;
2023-06-20 13:26:43 +02:00
2023-06-22 14:54:54 +02:00
// DEBUG
qCritical ( ) < < " NumberOfCoinVariants = " < < numberOfCoinVariants ;
2023-06-20 13:26:43 +02:00
// limit numberOfCoinVariants:
if ( numberOfCoinVariants > 16 ) { numberOfCoinVariants = 16 ; }
accountData . insert ( " NumberOfCoinVariants " , numberOfCoinVariants ) ;
2023-11-29 16:10:38 +01:00
for ( int i = 0 ; i < numberOfCoinVariants ; + + i ) {
accountData . insert ( " COIN_ " + QString : : number ( i + 1 ) + " _Quantity " , retVR . coinsInVault [ i ] ) ;
accountData . insert ( " COIN_ " + QString : : number ( i + 1 ) + " _Value " , retVR . coinDenomination [ i ] ) ;
2023-06-19 16:27:20 +02:00
// DEBUG
2023-11-29 16:10:38 +01:00
qCritical ( ) < < " COIN_ " + QString : : number ( i + 1 ) + " _Quantity = " < < accountData [ " COIN_ " + QString : : number ( i ) + " _Quantity " ] ;
qCritical ( ) < < " COIN_ " + QString : : number ( i + 1 ) + " _Value = " < < accountData [ " COIN_ " + QString : : number ( i ) + " _Value " ] ;
2023-06-19 16:26:33 +02:00
}
2023-11-29 12:31:52 +01:00
// NOTES in stacker: --------------------------------------------------------
2023-11-29 16:10:38 +01:00
int numberOfBillVariants = sizeof ( retVR . billsInStacker ) / sizeof ( retVR . billsInStacker [ 0 ] ) ;
2023-11-29 12:31:52 +01:00
// DEBUG
qCritical ( ) < < " numberOfBillVariants = " < < numberOfBillVariants ;
// limit numberOfBillVariants:
if ( numberOfBillVariants > 16 ) { numberOfBillVariants = 16 ; }
accountData . insert ( " NumberOfBillVariants " , numberOfBillVariants ) ;
2023-11-29 16:10:38 +01:00
for ( int i = 0 ; i < numberOfBillVariants ; + + i ) {
accountData . insert ( " NOTE_ " + QString : : number ( i + 1 ) + " _Quantity " , retVR . billsInStacker [ i ] ) ;
accountData . insert ( " NOTE_ " + QString : : number ( i + 1 ) + " _Value " , retVR . billDenom [ i ] ) ;
2023-11-29 12:31:52 +01:00
// DEBUG
2023-11-29 16:10:38 +01:00
qCritical ( ) < < " NOTE_ " + QString : : number ( i + 1 ) + " _Quantity = " < < accountData [ " NOTE_ " + QString : : number ( i + 1 ) + " _Quantity " ] ;
qCritical ( ) < < " NOTE_ " + QString : : number ( i + 1 ) + " _Value = " < < accountData [ " NOTE_ " + QString : : number ( i + 1 ) + " _Value " ] ;
2023-11-29 12:31:52 +01:00
}
2023-06-19 16:26:33 +02:00
emit requestAccountResponse ( accountData ) ;
2023-06-01 16:30:50 +02:00
}
2023-04-19 16:26:12 +02:00
2023-06-13 17:00:17 +02:00
// Door Events / Hardware contacts --------------------------------------------
void ATBDeviceControllerPlugin : : onServiceDoorOpened ( )
{
qCritical ( ) < < " ATBDeviceControllerPlugin::onServiceDoorOpened() " ;
2023-07-27 15:30:24 +02:00
// ... to detect alarm etc.
this - > diag - > diagRequest ( ) ;
2023-06-13 17:00:17 +02:00
// switch to mode service
emit this - > requestModeSERVICE ( ) ;
// TODO:
// - create an HealthEvent (-> ISMAS-Event)
}
void ATBDeviceControllerPlugin : : onVaultDoorOpened ( )
{
// TODO:
// - show special screen / message on screen
// - create an HealthEvent (-> ISMAS-Event)
2023-06-14 14:37:34 +02:00
qCritical ( ) < < " ATBDeviceControllerPlugin::onVaultDoorOpened() " ;
2023-06-20 13:23:36 +02:00
2023-07-27 15:30:24 +02:00
// ... to detect alarm etc.
this - > diag - > diagRequest ( ) ;
// this is started here because we want to keep ptu awake in order to get
// coin box removed / inserted etc.
// BackgroundTask("ACCOUNT") is finished, if account message is sent to ISMAS!
2023-10-10 08:17:21 +02:00
this - > dbus - > startBackgroundTask ( " DOOR_OPEN " ) ;
2023-06-20 13:23:36 +02:00
// do not: emit this->requestModeSERVICE();
2023-06-13 17:00:17 +02:00
}
void ATBDeviceControllerPlugin : : onCoinBoxRemoved ( )
{
2023-06-14 14:37:34 +02:00
qCritical ( ) < < " ATBDeviceControllerPlugin::onCoinBoxRemoved() " ;
2023-06-19 16:26:33 +02:00
2023-10-10 08:15:35 +02:00
// BackgroundTask("ACCOUNT") is finished, if account message is sent to ISMAS!
this - > dbus - > startBackgroundTask ( " ACCOUNT " ) ;
2023-07-20 11:02:46 +02:00
QTimer : : singleShot ( 4000 , this , SLOT ( private_startAccount ( ) ) ) ;
2023-06-13 17:00:17 +02:00
}
void ATBDeviceControllerPlugin : : onCoinBoxInserted ( )
{
2023-06-14 14:37:34 +02:00
qCritical ( ) < < " ATBDeviceControllerPlugin::onCoinBoxInserted() " ;
2023-06-13 17:00:17 +02:00
}
2023-10-10 08:17:21 +02:00
/**
* This is called , when all CoinBox is inserted and all doors
* are closed .
*/
2023-06-20 13:23:36 +02:00
void ATBDeviceControllerPlugin : : onCBinAndAllDoorsClosed ( )
2023-06-13 17:00:17 +02:00
{
2023-06-20 13:23:36 +02:00
qCritical ( ) < < " ATBDeviceControllerPlugin::onCBinAndAllDoorsClosed() " ;
QTimer : : singleShot ( 2000 , this , SIGNAL ( requestModeIDLE ( ) ) ) ;
2023-10-10 08:17:21 +02:00
this - > dbus - > finishedBackgroundTask ( " DOOR_OPEN " ) ;
}
2023-06-20 13:23:36 +02:00
2023-10-10 08:17:21 +02:00
/**
* This is called , when all no coinbox is inserted and all doors are
* closed .
*/
2023-06-20 13:23:36 +02:00
void ATBDeviceControllerPlugin : : onAllDoorsClosed ( )
{
2023-06-14 14:37:34 +02:00
qCritical ( ) < < " ATBDeviceControllerPlugin::onAllDoorsClosed() " ;
2023-06-13 17:00:17 +02:00
emit this - > requestModeIDLE ( ) ;
2023-10-10 08:17:21 +02:00
this - > dbus - > finishedBackgroundTask ( " DOOR_OPEN " ) ;
// TODO: check for errors and create a machine event
2023-06-13 17:00:17 +02:00
}
2023-07-05 18:47:45 +02:00
void ATBDeviceControllerPlugin : : onNewVoltage ( uint32_t voltage )
{
qCritical ( ) < < " ATBDeviceControllerPlugin::onNewVoltage() = " < < voltage ;
QString voltageString = QString : : number ( voltage ) ;
JSON : : setPrettySerialize ( true ) ;
JSON : : JsonObject json ;
json = JSON : : objectBuilder ( )
- > set ( " Name " , " batt " )
- > set ( " Value " , voltageString )
- > set ( " Unit " , " V " )
- > create ( ) ;
ATBHealthEvent * healthEvent = new ATBHealthEvent (
ATB_HEALTH_MODE : : STATE ,
" VOLTAGE " ,
JSON : : serialize ( json )
) ;
QCoreApplication : : postEvent ( eventReceiver , healthEvent ) ;
}
2023-06-13 17:00:17 +02:00
2023-04-19 16:26:12 +02:00
// TASKS: printing ------------------------------------------------------------
2023-06-26 19:47:01 +02:00
void ATBDeviceControllerPlugin : : requestPrintTicket ( nsDeviceControllerInterface : : TICKET_VARIANT ticketVariant , const QHash < QString , QVariant > & printingData )
{
struct T_dynDat * dynTicketData = new T_dynDat ;
memset ( dynTicketData , 0 , sizeof ( * dynTicketData ) ) ;
QDateTime parkingEndDateTime = QDateTime : : fromString ( printingData [ " parkingEnd " ] . toString ( ) , Qt : : ISODate ) ;
QDateTime currentDateTime = QDateTime : : fromString ( printingData [ " currentDateTime " ] . toString ( ) , Qt : : ISODate ) ;
2023-12-01 15:07:29 +01:00
QString parkingEndDateString = this - > printerLocale . toString ( parkingEndDateTime . date ( ) , QLocale : : ShortFormat ) ;
QString currentDateString = this - > printerLocale . toString ( currentDateTime . date ( ) , QLocale : : ShortFormat ) ;
2023-11-30 16:33:47 +01:00
2023-06-26 19:47:01 +02:00
// set dynamic printer data:
QByteArray ba_licenseplate = codec - > fromUnicode ( printingData [ " licenseplate " ] . toString ( ) ) ;
memcpy ( ( char * ) dynTicketData - > licensePlate , ba_licenseplate . data ( ) , std : : min ( ba_licenseplate . size ( ) , 8 ) ) ;
QByteArray ba_amount = codec - > fromUnicode ( printingData [ " amount " ] . toString ( ) ) ;
2023-11-27 11:10:21 +01:00
memcpy ( ( char * ) dynTicketData - > vendingPrice , ba_amount . data ( ) , std : : min ( ba_amount . size ( ) , 8 ) ) ; // Szeged
memcpy ( ( char * ) dynTicketData - > dynDat6 , ba_amount . data ( ) , std : : min ( ba_amount . size ( ) , 8 ) ) ; // Schoenau
2023-06-26 19:47:01 +02:00
QByteArray ba_parkingEndTime = codec - > fromUnicode ( parkingEndDateTime . toString ( " hh:mm " ) ) ;
memcpy ( ( char * ) dynTicketData - > parkingEnd , ba_parkingEndTime . data ( ) , std : : min ( ba_parkingEndTime . size ( ) , 8 ) ) ;
2023-11-30 16:33:47 +01:00
QByteArray ba_parkingEndDate = codec - > fromUnicode ( parkingEndDateString ) ;
2023-06-26 19:47:01 +02:00
memcpy ( ( char * ) dynTicketData - > currentTime , ba_parkingEndDate . data ( ) , std : : min ( ba_parkingEndDate . size ( ) , 8 ) ) ;
// ! and yes... 'ParkingEndDate' is 'currentTime'
2023-11-30 16:33:47 +01:00
QByteArray ba_currentDate = codec - > fromUnicode ( currentDateString ) ;
2023-06-26 19:47:01 +02:00
memcpy ( ( char * ) dynTicketData - > currentDate , ba_currentDate . data ( ) , std : : min ( ba_currentDate . size ( ) , 8 ) ) ;
// STAN for Szeged Start/Stop: must be 9 digits
// --------------------------------------------------------------------------------------
QString stan = codec - > fromUnicode ( printingData [ " STAN " ] . toString ( ) ) ;
qCritical ( ) < < " requestPrintTicket() STAN = " < < stan ;
QString stan1 ;
QString stan2 ;
if ( stan . length ( ) = = 9 ) {
stan1 = " " + stan . mid ( 0 , 3 ) ;
stan2 = stan . mid ( 3 , 3 ) + " " + stan . mid ( 6 , 3 ) ;
}
else {
qCritical ( ) < < " ASSERT: ATBDeviceControllerPlugin::requestPrintTicket() invalid STAN: " < < stan ;
stan1 = " 000 " ;
stan2 = " 000 000 " ;
}
QByteArray ba_stan1 = codec - > fromUnicode ( stan1 ) ;
QByteArray ba_stan2 = codec - > fromUnicode ( stan2 ) ;
// --------------------------------------------------------------------------------------
this - > templateList . clear ( ) ;
switch ( ticketVariant ) {
case nsDeviceControllerInterface : : TICKET_VARIANT : : START_RECEIPT :
qCritical ( ) < < " -> TICKET_VARIANT::START_RECEIPT " ;
memcpy ( ( char * ) dynTicketData - > dynDat6 , ba_stan1 . data ( ) , std : : min ( ba_stan1 . size ( ) , 8 ) ) ;
memcpy ( ( char * ) dynTicketData - > dynDat7 , ba_stan2 . data ( ) , std : : min ( ba_stan2 . size ( ) , 8 ) ) ;
this - > templateList < < 21 < < 22 < < 23 ;
break ;
case nsDeviceControllerInterface : : TICKET_VARIANT : : STOP_RECEIPT :
qCritical ( ) < < " -> TICKET_VARIANT::STOP_RECEIPT " ;
memcpy ( ( char * ) dynTicketData - > dynDat6 , ba_stan1 . data ( ) , std : : min ( ba_stan1 . size ( ) , 8 ) ) ;
memcpy ( ( char * ) dynTicketData - > dynDat7 , ba_stan2 . data ( ) , std : : min ( ba_stan2 . size ( ) , 8 ) ) ;
this - > templateList < < 24 < < 25 < < 26 ;
break ;
case nsDeviceControllerInterface : : TICKET_VARIANT : : RECEIPT :
break ;
case nsDeviceControllerInterface : : TICKET_VARIANT : : ERROR_RECEIPT :
break ;
case nsDeviceControllerInterface : : TICKET_VARIANT : : PARKING_TICKET :
break ;
}
// DEBUG
qCritical ( ) < < " ATBDeviceControllerPlugin::requestPrintTicket() " ;
2023-06-27 16:11:34 +02:00
for ( int i = 0 ; i < this - > templateList . size ( ) ; + + i ) {
2023-06-26 19:47:01 +02:00
qCritical ( ) < < " template: " < < this - > templateList . at ( i ) ;
}
2023-12-11 18:32:37 +01:00
/*
2023-06-26 19:47:01 +02:00
if ( ! this - > hw - > dc_isPortOpen ( ) ) {
qCritical ( ) < < " ... serial port is not open! " ;
this - > onPrintFinishedERR ( ) ;
return ;
}
2023-12-11 18:32:37 +01:00
*/
2023-06-26 19:47:01 +02:00
// TODO: wird hier nur 'licensePlate' gedruckt?
if ( ! this - > hw - > prn_sendDynamicPrnValues ( dynTicketData - > licensePlate ) ) {
this - > errorCode = " hwapi::prn_sendDynamicPrnValues " ;
this - > errorDescription = " hwapi method 'hwapi::prn_sendDynamicPrnValues' result is false " ;
qCritical ( ) < < " ERROR: " ;
qCritical ( ) < < " ATBDeviceControllerPlugin::requestPrintTicket( " < < endl
< < " licenseplate = " < < printingData [ " licenseplate " ] < < endl
< < " amount = " < < printingData [ " amount " ] < < endl
< < " parkingEnd = " < < printingData [ " parkingEnd " ] < < endl
< < " currentTime = " < < printingData [ " currentTime " ] < < endl
< < " currentDate = " < < printingData [ " currentDate " ] < < endl
< < " stan = " < < printingData [ " STAN " ] < < endl ;
this - > onPrintFinishedERR ( ) ;
return ;
}
QTimer : : singleShot ( 1000 , this , SLOT ( onPrinterDataPreparedForTemplates ( ) ) ) ;
}
void ATBDeviceControllerPlugin : : requestPrintReceipt ( const QHash < QString , QVariant > & printingData )
{
Q_UNUSED ( printingData )
qCritical ( ) < < " ATBDeviceControllerPlugin::requestPrintReceipt() is currently not implemented " ;
}
2023-08-07 17:38:29 +02:00
void ATBDeviceControllerPlugin : : requestPrintReceipt ( const QString & printingString )
{
QByteArray ba = printingString . toUtf8 ( ) ;
hw - > prn_switchPower ( true ) ;
hw - > prn_sendText ( & ba ) ;
QTimer : : singleShot ( 4000 , this , SLOT ( onPrinterWaitForPrintingReceipt ( ) ) ) ;
//QTimer::singleShot(2000, this, [this](){ hw->prn_cut(3); } );
}
void ATBDeviceControllerPlugin : : onPrinterWaitForPrintingReceipt ( )
{
quint8 printerResult = this - > hw - > prn_getPrintResult ( ) ;
switch ( printerResult ) {
case 0 : // still printing
qCritical ( ) < < " --> printer: WaitForPrintingReceipt " ;
QTimer : : singleShot ( 2000 , this , SLOT ( onPrinterWaitForPrintingReceipt ( ) ) ) ;
break ;
case 1 : // printing finished, Ok
qCritical ( ) < < " DC Finished printing receipt " ;
emit this - > printReceiptFinished ( nsDeviceControllerInterface : : RESULT_STATE : : SUCCESS ,
// TODO: TicketNumber
" " ,
" " ) ;
hw - > prn_switchPower ( true ) ;
hw - > prn_cut ( 3 ) ;
break ;
case 2 : // printing finished, Error
qCritical ( ) < < " DC Error: wait for printing receipt " ;
this - > errorCode = " PRINTER " ; // TODO: get more detailed error code from low level API
this - > errorDescription = " Printer error " ; // TODO: get more detailed error description from low level API
emit this - > printReceiptFinished ( nsDeviceControllerInterface : : RESULT_STATE : : ERROR_BACKEND ,
this - > errorCode ,
this - > errorDescription ) ;
break ;
default :
qCritical ( ) < < " DC Error: wait for printing receipt " ;
this - > errorCode = " PRINTER " ; // TODO: get more detailed error code from low level API
this - > errorDescription = " Printer error " ; // TODO: get more detailed error description from low level API
emit this - > printReceiptFinished ( nsDeviceControllerInterface : : RESULT_STATE : : ERROR_BACKEND ,
this - > errorCode ,
this - > errorDescription ) ;
break ;
}
}
2023-06-26 19:47:01 +02:00
2023-04-19 16:26:12 +02:00
void ATBDeviceControllerPlugin : : requestPrintTicket ( const QHash < QString , QVariant > & printingData )
{
struct T_dynDat * dynTicketData = new T_dynDat ;
2023-05-04 13:21:14 +02:00
memset ( dynTicketData , 0 , sizeof ( * dynTicketData ) ) ;
2023-04-19 16:26:12 +02:00
2023-05-18 11:57:54 +02:00
qCritical ( ) < < " ATBDeviceControllerPlugin::requestPrintTicket( " < < endl
< < " licenseplate = " < < printingData [ " licenseplate " ] < < endl
< < " amount = " < < printingData [ " amount " ] < < endl
< < " parkingEnd = " < < printingData [ " parkingEnd " ] < < endl
< < " currentDateTime = " < < printingData [ " currentDateTime " ] < < endl ;
2023-05-03 11:56:36 +02:00
2023-05-18 11:57:54 +02:00
QDateTime parkingEndDateTime = QDateTime : : fromString ( printingData [ " parkingEnd " ] . toString ( ) , Qt : : ISODate ) ;
QDateTime currentDateTime = QDateTime : : fromString ( printingData [ " currentDateTime " ] . toString ( ) , Qt : : ISODate ) ;
2023-12-01 15:07:29 +01:00
QString parkingEndDateString = this - > printerLocale . toString ( parkingEndDateTime . date ( ) , QLocale : : ShortFormat ) ;
QString currentDateString = this - > printerLocale . toString ( currentDateTime . date ( ) , QLocale : : ShortFormat ) ;
2023-11-30 16:33:47 +01:00
2023-05-18 11:57:54 +02:00
/* -----------------------------------------------------------------------------------------
* note : the following highly depends on printer template files !
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
2023-05-03 11:56:36 +02:00
2023-05-04 13:21:14 +02:00
// set dynamic printer data:
2023-05-18 11:57:54 +02:00
QByteArray ba_licenseplate = codec - > fromUnicode ( printingData [ " licenseplate " ] . toString ( ) ) ;
memcpy ( ( char * ) dynTicketData - > licensePlate , ba_licenseplate . data ( ) , std : : min ( ba_licenseplate . size ( ) , 8 ) ) ;
QByteArray ba_amount = codec - > fromUnicode ( printingData [ " amount " ] . toString ( ) ) ;
2023-11-27 11:10:21 +01:00
memcpy ( ( char * ) dynTicketData - > vendingPrice , ba_amount . data ( ) , std : : min ( ba_amount . size ( ) , 8 ) ) ; // Szeged
memcpy ( ( char * ) dynTicketData - > dynDat6 , ba_amount . data ( ) , std : : min ( ba_amount . size ( ) , 8 ) ) ; // Schoenau
2023-05-18 11:57:54 +02:00
QByteArray ba_parkingEndTime = codec - > fromUnicode ( parkingEndDateTime . toString ( " hh:mm " ) ) ;
2023-06-05 12:51:55 +02:00
memcpy ( ( char * ) dynTicketData - > parkingEnd , ba_parkingEndTime . data ( ) , std : : min ( ba_parkingEndTime . size ( ) , 8 ) ) ;
2023-05-18 11:57:54 +02:00
2023-11-30 16:33:47 +01:00
QByteArray ba_parkingEndDate = codec - > fromUnicode ( parkingEndDateString ) ;
2023-06-05 12:51:55 +02:00
memcpy ( ( char * ) dynTicketData - > currentTime , ba_parkingEndDate . data ( ) , std : : min ( ba_parkingEndDate . size ( ) , 8 ) ) ;
// ! and yes... 'ParkingEndDate' is 'currentTime'
2023-05-04 13:21:14 +02:00
2023-11-30 16:33:47 +01:00
QByteArray ba_currentDate = codec - > fromUnicode ( currentDateString ) ;
2023-05-18 11:57:54 +02:00
memcpy ( ( char * ) dynTicketData - > currentDate , ba_currentDate . data ( ) , std : : min ( ba_currentDate . size ( ) , 8 ) ) ;
2023-05-04 13:21:14 +02:00
2023-05-18 11:57:54 +02:00
// DEBUG
/*
uint8_t * buf = dynTicketData - > licensePlate ;
int length = 64 ;
for ( int i = 0 ; i < length ; + + i ) {
fprintf ( stderr , " %d %02x %c \n " , i , buf [ i ] , buf [ i ] ) ;
}
fprintf ( stderr , " \n " ) ;
*/
2023-04-19 16:26:12 +02:00
2023-05-02 17:10:17 +02:00
// DEBUG
qCritical ( ) < < " ATBDeviceControllerPlugin::requestPrintTicket() " ;
2023-05-04 13:21:14 +02:00
2023-12-11 18:32:37 +01:00
/*
2023-05-02 17:10:17 +02:00
if ( ! this - > hw - > dc_isPortOpen ( ) ) {
qCritical ( ) < < " ... serial port is not open! " ;
2023-05-04 13:21:14 +02:00
this - > onPrintFinishedERR ( ) ;
return ;
2023-05-02 17:10:17 +02:00
}
2023-12-11 18:32:37 +01:00
*/
2023-05-03 11:56:36 +02:00
// TODO: wird hier nur 'licensePlate' gedruckt?
if ( ! this - > hw - > prn_sendDynamicPrnValues ( dynTicketData - > licensePlate ) ) {
this - > errorCode = " hwapi::prn_sendDynamicPrnValues " ;
this - > errorDescription = " hwapi method 'hwapi::prn_sendDynamicPrnValues' result is false " ;
2023-05-02 17:10:17 +02:00
qCritical ( ) < < " ERROR: " ;
qCritical ( ) < < " ATBDeviceControllerPlugin::requestPrintTicket( " < < endl
< < " licenseplate = " < < printingData [ " licenseplate " ] < < endl
< < " amount = " < < printingData [ " amount " ] < < endl
< < " parkingEnd = " < < printingData [ " parkingEnd " ] < < endl
< < " currentTime = " < < printingData [ " currentTime " ] < < endl
< < " currentDate = " < < printingData [ " currentDate " ] < < endl ;
2023-05-04 13:21:14 +02:00
this - > onPrintFinishedERR ( ) ;
2023-05-03 11:56:36 +02:00
return ;
2023-05-02 17:10:17 +02:00
}
2023-05-03 11:56:36 +02:00
2023-06-09 11:19:39 +02:00
// set ticket type:
// 00281 - Szeged:
// 1 - Cash / ShortTimeParking
// 2 - Card / ShortTimeParking
// 3 - Cash / DayTicket
// 4 - Card / DayTicket
QString paymentType = printingData [ " paymentType " ] . toString ( ) ; // must be "CASH" | "CARD"
QString productName = printingData [ " product " ] . toString ( ) ; // must be "ShortTimeParking" | "DayTicket"
if ( ( paymentType = = " CASH " ) & & ( productName = = " ShortTimeParking " ) ) {
this - > currentSelectedTicketType = 1 ;
}
else
if ( ( paymentType = = " CARD " ) & & ( productName = = " ShortTimeParking " ) ) {
this - > currentSelectedTicketType = 2 ;
}
else
if ( ( paymentType = = " CASH " ) & & ( productName = = " DayTicket " ) ) {
this - > currentSelectedTicketType = 3 ;
}
else
if ( ( paymentType = = " CARD " ) & & ( productName = = " DayTicket " ) ) {
this - > currentSelectedTicketType = 4 ;
}
else {
qCritical ( ) < < " ERROR: requestPrintTicket(): invalid payment data: " ;
qCritical ( ) < < " paymentType = " < < paymentType < < endl
< < " productName = " < < productName < < endl ;
this - > onPrintFinishedERR ( ) ;
return ;
}
2023-06-27 16:11:04 +02:00
QTimer : : singleShot ( 3000 , this , SLOT ( onPrinterDataPrepared ( ) ) ) ;
2023-04-19 16:26:12 +02:00
}
2023-05-04 13:21:14 +02:00
2023-06-26 19:47:01 +02:00
void ATBDeviceControllerPlugin : : onPrinterDataPreparedForTemplates ( )
{
if ( this - > templateList . isEmpty ( ) ) return ;
this - > onPrinterPrintNextTemplate ( ) ;
}
2023-05-04 13:21:14 +02:00
2023-05-03 11:56:36 +02:00
void ATBDeviceControllerPlugin : : onPrinterDataPrepared ( )
{
2023-06-09 11:18:39 +02:00
this - > hw - > prn_printKombiticket ( this - > currentSelectedTicketType ) ;
2023-06-22 12:14:55 +02:00
// note: calling prn_getPrintResult() immediately may result in wrong answer!
// We have to wait "about some seconds" until calling this function!
2023-08-07 17:38:29 +02:00
QTimer : : singleShot ( 4000 , this , SLOT ( onPrinterWaitForPrintingTicket ( ) ) ) ;
2023-06-09 11:18:39 +02:00
// old: use printer templates:
// this->currentTemplate = 1;
// this->onPrinterPrintNextTemplate();
2023-05-04 13:21:14 +02:00
}
2023-05-03 11:56:36 +02:00
2023-08-07 17:38:29 +02:00
void ATBDeviceControllerPlugin : : onPrinterWaitForPrintingTicket ( )
2023-06-22 12:14:55 +02:00
{
quint8 printerResult = this - > hw - > prn_getPrintResult ( ) ;
switch ( printerResult ) {
case 0 : // still printing
2023-08-07 17:38:29 +02:00
qCritical ( ) < < " --> printer: WaitForPrintingTicket " ;
QTimer : : singleShot ( 2000 , this , SLOT ( onPrinterWaitForPrintingTicket ( ) ) ) ;
2023-06-22 12:14:55 +02:00
break ;
case 1 : // printing finished, Ok
this - > onPrintFinishedOK ( ) ;
break ;
case 2 : // printing finished, Error
this - > onPrintFinishedERR ( ) ;
break ;
default :
qCritical ( ) < < " DC Error: wait for printing " ;
this - > onPrintFinishedERR ( ) ;
break ;
}
}
2023-05-03 11:56:36 +02:00
2023-05-04 13:21:14 +02:00
void ATBDeviceControllerPlugin : : onPrinterPrintNextTemplate ( )
{
2023-06-26 19:47:01 +02:00
// template list must not be empty
if ( this - > templateList . isEmpty ( ) ) {
this - > onPrintFinishedERR ( ) ;
return ;
}
2023-05-04 13:21:14 +02:00
2023-06-26 19:47:01 +02:00
qCritical ( ) < < " ... print template " < < this - > templateList . first ( ) ;
if ( ! this - > hw - > prn_printTemplate ( this - > templateList . first ( ) ) ) {
2023-05-04 13:21:14 +02:00
this - > errorCode = " hwapi::prn_printTemplate " ;
2023-06-26 19:47:01 +02:00
this - > errorDescription = QString ( " hwapi method 'hwapi::onPrinterPrintNextTemplate(%1)' result is false " ) . arg ( this - > templateList . first ( ) ) ;
2023-05-04 13:21:14 +02:00
this - > onPrintFinishedERR ( ) ;
return ;
2023-05-03 11:56:36 +02:00
}
2023-06-26 19:47:01 +02:00
this - > templateList . removeFirst ( ) ;
2023-05-03 11:56:36 +02:00
2023-06-26 19:47:01 +02:00
if ( templateList . isEmpty ( ) ) {
2023-05-04 13:21:14 +02:00
// all templates are printed
2023-08-10 15:01:39 +02:00
QTimer : : singleShot ( 2000 , this , SLOT ( onPrinterWaitForPrintingTicket ( ) ) ) ;
2023-05-04 13:21:14 +02:00
}
else {
// print next template
2023-05-22 11:23:28 +02:00
QTimer : : singleShot ( 2000 , this , SLOT ( onPrinterPrintNextTemplate ( ) ) ) ;
2023-05-04 13:21:14 +02:00
}
}
2023-05-03 11:56:36 +02:00
2023-05-02 17:10:17 +02:00
/************************************************************************************************
* private slots , interface to low level hwapi
*
*/
void ATBDeviceControllerPlugin : : onPrintFinishedOK ( )
{
2023-05-04 13:21:14 +02:00
// DEBUG
qCritical ( ) < < " ATBDeviceControllerPlugin::onPrintFinishedOK() " ;
2023-05-02 17:10:17 +02:00
emit this - > printTicketFinished ( nsDeviceControllerInterface : : RESULT_STATE : : SUCCESS ,
2023-06-16 15:49:56 +02:00
// TODO: TicketNumber
2023-05-02 17:10:17 +02:00
" " ,
" " ) ;
}
void ATBDeviceControllerPlugin : : onPrintFinishedERR ( )
{
2023-05-04 13:21:14 +02:00
// DEBUG
qCritical ( ) < < " ATBDeviceControllerPlugin::onPrintFinishedERR() " ;
2023-05-02 17:10:17 +02:00
this - > errorCode = " PRINTER " ; // TODO: get more detailed error code from low level API
this - > errorDescription = " Printer error " ; // TODO: get more detailed error description from low level API
emit this - > printTicketFinished ( nsDeviceControllerInterface : : RESULT_STATE : : ERROR_BACKEND ,
this - > errorCode ,
this - > errorDescription ) ;
}
2023-05-04 14:28:38 +02:00
/************************************************************************************************
* cash payment
*/
void ATBDeviceControllerPlugin : : onCashGotCoin ( )
2023-05-02 17:10:17 +02:00
{
2023-05-04 14:28:38 +02:00
// DEBUG
qCritical ( ) < < " ATBDeviceControllerPlugin::onGotCoin() " ;
2023-06-16 15:50:25 +02:00
this - > currentCashState = CASH_STATE : : CACHE_INPUT ;
2023-05-04 14:28:38 +02:00
uint32_t amountInt = this - > hw - > getInsertedAmount ( ) ;
2023-05-02 17:10:17 +02:00
2023-05-04 14:28:38 +02:00
QString amountString = QString : : number ( amountInt ) ;
emit this - > cashInputEvent ( nsDeviceControllerInterface : : RESULT_STATE : : SUCCESS ,
nsDeviceControllerInterface : : CASH_STATE : : CACHE_INPUT ,
amountString ,
" " ,
" " ) ;
2023-05-02 17:10:17 +02:00
}
2023-11-23 17:59:49 +01:00
void ATBDeviceControllerPlugin : : onCashPayStopByPushbutton ( )
{
// DEBUG
qCritical ( ) < < " ATBDeviceControllerPlugin::onCashPayStopByPushbutton() " ;
// we need new cash value in application...
QTimer : : singleShot ( 500 , this , SLOT ( onCashPayStopedSuccess ( ) ) ) ;
}
2023-04-19 16:26:12 +02:00
2023-05-22 11:20:28 +02:00
void ATBDeviceControllerPlugin : : onCashPayStopByMax ( )
2023-05-04 14:28:38 +02:00
{
// DEBUG
qCritical ( ) < < " ATBDeviceControllerPlugin::onCashVendStopByMax() " ;
2023-06-15 18:49:59 +02:00
// we need new cash value in application...
QTimer : : singleShot ( 500 , this , SLOT ( onCashPayStopedSuccess ( ) ) ) ;
2023-05-04 14:28:38 +02:00
}
2023-04-19 16:26:12 +02:00
2023-05-22 11:20:28 +02:00
void ATBDeviceControllerPlugin : : onCashPayStopByEscrow ( )
{
// DEBUG
qCritical ( ) < < " ATBDeviceControllerPlugin::onCashPayStopByEscrow() " ;
uint32_t amountInt = this - > hw - > getInsertedAmount ( ) ;
QString amountString = QString : : number ( amountInt ) ;
emit this - > cashInputFinished ( nsDeviceControllerInterface : : RESULT_STATE : : ERROR_BACKEND ,
amountString ,
" " ,
2023-11-30 12:04:11 +01:00
" " ,
" " ,
" " ,
2023-05-22 11:20:28 +02:00
" " ) ;
}
void ATBDeviceControllerPlugin : : onCashPayStopByError ( )
{
// DEBUG
qCritical ( ) < < " ATBDeviceControllerPlugin::onCashPayStopByError() " ;
uint32_t amountInt = this - > hw - > getInsertedAmount ( ) ;
QString amountString = QString : : number ( amountInt ) ;
emit this - > cashInputFinished ( nsDeviceControllerInterface : : RESULT_STATE : : ERROR_BACKEND ,
amountString ,
" " ,
2023-11-30 12:04:11 +01:00
" " ,
" " ,
" " ,
2023-05-22 11:20:28 +02:00
" " ) ;
}
void ATBDeviceControllerPlugin : : onCashPayStopByTimeout ( )
{
// DEBUG
qCritical ( ) < < " ATBDeviceControllerPlugin::onCashPayStopByTimeout() " ;
uint32_t amountInt = this - > hw - > getInsertedAmount ( ) ;
QString amountString = QString : : number ( amountInt ) ;
emit this - > cashInputFinished ( nsDeviceControllerInterface : : RESULT_STATE : : ERROR_BACKEND ,
amountString ,
" " ,
2023-11-30 12:04:11 +01:00
" " ,
" " ,
" " ,
2023-05-22 11:20:28 +02:00
" " ) ;
}
2023-06-15 18:49:13 +02:00
void ATBDeviceControllerPlugin : : onCashPayStopedSuccess ( )
2023-06-05 18:04:34 +02:00
{
// DEBUG
2023-11-23 17:59:49 +01:00
qCritical ( ) < < " ATBDeviceControllerPlugin::onCashPayStopedSuccess() " ;
2023-06-05 18:04:34 +02:00
2023-11-30 18:18:43 +01:00
// inserted amount
2023-06-05 18:04:34 +02:00
uint32_t amountInt = this - > hw - > getInsertedAmount ( ) ;
QString amountString = QString : : number ( amountInt ) ;
2023-11-30 18:18:43 +01:00
// inserted coins
uint32_t amountCoinsInt = CashUtils : : getAmountOfInsertedCoins ( this - > hw ) ;
QString amountCoinsString = QString : : number ( amountCoinsInt ) ;
// inserted notes
uint32_t amountNotesInt = CashUtils : : getAmountOfInsertedNotes ( this - > hw ) ;
QString amountNotesString = QString : : number ( amountNotesInt ) ;
// amount due to change
2023-12-08 12:41:57 +01:00
uint32_t amountDueToChangeInt ;
if ( amountInt > this - > cashStartAmountInt ) {
amountDueToChangeInt = amountInt - this - > cashStartAmountInt ;
}
else {
amountDueToChangeInt = 0 ;
}
2023-11-30 18:18:43 +01:00
QString amountDueToChangeString = QString : : number ( amountDueToChangeInt ) ;
// DEBUG
2023-12-08 12:41:57 +01:00
qCritical ( ) < < " --------------------------------------------------------- " ;
qCritical ( ) < < " ATBDeviceControllerPlugin::onCashPayStopedSuccess() " ;
qCritical ( ) < < " " ;
qCritical ( ) < < " amountInt: " < < amountInt ;
qCritical ( ) < < " amountString: " < < amountString ;
qCritical ( ) < < " " ;
qCritical ( ) < < " amountNotesInt: " < < amountNotesInt ;
qCritical ( ) < < " amountNotesString: " < < amountNotesString ;
qCritical ( ) < < " " ;
qCritical ( ) < < " amountCoinsInt: " < < amountCoinsInt ;
qCritical ( ) < < " amountCoinsString: " < < amountCoinsString ;
qCritical ( ) < < " " ;
qCritical ( ) < < " this->cashStartAmountInt: " < < this - > cashStartAmountInt ;
qCritical ( ) < < " amountDueToChangeInt: " < < amountDueToChangeInt ;
qCritical ( ) < < " amountDueToChangeString: " < < amountDueToChangeString ;
qCritical ( ) < < " --------------------------------------------------------- " ;
2023-06-15 18:49:29 +02:00
2023-06-05 18:04:34 +02:00
emit this - > cashInputFinished ( nsDeviceControllerInterface : : RESULT_STATE : : SUCCESS ,
amountString ,
2023-11-30 18:18:43 +01:00
amountCoinsString , // coins
amountNotesString , // notes
amountDueToChangeString , // proposed change
2023-06-05 18:04:34 +02:00
" " ,
" " ) ;
}
2023-12-08 12:41:57 +01:00
void ATBDeviceControllerPlugin : : onCashChangerState ( )
{
uint32_t amountThatCouldNotBeChangedInt ;
static int changerStateRequestCounter = 0 ;
static uint8_t lastChangerResult = 0 ;
// inserted amount
uint32_t amountInt = this - > hw - > getInsertedAmount ( ) ;
QString amountString = QString : : number ( amountInt ) ;
// inserted coins
uint32_t amountCoinsInt = CashUtils : : getAmountOfInsertedCoins ( this - > hw ) ;
QString amountCoinsString = QString : : number ( amountCoinsInt ) ;
// inserted notes
uint32_t amountNotesInt = CashUtils : : getAmountOfInsertedNotes ( this - > hw ) ;
QString amountNotesString = QString : : number ( amountNotesInt ) ;
// amount due to change
uint32_t amountCoinsChangedInt ;
if ( amountInt > this - > cashStartAmountInt ) {
amountCoinsChangedInt = amountInt - this - > cashStartAmountInt ;
}
else {
amountCoinsChangedInt = 0 ;
}
QString amountCoinsChangedString = QString : : number ( amountCoinsChangedInt ) ;
// get changer state ------------------------------------------------
// Note: 'returnedAmount'-parameter is missleading here!
// 'returnedAmount' is the amount which could not be changed!
lastChangerResult = hw - > changer_getChangeResult ( & amountThatCouldNotBeChangedInt ) ;
// DEBUG
qCritical ( ) < < " --------------------------------------------------------- " ;
qCritical ( ) < < " ATBDeviceControllerPlugin::onCashChangerState() " ;
qCritical ( ) < < " changerStateRequestCounter: " < < changerStateRequestCounter ;
qCritical ( ) < < " lastChangerResult: " < < lastChangerResult ;
qCritical ( ) < < " amountThatCouldNotBeChangedInt: " < < amountThatCouldNotBeChangedInt ;
qCritical ( ) < < " " ;
qCritical ( ) < < " amountInt: " < < amountInt ;
qCritical ( ) < < " amountString: " < < amountString ;
qCritical ( ) < < " " ;
qCritical ( ) < < " amountCoinsInt: " < < amountCoinsInt ;
qCritical ( ) < < " amountCoinsString: " < < amountCoinsString ;
qCritical ( ) < < " " ;
qCritical ( ) < < " amountNotesInt: " < < amountNotesInt ;
qCritical ( ) < < " amountNotesString: " < < amountNotesString ;
qCritical ( ) < < " " ;
qCritical ( ) < < " this->cashStartAmountInt: " < < this - > cashStartAmountInt ;
qCritical ( ) < < " amountCoinsChangedInt: " < < amountCoinsChangedInt ;
qCritical ( ) < < " amountCoinsChangedString: " < < amountCoinsChangedString ;
qCritical ( ) < < " --------------------------------------------------------- " ;
if ( lastChangerResult = = 1 ) { // change is returned
QString amountCoinsChangedString = QString : : number ( amountCoinsChangedInt ) ;
emit this - > cashPaymentFinished ( nsDeviceControllerInterface : : RESULT_STATE : : SUCCESS ,
amountString ,
amountCoinsString , // coins
amountNotesString , // notes
amountCoinsChangedString , // change
" " ,
" " ) ;
changerStateRequestCounter = 0 ;
lastChangerResult = 0 ;
return ;
}
else
if ( lastChangerResult = = 0 ) { // not yet started
qCritical ( ) < < " ATBDeviceControllerPlugin::onCashChangerState(): ERROR: change not yet started: amount due to return: " < < amountCoinsChangedString ;
}
else
if ( lastChangerResult = = 2 ) { // only partial return
qCritical ( ) < < " ATBDeviceControllerPlugin::onCashChangerState(): ERROR: only partial return: amount due to return: " < < amountCoinsChangedString ;
}
else
if ( lastChangerResult = = 3 ) { // no return possible
qCritical ( ) < < " ATBDeviceControllerPlugin::onCashChangerState(): ERROR: no return possible: amount due to return: " < < amountCoinsChangedString ;
}
else {
qCritical ( ) < < " ATBDeviceControllerPlugin::onCashChangerState(): ERROR: invalid changerState ( " < < lastChangerResult < < " ) " ;
}
// handle timeout ------------------------------------------------
if ( changerStateRequestCounter > 15 ) {
QString errorCode ;
QString errorDescription ;
switch ( lastChangerResult ) {
case 0 : // not yet started
errorCode = " DC::CHANGER::START " ;
errorDescription = " Changer does not start " ;
break ;
case 1 : // amount returned
// This error should not occur!
errorCode = " DC::CHANGER::INVALID " ;
errorDescription = " Changer returned amount " ;
break ;
case 2 : // only partial return
errorCode = " DC::CHANGER::CHANGE " ;
errorDescription = " Changer does only partial return " ;
break ;
case 3 : // no return possible
errorCode = " DC::CHANGER::CHANGE_NOT_POSSIBLE " ;
errorDescription = " Changing not possible " ;
break ;
default :
break ;
}
emit this - > cashPaymentFinished ( nsDeviceControllerInterface : : RESULT_STATE : : ERROR_BACKEND ,
amountString ,
amountCoinsString ,
amountNotesString ,
0 ,
errorCode ,
errorDescription ) ;
changerStateRequestCounter = 0 ;
lastChangerResult = 0 ;
return ;
}
// restart changer check:
changerStateRequestCounter + + ;
QTimer : : singleShot ( 1000 , this , & ATBDeviceControllerPlugin : : onCashChangerState ) ;
}
2023-05-22 11:20:28 +02:00
2023-06-05 18:07:12 +02:00
/**
* Load CashAgentLib
* @ brief ATBDeviceControllerPlugin : : private_loadCashAgentLib
* @ param pluginName
* @ return
*/
2023-06-05 12:49:20 +02:00
bool ATBDeviceControllerPlugin : : private_loadCashAgentLib ( QString pluginName )
{
if ( pluginName = = " " ) {
2023-06-15 14:15:13 +02:00
// search list for plugin (.so) file:
QStringList pluginNameList ;
2023-11-21 11:21:28 +01:00
pluginNameList < < " /usr/lib/libCAslave.so "
< < " /usr/lib/libCAmaster.so "
2023-06-15 14:15:13 +02:00
< < " /usr/lib/libCashAgentLib.so " ;
// using C++11 range based loop:
for ( const auto & filename : pluginNameList ) {
if ( QFileInfo ( filename ) . isReadable ( ) ) {
pluginName = filename ;
break ;
}
}
if ( pluginName = = " " ) {
qCritical ( ) < < " ATBDeviceControllerPlugin: CashAgentLib not installed! " ;
this - > errorCode = " CashAgentLib::NOT_FOUND " ;
this - > errorDescription = " ERROR: no CashAgentLib: " ;
return false ;
}
2023-06-05 12:49:20 +02:00
}
if ( ! QLibrary : : isLibrary ( pluginName ) ) {
qCritical ( ) < < " ATBDeviceControllerPlugin: can not load CashAgentLib: " < < pluginName ;
2023-06-15 14:16:03 +02:00
this - > errorCode = " CashAgentLib::NO_LIBRARY " ;
2023-06-05 12:49:20 +02:00
this - > errorDescription = " ERROR: can not load CashAgentLib: " + pluginName ;
return false ;
}
2023-11-21 11:21:28 +01:00
if ( pluginName . contains ( " slave " , Qt : : CaseInsensitive ) ) {
this - > isMaster = false ;
}
else
if ( pluginName . contains ( " master " , Qt : : CaseInsensitive ) ) {
this - > isMaster = true ;
}
2023-06-05 12:49:20 +02:00
QPluginLoader * pluginLoader = new QPluginLoader ( ) ;
pluginLoader - > setFileName ( pluginName ) ;
QObject * plugin = pluginLoader - > instance ( ) ;
if ( ! pluginLoader - > isLoaded ( ) ) {
qCritical ( ) < < " ATBDeviceControllerPlugin: can not instantiate CashAgentLib: " < < pluginName ;
2023-06-15 10:54:32 +02:00
qCritical ( ) < < " error: " < < pluginLoader - > errorString ( ) ;
2023-06-15 14:16:03 +02:00
this - > errorCode = " CashAgentLib::NO_INSTANCE " ;
2023-06-05 12:49:20 +02:00
this - > errorDescription = " ERROR: can not instantiate CashAgentLib: " + pluginName ;
return false ;
}
if ( plugin = = nullptr ) {
qCritical ( ) < < " ATBDeviceControllerPlugin: plugin is NULL " ;
2023-06-15 14:16:03 +02:00
this - > errorCode = " CashAgentLib::INSTANCE_IS_NULL " ;
this - > errorDescription = " ERROR: CashAgentLib instance is NULL: " + pluginName ;
2023-06-05 12:49:20 +02:00
}
qCritical ( ) < < " ATBDeviceControllerPlugin: instantiate CashAgentLib: " < < pluginName ;
this - > hw = qobject_cast < hwinf * > ( plugin ) ;
if ( this - > hw = = nullptr ) {
qCritical ( ) < < " ATBDeviceControllerPlugin: hw is NULL " ;
2023-06-15 14:16:03 +02:00
this - > errorCode = " CashAgentLib::HW_IS_NULL " ;
this - > errorDescription = " ERROR: CashAgentLib object_cast is NULL: " + pluginName ;
2023-06-16 10:53:27 +02:00
return false ;
2023-06-05 12:49:20 +02:00
}
2023-06-15 10:54:32 +02:00
qCritical ( ) < < " ATBDeviceControllerPlugin: loaded CashAgentLib " ;
2023-06-05 12:49:20 +02:00
return true ;
}
2023-05-22 11:20:28 +02:00
2023-07-20 08:15:03 +02:00
/***********************************************************************************************
* dbus
*/
int ATBDeviceControllerPlugin : : init_sc_dbus ( )
{
# if defined (ARCH_PTU4)
this - > dbus = new DBusControllerInterface ( " eu.atb.ptu " , " /systemcontrol " , QDBusConnection : : systemBus ( ) , 0 ) ;
# elif defined (ARCH_PTU5)
this - > dbus = new DBusControllerInterface ( " eu.atb.ptu.systemcontrol " , " /systemcontrol " , QDBusConnection : : systemBus ( ) , 0 ) ;
# else
this - > dbus = new DBusControllerInterface ( " eu.atb.ptu " , " /systemcontrol " , QDBusConnection : : sessionBus ( ) , 0 ) ;
# endif
if ( ! dbus - > isValid ( ) ) {
QString errorString = QDBusError : : errorString ( dbus - > lastError ( ) . type ( ) ) ;
qCritical ( ) < < errorString ;
if ( dbus - > lastError ( ) . isValid ( ) ) {
qCritical ( ) < < " last error is valid. " ;
}
qCritical ( ) < < " message: " < < dbus - > lastError ( ) . message ( ) ;
qCritical ( ) < < " SystemController is not valid. " ;
return 0 ;
}
if ( ! dbus - > connection ( ) . isConnected ( ) ) {
qCritical ( ) < < " SystemController is not connected. " ;
return 0 ;
}
connect ( this - > dbus , SIGNAL ( wokeUpFrom ( uchar ) ) , this , SLOT ( onWokeUp ( uchar ) ) ) ;
return 1 ;
}
2023-07-25 12:56:15 +02:00
void ATBDeviceControllerPlugin : : onWokeUp ( uchar source )
{
if ( source = = 0x01 ) {
// woke up from device controller
this - > diag - > diagRequest ( ) ;
}
}
2023-07-20 08:15:03 +02:00
2023-04-19 16:26:12 +02:00
/************************************************************************************************
* Mandatory plugin methods
*
*/
PLUGIN_STATE ATBDeviceControllerPlugin : : getState ( )
{
return this - > pluginState ;
}
2023-05-02 17:07:48 +02:00
QString & ATBDeviceControllerPlugin : : getLastError ( )
2023-04-19 16:26:12 +02:00
{
return this - > errorCode ;
}
const QString & ATBDeviceControllerPlugin : : getLastErrorDescription ( )
{
return this - > errorDescription ;
}
const QString & ATBDeviceControllerPlugin : : getPluginInfo ( )
{
return this - > pluginInfo ;
}
const QString ATBDeviceControllerPlugin : : getString ( nsDeviceControllerInterface : : RESULT_STATE resultState )
{
QString str ;
switch ( resultState ) {
case nsDeviceControllerInterface : : RESULT_STATE : : SUCCESS :
str = QString ( " RESULT_STATE::SUCCESS " ) ;
break ;
case nsDeviceControllerInterface : : RESULT_STATE : : ERROR_BACKEND :
str = QString ( " RESULT_STATE::ERROR_BACKEND " ) ;
break ;
case nsDeviceControllerInterface : : RESULT_STATE : : ERROR_TIMEOUT :
str = QString ( " RESULT_STATE::ERROR_TIMEOUT " ) ;
break ;
case nsDeviceControllerInterface : : RESULT_STATE : : ERROR_PROCESS :
str = QString ( " RESULT_STATE::ERROR_PROCESS " ) ;
break ;
case nsDeviceControllerInterface : : RESULT_STATE : : ERROR_RETRY :
str = QString ( " RESULT_STATE::ERROR_RETRY " ) ;
break ;
case nsDeviceControllerInterface : : RESULT_STATE : : INFO :
str = QString ( " RESULT_STATE::INFO " ) ;
break ;
}
return str ;
}
2023-06-22 08:50:10 +02:00
2023-04-19 16:26:12 +02:00
/************************************************************************************************
* . . . end
*/
# if QT_VERSION < 0x050000
Q_EXPORT_PLUGIN2 ( ATBDeviceControllerPlugin , ATBDeviceControllerPlugin )
# endif