Compare commits

..

60 Commits

Author SHA1 Message Date
ea7542a248 DiagRequest: start also on wakeupSimulation (mains powered machines) 2024-04-11 12:40:02 +02:00
4541699ec3 Load/init libCA in plugin init method (not in contructor) 2024-03-20 11:43:31 +01:00
87d50a05dd Check error-state if doors are closed 2024-03-19 13:43:45 +01:00
379a5d4e3e Diag: track ErrorState 2024-03-19 13:43:01 +01:00
6a08cf0b62 Implement new interface method sendDeviceParameter() 2024-03-18 17:02:49 +01:00
849305bc8f Update DeviceControllerInterface 1.1.4 2024-03-18 17:01:50 +01:00
a5c900b9fe Fix: send operate 2024-03-15 13:40:16 +01:00
70b488de66 Diag: send operate (O000) only if State has changed 2024-03-12 16:20:39 +01:00
58f50b0ea6 Fix: implement unresolved symbol 2024-03-11 15:30:13 +01:00
bc5beb4b96 Fix: init variable 2024-03-11 15:29:47 +01:00
2a0aa2abe2 Merge branch 'PrintProducts' into pu/integration 2024-03-11 14:21:22 +01:00
f94f33862f Printing: dynamically set template dyn-data using Ticket-class
See DC_printer_interface.graphml/pdf
2024-03-11 14:06:05 +01:00
b7cedf5444 Add class Ticket 2024-03-11 14:02:52 +01:00
f81369944c FOOD_STAMP: build template list ...
Ths last template printed is different (this includes e.g. a full cut
whereas the other templates have only a semi-cut.
2024-03-08 13:09:19 +01:00
6072970bf0 Rework Printing: add private methods depending on TICKET_VARIANT 2024-03-08 13:06:53 +01:00
8659627171 Add object variable currentTicketType 2024-03-08 13:04:28 +01:00
d5786aa5ab Add COIN_PROCESSER::NONE (machine without coin processing) 2024-03-08 12:44:41 +01:00
ba7d801330 Update DeviceController Interface 1.1.3 (TICKET_VARIANT::FOOD_STAMP) 2024-03-08 10:50:07 +01:00
19ce57e680 PersistentData: save only if data has changed 2024-02-29 08:56:59 +01:00
d0ee6d175e Print tickets for products DAY_TICKET_ADULT, DAY_TICKET_TEEN 2024-02-28 16:42:35 +01:00
3eaf98fb09 Change product-names 2024-02-21 16:34:23 +01:00
bab7423965 Propagate Signal coinAttached 2024-02-21 16:33:39 +01:00
a76e3cd10e Update interfaces.h 2024-02-21 16:31:26 +01:00
eb1eab690b Update DeviceControllerInterface 1.1.2 (coinAttached-Signal) 2024-02-21 16:29:21 +01:00
7ae4ddd851 Use global interfaces.h 2024-01-31 13:42:51 +01:00
0cc89cefab Read dc-firmware-version: filter return value (null-character) 2024-01-31 12:22:18 +01:00
14755cd5b4 Start physical layer, if only master lib is available (e.g. in Szeged) 2024-01-31 11:38:32 +01:00
d2efe566c5 Add persistentData to store dc-fw-version
Reading dc-fw-version is somehow complicated ...
Id does not work reliable on startup, so we do read it also on every
diagRequest().
Version string is then stored in persistent data.
This data can be used e.g. by other tools to show the
device-controller-firmware-version.
2024-01-31 11:34:00 +01:00
b058b6aee0 Changer: skip polling, if amount due to change is 0 2024-01-25 14:26:19 +01:00
bdb0f9911b Print: set font on bank-receipt 2024-01-08 17:29:44 +01:00
c679b489ba Merge branch 'pu/AccountMessage' into pu/integration 2023-12-22 10:08:38 +01:00
1c643c6caf Update DeviceControllerInterface to 1.1.1 2023-12-22 09:26:13 +01:00
246e23bffd Fix: typo 2023-12-18 08:21:08 +01:00
07bb1bde50 Send interface signal on VaultDoor opened 2023-12-15 11:54:36 +01:00
81a70bf387 Upate DeviceControllerInterface to 1.1.0 2023-12-15 11:29:08 +01:00
012f3430c5 Rework for getAmountOfInsertedNotes due to wrong description in interface 2023-12-14 15:48:37 +01:00
80c7992d5b Start autoRequest allways ...
... we need this!
2023-12-13 09:23:03 +01:00
c603313d73 PrintTicket: skip check of serial port 2023-12-11 18:32:37 +01:00
b3ad8e1ee9 Interrupt DiagRequest on error 2023-12-11 18:32:27 +01:00
bee611651c Update interfaces.h 2023-12-08 12:42:58 +01:00
25cb23a587 Send cashPaymentFinished() onCashChangerState() ...
This is for checking changer result and includes lot of debug code!
2023-12-08 12:41:57 +01:00
05113057b0 CashUtils: is not a class, it is a namespace 2023-12-08 12:33:46 +01:00
7affcb0313 Update DeviceControllerInterface 1.0.3
Signal cashPaymentFinished()
2023-12-04 10:31:52 +01:00
60c4d5896a Set 'printerLocale' from settings 2023-12-01 15:07:29 +01:00
d2a0491bba cashInputFinished: return coins/notes/change 2023-11-30 18:18:43 +01:00
96db7be126 Add object variable cashStartAmountInt
Used to track proposed change amount.
2023-11-30 18:17:44 +01:00
247abb7520 Add class CashUtils: utility methods for CashProcessing 2023-11-30 18:15:07 +01:00
e95de7f9e4 Print: dates in QLocale::ShortFormat
Note: this needs test!
Expected behaviour is that date format switches with language switch!
This my be no problem in most cases however, e.g. in some cases there
would be a different date format on the tickets.
2023-11-30 16:33:47 +01:00
8c1aa26145 Update DeviceControllerInterface 1.0.2
Send cashInputFinished with coins/notes/change
2023-11-30 12:04:11 +01:00
30de664991 MDBwake: switch on/off during ModeSELL/ModeSERVICE 2023-11-30 09:27:57 +01:00
f938a75742 Account: read bill stacker values 2023-11-29 16:10:38 +01:00
49a13fd333 Account: insert NOTEs 2023-11-29 12:31:52 +01:00
07d812f5d9 Account: count coins from 1..X 2023-11-29 12:31:05 +01:00
350c2351b1 TicketPrint: 'amount' on dynDat6 ...
Additionally to vedingPrice (Szeged).
TODO: make configurable?
2023-11-27 11:10:21 +01:00
3dac861ca0 printerEncoding: check if configured codec is available 2023-11-24 09:32:00 +01:00
539e392c0d Fix: read settings: config-group name 2023-11-24 09:30:05 +01:00
ed5001c3a3 Handle signal hwapi_payStopByPushbutton 2023-11-23 17:59:49 +01:00
48d65b679f Add interface for coinProcessor() and billAcceptor() 2023-11-23 17:58:36 +01:00
2221463fe5 Update interfaces.h 2023-11-21 11:25:13 +01:00
3b32d04bac Use libCAslave 2023-11-21 11:21:28 +01:00
16 changed files with 2943 additions and 888 deletions

View File

@@ -9,7 +9,7 @@ QT += serialport
INCLUDEPATH += $${PWD}/plugins INCLUDEPATH += $${PWD}/plugins
INCLUDEPATH += $${PWD}/include INCLUDEPATH += $${PWD}/include
QMAKE_CXXFLAGS += -Wno-deprecated-copy -O QMAKE_CXXFLAGS += -Wno-deprecated-copy
# default # default
ARCH = PTU5 ARCH = PTU5
@@ -30,7 +30,14 @@ contains( CONFIG, PTU5 ) {
QMAKE_CXXFLAGS += -std=c++11 QMAKE_CXXFLAGS += -std=c++11
linux-clang { QMAKE_CXXFLAGS += -Qunused-arguments } linux-clang { QMAKE_CXXFLAGS += -Qunused-arguments }
CONFIG += link_pkgconfig CONFIG += link_pkgconfig
PTU5BASEPATH = /opt/devel/ptu5
ARCH = PTU5 ARCH = PTU5
INCLUDEPATH += $$PTU5BASEPATH/qt/libs/deviceController/include/
LIBS += -L$$PTU5BASEPATH/qt/libs/deviceController/library
LIBS += -lCAslave
LIBS += -lCAmaster
} }
contains( CONFIG, PTU5_YOCTO ) { contains( CONFIG, PTU5_YOCTO ) {
@@ -38,8 +45,8 @@ contains( CONFIG, PTU5_YOCTO ) {
PTU5BASEPATH = /opt/devel/ptu5 PTU5BASEPATH = /opt/devel/ptu5
ARCH = PTU5 ARCH = PTU5
# add qmqtt lib LIBS += -lCAslave
#LIBS += -lQt5Qmqtt LIBS += -lCAmaster
} }
TARGET = ATBDeviceControllerPlugin TARGET = ATBDeviceControllerPlugin
@@ -49,8 +56,6 @@ INTERFACE_DEFINITION = $${PWD}/src/ATBAPP/DeviceControllerInterface.h
DEFINES += DEVICECONTROLLERPLUGIN_LIBRARY DEFINES += DEVICECONTROLLERPLUGIN_LIBRARY
DEFINES += USE_DC_VMC_UNIFICATION
# The following define makes your compiler emit warnings if you use # The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings # any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the # depend on your compiler). Please consult the documentation of the
@@ -71,7 +76,6 @@ DEFINES += QT_DEPRECATED_WARNINGS
# ATBAPP interface # ATBAPP interface
HEADERS += \ HEADERS += \
include/interfaces.h \
src/ATBAPP/ATBAPPplugin.h \ src/ATBAPP/ATBAPPplugin.h \
src/ATBAPP/DeviceControllerDiag.h \ src/ATBAPP/DeviceControllerDiag.h \
src/ATBAPP/DeviceControllerInterface.h \ src/ATBAPP/DeviceControllerInterface.h \
@@ -79,10 +83,12 @@ HEADERS += \
src/ATBAPP/ATBMachineEvent.h \ src/ATBAPP/ATBMachineEvent.h \
src/ATBAPP/ATBDeviceControllerPlugin.h \ src/ATBAPP/ATBDeviceControllerPlugin.h \
src/ATBAPP/Utils.h \ src/ATBAPP/Utils.h \
src/ATBAPP/UnifiedDCVMCInterface.h \ src/ATBAPP/support/CashUtils.h \
src/ATBAPP/support/DBusControllerInterface.h \ src/ATBAPP/support/DBusControllerInterface.h \
src/ATBAPP/support/JSON.h \ src/ATBAPP/support/JSON.h \
src/ATBAPP/support/PTUSystem.h src/ATBAPP/support/PTUSystem.h \
src/ATBAPP/support/PersistentData.h \
src/ATBAPP/support/Ticket.h
SOURCES += \ SOURCES += \
src/ATBAPP/ATBHealthEvent.cpp \ src/ATBAPP/ATBHealthEvent.cpp \
@@ -90,9 +96,12 @@ SOURCES += \
src/ATBAPP/ATBDeviceControllerPlugin.cpp \ src/ATBAPP/ATBDeviceControllerPlugin.cpp \
src/ATBAPP/DeviceControllerDiag.cpp \ src/ATBAPP/DeviceControllerDiag.cpp \
src/ATBAPP/Utils.cpp \ src/ATBAPP/Utils.cpp \
src/ATBAPP/support/CashUtils.cpp \
src/ATBAPP/support/DBusControllerInterface.cpp \ src/ATBAPP/support/DBusControllerInterface.cpp \
src/ATBAPP/support/JSON.cpp \ src/ATBAPP/support/JSON.cpp \
src/ATBAPP/support/PTUSystem.cpp src/ATBAPP/support/PTUSystem.cpp \
src/ATBAPP/support/PersistentData.cpp \
src/ATBAPP/support/Ticket.cpp
DISTFILES += \ DISTFILES += \
generate-version.sh generate-version.sh

File diff suppressed because it is too large Load Diff

View File

@@ -5,63 +5,18 @@
* a simple class with only one method for plugin info * a simple class with only one method for plugin info
*/ */
#include <QObject> #include <QObject>
#include <QStringList> #include <QString>
struct ATBAPPplugin { class ATBAPPplugin
enum class PLUGIN_STATE : quint8 { {
NOT_INITIALIZED = 0,
INITIALIZED = 1
};
enum class RESULT_STATE : quint8 {
SUCCESS = 1, // operation was successfull
ERROR_BACKEND, // error from backend (e.g. backend replies with error)
ERROR_NETWORK,
ERROR_TIMEOUT, // the operation timed out
ERROR_PROCESS, // internal plugin error, should not occur (this is a bug in implementation)
ERROR_BUSY,
ERROR_STATE,
ERROR_RETRY, // retry operation
INFO // informational (e.g. display a message, log something etc.)
};
enum class CASH_STATE : quint8 {
CACHE_EMPTY, // Cache still empty, default state
CACHE_INPUT, // Coins are in Cache
OVERPAYED,
/* 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
};
enum class STEP : quint8 {
UP = 1,
DOWN = 2
};
enum class TERMINAL_STATE : quint8 {
NOT_AVAILABLE = 1,
AVAILABLE,
PREPARED_FOR_VENDING,
BUSY,
NEEDS_MAINTENANCE
};
public:
virtual const QString & getPluginInfo() = 0; virtual const QString & getPluginInfo() = 0;
virtual QStringList getPluginInfoList() {
return QStringList(QString());
}
}; };
using PLUGIN_STATE = ATBAPPplugin::PLUGIN_STATE;
using RESULT_STATE = ATBAPPplugin::RESULT_STATE;
using CASH_STATE = ATBAPPplugin::CASH_STATE;
using TICKET_VARIANT = ATBAPPplugin::TICKET_VARIANT;
using STEP = ATBAPPplugin::STEP;
using TERMINAL_STATE = ATBAPPplugin::TERMINAL_STATE;
Q_DECLARE_INTERFACE(ATBAPPplugin, Q_DECLARE_INTERFACE(ATBAPPplugin,
"eu.atb.ptu.plugin.ATBAPPplugin/0.9") "eu.atb.ptu.plugin.ATBAPPplugin/0.9")
#endif // ATBAPPPLUGIN_H #endif // ATBAPPPLUGIN_H

File diff suppressed because it is too large Load Diff

View File

@@ -2,27 +2,32 @@
#define ATBDEVICECONTROLLERPLUGIN_H #define ATBDEVICECONTROLLERPLUGIN_H
#include <QObject> #include <QObject>
#include <QLocale>
#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 "src/ATBAPP/DeviceControllerDiag.h"
#include "src/ATBAPP/support/Ticket.h"
#include "version.h" #include "version.h"
#include "support/PersistentData.h"
#include <DeviceController/interfaces.h>
#include "interfaces.h" #include <unistd.h>
class DBusControllerInterface; class DBusControllerInterface;
class QTextCodec; class QTextCodec;
using namespace nsDeviceControllerInterface;
// using namespace nsDeviceControllerInterface;
class QSettings; class QSettings;
class ATBDeviceControllerPlugin : public DeviceControllerInterface
class ATBDeviceControllerPlugin :
public DeviceControllerInterface
{ {
Q_OBJECT Q_OBJECT
Q_INTERFACES(ATBAPPplugin) Q_INTERFACES(ATBAPPplugin)
@@ -33,14 +38,13 @@ class ATBDeviceControllerPlugin : public DeviceControllerInterface
public: public:
explicit ATBDeviceControllerPlugin(QObject *parent = nullptr); explicit ATBDeviceControllerPlugin(QObject *parent = nullptr);
virtual ~ATBDeviceControllerPlugin(); ~ATBDeviceControllerPlugin();
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// interface: // interface:
virtual PLUGIN_STATE initPlugin(QObject *eventReceiver, QObject *atbSystem, QObject *hmiConfig, QSettings const &settings) override; PLUGIN_STATE initDCPlugin(QObject *eventReceiver, const QSettings & settings);
virtual PLUGIN_STATE initPlugin(QObject *eventReceiver, QSettings const &settings) override;
virtual PLUGIN_STATE initVMCPlugin(QObject *eventReceiver, QObject *atbSystem, QObject *hmiConfig, const QSettings & settings) override; void sendDeviceParameter(const QJsonObject & jsonObject);
virtual PLUGIN_STATE initDCPlugin(QObject *eventReceiver, const QSettings & settings) override;
// TASKS: Cash handling ------------------------------------------------------- // TASKS: Cash handling -------------------------------------------------------
void requestStartCashInput(const QString & amount); void requestStartCashInput(const QString & amount);
@@ -48,6 +52,10 @@ public:
void cashCollect(); void cashCollect();
void cashAbort(); void cashAbort();
// read coin/cash processing variants -----------------------------------------
nsDeviceControllerInterface::COIN_PROCESSOR coinProcessor();
nsDeviceControllerInterface::BILL_ACCEPTOR billAcceptor();
// 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 requestPrintTicket(nsDeviceControllerInterface::TICKET_VARIANT ticketVariant, const QHash<QString, QVariant> & printingData);
@@ -58,106 +66,43 @@ public:
void requestAccount(); void requestAccount();
// mandantory ATBAPP plugin methods: ------------------------------------------ // mandantory ATBAPP plugin methods: ------------------------------------------
nsDeviceControllerInterface::PLUGIN_STATE getState() override; nsDeviceControllerInterface::PLUGIN_STATE getState();
QString const &getLastError() override; QString & getLastError();
QString const &getLastErrorDescription() override; const QString & getLastErrorDescription();
virtual QStringList getPluginInfoList() override; const QString & getPluginInfo();
virtual const QString &getPluginInfo() override;
// helpers e.g. for debug / log // helpers e.g. for debug / log
virtual QString const &getString(RESULT_STATE resultState) override; const QString getString(nsDeviceControllerInterface::RESULT_STATE resultState);;
public slots: public slots:
virtual void onChangedProgramModeToSELL() override; void onChangedProgramModeToSELL();
virtual void onChangedProgramModeToSERVICE() override; void onChangedProgramModeToSERVICE();
virtual void onChangedProgramModeToIDLE() override; void onChangedProgramModeToIDLE();
virtual void onChangedProgramModeToOOO() override; void onChangedProgramModeToOOO();
virtual void startPhysicalLayer() override; void startPhysicalLayer();
virtual void stopPhysicalLayer() override; void stopPhysicalLayer();
virtual void reboot() override; void reboot();
virtual void reset() override; void reset();
signals: signals:
void printTicketFinished(RESULT_STATE resultState, // public Signals are defined in interface
const QString & errorCode,
const QString & errorDescription);
void printReceiptFinished(RESULT_STATE resultState,
const QString & errorCode,
const QString & errorDescription);
/**
* emitted on e.g. a coin input
*/
void cashInputEvent(RESULT_STATE resultState,
CASH_STATE cashState,
const QString & newCashValue,
/* additional variables? */
const QString & errorCode,
const QString & errorDescription);
/**
* emitted if cashInput has been stopped, e.g. in result to task requestStopCashInput():
* -> shutter is blocked
* -> no cash input is possible
* -> coins are in cache
*/
void cashInputFinished(RESULT_STATE resultState,
const QString & newCashValue,
/* additional variables? */
const QString & errorCode,
const QString & errorDescription);
/**
* emitted e.g. if service door is opened
*/
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
*/
void requestAccountResponse(const QHash<QString, QVariant> & accountData);
/**
* emitted on error
* depending on errorCode:
* -> interrupt selling process
* -> machine can go to state OOO
* -> send error event to ISMAS
* -> ...
*/
void Error(
/* additional variables? */
const QString & errorCode,
const QString & errorDescription);
private: private:
QString errorCode; QString errorCode;
QString errorDescription; QString errorDescription;
QString pluginInfo; QString pluginInfo;
QStringList pluginInfoList;
QList<int> templateList;
QString serialPortName; QString serialPortName;
bool useDebug; bool useDebug;
bool isMaster;
PLUGIN_STATE pluginState; PLUGIN_STATE pluginState;
QObject* eventReceiver; QObject* eventReceiver;
@@ -168,6 +113,10 @@ private:
DeviceControllerDiag* diag; DeviceControllerDiag* diag;
PersistentData *persistentData;
uint32_t cashStartAmountInt;
QTextCodec *codec; QTextCodec *codec;
@@ -183,6 +132,17 @@ private:
// dbus // dbus
int init_sc_dbus(); int init_sc_dbus();
// printer privates ----------------------------------------------------------------------------
Ticket * currentTicket;
QLocale printerLocale;
void prepareDynTemplateData();
void private_setupDynTemplateData_START_RECEIPT(struct T_dynDat *dynTicketData, Ticket *ticket);
void private_setupDynTemplatData_STOP_RECEIPT(struct T_dynDat *dynTicketData, Ticket *ticket);
void private_setupDynTemplatData_FOOD_STAMP(struct T_dynDat *dynTicketData, Ticket *ticket);
// ---------------------------------------------------------------------------------------------
private slots: private slots:
// printer // printer
@@ -192,6 +152,8 @@ private slots:
void onPrinterWaitForPrintingTicket(); void onPrinterWaitForPrintingTicket();
void onPrinterWaitForPrintingReceipt(); void onPrinterWaitForPrintingReceipt();
void onPrinterPrepareDynTemplateData();
void onPrintFinishedOK(); void onPrintFinishedOK();
void onPrintFinishedERR(); void onPrintFinishedERR();
@@ -199,9 +161,11 @@ private slots:
void onCashGotCoin(); void onCashGotCoin();
void onCashPayStopedSuccess(); void onCashPayStopedSuccess();
void onCashPayStopByMax(); void onCashPayStopByMax();
void onCashPayStopByPushbutton();
void onCashPayStopByEscrow(); void onCashPayStopByEscrow();
void onCashPayStopByError(); void onCashPayStopByError();
void onCashPayStopByTimeout(); void onCashPayStopByTimeout();
void onCashChangerState();
// doors and hardware contacts // doors and hardware contacts
void onServiceDoorOpened(); void onServiceDoorOpened();

View File

@@ -5,11 +5,16 @@
#include <QUuid> #include <QUuid>
#include <QDebug> #include <QDebug>
DeviceControllerDiag::DeviceControllerDiag(QObject *parent) DeviceControllerDiag::DeviceControllerDiag(PersistentData *pData, QObject *parent)
: QObject(parent) : QObject(parent)
, coinProcessorType(nsDeviceControllerInterface::COIN_PROCESSOR::ESCROW)
, billAcceptor(nsDeviceControllerInterface::BILL_ACCEPTOR::NO)
, eventReceiver(nullptr) , eventReceiver(nullptr)
, isRequestRunning(false) , isRequestRunning(false)
, flagInterruptDiag(false) , flagInterruptDiag(false)
, lastState(DeviceController::State::INITIAL_STATE)
, _isErrorState(false)
, pData(pData)
{ {
diagRequestTimeoutTimer = new QTimer(this); diagRequestTimeoutTimer = new QTimer(this);
diagRequestTimeoutTimer->setInterval(1000*20); // 20s diagRequestTimeoutTimer->setInterval(1000*20); // 20s
@@ -40,6 +45,16 @@ void DeviceControllerDiag::diagRequest()
this->diagRequestTimeoutTimer->start(); this->diagRequestTimeoutTimer->start();
this->private_startDiag(); this->private_startDiag();
// read dc-fw-version:
/* note: dc_getSWVersion() returns always 32 characters (QString)...
* if no version string could be read it will contain 32 null-characters:
* "\u0000\u0000..."
*/
QString dc_fw_version = hw->dc_getSWversion().remove(QChar('\0'));
qCritical() << "ATBDeviceControllerPlugin: DC firmware version: " << dc_fw_version;
this->pData->setDCFirmwareVersion(dc_fw_version);
this->pData->serializeToFile();
} }
@@ -49,12 +64,32 @@ void DeviceControllerDiag::onDiagRequestTimeoutTimerTimeout()
this->flagInterruptDiag = true; this->flagInterruptDiag = true;
} }
bool DeviceControllerDiag::isErrorState()
{
return this->_isErrorState;
}
bool DeviceControllerDiag::isOperatingState()
{
return !this->_isErrorState;
}
QSet<DeviceController::State> DeviceControllerDiag::getCurrentMachineState()
{
return this->machineEventSet;
}
void DeviceControllerDiag::private_startDiag() void DeviceControllerDiag::private_startDiag()
{ {
// check for DiagRequestTimeoutTimerTimeout: // check for DiagRequestTimeoutTimerTimeout:
if (this->flagInterruptDiag) { if (this->flagInterruptDiag) {
qCritical() << "DeviceControllerDiag::private_startDiag() interrupted!"; qCritical() << "DeviceControllerDiag::private_startDiag() interrupted!";
this->private_sendDiagEvent(DeviceController::State::E255); this->private_sendDiagEvent(DeviceController::State::E255);
this->isRequestRunning = false;
this->flagInterruptDiag = false;
return; return;
} }
@@ -87,6 +122,8 @@ void DeviceControllerDiag::sys_superviseSystem()
if (this->flagInterruptDiag) { if (this->flagInterruptDiag) {
qCritical() << "DeviceControllerDiag::sys_superviseSystem() interrupted!"; qCritical() << "DeviceControllerDiag::sys_superviseSystem() interrupted!";
this->private_sendDiagEvent(DeviceController::State::E255); this->private_sendDiagEvent(DeviceController::State::E255);
this->flagInterruptDiag = false;
this->isRequestRunning = false;
return; return;
} }
@@ -95,6 +132,8 @@ void DeviceControllerDiag::sys_superviseSystem()
// es gibt keinerlei gültige Daten vom DC // es gibt keinerlei gültige Daten vom DC
qCritical() << "DeviceControllerDiag::sys_superviseSystem() no valid data!"; qCritical() << "DeviceControllerDiag::sys_superviseSystem() no valid data!";
this->private_sendDiagEvent(DeviceController::State::E254); this->private_sendDiagEvent(DeviceController::State::E254);
this->diagRequestTimeoutTimer->stop();
this->isRequestRunning = false;
return; return;
} }
@@ -210,6 +249,19 @@ void DeviceControllerDiag::sub_componentAssessment()
} }
// ----------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------
switch (devPara.kindOfCoinChecker) {
case 0:
this->coinProcessorType = nsDeviceControllerInterface::COIN_PROCESSOR::NONE;
break;
case 1:
case 2:
this->coinProcessorType = nsDeviceControllerInterface::COIN_PROCESSOR::ESCROW;
break;
case 3:
this->coinProcessorType = nsDeviceControllerInterface::COIN_PROCESSOR::CHANGER;
break;
}
if (devPara.kindOfCoinChecker==1 || devPara.kindOfCoinChecker==2) // 0: without 1=EMP820 2=EMP900 3=currenza c² (MW) if (devPara.kindOfCoinChecker==1 || devPara.kindOfCoinChecker==2) // 0: without 1=EMP820 2=EMP900 3=currenza c² (MW)
{ {
if (modCond.coinEscrow>=200) { if (modCond.coinEscrow>=200) {
@@ -242,6 +294,15 @@ void DeviceControllerDiag::sub_componentAssessment()
} }
} }
switch (devPara.BillAcceptor) {
case 0:
this->billAcceptor = nsDeviceControllerInterface::BILL_ACCEPTOR::NO;
break;
default:
this->billAcceptor = nsDeviceControllerInterface::BILL_ACCEPTOR::YES;
break;
}
/* /*
if ( modCond.billReader>=200 && devPara.BillAcceptor>0) if ( modCond.billReader>=200 && devPara.BillAcceptor>0)
{ {
@@ -324,7 +385,6 @@ void DeviceControllerDiag::private_sendDiagEvent(DeviceController::State result)
{ {
qCritical() << "DeviceControllerDiag::private_sendDiagEvent() result: " << result; qCritical() << "DeviceControllerDiag::private_sendDiagEvent() result: " << result;
if (this->eventReceiver == nullptr) { if (this->eventReceiver == nullptr) {
qCritical() << "DeviceControllerDiag: no eventReceiver"; qCritical() << "DeviceControllerDiag: no eventReceiver";
return; return;
@@ -347,61 +407,77 @@ void DeviceControllerDiag::private_sendDiagEvent(DeviceController::State result)
QString parameter; QString parameter;
switch (result) { switch (result) {
case DeviceController::State::INITIAL_STATE:
break;
case DeviceController::State::A000: // alarm / intrusion case DeviceController::State::A000: // alarm / intrusion
eventClass = EVENT_CLASS::ALARM; eventClass = EVENT_CLASS::ALARM;
parameter = "alarm / intrusion"; parameter = "alarm / intrusion";
this->_isErrorState = true;
break; break;
case DeviceController::State::E002: // real time clock error case DeviceController::State::E002: // real time clock error
eventClass = EVENT_CLASS::ERROR; eventClass = EVENT_CLASS::ERROR;
parameter = "real time clock error"; parameter = "real time clock error";
this->_isErrorState = true;
break; break;
case DeviceController::State::E003: // voltage error case DeviceController::State::E003: // voltage error
eventClass = EVENT_CLASS::ERROR; eventClass = EVENT_CLASS::ERROR;
parameter = "voltage error"; parameter = "voltage error";
this->_isErrorState = true;
break; break;
case DeviceController::State::E004: // temperature error case DeviceController::State::E004: // temperature error
eventClass = EVENT_CLASS::ERROR; eventClass = EVENT_CLASS::ERROR;
parameter = "temperature error"; parameter = "temperature error";
this->_isErrorState = true;
break; break;
case DeviceController::State::E007: // coin safe full case DeviceController::State::E007: // coin safe full
eventClass = EVENT_CLASS::ERROR; eventClass = EVENT_CLASS::ERROR;
parameter = "coin safe full"; parameter = "coin safe full";
this->_isErrorState = true;
break; break;
case DeviceController::State::E008: // bill acceptor full case DeviceController::State::E008: // bill acceptor full
eventClass = EVENT_CLASS::ERROR; eventClass = EVENT_CLASS::ERROR;
parameter = "bill acceptor full"; parameter = "bill acceptor full";
this->_isErrorState = true;
break; break;
case DeviceController::State::E009: // no cash box case DeviceController::State::E009: // no cash box
eventClass = EVENT_CLASS::ERROR; eventClass = EVENT_CLASS::ERROR;
parameter = "no cash box"; parameter = "no cash box";
this->_isErrorState = true;
break; break;
case DeviceController::State::E010: // coin escrow case DeviceController::State::E010: // coin escrow
eventClass = EVENT_CLASS::ERROR; eventClass = EVENT_CLASS::ERROR;
parameter = "coin escrow"; parameter = "coin escrow";
this->_isErrorState = true;
break; break;
case DeviceController::State::E011: // mem error int.ee. case DeviceController::State::E011: // mem error int.ee.
eventClass = EVENT_CLASS::ERROR; eventClass = EVENT_CLASS::ERROR;
parameter = "mem error int.ee."; parameter = "mem error int.ee.";
this->_isErrorState = true;
break; break;
case DeviceController::State::E018: // no paper case DeviceController::State::E018: // no paper
eventClass = EVENT_CLASS::ERROR; eventClass = EVENT_CLASS::ERROR;
parameter = "no paper"; parameter = "no paper";
this->_isErrorState = true;
break; break;
case DeviceController::State::E020: // printer error case DeviceController::State::E020: // printer error
eventClass = EVENT_CLASS::ERROR; eventClass = EVENT_CLASS::ERROR;
parameter = "printer error"; parameter = "printer error";
this->_isErrorState = true;
break; break;
case DeviceController::State::E025: // coin blocker case DeviceController::State::E025: // coin blocker
eventClass = EVENT_CLASS::ERROR; eventClass = EVENT_CLASS::ERROR;
parameter = "coin blocker"; parameter = "coin blocker";
this->_isErrorState = true;
break; break;
case DeviceController::State::E026: // error coin validator case DeviceController::State::E026: // error coin validator
eventClass = EVENT_CLASS::ERROR; eventClass = EVENT_CLASS::ERROR;
parameter = "error coin validator"; parameter = "error coin validator";
this->_isErrorState = true;
break; break;
case DeviceController::State::E034: // mdb error case DeviceController::State::E034: // mdb error
eventClass = EVENT_CLASS::ERROR; eventClass = EVENT_CLASS::ERROR;
parameter = "mdb error"; parameter = "mdb error";
this->_isErrorState = true;
break; break;
case DeviceController::State::E071: // cash box change is ongoing case DeviceController::State::E071: // cash box change is ongoing
@@ -437,9 +513,16 @@ void DeviceControllerDiag::private_sendDiagEvent(DeviceController::State result)
break; break;
case DeviceController::State::O000: // everything is fine case DeviceController::State::O000: // everything is fine
this->machineEventSet.clear(); this->machineEventSet.clear();
this->_isErrorState = false;
eventClass = EVENT_CLASS::OPERATE; eventClass = EVENT_CLASS::OPERATE;
parameter = ""; parameter = "";
if (this->lastState == DeviceController::State::O000) {
qCritical() << " ... everything fine, no state change -> skip sending";
return;
}
else {
qCritical() << " ... everything fine"; qCritical() << " ... everything fine";
}
break; break;
case DeviceController::State::W001: // paper low case DeviceController::State::W001: // paper low
@@ -460,6 +543,7 @@ void DeviceControllerDiag::private_sendDiagEvent(DeviceController::State result)
break; break;
} }
this->lastState = result;
ATBMachineEvent *machineEvent = new ATBMachineEvent( ATBMachineEvent *machineEvent = new ATBMachineEvent(
eventId, eventId,

View File

@@ -5,8 +5,13 @@
#include <QSet> #include <QSet>
#include <QTimer> #include <QTimer>
#include <DeviceController/interfaces.h>
#include "DeviceControllerInterface.h"
#include "ATBMachineEvent.h" #include "ATBMachineEvent.h"
#include "interfaces.h"
#include "support/PersistentData.h"
namespace DeviceController { namespace DeviceController {
Q_NAMESPACE Q_NAMESPACE
@@ -47,7 +52,9 @@ namespace DeviceController {
W001, W001,
W002, W002,
W003, W003,
W004 W004,
INITIAL_STATE
}; };
Q_ENUM_NS(State) Q_ENUM_NS(State)
} }
@@ -58,10 +65,20 @@ class DeviceControllerDiag : public QObject
Q_OBJECT Q_OBJECT
public: public:
DeviceControllerDiag(QObject *parent = nullptr); DeviceControllerDiag(PersistentData *pData, QObject *parent = nullptr);
void init(hwinf* hw, QObject* eventReceiver); void init(hwinf* hw, QObject* eventReceiver);
nsDeviceControllerInterface::COIN_PROCESSOR coinProcessorType;
nsDeviceControllerInterface::BILL_ACCEPTOR billAcceptor;
/**
* return true, if machineEventSet contains an error
*/
bool isErrorState();
bool isOperatingState();
QSet<DeviceController::State> getCurrentMachineState();
public slots: public slots:
void diagRequest(); void diagRequest();
@@ -83,7 +100,11 @@ private:
int lastVoltage; int lastVoltage;
DeviceController::State lastState;
QSet<DeviceController::State> machineEventSet; QSet<DeviceController::State> machineEventSet;
bool _isErrorState;
PersistentData* pData;
private slots: private slots:
void onDiagRequestTimeoutTimerTimeout(); void onDiagRequestTimeoutTimerTimeout();

