Compare commits

...

14 Commits
2.2.7 ... 2.4.0

Author SHA1 Message Date
a43af8ab86 Print ticket-number on ticket 2024-08-07 15:29:12 +02:00
d7443974e2 requestPrintTicket() add new product names 2024-07-23 14:36:45 +02:00
346c953175 Print ticket FREE_TICKET 2024-07-23 11:01:13 +02:00
8cf6897a21 FREE_TICKET defaults to templates 24, 25, 26 2024-07-23 11:00:03 +02:00
69eb87e358 DeviceController Interface 1.1.6 (Ticket Variant FREE_TICKET) 2024-07-23 10:58:56 +02:00
8eab11479c Merge branch 'pu/klaipeda' into pu/integration 2024-07-15 15:30:54 +02:00
ac93e9e631 Send W255 on restart CArun 2024-07-15 11:09:37 +02:00
c1dd20ec4f Restart carun on consecutive E255 2024-07-15 11:09:28 +02:00
2d60a7bd5c Send W255 on restart CArun 2024-07-15 10:08:56 +02:00
6d7d9ade70 Restart carun on consecutive E255 2024-07-15 10:03:41 +02:00
72dbc8b858 Print receipt: encode QString 2024-06-27 11:55:35 +02:00
32d70abf44 Proposal for usage of TICKET_VARIANT::FINE_PAYMENT 2024-06-27 11:48:16 +02:00
c076090e03 DeviceController Interface 1.1.5 (Ticket Variant FINE_PAYMENT) 2024-06-27 11:46:40 +02:00
6c2717c56b Diag: check doors in sub_componentAssessment ...
... this prevents sending Operate "O000" in case of an opend door and
enables sending Operate "O000" after closing all doors because
'lastResult' has not changed.
2024-06-11 09:27:07 +02:00
6 changed files with 181 additions and 31 deletions

View File

