Compare commits
52 Commits
pu/use_cas
...
szeged_rel
Author | SHA1 | Date | |
---|---|---|---|
2cd73aaa86
|
|||
37d45f3c69
|
|||
f76a30cb07
|
|||
2b6eecfed7
|
|||
7be678fbe0
|
|||
6e9b1018e5
|
|||
04e2da390c
|
|||
e367538fc4
|
|||
7d722e2b2c
|
|||
80112f23b4
|
|||
9cd10bfed8
|
|||
ba3eabec2c
|
|||
a4d74ed0f7
|
|||
4a7022fd00
|
|||
31f178b241
|
|||
6a19fd7608
|
|||
8fc88662d3
|
|||
29cee7fd1c
|
|||
b39bbcfad5
|
|||
7c3bc484af
|
|||
2b71705c81
|
|||
18ff5d42a7
|
|||
ac9486879e
|
|||
1467530e3c
|
|||
414dda009e
|
|||
74753ce644
|
|||
c4cbf89182
|
|||
0baad4689a
|
|||
a4a746658c
|
|||
7e65c4feda
|
|||
e236fc8bce
|
|||
76e67dbbaa
|
|||
b52de16dbc
|
|||
cade03b400
|
|||
7a9f837b88
|
|||
b10e597e59
|
|||
4cc4247744
|
|||
59432735d0
|
|||
1f0720e52b
|
|||
5f3e0babb1
|
|||
f2637e3af8
|
|||
ac6331e5a7
|
|||
7ccbc8bb23
|
|||
017543dd5b
|
|||
d5d2b8917a
|
|||
9d686ae48d
|
|||
a037626d6d
|
|||
a3f32b576e
|
|||
668b10e55d
|
|||
596cf3ed25
|
|||
c330be4f30
|
|||
3722dd4d28
|
10
DCPlugin.pro
10
DCPlugin.pro
@@ -71,13 +71,19 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
|||||||
HEADERS += \
|
HEADERS += \
|
||||||
include/interfaces.h \
|
include/interfaces.h \
|
||||||
src/ATBAPP/ATBAPPplugin.h \
|
src/ATBAPP/ATBAPPplugin.h \
|
||||||
|
src/ATBAPP/DeviceControllerDiag.h \
|
||||||
src/ATBAPP/DeviceControllerInterface.h \
|
src/ATBAPP/DeviceControllerInterface.h \
|
||||||
src/ATBAPP/ATBHealthEvent.h \
|
src/ATBAPP/ATBHealthEvent.h \
|
||||||
src/ATBAPP/ATBDeviceControllerPlugin.h
|
src/ATBAPP/ATBMachineEvent.h \
|
||||||
|
src/ATBAPP/ATBDeviceControllerPlugin.h \
|
||||||
|
src/ATBAPP/Utils.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
src/ATBAPP/ATBHealthEvent.cpp \
|
src/ATBAPP/ATBHealthEvent.cpp \
|
||||||
src/ATBAPP/ATBDeviceControllerPlugin.cpp
|
src/ATBAPP/ATBMachineEvent.cpp \
|
||||||
|
src/ATBAPP/ATBDeviceControllerPlugin.cpp \
|
||||||
|
src/ATBAPP/DeviceControllerDiag.cpp \
|
||||||
|
src/ATBAPP/Utils.cpp
|
||||||
|
|
||||||
DISTFILES += \
|
DISTFILES += \
|
||||||
generate-version.sh
|
generate-version.sh
|
||||||
|
1310
include/interfaces.h
1310
include/interfaces.h
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,7 @@
|
|||||||
#include "src/ATBAPP/ATBDeviceControllerPlugin.h"
|
#include "src/ATBAPP/ATBDeviceControllerPlugin.h"
|
||||||
#include "src/ATBAPP/ATBHealthEvent.h"
|
#include "src/ATBAPP/ATBHealthEvent.h"
|
||||||
|
#include "src/ATBAPP/ATBMachineEvent.h"
|
||||||
|
#include "src/ATBAPP/Utils.h"
|
||||||
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
@@ -7,51 +9,75 @@
|
|||||||
|
|
||||||
#include <QPluginLoader>
|
#include <QPluginLoader>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QUuid>
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
|
||||||
ATBDeviceControllerPlugin::ATBDeviceControllerPlugin(QObject *parent) : QObject(parent),
|
|
||||||
pluginState(PLUGIN_STATE::NOT_INITIALIZED)
|
ATBDeviceControllerPlugin::ATBDeviceControllerPlugin(QObject *parent)
|
||||||
|
: pluginState(PLUGIN_STATE::NOT_INITIALIZED)
|
||||||
|
, eventReceiver(nullptr)
|
||||||
{
|
{
|
||||||
|
this->setParent(parent);
|
||||||
|
|
||||||
this->pluginInfo = QString::fromUtf8(pluginInfoString.c_str());
|
this->pluginInfo = QString::fromUtf8(pluginInfoString.c_str());
|
||||||
|
|
||||||
if (!this->private_loadCashAgentLib("")) {
|
if (!this->private_loadCashAgentLib("")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//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);
|
||||||
|
|
||||||
|
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_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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
connect(dynamic_cast<QObject*>(hw), SIGNAL(hwapi_doorCBinAndAllDoorsClosed()), this, SLOT(onCBinAndAllDoorsClosed()), Qt::QueuedConnection);
|
||||||
|
connect(dynamic_cast<QObject*>(hw), SIGNAL(hwapi_doorAllDoorsClosed()), this, SLOT(onAllDoorsClosed()), Qt::QueuedConnection); // check for errors, switch to mode IDLE
|
||||||
|
|
||||||
|
|
||||||
|
this->diag = new DeviceControllerDiag(this);
|
||||||
|
|
||||||
//connect(dynamic_cast<QObject*>(hw), SIGNAL(hwapi_templatePrintFinished_OK()), this, SLOT(onPrintFinishedOK()));
|
|
||||||
//connect(dynamic_cast<QObject*>(hw), SIGNAL(hwapi_templatePrintFinished_Err()), this, SLOT(onPrintFinishedERR()));
|
|
||||||
|
|
||||||
connect(dynamic_cast<QObject*>(hw), SIGNAL(hwapi_gotNewCoin()), this, SLOT(onCashGotCoin()));
|
this->currentSelectedTicketType = 0;
|
||||||
connect(dynamic_cast<QObject*>(hw), SIGNAL(hwapi_payStopByMax()), this, SLOT(onCashPayStopByMax()));
|
this->currentCashState = CASH_STATE::CACHE_EMPTY;
|
||||||
connect(dynamic_cast<QObject*>(hw), SIGNAL(hwapi_payStopByEscrow()), this, SLOT(onCashPayStopByEscrow()));
|
|
||||||
connect(dynamic_cast<QObject*>(hw), SIGNAL(hwapi_payStopByError()), this, SLOT(onCashPayStopByError()));
|
|
||||||
connect(dynamic_cast<QObject*>(hw), SIGNAL(hwapi_payStopByTimeout()), this, SLOT(onCashPayStopByTimeout()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ATBDeviceControllerPlugin::~ATBDeviceControllerPlugin() {}
|
ATBDeviceControllerPlugin::~ATBDeviceControllerPlugin() {}
|
||||||
|
|
||||||
PLUGIN_STATE ATBDeviceControllerPlugin::initDCPlugin(QObject *healthEventReceiver, const QSettings & settings)
|
PLUGIN_STATE ATBDeviceControllerPlugin::initDCPlugin(QObject *eventReceiver, const QSettings & settings)
|
||||||
{
|
{
|
||||||
this->healthEventReceiver = healthEventReceiver;
|
this->eventReceiver = eventReceiver;
|
||||||
|
|
||||||
// read variables from setting
|
// read variables from setting
|
||||||
QString serialPort = settings.value("DEVICE_CONTROLLER/serialPort", "ttymxc2").toString();
|
this->serialPortName = settings.value("DEVICE_CONTROLLER/serialPort", "ttymxc2").toString();
|
||||||
QByteArray printerEncoding = settings.value("DEVICE_CONTROLLER/printerEnconding", "ISO 8859-2").toString().toLatin1();
|
QByteArray printerEncoding = settings.value("DEVICE_CONTROLLER/printerEnconding", "ISO 8859-2").toString().toLatin1();
|
||||||
|
|
||||||
|
// open serial port
|
||||||
|
hw->dc_openSerial(5, "115200", this->serialPortName, 1);
|
||||||
|
|
||||||
hw->dc_autoRequest(true);
|
hw->dc_autoRequest(true);
|
||||||
|
|
||||||
// open serial port
|
hw->rtc_setDateTime();
|
||||||
hw->dc_openSerial(5, "115200", serialPort, 1);
|
|
||||||
|
// this is necessary to init the CashAgentLib (!)
|
||||||
|
hw->vend_failed();
|
||||||
|
|
||||||
|
|
||||||
// text encoding for printer
|
// text encoding for printer
|
||||||
this->codec = QTextCodec::codecForName(printerEncoding);
|
this->codec = QTextCodec::codecForName(printerEncoding);
|
||||||
|
|
||||||
|
this->diag->init(this->hw, this->eventReceiver);
|
||||||
|
|
||||||
this->pluginState = PLUGIN_STATE::INITIALIZED;
|
this->pluginState = PLUGIN_STATE::INITIALIZED;
|
||||||
|
|
||||||
@@ -59,6 +85,64 @@ PLUGIN_STATE ATBDeviceControllerPlugin::initDCPlugin(QObject *healthEventReceive
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ATBDeviceControllerPlugin::startPhysicalLayer()
|
||||||
|
{
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
if (this->pluginState == PLUGIN_STATE::NOT_INITIALIZED)
|
||||||
|
{
|
||||||
|
qCritical() << "ATBDeviceControllerPlugin::startPhysicalLayer(): plugin is not initialized";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hw->dc_autoRequest(false);
|
||||||
|
|
||||||
|
hw->dc_closeSerial();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Handle Mode-Changes --------------------------------------------------------
|
||||||
|
|
||||||
|
void ATBDeviceControllerPlugin::onChangedProgramModeToSELL()
|
||||||
|
{
|
||||||
|
//hw->dc_autoRequest(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ATBDeviceControllerPlugin::onChangedProgramModeToSERVICE()
|
||||||
|
{
|
||||||
|
//hw->dc_autoRequest(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ATBDeviceControllerPlugin::onChangedProgramModeToIDLE()
|
||||||
|
{
|
||||||
|
//hw->dc_autoRequest(false); // <-- TODO: ???
|
||||||
|
|
||||||
|
this->diag->diagRequest();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ATBDeviceControllerPlugin::onChangedProgramModeToOOO()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// TASKS: Cash handling -------------------------------------------------------
|
// TASKS: Cash handling -------------------------------------------------------
|
||||||
void ATBDeviceControllerPlugin::requestStartCashInput(const QString & amount)
|
void ATBDeviceControllerPlugin::requestStartCashInput(const QString & amount)
|
||||||
{
|
{
|
||||||
@@ -76,27 +160,293 @@ void ATBDeviceControllerPlugin::requestStopCashInput()
|
|||||||
hw->cash_stopPayment();
|
hw->cash_stopPayment();
|
||||||
|
|
||||||
// we need new cash value in application...
|
// we need new cash value in application...
|
||||||
QTimer::singleShot(500, this, SLOT(onCashPayStoped()));
|
QTimer::singleShot(2500, this, SLOT(onCashPayStopedSuccess()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ATBDeviceControllerPlugin::cashCollect()
|
void ATBDeviceControllerPlugin::cashCollect()
|
||||||
{
|
{
|
||||||
hw->vend_success();
|
hw->vend_success();
|
||||||
|
this->currentCashState = CASH_STATE::CACHE_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ATBDeviceControllerPlugin::cashAbort()
|
void ATBDeviceControllerPlugin::cashAbort()
|
||||||
{
|
{
|
||||||
hw->vend_failed();
|
hw->vend_failed();
|
||||||
|
this->currentCashState = CASH_STATE::CACHE_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TASKS: Account -------------------------------------------------------------
|
// TASKS: Account -------------------------------------------------------------
|
||||||
|
|
||||||
|
// for an external account request, e.g. by an ui-button:
|
||||||
void ATBDeviceControllerPlugin::requestAccount()
|
void ATBDeviceControllerPlugin::requestAccount()
|
||||||
{
|
{
|
||||||
qCritical() << "TODO: implement ATBDeviceControllerPlugin::requestAccount()";
|
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);
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
qCritical() << "Start account: ";
|
||||||
|
qCritical() << " nrOfVals = " << nrOfVals;
|
||||||
|
for (int i=0; i<nrOfVals; ++i) {
|
||||||
|
qCritical() << " backupedAccNumbers[" << i << "] = " << backupedAccNumbers[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
qsort( backupedAccNumbers, nrOfVals, sizeof (uint16_t), Utils::compare );
|
||||||
|
|
||||||
|
uint16_t latestAccountNumber = backupedAccNumbers[nrOfVals-1];
|
||||||
|
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
qCritical() << " latestAccountNumber = " << latestAccountNumber;
|
||||||
|
|
||||||
|
hw->log_selectVaultRecord(latestAccountNumber);
|
||||||
|
|
||||||
|
this->accountCheckCounter = 0;
|
||||||
|
QTimer::singleShot(500, this, SLOT(private_checkAccountData()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ATBDeviceControllerPlugin::private_checkAccountData()
|
||||||
|
{
|
||||||
|
// DEBUG
|
||||||
|
qCritical() << " --> private_checkAccountData()";
|
||||||
|
|
||||||
|
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";
|
||||||
|
|
||||||
|
// simulate:
|
||||||
|
this->private_getAccountData();
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: create and send an HealthEvent...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ATBDeviceControllerPlugin::private_getAccountData()
|
||||||
|
{
|
||||||
|
// DEBUG
|
||||||
|
qCritical() << " --> private_getAccountData()";
|
||||||
|
|
||||||
|
struct T_vaultRecord retVR;
|
||||||
|
|
||||||
|
hw->log_getVaultRecord(&retVR);
|
||||||
|
|
||||||
|
QHash<QString, QVariant> accountData;
|
||||||
|
|
||||||
|
accountData.insert("AccountingNumber", QString::number(retVR.AccountingNumber));
|
||||||
|
|
||||||
|
int numberOfCoinVariants = sizeof(retVR.coinsInVault);
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
qCritical() << " NumberOfCoinVariants = " << numberOfCoinVariants;
|
||||||
|
|
||||||
|
// limit numberOfCoinVariants:
|
||||||
|
if (numberOfCoinVariants > 16) { numberOfCoinVariants = 16; }
|
||||||
|
|
||||||
|
accountData.insert("NumberOfCoinVariants", numberOfCoinVariants);
|
||||||
|
for (int i = 0; i < numberOfCoinVariants; ++i) {
|
||||||
|
accountData.insert("COIN_" + QString::number(i) + "_Quantity", retVR.coinsInVault[i]);
|
||||||
|
accountData.insert("COIN_" + QString::number(i) + "_Value", retVR.coinDenomination[i]);
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
qCritical() << "COIN_" + QString::number(i) + "_Quantity = " << accountData["COIN_" + QString::number(i) + "_Quantity"];
|
||||||
|
qCritical() << "COIN_" + QString::number(i) + "_Value = " << accountData["COIN_" + QString::number(i) + "_Value"];
|
||||||
|
}
|
||||||
|
|
||||||
|
emit requestAccountResponse(accountData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Door Events / Hardware contacts --------------------------------------------
|
||||||
|
void ATBDeviceControllerPlugin::onServiceDoorOpened()
|
||||||
|
{
|
||||||
|
qCritical() << "ATBDeviceControllerPlugin::onServiceDoorOpened()";
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
qCritical() << "ATBDeviceControllerPlugin::onVaultDoorOpened()";
|
||||||
|
|
||||||
|
// TODO: Start background task "ACCOUNT"
|
||||||
|
|
||||||
|
// do not: emit this->requestModeSERVICE();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ATBDeviceControllerPlugin::onCoinBoxRemoved()
|
||||||
|
{
|
||||||
|
qCritical() << "ATBDeviceControllerPlugin::onCoinBoxRemoved()";
|
||||||
|
|
||||||
|
this->private_startAccount();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ATBDeviceControllerPlugin::onCoinBoxInserted()
|
||||||
|
{
|
||||||
|
qCritical() << "ATBDeviceControllerPlugin::onCoinBoxInserted()";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ATBDeviceControllerPlugin::onCBinAndAllDoorsClosed()
|
||||||
|
{
|
||||||
|
qCritical() << "ATBDeviceControllerPlugin::onCBinAndAllDoorsClosed()";
|
||||||
|
|
||||||
|
this->diag->diagRequest();
|
||||||
|
|
||||||
|
// TODO: Stop background task "ACCOUNT"
|
||||||
|
|
||||||
|
QTimer::singleShot(2000, this, SIGNAL(requestModeIDLE()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ATBDeviceControllerPlugin::onAllDoorsClosed()
|
||||||
|
{
|
||||||
|
qCritical() << "ATBDeviceControllerPlugin::onAllDoorsClosed()";
|
||||||
|
|
||||||
|
emit this->requestModeIDLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TASKS: printing ------------------------------------------------------------
|
// TASKS: printing ------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 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());
|
||||||
|
memcpy((char*)dynTicketData->vendingPrice, ba_amount.data(), std::min(ba_amount.size(),8));
|
||||||
|
|
||||||
|
QByteArray ba_parkingEndTime = codec->fromUnicode(parkingEndDateTime.toString("hh:mm"));
|
||||||
|
memcpy((char*)dynTicketData->parkingEnd, ba_parkingEndTime.data(), std::min(ba_parkingEndTime.size(),8));
|
||||||
|
|
||||||
|
QByteArray ba_parkingEndDate = codec->fromUnicode(parkingEndDateTime.toString("dd.MM.yy"));
|
||||||
|
memcpy((char*)dynTicketData->currentTime, ba_parkingEndDate.data(), std::min(ba_parkingEndDate.size(),8));
|
||||||
|
// ! and yes... 'ParkingEndDate' is 'currentTime'
|
||||||
|
|
||||||
|
QByteArray ba_currentDate = codec->fromUnicode(currentDateTime.toString("dd.MM.yy"));
|
||||||
|
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()";
|
||||||
|
for (int i =0; i < this->templateList.size(); ++i) {
|
||||||
|
qCritical() << " template: " << this->templateList.at(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!this->hw->dc_isPortOpen()) {
|
||||||
|
qCritical() << " ... serial port is not open!";
|
||||||
|
this->onPrintFinishedERR();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ATBDeviceControllerPlugin::requestPrintTicket(const QHash<QString, QVariant> & printingData)
|
void ATBDeviceControllerPlugin::requestPrintTicket(const QHash<QString, QVariant> & printingData)
|
||||||
{
|
{
|
||||||
struct T_dynDat *dynTicketData = new T_dynDat;
|
struct T_dynDat *dynTicketData = new T_dynDat;
|
||||||
@@ -154,8 +504,6 @@ void ATBDeviceControllerPlugin::requestPrintTicket(const QHash<QString, QVariant
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: wird hier nur 'licensePlate' gedruckt?
|
// TODO: wird hier nur 'licensePlate' gedruckt?
|
||||||
if (!this->hw->prn_sendDynamicPrnValues(dynTicketData->licensePlate)) {
|
if (!this->hw->prn_sendDynamicPrnValues(dynTicketData->licensePlate)) {
|
||||||
this->errorCode = "hwapi::prn_sendDynamicPrnValues";
|
this->errorCode = "hwapi::prn_sendDynamicPrnValues";
|
||||||
@@ -174,45 +522,117 @@ void ATBDeviceControllerPlugin::requestPrintTicket(const QHash<QString, QVariant
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTimer::singleShot(1000, this, SLOT(onPrinterDataPrepared()));
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTimer::singleShot(3000, this, SLOT(onPrinterDataPrepared()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ATBDeviceControllerPlugin::onPrinterDataPreparedForTemplates()
|
||||||
|
{
|
||||||
|
if (this->templateList.isEmpty()) return;
|
||||||
|
|
||||||
|
this->onPrinterPrintNextTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
void ATBDeviceControllerPlugin::onPrinterDataPrepared()
|
void ATBDeviceControllerPlugin::onPrinterDataPrepared()
|
||||||
{
|
{
|
||||||
this->currentTemplate = 1;
|
this->hw->prn_printKombiticket(this->currentSelectedTicketType);
|
||||||
this->onPrinterPrintNextTemplate();
|
|
||||||
|
// note: calling prn_getPrintResult() immediately may result in wrong answer!
|
||||||
|
// We have to wait "about some seconds" until calling this function!
|
||||||
|
QTimer::singleShot(4000, this, SLOT(onPrinterWaitForPrinting()));
|
||||||
|
|
||||||
|
// old: use printer templates:
|
||||||
|
// this->currentTemplate = 1;
|
||||||
|
// this->onPrinterPrintNextTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ATBDeviceControllerPlugin::onPrinterWaitForPrinting()
|
||||||
|
{
|
||||||
|
quint8 printerResult = this->hw->prn_getPrintResult();
|
||||||
|
|
||||||
|
switch (printerResult) {
|
||||||
|
case 0: // still printing
|
||||||
|
qCritical() << "--> printer: WaitForPrinting";
|
||||||
|
QTimer::singleShot(2000, this, SLOT(onPrinterWaitForPrinting()));
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ATBDeviceControllerPlugin::onPrinterPrintNextTemplate()
|
void ATBDeviceControllerPlugin::onPrinterPrintNextTemplate()
|
||||||
{
|
{
|
||||||
qCritical() << " ... print template " << this->currentTemplate;
|
// template list must not be empty
|
||||||
|
if (this->templateList.isEmpty()) {
|
||||||
if (!this->hw->prn_printTemplate(this->currentTemplate)) {
|
|
||||||
this->errorCode = "hwapi::prn_printTemplate";
|
|
||||||
this->errorDescription = QString("hwapi method 'hwapi::onPrinterPrintNextTemplate(%1)' result is false").arg(this->currentTemplate);
|
|
||||||
this->onPrintFinishedERR();
|
this->onPrintFinishedERR();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->currentTemplate >= 3) {
|
qCritical() << " ... print template " << this->templateList.first();
|
||||||
|
|
||||||
|
if (!this->hw->prn_printTemplate(this->templateList.first())) {
|
||||||
|
this->errorCode = "hwapi::prn_printTemplate";
|
||||||
|
this->errorDescription = QString("hwapi method 'hwapi::onPrinterPrintNextTemplate(%1)' result is false").arg(this->templateList.first());
|
||||||
|
this->onPrintFinishedERR();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->templateList.removeFirst();
|
||||||
|
|
||||||
|
if (templateList.isEmpty()) {
|
||||||
// all templates are printed
|
// all templates are printed
|
||||||
this->currentTemplate = 0;
|
|
||||||
|
|
||||||
// FAKE SIGNAL:
|
// FAKE SIGNAL:
|
||||||
QTimer::singleShot(500, this, SLOT(onPrintFinishedOK()));
|
QTimer::singleShot(2000, this, SLOT(onPrintFinishedOK()));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// print next template
|
// print next template
|
||||||
this->currentTemplate++;
|
|
||||||
QTimer::singleShot(2000, this, SLOT(onPrinterPrintNextTemplate()));
|
QTimer::singleShot(2000, this, SLOT(onPrinterPrintNextTemplate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************************************
|
/************************************************************************************************
|
||||||
* private slots, interface to low level hwapi
|
* private slots, interface to low level hwapi
|
||||||
*
|
*
|
||||||
@@ -223,6 +643,7 @@ void ATBDeviceControllerPlugin::onPrintFinishedOK()
|
|||||||
qCritical() << "ATBDeviceControllerPlugin::onPrintFinishedOK()";
|
qCritical() << "ATBDeviceControllerPlugin::onPrintFinishedOK()";
|
||||||
|
|
||||||
emit this->printTicketFinished(nsDeviceControllerInterface::RESULT_STATE::SUCCESS,
|
emit this->printTicketFinished(nsDeviceControllerInterface::RESULT_STATE::SUCCESS,
|
||||||
|
// TODO: TicketNumber
|
||||||
"",
|
"",
|
||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
@@ -250,6 +671,8 @@ void ATBDeviceControllerPlugin::onCashGotCoin()
|
|||||||
// DEBUG
|
// DEBUG
|
||||||
qCritical() << "ATBDeviceControllerPlugin::onGotCoin()";
|
qCritical() << "ATBDeviceControllerPlugin::onGotCoin()";
|
||||||
|
|
||||||
|
this->currentCashState = CASH_STATE::CACHE_INPUT;
|
||||||
|
|
||||||
uint32_t amountInt = this->hw->getInsertedAmount();
|
uint32_t amountInt = this->hw->getInsertedAmount();
|
||||||
|
|
||||||
QString amountString = QString::number(amountInt);
|
QString amountString = QString::number(amountInt);
|
||||||
@@ -268,14 +691,8 @@ void ATBDeviceControllerPlugin::onCashPayStopByMax()
|
|||||||
// DEBUG
|
// DEBUG
|
||||||
qCritical() << "ATBDeviceControllerPlugin::onCashVendStopByMax()";
|
qCritical() << "ATBDeviceControllerPlugin::onCashVendStopByMax()";
|
||||||
|
|
||||||
uint32_t amountInt = this->hw->getInsertedAmount();
|
// we need new cash value in application...
|
||||||
|
QTimer::singleShot(500, this, SLOT(onCashPayStopedSuccess()));
|
||||||
QString amountString = QString::number(amountInt);
|
|
||||||
|
|
||||||
emit this->cashInputFinished(nsDeviceControllerInterface::RESULT_STATE::SUCCESS,
|
|
||||||
amountString,
|
|
||||||
"",
|
|
||||||
"");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,7 +741,7 @@ void ATBDeviceControllerPlugin::onCashPayStopByTimeout()
|
|||||||
"");
|
"");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ATBDeviceControllerPlugin::onCashPayStoped()
|
void ATBDeviceControllerPlugin::onCashPayStopedSuccess()
|
||||||
{
|
{
|
||||||
// DEBUG
|
// DEBUG
|
||||||
qCritical() << "ATBDeviceControllerPlugin::onCashPayStoped()";
|
qCritical() << "ATBDeviceControllerPlugin::onCashPayStoped()";
|
||||||
@@ -333,6 +750,9 @@ void ATBDeviceControllerPlugin::onCashPayStoped()
|
|||||||
|
|
||||||
QString amountString = QString::number(amountInt);
|
QString amountString = QString::number(amountInt);
|
||||||
|
|
||||||
|
qCritical() << " insertedAmount (int) = " << amountInt;
|
||||||
|
qCritical() << " insertedAmount = " << amountString;
|
||||||
|
|
||||||
emit this->cashInputFinished(nsDeviceControllerInterface::RESULT_STATE::SUCCESS,
|
emit this->cashInputFinished(nsDeviceControllerInterface::RESULT_STATE::SUCCESS,
|
||||||
amountString,
|
amountString,
|
||||||
"",
|
"",
|
||||||
@@ -350,12 +770,31 @@ void ATBDeviceControllerPlugin::onCashPayStoped()
|
|||||||
bool ATBDeviceControllerPlugin::private_loadCashAgentLib(QString pluginName)
|
bool ATBDeviceControllerPlugin::private_loadCashAgentLib(QString pluginName)
|
||||||
{
|
{
|
||||||
if (pluginName == "") {
|
if (pluginName == "") {
|
||||||
pluginName = "/usr/lib/libCashAgentLib.so";
|
|
||||||
|
// search list for plugin (.so) file:
|
||||||
|
QStringList pluginNameList;
|
||||||
|
pluginNameList << "/usr/lib/libCAmaster.so"
|
||||||
|
<< "/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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!QLibrary::isLibrary(pluginName)) {
|
if (!QLibrary::isLibrary(pluginName)) {
|
||||||
qCritical() << "ATBDeviceControllerPlugin: can not load CashAgentLib: " << pluginName;
|
qCritical() << "ATBDeviceControllerPlugin: can not load CashAgentLib: " << pluginName;
|
||||||
this->errorCode = 5;
|
this->errorCode = "CashAgentLib::NO_LIBRARY";
|
||||||
this->errorDescription = "ERROR: can not load CashAgentLib: " + pluginName;
|
this->errorDescription = "ERROR: can not load CashAgentLib: " + pluginName;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -366,13 +805,16 @@ bool ATBDeviceControllerPlugin::private_loadCashAgentLib(QString pluginName)
|
|||||||
QObject* plugin = pluginLoader->instance();
|
QObject* plugin = pluginLoader->instance();
|
||||||
if (!pluginLoader->isLoaded()) {
|
if (!pluginLoader->isLoaded()) {
|
||||||
qCritical() << "ATBDeviceControllerPlugin: can not instantiate CashAgentLib: " << pluginName;
|
qCritical() << "ATBDeviceControllerPlugin: can not instantiate CashAgentLib: " << pluginName;
|
||||||
this->errorCode = 6;
|
qCritical() << " error: " << pluginLoader->errorString();
|
||||||
|
this->errorCode = "CashAgentLib::NO_INSTANCE";
|
||||||
this->errorDescription = "ERROR: can not instantiate CashAgentLib: " + pluginName;
|
this->errorDescription = "ERROR: can not instantiate CashAgentLib: " + pluginName;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plugin == nullptr) {
|
if (plugin == nullptr) {
|
||||||
qCritical() << "ATBDeviceControllerPlugin: plugin is NULL";
|
qCritical() << "ATBDeviceControllerPlugin: plugin is NULL";
|
||||||
|
this->errorCode = "CashAgentLib::INSTANCE_IS_NULL";
|
||||||
|
this->errorDescription = "ERROR: CashAgentLib instance is NULL: " + pluginName;
|
||||||
}
|
}
|
||||||
|
|
||||||
qCritical() << "ATBDeviceControllerPlugin: instantiate CashAgentLib: " << pluginName;
|
qCritical() << "ATBDeviceControllerPlugin: instantiate CashAgentLib: " << pluginName;
|
||||||
@@ -381,8 +823,13 @@ bool ATBDeviceControllerPlugin::private_loadCashAgentLib(QString pluginName)
|
|||||||
|
|
||||||
if (this->hw == nullptr) {
|
if (this->hw == nullptr) {
|
||||||
qCritical() << "ATBDeviceControllerPlugin: hw is NULL";
|
qCritical() << "ATBDeviceControllerPlugin: hw is NULL";
|
||||||
|
this->errorCode = "CashAgentLib::HW_IS_NULL";
|
||||||
|
this->errorDescription = "ERROR: CashAgentLib object_cast is NULL: " + pluginName;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qCritical() << "ATBDeviceControllerPlugin: loaded CashAgentLib";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#include "src/ATBAPP/DeviceControllerInterface.h"
|
#include "src/ATBAPP/DeviceControllerInterface.h"
|
||||||
#include "src/ATBAPP/ATBAPPplugin.h"
|
#include "src/ATBAPP/ATBAPPplugin.h"
|
||||||
|
#include "src/ATBAPP/DeviceControllerDiag.h"
|
||||||
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -12,9 +14,6 @@
|
|||||||
#include "interfaces.h"
|
#include "interfaces.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <thread>
|
|
||||||
#include <memory>
|
|
||||||
#include <QSharedMemory>
|
|
||||||
|
|
||||||
|
|
||||||
class QTextCodec;
|
class QTextCodec;
|
||||||
@@ -24,7 +23,7 @@ using namespace nsDeviceControllerInterface;
|
|||||||
|
|
||||||
class QSettings;
|
class QSettings;
|
||||||
|
|
||||||
class ATBDeviceControllerPlugin : public QObject,
|
class ATBDeviceControllerPlugin :
|
||||||
public DeviceControllerInterface
|
public DeviceControllerInterface
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -40,7 +39,7 @@ public:
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// interface:
|
// interface:
|
||||||
PLUGIN_STATE initDCPlugin(QObject *healthEventReceiver, const QSettings & settings);
|
PLUGIN_STATE initDCPlugin(QObject *eventReceiver, const QSettings & settings);
|
||||||
|
|
||||||
// TASKS: Cash handling -------------------------------------------------------
|
// TASKS: Cash handling -------------------------------------------------------
|
||||||
void requestStartCashInput(const QString & amount);
|
void requestStartCashInput(const QString & amount);
|
||||||
@@ -50,6 +49,8 @@ public:
|
|||||||
|
|
||||||
// TASKS: printing ------------------------------------------------------------
|
// TASKS: printing ------------------------------------------------------------
|
||||||
void requestPrintTicket(const QHash<QString, QVariant> & printingData);
|
void requestPrintTicket(const QHash<QString, QVariant> & printingData);
|
||||||
|
void requestPrintTicket(nsDeviceControllerInterface::TICKET_VARIANT ticketVariant, const QHash<QString, QVariant> & printingData);
|
||||||
|
void requestPrintReceipt(const QHash<QString, QVariant> & printingData);
|
||||||
|
|
||||||
// TASKS: Account -------------------------------------------------------------
|
// TASKS: Account -------------------------------------------------------------
|
||||||
void requestAccount();
|
void requestAccount();
|
||||||
@@ -62,37 +63,20 @@ public:
|
|||||||
const QString & getPluginInfo();
|
const QString & getPluginInfo();
|
||||||
|
|
||||||
// helpers e.g. for debug / log
|
// helpers e.g. for debug / log
|
||||||
const QString getString(nsDeviceControllerInterface::RESULT_STATE resultState);
|
const QString getString(nsDeviceControllerInterface::RESULT_STATE resultState);;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void onChangedProgramModeToSELL();
|
||||||
|
void onChangedProgramModeToSERVICE();
|
||||||
|
void onChangedProgramModeToIDLE();
|
||||||
|
void onChangedProgramModeToOOO();
|
||||||
|
|
||||||
|
void startPhysicalLayer();
|
||||||
|
void stopPhysicalLayer();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void printTicketFinished(nsDeviceControllerInterface::RESULT_STATE resultState,
|
|
||||||
const QString & errorCode,
|
|
||||||
const QString & errorDescription);
|
|
||||||
|
|
||||||
void cashInputEvent(nsDeviceControllerInterface::RESULT_STATE resultState,
|
|
||||||
nsDeviceControllerInterface::CASH_STATE cashState,
|
|
||||||
const QString & newCashValue,
|
|
||||||
const QString & errorCode,
|
|
||||||
const QString & errorDescription);
|
|
||||||
|
|
||||||
void cashInputFinished(nsDeviceControllerInterface::RESULT_STATE resultState,
|
|
||||||
const QString & newCashValue,
|
|
||||||
const QString & errorCode,
|
|
||||||
const QString & errorDescription);
|
|
||||||
|
|
||||||
void requestServiceMode();
|
|
||||||
|
|
||||||
void requestAccountResponse(const QHash<QString, QVariant> & accountData);
|
|
||||||
|
|
||||||
|
|
||||||
void Error(
|
|
||||||
const QString & errorCode,
|
|
||||||
const QString & errorDescription);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -101,37 +85,64 @@ private:
|
|||||||
QString errorDescription;
|
QString errorDescription;
|
||||||
QString pluginInfo;
|
QString pluginInfo;
|
||||||
|
|
||||||
int currentTemplate;
|
QList<int> templateList;
|
||||||
|
|
||||||
|
QString serialPortName;
|
||||||
|
|
||||||
bool useDebug;
|
bool useDebug;
|
||||||
|
|
||||||
PLUGIN_STATE pluginState;
|
PLUGIN_STATE pluginState;
|
||||||
|
|
||||||
QObject* healthEventReceiver;
|
QObject* eventReceiver;
|
||||||
|
|
||||||
hwinf* hw;
|
hwinf* hw;
|
||||||
|
|
||||||
|
DeviceControllerDiag* diag;
|
||||||
|
|
||||||
|
|
||||||
QTextCodec *codec;
|
QTextCodec *codec;
|
||||||
|
|
||||||
bool private_loadCashAgentLib(QString pluginName);
|
bool private_loadCashAgentLib(QString pluginName);
|
||||||
|
|
||||||
|
quint8 currentSelectedTicketType;
|
||||||
|
|
||||||
|
nsDeviceControllerInterface::CASH_STATE currentCashState;
|
||||||
|
|
||||||
|
// counts failed hw->log_chkIfVaultRecordAvailable()
|
||||||
|
int accountCheckCounter;
|
||||||
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
// printer
|
// printer
|
||||||
|
|
||||||
void onPrinterDataPrepared();
|
void onPrinterDataPrepared();
|
||||||
|
void onPrinterDataPreparedForTemplates();
|
||||||
void onPrinterPrintNextTemplate();
|
void onPrinterPrintNextTemplate();
|
||||||
|
void onPrinterWaitForPrinting();
|
||||||
|
|
||||||
void onPrintFinishedOK();
|
void onPrintFinishedOK();
|
||||||
void onPrintFinishedERR();
|
void onPrintFinishedERR();
|
||||||
|
|
||||||
// cash payment
|
// cash payment
|
||||||
void onCashGotCoin();
|
void onCashGotCoin();
|
||||||
void onCashPayStoped();
|
void onCashPayStopedSuccess();
|
||||||
void onCashPayStopByMax();
|
void onCashPayStopByMax();
|
||||||
void onCashPayStopByEscrow();
|
void onCashPayStopByEscrow();
|
||||||
void onCashPayStopByError();
|
void onCashPayStopByError();
|
||||||
void onCashPayStopByTimeout();
|
void onCashPayStopByTimeout();
|
||||||
|
|
||||||
|
// doors and hardware contacts
|
||||||
|
void onServiceDoorOpened();
|
||||||
|
void onVaultDoorOpened();
|
||||||
|
void onCoinBoxRemoved();
|
||||||
|
void onCoinBoxInserted();
|
||||||
|
void onAllDoorsClosed();
|
||||||
|
void onCBinAndAllDoorsClosed();
|
||||||
|
|
||||||
|
// account handling
|
||||||
|
void private_startAccount();
|
||||||
|
void private_checkAccountData();
|
||||||
|
void private_getAccountData();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ATBDEVICECONTROLLERPLUGIN_H
|
#endif // ATBDEVICECONTROLLERPLUGIN_H
|
||||||
|
66
src/ATBAPP/ATBMachineEvent.cpp
Normal file
66
src/ATBAPP/ATBMachineEvent.cpp
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/* Machine Event
|
||||||
|
*
|
||||||
|
* Used e.g. to send events to ISMAS
|
||||||
|
*
|
||||||
|
* Note: It's an Event, not a State!
|
||||||
|
* -> An Event may cause a transition to a different state, depending on the current state.
|
||||||
|
* -> Compare to edge/level trigger: Event is an "edge", State is a "level"
|
||||||
|
* => Do not mix both
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
|
#include "ATBMachineEvent.h"
|
||||||
|
|
||||||
|
|
||||||
|
ATBMachineEvent::ATBMachineEvent(
|
||||||
|
const QString & id,
|
||||||
|
const QString & deviceName, // PTU/PRINTER/DC/...
|
||||||
|
EVENT_CLASS eventClass, // reason of event: Error/Warning/Alarm
|
||||||
|
const QString & name, // 'Event': "E001", "W003"
|
||||||
|
const int state,
|
||||||
|
const QString & parameter,
|
||||||
|
const QString & secondLevelInfo)
|
||||||
|
: QEvent(ATB_MACHINE_EVENT)
|
||||||
|
, eventId(id)
|
||||||
|
, deviceName(deviceName)
|
||||||
|
, machineEventClass(eventClass)
|
||||||
|
, eventName(name)
|
||||||
|
, eventState(state)
|
||||||
|
// timestamp including timezone offset
|
||||||
|
, timestampString(QDateTime::currentDateTime().toOffsetFromUtc(
|
||||||
|
QDateTime::currentDateTime().offsetFromUtc()).toString(Qt::ISODate)
|
||||||
|
)
|
||||||
|
, parameterString(parameter)
|
||||||
|
, secondLevelInfoString(secondLevelInfo)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString ATBMachineEvent::getEventClassString(EVENT_CLASS eventClass)
|
||||||
|
{
|
||||||
|
switch (eventClass) {
|
||||||
|
case EVENT_CLASS::WARNING:
|
||||||
|
return "WARNING";
|
||||||
|
break;
|
||||||
|
case EVENT_CLASS::ERROR:
|
||||||
|
return "ERROR";
|
||||||
|
break;
|
||||||
|
case EVENT_CLASS::ALARM:
|
||||||
|
return "ALARM";
|
||||||
|
break;
|
||||||
|
case EVENT_CLASS::DEBUG:
|
||||||
|
return "DEBUG";
|
||||||
|
break;
|
||||||
|
case EVENT_CLASS::STATE:
|
||||||
|
return "STATE";
|
||||||
|
break;
|
||||||
|
case EVENT_CLASS::NOT_DEFINED:
|
||||||
|
return "NOT_DEFINED";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "NOT_DEFINED";
|
||||||
|
}
|
||||||
|
|
47
src/ATBAPP/ATBMachineEvent.h
Normal file
47
src/ATBAPP/ATBMachineEvent.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#ifndef ATBMACHINECONDITIONEVENT_H
|
||||||
|
#define ATBMACHINECONDITIONEVENT_H
|
||||||
|
|
||||||
|
#include <QEvent>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
enum class EVENT_CLASS : quint8;
|
||||||
|
|
||||||
|
const QEvent::Type ATB_MACHINE_EVENT = static_cast<QEvent::Type>(QEvent::User + 2);
|
||||||
|
|
||||||
|
|
||||||
|
class ATBMachineEvent : public QEvent
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ATBMachineEvent(const QString & id,
|
||||||
|
const QString & deviceName, // PTU/PRINTER/DC/...
|
||||||
|
EVENT_CLASS eventClass, // reason of event: Error/Warning/Alarm
|
||||||
|
const QString & name, // 'Event': "E001", "W003"
|
||||||
|
const int state,
|
||||||
|
const QString & parameter,
|
||||||
|
const QString & secondLevelInfo
|
||||||
|
);
|
||||||
|
|
||||||
|
QString eventId;
|
||||||
|
QString deviceName;
|
||||||
|
EVENT_CLASS machineEventClass;
|
||||||
|
QString eventName;
|
||||||
|
int eventState;
|
||||||
|
QString timestampString;
|
||||||
|
QString parameterString;
|
||||||
|
QString secondLevelInfoString;
|
||||||
|
|
||||||
|
static QString getEventClassString(EVENT_CLASS eventClass);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum class EVENT_CLASS : quint8 {
|
||||||
|
WARNING,
|
||||||
|
ERROR,
|
||||||
|
ALARM,
|
||||||
|
DEBUG,
|
||||||
|
STATE,
|
||||||
|
NOT_DEFINED
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ATBMACHINEEVENT_H
|
382
src/ATBAPP/DeviceControllerDiag.cpp
Normal file
382
src/ATBAPP/DeviceControllerDiag.cpp
Normal file
@@ -0,0 +1,382 @@
|
|||||||
|
#include "DeviceControllerDiag.h"
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QUuid>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
DeviceControllerDiag::DeviceControllerDiag(QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, eventReceiver(nullptr)
|
||||||
|
, isRequestRunning(false)
|
||||||
|
, flagInterruptDiag(false)
|
||||||
|
{
|
||||||
|
diagRequestTimeoutTimer = new QTimer(this);
|
||||||
|
diagRequestTimeoutTimer->setInterval(1000*20); // 20s
|
||||||
|
diagRequestTimeoutTimer->setSingleShot(true);
|
||||||
|
connect(diagRequestTimeoutTimer, &QTimer::timeout, this, &DeviceControllerDiag::onDiagRequestTimeoutTimerTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DeviceControllerDiag::init(hwinf *hw, QObject* eventReceiver)
|
||||||
|
{
|
||||||
|
this->hw = hw;
|
||||||
|
this->eventReceiver = eventReceiver;
|
||||||
|
|
||||||
|
// make a system check on startup:
|
||||||
|
QTimer::singleShot(2000, this, &DeviceControllerDiag::diagRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DeviceControllerDiag::diagRequest()
|
||||||
|
{
|
||||||
|
qCritical() << "DeviceControllerDiag::diagRequest()";
|
||||||
|
|
||||||
|
if (this->isRequestRunning) {
|
||||||
|
qCritical() << "DeviceControllerDiag::diagRequest() is already running";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->isRequestRunning = true;
|
||||||
|
this->diagRequestTimeoutTimer->start();
|
||||||
|
|
||||||
|
this->private_startDiag();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DeviceControllerDiag::onDiagRequestTimeoutTimerTimeout()
|
||||||
|
{
|
||||||
|
qCritical() << "DeviceControllerDiag::onDiagRequestTimeoutTimerTimeout()";
|
||||||
|
this->flagInterruptDiag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceControllerDiag::private_startDiag()
|
||||||
|
{
|
||||||
|
// check for DiagRequestTimeoutTimerTimeout:
|
||||||
|
if (this->flagInterruptDiag) {
|
||||||
|
qCritical() << "DeviceControllerDiag::private_startDiag() interrupted!";
|
||||||
|
this->private_finishedDiag(0xff);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result;
|
||||||
|
result = hw->sys_areDCdataValid();
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
qCritical() << "DeviceControllerDiag::private_startDiag() DCdata is valid";
|
||||||
|
QTimer::singleShot(200, this, &DeviceControllerDiag::sys_superviseSystem);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qCritical() << "DeviceControllerDiag::private_startDiag() DCdata is +++not+++ valid";
|
||||||
|
|
||||||
|
// try it again
|
||||||
|
QTimer::singleShot(200, this, &DeviceControllerDiag::private_startDiag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceControllerDiag::sys_superviseSystem()
|
||||||
|
{ // this function proofs if vending is possible depending of doors state
|
||||||
|
|
||||||
|
struct T_dynamicCondition dynMaCond;
|
||||||
|
struct T_moduleCondition modCond;
|
||||||
|
|
||||||
|
|
||||||
|
qCritical() << " sys_superviseSystem()";
|
||||||
|
|
||||||
|
|
||||||
|
// check for DiagRequestTimeoutTimerTimeout:
|
||||||
|
if (this->flagInterruptDiag) {
|
||||||
|
qCritical() << "DeviceControllerDiag::sys_superviseSystem() interrupted!";
|
||||||
|
this->private_finishedDiag(0xff);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hw->sys_areDCdataValid())
|
||||||
|
{
|
||||||
|
// es gibt keinerlei gültige Daten vom DC
|
||||||
|
qCritical() << "DeviceControllerDiag::sys_superviseSystem() no valid data!";
|
||||||
|
this->private_finishedDiag(0xfe);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// jetzt sind die DC-Daten aktuell, also reinholen:
|
||||||
|
hw->sys_getDynMachineConditions(&dynMaCond);
|
||||||
|
hw->sys_getDeviceConditions(&modCond);
|
||||||
|
|
||||||
|
qCritical() << "DeviceControllerDiag::sys_superviseSystem() get condition data";
|
||||||
|
if (!modCond.allModulesChecked)
|
||||||
|
{
|
||||||
|
// noch keine Testergebnisse
|
||||||
|
if (dynMaCond.startupTestIsRunning) {
|
||||||
|
// TODO?
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
qCritical() << " allModulesChecked is false --> call again";
|
||||||
|
|
||||||
|
QTimer::singleShot(200, this, &DeviceControllerDiag::sys_superviseSystem);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// all doors: 99: undefined 0:closed 1:open
|
||||||
|
if (dynMaCond.lowerDoor || dynMaCond.upperDoor) {
|
||||||
|
// Service or battery door is open, goto INTRUSION MODE
|
||||||
|
qCritical() << "DeviceControllerDiag::sys_superviseSystem() Service or battery door is open, goto INTRUSION MODE";
|
||||||
|
this->private_finishedDiag(0xFD);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (dynMaCond.middleDoor) {
|
||||||
|
// vault door is open, goto INTRUSION MODE
|
||||||
|
qCritical() << "DeviceControllerDiag::sys_superviseSystem() vault door is open, goto INTRUSION MODE";
|
||||||
|
this->private_finishedDiag(0xFC);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qCritical() << " --> call sub_componentAssessment()";
|
||||||
|
|
||||||
|
uint8_t proposedError = sub_componentAssessment();
|
||||||
|
if (proposedError) {
|
||||||
|
// All doors are closed but errors found, goto OOO MODE (out-of-order)
|
||||||
|
qCritical() << "DeviceControllerDiag::sys_superviseSystem() All doors are closed but errors found, goto OOO MODE (out-of-order)";
|
||||||
|
this->private_finishedDiag(proposedError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// everything fine
|
||||||
|
qCritical() << "DeviceControllerDiag::sys_superviseSystem() everything fine";
|
||||||
|
this->private_finishedDiag(0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t DeviceControllerDiag::sub_componentAssessment()
|
||||||
|
{
|
||||||
|
// this function decides if vending mode is possible, independant from door
|
||||||
|
// return >0 in case of error
|
||||||
|
|
||||||
|
struct T_moduleCondition modCond;
|
||||||
|
hw->sys_getDeviceConditions(&modCond);
|
||||||
|
|
||||||
|
struct T_dynamicCondition dynMaCond;
|
||||||
|
hw->sys_getDynMachineConditions(&dynMaCond);
|
||||||
|
|
||||||
|
struct T_devices devPara;
|
||||||
|
hw->sys_restoreDeviceParameter(&devPara);
|
||||||
|
|
||||||
|
if (modCond.rtc>=200)
|
||||||
|
return 1;
|
||||||
|
if (modCond.printer==200 || modCond.printer==201) // 200: not connected 201: printer-HW-error 202: no paper
|
||||||
|
return 2;
|
||||||
|
if (modCond.printer==202)
|
||||||
|
return 3;
|
||||||
|
|
||||||
|
if (modCond.coinBlocker>=200)
|
||||||
|
return 4;
|
||||||
|
if (modCond.mdbBus>=200)
|
||||||
|
return 5;
|
||||||
|
if (modCond.intEe>=200)
|
||||||
|
return 6;
|
||||||
|
|
||||||
|
if (devPara.kindOfCoinChecker==1 || devPara.kindOfCoinChecker==2) // 0: without 1=EMP820 2=EMP900 3=currenza c² (MW)
|
||||||
|
{
|
||||||
|
if (modCond.coinChecker>=200 || modCond.coinEscrow>=200)
|
||||||
|
{
|
||||||
|
// Fehler Münzver.
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
if (modCond.coinSafe>200) // 200: kasse fehlt 201: voll 100:fast voll 1:ok
|
||||||
|
{
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (devPara.kindOfCoinChecker==3)
|
||||||
|
{
|
||||||
|
if (modCond.changer>=200)
|
||||||
|
{
|
||||||
|
// Fehler Münzver.
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
if (modCond.coinSafe>200) // 200: kasse fehlt 201: voll 100:fast voll 1:ok
|
||||||
|
{
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( modCond.billReader>=200 && devPara.BillAcceptor>0)
|
||||||
|
{
|
||||||
|
// Fehler BNA
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dynMaCond.onAlarm>0)
|
||||||
|
return 10;
|
||||||
|
|
||||||
|
if (dynMaCond.modeAbrech>0)
|
||||||
|
return 11;
|
||||||
|
|
||||||
|
if (dynMaCond.nowCardTest>0)
|
||||||
|
return 12;
|
||||||
|
|
||||||
|
if (dynMaCond.startupTestIsRunning>0)
|
||||||
|
return 13;
|
||||||
|
|
||||||
|
if (modCond.voltage>=200)
|
||||||
|
return 14;
|
||||||
|
if (modCond.temper>=200)
|
||||||
|
return 15;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t DeviceControllerDiag::sys_getSystemErrors()
|
||||||
|
{
|
||||||
|
// 0: everything fine 1..15: errors
|
||||||
|
/* 1: real time clock error
|
||||||
|
2: printer error
|
||||||
|
3: no paper
|
||||||
|
4: coin blocker
|
||||||
|
5: mdb error
|
||||||
|
6: mem error int.ee.
|
||||||
|
7: error coin validator
|
||||||
|
8: coin safe missed or full
|
||||||
|
9: bill acceptor error
|
||||||
|
10: alarm / intrusion
|
||||||
|
11: cash box change is ongoing
|
||||||
|
12: card test running
|
||||||
|
13: startup-test is running
|
||||||
|
14: voltage error
|
||||||
|
15: temperature error
|
||||||
|
*/
|
||||||
|
return this->sub_componentAssessment();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief DeviceControllerDiag::private_finishedDiag
|
||||||
|
* @param result - result value from 'sub_componentAssessment()',
|
||||||
|
* - 0xFF on timer interrupt
|
||||||
|
* - 0xFE no valid data from DeviceController
|
||||||
|
* - 0xFD Service or battery door is open
|
||||||
|
* - 0xFE vault door is open
|
||||||
|
*/
|
||||||
|
void DeviceControllerDiag::private_finishedDiag(uint8_t result)
|
||||||
|
{
|
||||||
|
this->diagRequestTimeoutTimer->stop();
|
||||||
|
this->isRequestRunning = false;
|
||||||
|
this->flagInterruptDiag = false;
|
||||||
|
|
||||||
|
if (result == 0) return;
|
||||||
|
|
||||||
|
qCritical() << "DeviceControllerDiag::private_finishedDiag() result: " << result;
|
||||||
|
|
||||||
|
|
||||||
|
if (this->eventReceiver == nullptr) {
|
||||||
|
qCritical() << "DeviceControllerDiag: no eventReceiver";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result > 15 && result != 0xFE) return;
|
||||||
|
|
||||||
|
|
||||||
|
// Errors are in this range 1...15:
|
||||||
|
QString eventId = QUuid::createUuid().toString(QUuid::WithoutBraces).mid(0, 8);
|
||||||
|
QString eventName;
|
||||||
|
EVENT_CLASS eventClass = EVENT_CLASS::STATE;
|
||||||
|
QString parameter;
|
||||||
|
switch (result) {
|
||||||
|
case 1: // real time clock error
|
||||||
|
eventName = "E001";
|
||||||
|
eventClass = EVENT_CLASS::ERROR;
|
||||||
|
parameter = "real time clock error";
|
||||||
|
break;
|
||||||
|
case 2: // printer error
|
||||||
|
eventName = "E002";
|
||||||
|
eventClass = EVENT_CLASS::ERROR;
|
||||||
|
parameter = "printer error";
|
||||||
|
break;
|
||||||
|
case 3: // no paper
|
||||||
|
eventName = "E003";
|
||||||
|
eventClass = EVENT_CLASS::ERROR;
|
||||||
|
parameter = "no paper";
|
||||||
|
break;
|
||||||
|
case 4: // coin blocker
|
||||||
|
eventName = "E004";
|
||||||
|
eventClass = EVENT_CLASS::ERROR;
|
||||||
|
parameter = "coin blocker";
|
||||||
|
break;
|
||||||
|
case 5: // mdb error
|
||||||
|
eventName = "E005";
|
||||||
|
eventClass = EVENT_CLASS::ERROR;
|
||||||
|
parameter = "mdb error";
|
||||||
|
break;
|
||||||
|
case 6: // mem error int.ee.
|
||||||
|
eventName = "E006";
|
||||||
|
eventClass = EVENT_CLASS::ERROR;
|
||||||
|
parameter = "mem error int.ee.";
|
||||||
|
break;
|
||||||
|
case 7: // error coin validator
|
||||||
|
eventName = "E007";
|
||||||
|
eventClass = EVENT_CLASS::ERROR;
|
||||||
|
parameter = "error coin validator";
|
||||||
|
break;
|
||||||
|
case 8: // coin safe missed or full
|
||||||
|
eventName = "E008";
|
||||||
|
eventClass = EVENT_CLASS::ERROR;
|
||||||
|
parameter = "coin safe missed or full";
|
||||||
|
break;
|
||||||
|
case 9: // bill acceptor error
|
||||||
|
eventName = "E009";
|
||||||
|
eventClass = EVENT_CLASS::ERROR;
|
||||||
|
parameter = "bill acceptor error";
|
||||||
|
break;
|
||||||
|
case 10: // alarm / intrusion
|
||||||
|
eventName = "E010";
|
||||||
|
eventClass = EVENT_CLASS::ERROR;
|
||||||
|
parameter = "alarm / intrusion";
|
||||||
|
break;
|
||||||
|
case 11: // cash box change is ongoing
|
||||||
|
eventName = "E011";
|
||||||
|
eventClass = EVENT_CLASS::STATE;
|
||||||
|
parameter = "cash box change is ongoing";
|
||||||
|
break;
|
||||||
|
case 12: // card test running
|
||||||
|
eventName = "E012";
|
||||||
|
eventClass = EVENT_CLASS::STATE;
|
||||||
|
parameter = "card test running";
|
||||||
|
break;
|
||||||
|
case 13: // startup-test is running
|
||||||
|
eventName = "E013";
|
||||||
|
eventClass = EVENT_CLASS::STATE;
|
||||||
|
parameter = "startup-test is running";
|
||||||
|
break;
|
||||||
|
case 14: // voltage error
|
||||||
|
eventName = "E014";
|
||||||
|
eventClass = EVENT_CLASS::ERROR;
|
||||||
|
parameter = "voltage error";
|
||||||
|
break;
|
||||||
|
case 15: // temperature error
|
||||||
|
eventName = "E015";
|
||||||
|
eventClass = EVENT_CLASS::STATE;
|
||||||
|
parameter = "temperature error";
|
||||||
|
break;
|
||||||
|
case 0xFE: // no valid data from DeviceController
|
||||||
|
eventName = "E254";
|
||||||
|
eventClass = EVENT_CLASS::STATE;
|
||||||
|
parameter = "no valid data from DeviceController";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ATBMachineEvent *machineEvent = new ATBMachineEvent(
|
||||||
|
eventId,
|
||||||
|
"DC",
|
||||||
|
eventClass,
|
||||||
|
eventName,
|
||||||
|
1,
|
||||||
|
parameter,
|
||||||
|
"" // second level info
|
||||||
|
);
|
||||||
|
|
||||||
|
//emit diagResponse(machineEvent);
|
||||||
|
|
||||||
|
QCoreApplication::postEvent(eventReceiver, machineEvent);
|
||||||
|
|
||||||
|
}
|
49
src/ATBAPP/DeviceControllerDiag.h
Normal file
49
src/ATBAPP/DeviceControllerDiag.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#ifndef DEVICECONTROLLERDIAG_H
|
||||||
|
#define DEVICECONTROLLERDIAG_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include "ATBMachineEvent.h"
|
||||||
|
#include "interfaces.h"
|
||||||
|
|
||||||
|
class DeviceControllerDiag : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
DeviceControllerDiag(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
void init(hwinf* hw, QObject* eventReceiver);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void diagRequest();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void diagResponse(ATBMachineEvent* machineEvent);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
QObject *eventReceiver;
|
||||||
|
hwinf* hw;
|
||||||
|
|
||||||
|
bool isRequestRunning;
|
||||||
|
bool flagInterruptDiag;
|
||||||
|
|
||||||
|
QTimer *diagRequestTimeoutTimer;
|
||||||
|
|
||||||
|
uint8_t sub_componentAssessment();
|
||||||
|
uint8_t sys_getSystemErrors();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onDiagRequestTimeoutTimerTimeout();
|
||||||
|
|
||||||
|
void private_startDiag(); // diag entry method
|
||||||
|
void private_finishedDiag(uint8_t result); // diag exit method
|
||||||
|
|
||||||
|
void sys_superviseSystem();
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DEVICECONTROLLERDIAG_H
|
@@ -12,17 +12,26 @@ namespace nsDeviceControllerInterface {
|
|||||||
enum class PLUGIN_STATE : quint8;
|
enum class PLUGIN_STATE : quint8;
|
||||||
enum class RESULT_STATE : quint8;
|
enum class RESULT_STATE : quint8;
|
||||||
enum class CASH_STATE : quint8;
|
enum class CASH_STATE : quint8;
|
||||||
|
enum class TICKET_VARIANT : quint8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class DeviceControllerInterface : public ATBAPPplugin
|
class DeviceControllerInterface : public QObject
|
||||||
|
, public ATBAPPplugin
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
Q_INTERFACES(ATBAPPplugin)
|
Q_INTERFACES(ATBAPPplugin)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~DeviceControllerInterface() {}
|
virtual ~DeviceControllerInterface() {}
|
||||||
|
|
||||||
virtual nsDeviceControllerInterface::PLUGIN_STATE initDCPlugin(QObject *healthEventReceiver,
|
/**
|
||||||
|
* @brief initDCPlugin
|
||||||
|
* @param eventReceiver - QObject to receive ATBMachineEvents or HealthEvents
|
||||||
|
* @param settings
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual nsDeviceControllerInterface::PLUGIN_STATE initDCPlugin(QObject *eventReceiver,
|
||||||
const QSettings & settings) = 0;
|
const QSettings & settings) = 0;
|
||||||
|
|
||||||
// TASKS: Cash handling -------------------------------------------------------
|
// TASKS: Cash handling -------------------------------------------------------
|
||||||
@@ -51,6 +60,8 @@ public:
|
|||||||
|
|
||||||
// TASKS: printing ------------------------------------------------------------
|
// TASKS: printing ------------------------------------------------------------
|
||||||
virtual void requestPrintTicket(const QHash<QString, QVariant> & printingData) = 0;
|
virtual void requestPrintTicket(const QHash<QString, QVariant> & printingData) = 0;
|
||||||
|
virtual void requestPrintTicket(nsDeviceControllerInterface::TICKET_VARIANT ticketVariant, const QHash<QString, QVariant> & printingData) = 0;
|
||||||
|
virtual void requestPrintReceipt(const QHash<QString, QVariant> & printingData) = 0;
|
||||||
|
|
||||||
|
|
||||||
// mandantory ATBAPP plugin methods:
|
// mandantory ATBAPP plugin methods:
|
||||||
@@ -64,21 +75,30 @@ public:
|
|||||||
// helpers e.g. for debug / log
|
// helpers e.g. for debug / log
|
||||||
virtual const QString getString(nsDeviceControllerInterface::RESULT_STATE resultState) = 0;
|
virtual const QString getString(nsDeviceControllerInterface::RESULT_STATE resultState) = 0;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void onChangedProgramModeToSELL() = 0;
|
||||||
|
virtual void onChangedProgramModeToSERVICE() = 0;
|
||||||
|
virtual void onChangedProgramModeToIDLE() = 0;
|
||||||
|
virtual void onChangedProgramModeToOOO() = 0;
|
||||||
|
|
||||||
|
virtual void startPhysicalLayer() = 0;
|
||||||
|
virtual void stopPhysicalLayer() = 0;
|
||||||
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
virtual void printTicketFinished(nsDeviceControllerInterface::RESULT_STATE resultState,
|
void printTicketFinished(nsDeviceControllerInterface::RESULT_STATE resultState,
|
||||||
const QString & errorCode,
|
const QString & errorCode,
|
||||||
const QString & errorDescription) = 0;
|
const QString & errorDescription);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* emitted on e.g. a coin input
|
* emitted on e.g. a coin input
|
||||||
*/
|
*/
|
||||||
virtual void cashInputEvent(nsDeviceControllerInterface::RESULT_STATE resultState,
|
void cashInputEvent(nsDeviceControllerInterface::RESULT_STATE resultState,
|
||||||
nsDeviceControllerInterface::CASH_STATE cashState,
|
nsDeviceControllerInterface::CASH_STATE cashState,
|
||||||
const QString & newCashValue,
|
const QString & newCashValue,
|
||||||
/* additional variables? */
|
/* additional variables? */
|
||||||
const QString & errorCode,
|
const QString & errorCode,
|
||||||
const QString & errorDescription) = 0;
|
const QString & errorDescription);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* emitted if cashInput has been stopped, e.g. in result to task requestStopCashInput():
|
* emitted if cashInput has been stopped, e.g. in result to task requestStopCashInput():
|
||||||
@@ -86,22 +106,32 @@ signals:
|
|||||||
* -> no cash input is possible
|
* -> no cash input is possible
|
||||||
* -> coins are in cache
|
* -> coins are in cache
|
||||||
*/
|
*/
|
||||||
virtual void cashInputFinished(nsDeviceControllerInterface::RESULT_STATE resultState,
|
void cashInputFinished(nsDeviceControllerInterface::RESULT_STATE resultState,
|
||||||
const QString & newCashValue,
|
const QString & newCashValue,
|
||||||
/* additional variables? */
|
/* additional variables? */
|
||||||
const QString & errorCode,
|
const QString & errorCode,
|
||||||
const QString & errorDescription) = 0;
|
const QString & errorDescription);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* emitted e.g. if service door is opened
|
* emitted e.g. if service door is opened
|
||||||
*/
|
*/
|
||||||
virtual void requestServiceMode() = 0;
|
void requestModeSERVICE();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* emitted e.g. if doors are closed
|
||||||
|
*/
|
||||||
|
void requestModeIDLE();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* emitted e.g. on severe errors
|
||||||
|
*/
|
||||||
|
void requestModeOOO();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* emitted e.g. if service door is opened
|
* emitted e.g. if service door is opened
|
||||||
*/
|
*/
|
||||||
virtual void requestAccountResponse(const QHash<QString, QVariant> & accountData) = 0;
|
void requestAccountResponse(const QHash<QString, QVariant> & accountData);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* emitted on error
|
* emitted on error
|
||||||
@@ -111,10 +141,10 @@ signals:
|
|||||||
* -> send error event to ISMAS
|
* -> send error event to ISMAS
|
||||||
* -> ...
|
* -> ...
|
||||||
*/
|
*/
|
||||||
virtual void Error(
|
void Error(
|
||||||
/* additional variables? */
|
/* additional variables? */
|
||||||
const QString & errorCode,
|
const QString & errorCode,
|
||||||
const QString & errorDescription) = 0;
|
const QString & errorDescription);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -145,6 +175,16 @@ namespace nsDeviceControllerInterface {
|
|||||||
OVERPAYED,
|
OVERPAYED,
|
||||||
/* t.b.d. */
|
/* t.b.d. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum class TICKET_VARIANT : quint8 {
|
||||||
|
PARKING_TICKET,
|
||||||
|
RECEIPT,
|
||||||
|
ERROR_RECEIPT,
|
||||||
|
START_RECEIPT, // e.g. Szeged Start
|
||||||
|
STOP_RECEIPT, // e.g. Szeged Stop
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // DEVICECONTROLLERINTERFACE_H
|
#endif // DEVICECONTROLLERINTERFACE_H
|
||||||
|
18
src/ATBAPP/Utils.cpp
Normal file
18
src/ATBAPP/Utils.cpp
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
Utils::Utils(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int Utils::compare(const void* a, const void* b)
|
||||||
|
{
|
||||||
|
int int_a = * ( (int*) a );
|
||||||
|
int int_b = * ( (int*) b );
|
||||||
|
|
||||||
|
if ( int_a == int_b ) return 0;
|
||||||
|
else if ( int_a < int_b ) return -1;
|
||||||
|
else return 1;
|
||||||
|
}
|
23
src/ATBAPP/Utils.h
Normal file
23
src/ATBAPP/Utils.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef UTILS_H
|
||||||
|
#define UTILS_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
|
||||||
|
class Utils : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
static int compare(const void* a, const void* b);
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit Utils(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // UTILS_H
|
Reference in New Issue
Block a user