View File

@@ -5,25 +5,30 @@
#include <QSettings> #include <QSettings>
#include <QString> #include <QString>
#include <QJsonObject>
#include "ATBAPPplugin.h" #include "ATBAPPplugin.h"
#include "UnifiedDCVMCInterface.h"
namespace nsDeviceControllerInterface { namespace nsDeviceControllerInterface {
using PLUGIN_STATE = ATBAPPplugin::PLUGIN_STATE; enum class PLUGIN_STATE : quint8;
using RESULT_STATE = ATBAPPplugin::RESULT_STATE; enum class RESULT_STATE : quint8;
using CASH_STATE = ATBAPPplugin::CASH_STATE; enum class CASH_STATE : quint8;
using TICKET_VARIANT = ATBAPPplugin::TICKET_VARIANT; enum class TICKET_VARIANT : quint8;
enum class COIN_PROCESSOR : quint8;
enum class BILL_ACCEPTOR : quint8;
enum class SERVICE_TEXT : quint16;
} }
class DeviceControllerInterface : public QObject, public UnifiedDCVMCInterface
class DeviceControllerInterface : public QObject
, public ATBAPPplugin
{ {
Q_OBJECT Q_OBJECT
Q_INTERFACES(ATBAPPplugin) Q_INTERFACES(ATBAPPplugin)
Q_INTERFACES(UnifiedDCVMCInterface)
public: public:
virtual ~DeviceControllerInterface() {} virtual ~DeviceControllerInterface() {}
/** /**
@@ -32,7 +37,14 @@ public:
* @param settings * @param settings
* @return * @return
*/ */
virtual PLUGIN_STATE initDCPlugin(QObject *eventReceiver, const QSettings & settings) = 0; virtual nsDeviceControllerInterface::PLUGIN_STATE initDCPlugin(QObject *eventReceiver,
const QSettings & settings) = 0;
/**
* e.g. send location
*/
virtual void sendDeviceParameter(const QJsonObject & jsonObject) = 0;
// TASKS: Cash handling ------------------------------------------------------- // TASKS: Cash handling -------------------------------------------------------
/** /**
@@ -60,10 +72,13 @@ 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(TICKET_VARIANT ticketVariant, 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; virtual void requestPrintReceipt(const QHash<QString, QVariant> & printingData) = 0;
virtual void requestPrintReceipt(const QString & printingString) = 0; virtual void requestPrintReceipt(const QString & printingString) = 0;
// read coin/cash processing variants
virtual nsDeviceControllerInterface::COIN_PROCESSOR coinProcessor() = 0;
virtual nsDeviceControllerInterface::BILL_ACCEPTOR billAcceptor() = 0;
// mandantory ATBAPP plugin methods: // mandantory ATBAPP plugin methods:
virtual nsDeviceControllerInterface::PLUGIN_STATE getState() = 0; virtual nsDeviceControllerInterface::PLUGIN_STATE getState() = 0;
@@ -74,7 +89,7 @@ public:
// -> ATBAPPplugin::getPluginInfo() // -> ATBAPPplugin::getPluginInfo()
// 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: public slots:
virtual void onChangedProgramModeToSELL() = 0; virtual void onChangedProgramModeToSELL() = 0;
@@ -87,6 +102,7 @@ public slots:
virtual void reboot() = 0; virtual void reboot() = 0;
virtual void reset() = 0; virtual void reset() = 0;
signals: signals:
void printTicketFinished(nsDeviceControllerInterface::RESULT_STATE resultState, void printTicketFinished(nsDeviceControllerInterface::RESULT_STATE resultState,
const QString & errorCode, const QString & errorCode,
@@ -95,6 +111,9 @@ signals:
const QString & errorCode, const QString & errorCode,
const QString & errorDescription); const QString & errorDescription);
void coinAttached();
/** /**
* emitted on e.g. a coin input * emitted on e.g. a coin input
*/ */
@@ -113,15 +132,38 @@ signals:
*/ */
void cashInputFinished(nsDeviceControllerInterface::RESULT_STATE resultState, void cashInputFinished(nsDeviceControllerInterface::RESULT_STATE resultState,
const QString & newCashValue, const QString & newCashValue,
/* additional variables? */ const QString & coinValue,
const QString & noteValue,
const QString & changeValue,
const QString & errorCode, const QString & errorCode,
const QString & errorDescription); const QString & errorDescription);
/**
* emitted if cashPayment has been finished, e.g. in result to task cashCollect():
* -> ticket should be printed sucessfully
* -> coins in excrow or changer are given back to user
* Provides data for logging, especially changed value
*/
void cashPaymentFinished(nsDeviceControllerInterface::RESULT_STATE resultState,
const QString & newCashValue, // total inserted amount amount
const QString & coinValue, // inserted amount, paid with coins
const QString & noteValue, // inserted amount, paid with notes
const QString & changeValue, // amount changed by changer/escrow
const QString & errorCode,
const QString & errorDescription);
/** /**
* emitted e.g. if service door is opened * emitted e.g. if service door is opened
*/ */
void requestModeSERVICE(); void requestModeSERVICE();
/**
* emitted e.g. if vault door is opened
*/
void requestModeACCOUNT();
/** /**
* emitted e.g. if doors are closed * emitted e.g. if doors are closed
*/ */
@@ -138,6 +180,12 @@ signals:
void requestAccountResponse(const QHash<QString, QVariant> & accountData); void requestAccountResponse(const QHash<QString, QVariant> & accountData);
/**
* show text messages in service mode
*/
void showServiceText(nsDeviceControllerInterface::SERVICE_TEXT serviceText, const QString & text);
/** /**
* emitted on error * emitted on error
* depending on errorCode: * depending on errorCode:
@@ -153,7 +201,62 @@ signals:
}; };
Q_DECLARE_INTERFACE(DeviceControllerInterface, Q_DECLARE_INTERFACE(DeviceControllerInterface,
"eu.atb.ptu.plugin.DeviceControllerInterface/1.0") "eu.atb.ptu.plugin.DeviceControllerInterface/1.1.4")
namespace nsDeviceControllerInterface {
enum class PLUGIN_STATE : quint8 {
NOT_INITIALIZED = 0,
INITIALIZED = 1
};
enum class RESULT_STATE : quint8 {
SUCCESS = 1, // operation was successfull
ERROR_BACKEND, // error from backend (e.g. backend replies with error)
ERROR_TIMEOUT, // the operation timed out
ERROR_PROCESS, // internal plugin error, should not occur (this is a bug in implementation)
ERROR_RETRY, // retry operation
INFO // informational (e.g. display a message, log something etc.)
};
enum class CASH_STATE : quint8 {
CACHE_EMPTY, // Cache still empty, default state
CACHE_INPUT, // Coins are in Cache
OVERPAYED,
/* 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
FOOD_STAMP
};
enum class COIN_PROCESSOR : quint8 {
CHANGER,
ESCROW,
NONE
};
enum class BILL_ACCEPTOR : quint8 {
YES,
NO
};
enum class SERVICE_TEXT : quint16 {
SERVICE_DOOR_OPENED,
VAULT_DOOR_OPENED,
COIN_BOX_REMOVED,
COIN_BOX_INSERTED
/* t.b.d. */
};
}
#endif // DEVICECONTROLLERINTERFACE_H #endif // DEVICECONTROLLERINTERFACE_H