@@ -654,10 +654,21 @@ void ATBDeviceControllerPlugin::requestPrintReceipt(const QHash<QString, QVarian
void ATBDeviceControllerPlugin::requestPrintReceipt(const QString & printingString)
{
QByteArray ba = printingString.toUtf8();
QByteArray ba_receipt = this->codec->fromUnicode(printingString);
//QByteArray ba = printingString.toUtf8();
hw->prn_switchPower(true);
hw->prn_setFonts(8,12,0,0);
hw->prn_sendText(&ba);
hw->prn_sendText(&ba_receipt);
// DEBUG
//qCritical() << "---------------------------------------------------------------";
//qCritical() << "ATBDeviceControllerPlugin::requestPrintReceipt()";
//qCritical() << " receipt data:";
//qCritical() << QString(ba_receipt);
//qCritical() << "---------------------------------------------------------------";
this->printResultCheckCounter = 0;
QTimer::singleShot(4000, this, SLOT(onPrinterWaitForPrintingReceipt()));
@@ -715,7 +726,8 @@ void ATBDeviceControllerPlugin::requestPrintTicket(const QHash<QString, QVariant
<< " licenseplate = " << printingData["licenseplate"] << endl
<< " amount = " << printingData["amount"] << endl
<< " parkingEnd = " << printingData["parkingEnd"] << endl
<< " currentDateTime = " << printingData["currentDateTime"] << endl;
<< " currentDateTime = " << printingData["currentDateTime"] << endl
<< " ticketNumber = " << printingData["ticketNumber"] << endl;
QDateTime parkingEndDateTime = QDateTime::fromString(printingData["parkingEnd"].toString(), Qt::ISODate);
QDateTime currentDateTime = QDateTime::fromString(printingData["currentDateTime"].toString(), Qt::ISODate);
@@ -747,6 +759,10 @@ void ATBDeviceControllerPlugin::requestPrintTicket(const QHash<QString, QVariant
QByteArray ba_currentDate = codec->fromUnicode(currentDateString);
memcpy((char*)dynTicketData->currentDate, ba_currentDate.data(), std::min(ba_currentDate.size(),8));
// Ticket-Number
QByteArray ba_ticketNumber = codec->fromUnicode(printingData["ticketNumber"].toString());
memcpy((char*)dynTicketData->dynDat7, ba_ticketNumber.data(), std::min(ba_ticketNumber.size(),8));
// DEBUG
/*
@@ -780,7 +796,8 @@ void ATBDeviceControllerPlugin::requestPrintTicket(const QHash<QString, QVariant
<< " amount = " << printingData["amount"] << endl
<< " parkingEnd = " << printingData["parkingEnd"] << endl
<< " currentTime = " << printingData["currentTime"] << endl
<< " currentDate = " << printingData["currentDate"] << endl;
<< " currentDate = " << printingData["currentDate"] << endl
<< " ticketNumber = " << printingData["ticketNumber"] << endl;
this->onPrintFinishedERR();
@@ -801,19 +818,39 @@ void ATBDeviceControllerPlugin::requestPrintTicket(const QHash<QString, QVariant
QString paymentType = printingData["paymentType"].toString(); // must be "CASH" | "CARD"
QString productName = printingData["product"].toString(); // must be "ShortTimeParking" | "DayTicket"
if ( (paymentType == "CASH") && (productName == "SHORT_TERM_PARKING") ) {
if ( (paymentType == "CASH") && ( (productName == "SHORT_TERM_PARKING") ||
(productName == "SHORT_TERM_PARKING_CAR") ||
(productName == "SHORT_TERM_PARKING_VAN") ||
(productName == "SHORT_TERM_PARKING_CAMPER")
))
{
this->currentSelectedTicketType = 1; // "Kombiticket #1"
}
else
if ( (paymentType == "CARD") && (productName == "SHORT_TERM_PARKING") ) {
if ( (paymentType == "CARD") && ( (productName == "SHORT_TERM_PARKING") ||
(productName == "SHORT_TERM_PARKING_CAR") ||
(productName == "SHORT_TERM_PARKING_VAN") ||
(productName == "SHORT_TERM_PARKING_CAMPER")
))
{
this->currentSelectedTicketType = 2; // "Kombiticket #2"
}
else
if ( (paymentType == "CASH") && (productName == "DAY_TICKET") ) {
if ( (paymentType == "CASH") && ( (productName == "DAY_TICKET") ||
(productName == "DAY_TICKET_CAR") ||
(productName == "DAY_TICKET_VAN") ||
(productName == "DAY_TICKET_CAMPER")
))
{
this->currentSelectedTicketType = 3; // "Kombiticket #3"
}
else
if ( (paymentType == "CARD") && (productName == "DAY_TICKET") ) {
if ( (paymentType == "CARD") && ( (productName == "DAY_TICKET") ||
(productName == "DAY_TICKET_CAR") ||
(productName == "DAY_TICKET_VAN") ||
(productName == "DAY_TICKET_CAMPER")
))
{
this->currentSelectedTicketType = 4; // "Kombiticket #4"
}
else
@@ -983,12 +1020,18 @@ void ATBDeviceControllerPlugin::prepareDynTemplateData()
case nsDeviceControllerInterface::TICKET_VARIANT::STOP_RECEIPT:
private_setupDynTemplatData_STOP_RECEIPT(dynTicketData, this->currentTicket);
break;
case nsDeviceControllerInterface::TICKET_VARIANT::FINE_PAYMENT:
private_setupDynTemplatData_FINE_PAYMENT(dynTicketData, this->currentTicket);
break;
case nsDeviceControllerInterface::TICKET_VARIANT::RECEIPT:
break;
case nsDeviceControllerInterface::TICKET_VARIANT::ERROR_RECEIPT:
break;
case nsDeviceControllerInterface::TICKET_VARIANT::PARKING_TICKET:
break;
case nsDeviceControllerInterface::TICKET_VARIANT::FREE_TICKET:
private_setupDynTemplatData_FREE_TICKET(dynTicketData, this->currentTicket);
break;
case nsDeviceControllerInterface::TICKET_VARIANT::FOOD_STAMP:
private_setupDynTemplatData_FOOD_STAMP(dynTicketData, this->currentTicket);
break;
@@ -1091,6 +1134,62 @@ void ATBDeviceControllerPlugin::private_setupDynTemplatData_FOOD_STAMP(struct T_
qCritical() << "-------------------------------------------------------";
}
void ATBDeviceControllerPlugin::private_setupDynTemplatData_FINE_PAYMENT(struct T_dynDat *dynTicketData, Ticket *ticket)
{
QDateTime currentDateTime = QDateTime::fromString(ticket->getPrintingData()["currentDateTime"].toString(), Qt::ISODate);
QString currentDateString = this->printerLocale.toString(currentDateTime.date(), QLocale::ShortFormat);
// set dynamic printer data:
QByteArray ba_licenseplate = codec->fromUnicode(ticket->getPrintingData()["licenseplate"].toString());
memcpy((char*)dynTicketData->licensePlate, ba_licenseplate.data(), std::min(ba_licenseplate.size(),8));
QByteArray ba_amount = codec->fromUnicode(ticket->getPrintingData()["amount"].toString());
memcpy((char*)dynTicketData->vendingPrice, ba_amount.data(), std::min(ba_amount.size(),8)); // Szeged
memcpy((char*)dynTicketData->dynDat6, ba_amount.data(), std::min(ba_amount.size(),8)); // Schoenau
QByteArray ba_currentDate = codec->fromUnicode(currentDateString);
memcpy((char*)dynTicketData->currentDate, ba_currentDate.data(), std::min(ba_currentDate.size(),8));
QByteArray ba_ticketId = codec->fromUnicode(ticket->getPrintingData()["ticketId"].toString());
memcpy((char*)dynTicketData->dynDat7, ba_amount.data(), std::min(ba_ticketId.size(),8));
}
void ATBDeviceControllerPlugin::private_setupDynTemplatData_FREE_TICKET(struct T_dynDat *dynTicketData, Ticket *ticket)
{
QDateTime currentDateTime = QDateTime::fromString(ticket->getPrintingData()["currentDateTime"].toString(), Qt::ISODate);
QString currentDateString = this->printerLocale.toString(currentDateTime.date(), QLocale::ShortFormat);
// set dynamic printer data:
QByteArray ba_licenseplate = codec->fromUnicode(ticket->getPrintingData()["licenseplate"].toString());
memcpy((char*)dynTicketData->licensePlate, ba_licenseplate.data(), std::min(ba_licenseplate.size(),8));
QByteArray ba_amount = codec->fromUnicode(ticket->getPrintingData()["amount"].toString());
memcpy((char*)dynTicketData->vendingPrice, ba_amount.data(), std::min(ba_amount.size(),8)); // Szeged
memcpy((char*)dynTicketData->dynDat6, ba_amount.data(), std::min(ba_amount.size(),8)); // Schoenau
QByteArray ba_currentDate = codec->fromUnicode(currentDateString);
memcpy((char*)dynTicketData->currentDate, ba_currentDate.data(), std::min(ba_currentDate.size(),8));
// FREE_TICKET needs parking endtime:
QDateTime parkingEndDateTime = QDateTime::fromString(ticket->getPrintingData()["parkingEnd"].toString(), Qt::ISODate);
QByteArray ba_parkingEndTime = codec->fromUnicode(parkingEndDateTime.toString("hh:mm"));
memcpy((char*)dynTicketData->parkingEnd, ba_parkingEndTime.data(), std::min(ba_parkingEndTime.size(),8));
QString parkingEndDateString = this->printerLocale.toString(parkingEndDateTime.date(), QLocale::ShortFormat);
QByteArray ba_parkingEndDate = codec->fromUnicode(parkingEndDateString);
memcpy((char*)dynTicketData->currentTime, ba_parkingEndDate.data(), std::min(ba_parkingEndDate.size(),8));
// ! and yes... 'ParkingEndDate' is 'currentTime'
}
/************************************************************************************************

View File

@@ -144,6 +144,8 @@ private:
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);
void private_setupDynTemplatData_FINE_PAYMENT(struct T_dynDat *dynTicketData, Ticket *ticket);
void private_setupDynTemplatData_FREE_TICKET(struct T_dynDat *dynTicketData, Ticket *ticket);
// ---------------------------------------------------------------------------------------------
private slots:

View File

@@ -5,6 +5,8 @@
#include <QUuid>
#include <QDebug>
#include <QProcess>
#include "support/JSON.h"
@@ -18,6 +20,7 @@ DeviceControllerDiag::DeviceControllerDiag(PersistentData *pData, QObject *paren
, lastState(DeviceController::State::INITIAL_STATE)
, _isErrorState(false)
, pData(pData)
, E255counter(0)
{
diagRequestTimeoutTimer = new QTimer(this);
diagRequestTimeoutTimer->setInterval(1000*45);
@@ -104,14 +107,20 @@ void DeviceControllerDiag::private_startDiag()
this->private_sendDiagEvent(DeviceController::State::E255);
this->isRequestRunning = false;
this->flagInterruptDiag = false;
if (this->E255counter > 5) {
this->restartCArun();
}
else {
this->E255counter++;
// try it again, until success:
QTimer::singleShot(400, this, &DeviceControllerDiag::diagRequest);
/**
* But please note:
* - diag does currently not stop suspend (start a background task)
* - diag is called again in ModeOOO wokeup()
*/
// try it again, until success:
QTimer::singleShot(400, this, &DeviceControllerDiag::diagRequest);
/**
* But please note:
* - diag does currently not stop suspend (start a background task)
* - diag is called again in ModeOOO wokeup()
*/
}
return;
}
@@ -146,6 +155,8 @@ void DeviceControllerDiag::sys_superviseSystem()
this->private_sendDiagEvent(DeviceController::State::E255);
this->flagInterruptDiag = false;
this->isRequestRunning = false;
if (this->E255counter > 5) { this->restartCArun(); }
else { this->E255counter++; }
return;
}
@@ -156,6 +167,8 @@ void DeviceControllerDiag::sys_superviseSystem()
this->private_sendDiagEvent(DeviceController::State::E254);
this->diagRequestTimeoutTimer->stop();
this->isRequestRunning = false;
if (this->E255counter > 5) { this->restartCArun(); }
else { this->E255counter++; }
return;
}
@@ -168,7 +181,7 @@ void DeviceControllerDiag::sys_superviseSystem()
{
// noch keine Testergebnisse
if (dynMaCond.startupTestIsRunning) {
// TODO?
qCritical() << " startupTestIsRunning --> call again";
}
@@ -178,18 +191,6 @@ void 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_sendDiagEvent(DeviceController::State::E253);
}
if (dynMaCond.middleDoor) {
// vault door is open, goto INTRUSION MODE
qCritical() << "DeviceControllerDiag::sys_superviseSystem() vault door is open, goto INTRUSION MODE";
this->private_sendDiagEvent(DeviceController::State::E252);
}
qCritical() << " --> call sub_componentAssessment()";
sub_componentAssessment();
@@ -223,6 +224,21 @@ void DeviceControllerDiag::sub_componentAssessment()
this->private_sendDiagEvent(DeviceController::State::A000);
}
// check for open doors
// all doors: 99: undefined 0:closed 1:open
if (dynMaCond.lowerDoor || dynMaCond.upperDoor) {
// Service or battery door is open
flag_sendOperate = false;
qCritical() << "DeviceControllerDiag::sys_superviseSystem() Service or battery door is open, goto INTRUSION MODE";
this->private_sendDiagEvent(DeviceController::State::E253);
}
if (dynMaCond.middleDoor) {
// vault door is open
flag_sendOperate = false;
qCritical() << "DeviceControllerDiag::sys_superviseSystem() vault door is open, goto INTRUSION MODE";
this->private_sendDiagEvent(DeviceController::State::E252);
}
// check for invalid states:
if (modCond.rtc>=200) {
@@ -567,6 +583,10 @@ void DeviceControllerDiag::private_sendDiagEvent(DeviceController::State result)
eventClass = EVENT_CLASS::WARNING;
parameter = "temperatur warning";
break;
case DeviceController::State::W255: // restart carun
eventClass = EVENT_CLASS::WARNING;
parameter = "restart carun";
break;
}
this->lastState = result;
@@ -596,3 +616,13 @@ void DeviceControllerDiag::private_sendDiagEvent(DeviceController::State result)
}
/**
* reset / restart / reinit deviceController
*/
void DeviceControllerDiag::restartCArun()
{
this->E255counter = 0;
this->private_sendDiagEvent(DeviceController::State::W255);
QProcess::startDetached("/bin/systemctl", {"restart", "carun"});
}

