Add class DeviceControllerDiag to supervise DeviceController state
This commit is contained in:
parent
8fc88662d3
commit
6a19fd7608
@ -71,6 +71,7 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
||||
HEADERS += \
|
||||
include/interfaces.h \
|
||||
src/ATBAPP/ATBAPPplugin.h \
|
||||
src/ATBAPP/DeviceControllerDiag.h \
|
||||
src/ATBAPP/DeviceControllerInterface.h \
|
||||
src/ATBAPP/ATBHealthEvent.h \
|
||||
src/ATBAPP/ATBMachineEvent.h \
|
||||
@ -81,6 +82,7 @@ SOURCES += \
|
||||
src/ATBAPP/ATBHealthEvent.cpp \
|
||||
src/ATBAPP/ATBMachineEvent.cpp \
|
||||
src/ATBAPP/ATBDeviceControllerPlugin.cpp \
|
||||
src/ATBAPP/DeviceControllerDiag.cpp \
|
||||
src/ATBAPP/Utils.cpp
|
||||
|
||||
DISTFILES += \
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
#include "src/ATBAPP/DeviceControllerInterface.h"
|
||||
#include "src/ATBAPP/ATBAPPplugin.h"
|
||||
#include "src/ATBAPP/DeviceControllerDiag.h"
|
||||
|
||||
#include "version.h"
|
||||
|
||||
|
||||
@ -94,6 +96,9 @@ private:
|
||||
|
||||
hwinf* hw;
|
||||
|
||||
DeviceControllerDiag* diag;
|
||||
|
||||
|
||||
QTextCodec *codec;
|
||||
|
||||
bool private_loadCashAgentLib(QString pluginName);
|
||||
|
373
src/ATBAPP/DeviceControllerDiag.cpp
Normal file
373
src/ATBAPP/DeviceControllerDiag.cpp
Normal file
@ -0,0 +1,373 @@
|
||||
#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) {
|
||||
QTimer::singleShot(200, this, &DeviceControllerDiag::sys_superviseSystem);
|
||||
}
|
||||
else {
|
||||
qCritical() << "DeviceControllerDiag::private_startDiag() DCdata is not valid";
|
||||
|
||||
|
||||
this->private_finishedDiag(0xfe);
|
||||
|
||||
// try it again
|
||||
// -> this results in a seg. fault after ~10 loops!
|
||||
//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=0;
|
||||
struct T_moduleCondition *modCond=0;
|
||||
|
||||
// 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);
|
||||
|
||||
if (!modCond->allModulesChecked)
|
||||
{
|
||||
// noch keine Testergebnisse
|
||||
if (dynMaCond->startupTestIsRunning) {
|
||||
// TODO?
|
||||
}
|
||||
|
||||
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(0xFE);
|
||||
return;
|
||||
}
|
||||
|
||||
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=0;
|
||||
hw->sys_getDeviceConditions(modCond);
|
||||
|
||||
struct T_dynamicCondition *dynMaCond=0;
|
||||
hw->sys_getDynMachineConditions(dynMaCond);
|
||||
|
||||
struct T_devices *devPara=0;
|
||||
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
|
Loading…
Reference in New Issue
Block a user