View File

@@ -1,19 +0,0 @@
#include "DeviceControllerInterface.h"
using UNIFIED_PLUGIN_STATE = UnifiedDCVMCInterface<DeviceControllerInterface>::UNIFIED_PLUGIN_STATE;
template<>
UNIFIED_PLUGIN_STATE UnifiedDCVMCInterface<DeviceControllerInterface>::initPlugin(QObject *eventReceiver, QSettings const &settings) {
switch(static_cast<DeviceControllerInterface*>(this)->initDCPlugin(eventReceiver, settings)) {
case nsDeviceControllerInterface::PLUGIN_STATE::INITIALIZED:
return UNIFIED_PLUGIN_STATE::INITIALIZED;
case nsDeviceControllerInterface::PLUGIN_STATE::NOT_INITIALIZED:
return UNIFIED_PLUGIN_STATE::NOT_INITIALIZED;
}
return UNIFIED_PLUGIN_STATE::NOT_INITIALIZED;
}

View File

@@ -1,62 +0,0 @@
#ifndef UNIFIED_DCVMC_INTERFACE_H_INCLUDED
#define UNIFIED_DCVMC_INTERFACE_H_INCLUDED
#include <QObject>
#include <QSettings>
#include <QtPlugin>
#include <QSettings>
#include <QString>
#include "ATBAPPplugin.h"
class UnifiedDCVMCInterface : public ATBAPPplugin {
Q_INTERFACES(ATBAPPplugin)
public:
explicit UnifiedDCVMCInterface() = default;
virtual ~UnifiedDCVMCInterface() = default;
virtual QStringList getPluginInfoList() = 0;
virtual const QString &getPluginInfo() = 0;
// mandantory ATBAPP plugin methods:
virtual PLUGIN_STATE getState() = 0;
virtual QString const &getLastError() = 0;
virtual QString const &getLastErrorDescription() = 0;
virtual PLUGIN_STATE initPlugin(QObject *eventReceiver,
QObject *atbSystem,
QObject *hmiConfig,
QSettings const &settings) = 0;
virtual PLUGIN_STATE initPlugin(QObject *eventReceiver, QSettings const &settings) = 0;
virtual PLUGIN_STATE initDCPlugin(QObject *eventReceiver,
const QSettings & settings) = 0;
virtual PLUGIN_STATE initVMCPlugin(QObject *eventReceiver,
QObject *atbSystem, QObject *hmiConfig,
const QSettings & settings) = 0;
virtual QString const &getString(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;
virtual void reboot() = 0;
virtual void reset() = 0;
};
Q_DECLARE_INTERFACE(UnifiedDCVMCInterface,
"eu.atb.ptu.plugin.UnifiedDCVMCInterface/1.0")
#endif // UNIFIED_DCVMC_INTERFACE_H_INCLUDED

View File

@@ -0,0 +1,74 @@
#include "CashUtils.h"
#include <QDebug>
#define MAX_COINS 64
#define MAX_NOTES 16
/*****************************************************************************
* Get current inserted coins
*
* getAllInsertedCoins(uint16_t *types, uint16_t *values)
* all inserted coins of this past transaction are stored, max 64
*/
uint32_t CashUtils::getAmountOfInsertedCoins(hwinf* hw)
{
uint32_t result = 0;
uint16_t types[MAX_COINS];
uint16_t values[MAX_COINS];
hw->getAllInsertedCoins(types, values);
for (int i = 0; i < MAX_COINS; i++) {
result += values[i];
}
return result;
}
/*****************************************************************************
* Get current inserted notes
*
* virtual uint8_t bna_getCurrentNotes(uint16_t latestBill, uint16_t *currentNotes) const =0;
* returns number of collected bank notes since start-command (current transaction)
* latestBill: last accepted bank note, value in cent
* currentNotes an array with up to 16 (further) notes collected
*
*/
uint32_t CashUtils::getAmountOfInsertedNotes(hwinf* hw)
{
uint32_t result = 0;
uint8_t numberOfInsertedNotes;
uint16_t beforeArray = 0;
uint16_t currentNotes[4];
uint16_t afterArray = 0;
numberOfInsertedNotes = hw->bna_getCurrentNotes(0, currentNotes);
if ( (beforeArray != 0) || (afterArray != 0) ) {
qCritical() << "CashUtils::getAmountOfInsertedNotes() ERROR: Array";
}
if (numberOfInsertedNotes == 99) {
// Error
qCritical() << "CashUtils::getAmountOfInsertedNotes() ERROR: ";
for (int i = 0; i < 4; i++) {
qCritical() << " currentNotes[" << i << "] = " << currentNotes[i];
}
}
else {
// no error
result = currentNotes[3];
result = ( result << 16 ) | currentNotes[2];
}
// DEBUG
qCritical() << "--------------------------------------------------";
qCritical() << "CashUtils::getAmountOfInsertedNotes()";
qCritical() << " numberOfInsertedNotes = " << numberOfInsertedNotes;
qCritical() << " result = " << result;
qCritical() << "--------------------------------------------------";
return result;
}

View File

@@ -0,0 +1,14 @@
#ifndef CASHUTILS_H
#define CASHUTILS_H
#include <QObject>
#include <DeviceController/interfaces.h>
namespace CashUtils {
uint32_t getAmountOfInsertedCoins(hwinf* hw);
uint32_t getAmountOfInsertedNotes(hwinf* hw);
}
#endif // CASHUTILS_H

View File

@@ -0,0 +1,145 @@
#include "PersistentData.h"
#include <QFile>
#include <QFileInfo>
#include <QDir>
#include <QDateTime>
#include <QDataStream>
#include <QDebug>
PersistentData::PersistentData(const QString &datafileName, QObject *parent)
: QObject(parent)
, isChangedFlag(false)
{
// load persistant data, if available
this->filename = datafileName;
QFileInfo dataFileInfo(this->filename);
QString dataFilePath = dataFileInfo.path();
QDir dir;
if ( ! dir.exists(dataFilePath)) {
qCritical() << "Persistent data file does not exist!";
qCritical() << " --> create new: " << this->filename;
dir.mkpath(dataFilePath);
}
this->read();
}
void PersistentData::serializeToFile()
{
if (this->isChangedFlag) {
qCritical() << "PersistentData::isChanged -> save";
this->save();
}
}
void PersistentData::save()
{
QFile fileOut(this->filename);
if (fileOut.open(QIODevice::WriteOnly))
{
QDataStream out(&fileOut);
out.setVersion(QDataStream::Qt_4_6);
out << this->hash;
fileOut.flush();
fileOut.close();
this->isChangedFlag = false;
}
}
void PersistentData::read()
{
QFile fileIn(this->filename);
if (fileIn.open(QIODevice::ReadOnly))
{
QDataStream in(&fileIn);
in.setVersion(QDataStream::Qt_4_6);
in >> hash;
fileIn.close();
}
}
QVariant PersistentData::getParameter(const QString & key) const {
#if defined (ARCH_DesktopLinux)
// note: QVariant.toString() returns empty string for custom types
qDebug() << "VendingData::getParameter() key = " << key << " value = " << hash.value(key).toString();
#endif
return hash.value(key);
}
QVariant PersistentData::getParameter(const QString & key)
{
#if defined (ARCH_DesktopLinux)
// note: QVariant.toString() returns empty string for custom types
qDebug() << "VendingData::getParameter() key = " << key << " value = " << hash.value(key).toString();
#endif
return hash.value(key);
}
void PersistentData::setParameter(const QString & key, QVariant value)
{
this->isChangedFlag = true;
#if defined (ARCH_DesktopLinux)
// note: QVariant.toString() returns empty string for custom types
qDebug() << "VendingData::setParameter() key = " << key << " value = " << value.toString();
#endif
this->hash.insert(key, value);
}
void PersistentData::clearParameter(const QString & key)
{
this->isChangedFlag = true;
this->hash.remove(key);
}
bool PersistentData::hasParameter(const QString & key) const
{
return hash.contains(key);
}
uint PersistentData::getUintParameter(const QString & key) const
{
qDebug() << "PersistentData::getUintParameter() key = " << key << " value = " << hash.value(key).toString();
uint returnValue = 0;
bool ok;
returnValue = hash.value(key).toString().toUInt(&ok);
if (!ok) returnValue = 0;
return returnValue;
}
QList<QString> PersistentData::uniqueKeys() const {
return hash.uniqueKeys();
}
void PersistentData::setDCFirmwareVersion(const QString & fw_version)
{
// there must be a version string!
if (fw_version.size() < 1) return;
if (this->hash["dc_fw_version"].toString() != fw_version) {
this->isChangedFlag = true;
this->hash.insert("dc_fw_version", fw_version);
}
}
QString PersistentData::getDCFirmwareVersion()
{
return this->hash["dc_fw_version"].toString();
}

View File

@@ -0,0 +1,49 @@
#ifndef PERSISTENTDATA_H
#define PERSISTENTDATA_H
#include <QObject>
#include <QHash>
#include <QVariant>
#include <QList>
#include <QString>
class PersistentData : public QObject
{
Q_OBJECT
public:
explicit PersistentData(const QString &datafileName, QObject *parent = nullptr);
void setDCFirmwareVersion(const QString & fw_version);
QString getDCFirmwareVersion();
QVariant getParameter(const QString & key);
QVariant getParameter(const QString & key) const;
void setParameter(const QString & key, QVariant value);
void clearParameter(const QString & key);
bool hasParameter(const QString & key) const;
uint getUintParameter(const QString & key) const;
QList<QString> uniqueKeys() const;
public slots:
void serializeToFile();
signals:
private:
QHash<QString, QVariant> hash;
QString dc_fw_version;
QString filename;
void save();
void read();
bool isChangedFlag;
};
#endif // PERSISTENTDATA_H

View File

@@ -0,0 +1,169 @@
#include "Ticket.h"
#include <QDebug>
Ticket::Ticket(TICKET_VARIANT ticketVariant, QObject *parent )
: QObject(parent)
, ticketVariant(ticketVariant)
, _hasTemplateDynData(false)
{
}
TICKET_VARIANT Ticket::variant()
{
return this->ticketVariant;
}
QList<quint8> * Ticket::templateList()
{
return &(this->_templateList);
}
bool Ticket::hasTemplateDynData()
{
return this->_hasTemplateDynData;
}
quint8 Ticket::getCurrentProcessedTemplateNumber()
{
return this->currentProcessedTemplateNumber;
}
void Ticket::setCurrentTemplateProcessed()
{
this->currentProcessedTemplateNumber++;
}
bool Ticket::initNew(TICKET_VARIANT ticketVariant, const QList<quint8> & templateList, const QHash<QString, QVariant> & printingData)
{
this->clear();
this->ticketVariant = ticketVariant;
this->printingData = printingData;
this->_templateList = templateList;
this->currentProcessedTemplateNumber = 0;
// DEBUG
qCritical() << "Ticket::initNew():";
qCritical() << " -> " << ticketVariant;
int multiplicatorInt = 1; // default
switch (this->ticketVariant) {
case TICKET_VARIANT::PARKING_TICKET:
break;
case TICKET_VARIANT::RECEIPT:
break;
case TICKET_VARIANT::ERROR_RECEIPT:
break;
case TICKET_VARIANT::START_RECEIPT:
this->_templateList << 21 << 22 << 23;
break;
case TICKET_VARIANT::STOP_RECEIPT:
this->_templateList << 24 << 25 << 26;
break;
case TICKET_VARIANT::FOOD_STAMP:
if (printingData.contains("dyn1_list")) {
this->_hasTemplateDynData = true;
this->dyn1List = printingData["dyn1_list"].toStringList();
this->dyn2List = printingData["dyn2_list"].toStringList();
}
if (printingData.contains("multiplicator")) {
multiplicatorInt = printingData["multiplicator"].toInt();
for (int i = 1; i < multiplicatorInt; i++) {
this->_templateList << 1;
}
// last template:
this->_templateList << 2;
}
// DEBUG FOOD_STAMP:
qCritical() << " --> printingData[\"multiplicator\"]" << multiplicatorInt;
break;
}
// DEBUG
QString templateListString;
for (int i =0; i < this->_templateList.size(); ++i) {
templateListString.append(QString(" %1").arg(this->_templateList.at(i)));
}
qCritical() << " -> templates: " << templateListString;
return true;
}
void Ticket::clear()
{
this->ticketVariant = TICKET_VARIANT::PARKING_TICKET;
this->printingData.clear();
this->_templateList.clear();
this->errorCode.clear();
this->errorDescription.clear();
this->_hasTemplateDynData = false;
this->dyn1List.clear();
this->dyn1List.clear();
}
QString Ticket::getErrorCode() { return this->errorCode; }
QString Ticket::getErrorDescription() { return this->errorDescription; }
/**
*/
QStringList Ticket::getDyn1List()
{
return this->dyn1List;
}
QStringList Ticket::getDyn2List()
{
return this->dyn2List;
}
QHash<QString, QVariant> & Ticket::getPrintingData()
{
return this->printingData;
}
/************************************************************************************************
* operator
*
*/
QDebug operator<<(QDebug debug, TICKET_VARIANT ticketVariant)
{
switch (ticketVariant) {
case TICKET_VARIANT::PARKING_TICKET:
debug << "TICKET_VARIANT::PARKING_TICKET";
break;
case TICKET_VARIANT::RECEIPT:
debug << "TICKET_VARIANT::RECEIPT";
break;
case TICKET_VARIANT::ERROR_RECEIPT:
debug << "TICKET_VARIANT::ERROR_RECEIPT";
break;
case TICKET_VARIANT::START_RECEIPT:
debug << "TICKET_VARIANT::START_RECEIPT";
break;
case TICKET_VARIANT::STOP_RECEIPT:
debug << "TICKET_VARIANT::STOP_RECEIPT";
break;
case TICKET_VARIANT::FOOD_STAMP:
debug << "TICKET_VARIANT::FOOD_STAMP";
break;
}
return debug;
}

View File

@@ -0,0 +1,88 @@
#ifndef TICKET_H
#define TICKET_H
#include <QObject>
#include <QHash>
#include "../DeviceControllerInterface.h"
using namespace nsDeviceControllerInterface;
QDebug operator<<(QDebug debug, TICKET_VARIANT ticketVariant);
class Ticket : public QObject
{
Q_OBJECT
public:
Ticket(TICKET_VARIANT ticketVariant, QObject *parent = nullptr);
bool initNew(TICKET_VARIANT ticketVariant, const QList<quint8> & templateList, const QHash<QString, QVariant> & printingData);
void clear();
TICKET_VARIANT variant();
QList<quint8> * templateList();
/**
* @brief getPrintingData - generic getter for printingData
* Used mainly for simple tickets (single tickets e.g. ParkingTicket)
* @return
*/
QHash<QString, QVariant> & getPrintingData();
/**
* @brief hasTemplateDynData
* @return true, if ticket has dynamic data for each template.
*
* This depends on TICKET_VARIANT and printingData
*/
bool hasTemplateDynData();
/**
* @brief getDyn1List
* contains dynamic template data
* The size of the lists must be exactly the same as the number of templates.
*/
QStringList getDyn1List();
QStringList getDyn2List();
quint8 getCurrentProcessedTemplateNumber();
/**
* Mark current template as processed
*/
void setCurrentTemplateProcessed();
// error handling
QString getErrorCode();
QString getErrorDescription();
private:
TICKET_VARIANT ticketVariant;
// printingData from application
QHash<QString, QVariant> printingData;
// templateList, from .ini or created by ticketVariant...
QList<quint8> _templateList;
bool _hasTemplateDynData;
quint8 currentProcessedTemplateNumber;
QStringList dyn1List;
QStringList dyn2List;
// error handling
QString errorCode;
QString errorDescription;
};
#endif // TICKET_H