View File

@@ -55,6 +55,8 @@ namespace DeviceController {
W003,
W004,
W255,
INITIAL_STATE
};
Q_ENUM_NS(State)
@@ -94,6 +96,11 @@ public slots:
*/
void diagReInit();
/**
* reset / restart / reinit deviceController
*/
void restartCArun();
signals:
void diagResponse(ATBMachineEvent* machineEvent);
@@ -118,6 +125,8 @@ private:
PersistentData* pData;
int E255counter;
private slots:
void onDiagRequestTimeoutTimerTimeout();
@@ -126,7 +135,6 @@ private slots:
void sys_superviseSystem();
};
#endif // DEVICECONTROLLERDIAG_H

View File

@@ -203,7 +203,7 @@ signals:
Q_DECLARE_INTERFACE(DeviceControllerInterface,
"eu.atb.ptu.plugin.DeviceControllerInterface/1.1.4")
"eu.atb.ptu.plugin.DeviceControllerInterface/1.1.6")
namespace nsDeviceControllerInterface {
@@ -236,7 +236,9 @@ namespace nsDeviceControllerInterface {
ERROR_RECEIPT,
START_RECEIPT, // e.g. Szeged Start
STOP_RECEIPT, // e.g. Szeged Stop
FOOD_STAMP
FINE_PAYMENT, // e.g. Klaipeda
FOOD_STAMP,
FREE_TICKET
};
enum class COIN_PROCESSOR : quint8 {

View File

@@ -64,6 +64,12 @@ bool Ticket::initNew(TICKET_VARIANT ticketVariant, const QList<quint8> & templat
case TICKET_VARIANT::STOP_RECEIPT:
this->_templateList << 24 << 25 << 26;
break;
case TICKET_VARIANT::FINE_PAYMENT:
this->_templateList << 24 << 25 << 26;
break;
case TICKET_VARIANT::FREE_TICKET:
this->_templateList << 24 << 25 << 26;
break;
case TICKET_VARIANT::FOOD_STAMP:
if (printingData.contains("dyn1_list")) {
this->_hasTemplateDynData = true;
@@ -160,6 +166,9 @@ QDebug operator<<(QDebug debug, TICKET_VARIANT ticketVariant)
case TICKET_VARIANT::STOP_RECEIPT:
debug << "TICKET_VARIANT::STOP_RECEIPT";
break;
case TICKET_VARIANT::FINE_PAYMENT:
debug << "TICKET_VARIANT::FINE_PAYMENT";
break;
case TICKET_VARIANT::FOOD_STAMP:
debug << "TICKET_VARIANT::FOOD_STAMP";
break;