Compare commits

..

7 Commits

Author SHA1 Message Date
b960638e91 Increase timeout for DcDataValid to 5s ...
... was: 20ms x  50 = 1000ms = 1s
    new: 20ms x 250 = 5000ms = 5s
2025-07-10 15:12:48 +02:00
d93b406040 Fix: Bill recocnition ...
... "datIf::case 112"
2025-04-01 14:06:49 +02:00
d5585cda3f Merge branch 'digitalOutputAbstraction' 2024-11-14 14:47:59 +01:00
2c09402bbb dCArun: Fix DigitalOutputAbstraction 2024-11-14 14:27:53 +01:00
cd6b1fed00 Remove CCWakelineAbstraction 2024-11-14 14:04:30 +01:00
0ea9ac9af3 dCArun: use DigitalOutputAbstraction 2024-11-14 14:03:13 +01:00
94a95eceb5 dCArun: add DigitalOutputAbstraction 2024-11-14 13:57:52 +01:00
10 changed files with 232 additions and 183 deletions

View File

@@ -1,7 +1,7 @@
#include "CArun.h" #include "CArun.h"
#include "datei.h" #include "datei.h"
#include "CCWakelineAbstraction.h" #include "DigitalOutputAbstraction.h"
CArun::CArun(QObject *parent) CArun::CArun(QObject *parent)
@@ -20,7 +20,11 @@ CArun::CArun(QObject *parent)
this->timerChainCtrl->start(); this->timerChainCtrl->start();
this->ccWakelineAbstraction = new CCWakelineAbstraction(this->HWaccess, this);
this->digitalOutputAbstraction = new DigitalOutputAbstraction(this->HWaccess, this);
this->digitalOutputAbstraction->addCCWake("/sys/class/leds/wakeupctrl_cc/brightness");
this->digitalOutputAbstraction->addCCPower("/run/powerctrl_cc");
this->digitalOutputAbstraction->addCCModem("/run/powerctrl_modem");
} }

View File

@@ -22,7 +22,7 @@ enum class SETUP_STEP {
}; };
class CCWakelineAbstraction; class DigitalOutputAbstraction;
class CArun : public QObject class CArun : public QObject
{ {
@@ -45,7 +45,7 @@ private:
void openSerialPort(); void openSerialPort();
CCWakelineAbstraction* ccWakelineAbstraction; DigitalOutputAbstraction* digitalOutputAbstraction;
signals: signals:

View File

@@ -1,51 +0,0 @@
#include <QFileSystemWatcher>
#include <QFile>
#include <QDebug>
#include "CCWakelineAbstraction.h"
#include "plugin.h"
/**
* this is based on a solution from:
* https://embeddeduse.com/2018/09/18/monitoring-sys-files-qfilesystemwatcher/
*
*/
CCWakelineAbstraction::CCWakelineAbstraction(hwinf *dc, QObject *parent)
: QObject(parent)
, dc(dc)
{
auto ccWakeMonitor = new QFileSystemWatcher(this);
ccWakeMonitor->addPath("/sys/class/leds/wakeupctrl_cc/brightness");
connect(ccWakeMonitor, &QFileSystemWatcher::fileChanged,
this, &CCWakelineAbstraction::ccWakeChanged);
qCritical() << "... init CCWakelineAbstraction";
}
void CCWakelineAbstraction::ccWakeChanged(const QString &path)
{
QFile ccWakeFile(path);
if (!ccWakeFile.open(QIODevice::ReadOnly)) {
qWarning() << "ERROR: Could not open ccWakeFile file.";
return;
}
auto ccWake = ccWakeFile.readAll();
if (!ccWake.isEmpty()) {
int state = ccWake.at(0);
//qCritical() << "INFO: ccWake = " << state;
switch (state) {
case 0x30: // '1'
qCritical() << "INFO: ccWake -> sleep";
this->dc->credit_switchWake(true); // switch 'sleep'
break;
case 0x31: // '0'
qCritical() << "INFO: ccWake -> wake";
this->dc->credit_switchWake(false); // switch 'wake'
break;
}
}
}

View File

@@ -1,25 +0,0 @@
#ifndef CCWAKELINEABSTRACTION_H
#define CCWAKELINEABSTRACTION_H
#include <QObject>
class hwinf;
class QFileSystemWatcher;
class CCWakelineAbstraction : public QObject
{
Q_OBJECT
public:
CCWakelineAbstraction(hwinf *dc, QObject *parent = nullptr);
private:
hwinf *dc;
QFileSystemWatcher *ccWakeMonitor;
void ccWakeChanged(const QString &path);
};
#endif // CCWAKELINEABSTRACTION_H

View File

@@ -0,0 +1,170 @@
#include <QFileSystemWatcher>
#include <QFile>
#include <QFileInfo>
#include <QTimer>
#include <QDebug>
#include "DigitalOutputAbstraction.h"
#include "plugin.h"
/**
* this is based on a solution from:
* https://embeddeduse.com/2018/09/18/monitoring-sys-files-qfilesystemwatcher/
*
*/
DigitalOutputAbstraction::DigitalOutputAbstraction(hwinf *dc, QObject *parent)
: QObject(parent)
, dc(dc)
{
this->fileMonitor = new QFileSystemWatcher(this);
connect(this->fileMonitor, &QFileSystemWatcher::fileChanged,
this, &DigitalOutputAbstraction::fileChanged);
qCritical() << "... init DigitalOutputAbstraction";
}
bool DigitalOutputAbstraction::addCCWake(const QString file)
{
// on PTU5: "/sys/class/leds/wakeupctrl_cc/brightness"
if (!QFileInfo::exists(file)) {
qCritical() << " ... create file: " << file;
QFile(file).open(QIODevice::ReadWrite | QIODevice::Text);
}
qCritical() << " ... add file: " << file;
this->ccWakePath = file;
return this->fileMonitor->addPath(file);
}
bool DigitalOutputAbstraction::addCCPower(const QString file)
{
if (!QFileInfo::exists(file)) {
qCritical() << " ... create file: " << file;
QFile(file).open(QIODevice::ReadWrite | QIODevice::Text);
}
qCritical() << " ... add file: " << file;
this->ccPowerPath = file;
return this->fileMonitor->addPath(file);
}
bool DigitalOutputAbstraction::addCCModem(const QString file)
{
if (!QFileInfo::exists(file)) {
qCritical() << " ... create file: " << file;
QFile(file).open(QIODevice::ReadWrite | QIODevice::Text);
}
qCritical() << " ... add file: " << file;
this->modemPowerPath = file;
return this->fileMonitor->addPath(file);
}
void DigitalOutputAbstraction::fileChanged(const QString &path)
{
if (path == this->ccPowerPath) this->private_ccPowerChanged();
if (path == this->ccWakePath) this->private_ccWakeChanged();
if (path == this->modemPowerPath) this->private_modemPowerChanged();
}
void DigitalOutputAbstraction::private_modemPowerChanged()
{
QFile modemPowerFile(this->modemPowerPath);
if (!modemPowerFile.open(QIODevice::ReadOnly)) {
qWarning() << "ERROR: Could not open modemPowerFile " << this->modemPowerPath;
return;
}
auto modemPower = modemPowerFile.readAll();
if (!modemPower.isEmpty()) {
int state = modemPower.at(0);
// qCritical() << "INFO: modemPower = " << state;
switch (state) {
case 0x30: // '0'
qCritical() << "INFO: modemPower -> off";
this->dc->mod_switchWake(false);
this->dc->mod_switchPower(false);
break;
case 0x31: // '1'
qCritical() << "INFO: modemPower -> on";
this->dc->mod_switchWake(true);
this->dc->mod_switchPower(true);
break;
}
}
}
void DigitalOutputAbstraction::private_ccPowerChanged()
{
QFile ccPowerFile(this->ccPowerPath);
if (!ccPowerFile.open(QIODevice::ReadOnly)) {
qWarning() << "ERROR: Could not open ccPowerFile file.";
return;
}
auto ccPower = ccPowerFile.readAll();
if (!ccPower.isEmpty()) {
int state = ccPower.at(0);
auto lambdaOn = [this]() -> void
{
this->dc->credit_switchPower(true);
this->dc->credit_switchWake(true);
};
auto lambdaOff = [this]() -> void
{
this->dc->credit_switchPower(false);
this->dc->credit_switchWake(false);
};
//qCritical() << "INFO: ccPower = " << state;
switch (state) {
case 0x30: // '0'
qCritical() << "INFO: ccPower -> off";
lambdaOff();
break;
case 0x31: // '1'
qCritical() << "INFO: ccPower -> on";
lambdaOn();
break;
case 0x32: // '2'
qCritical() << "INFO: ccPower -> on / off";
lambdaOff();
QTimer::singleShot(500, this, lambdaOn);
break;
}
}
}
void DigitalOutputAbstraction::private_ccWakeChanged()
{
QFile ccWakeFile(this->ccWakePath);
if (!ccWakeFile.open(QIODevice::ReadOnly)) {
qWarning() << "ERROR: Could not open ccWakeFile " << this->ccWakePath;
return;
}
auto ccWake = ccWakeFile.readAll();
if (!ccWake.isEmpty()) {
int state = ccWake.at(0);
//qCritical() << "INFO: ccWake = " << state;
switch (state) {
case 0x30: // '0'
qCritical() << "INFO: ccWake -> sleep";
this->dc->credit_switchWake(true); // switch 'sleep'
break;
case 0x31: // '1'
qCritical() << "INFO: ccWake -> wake";
this->dc->credit_switchWake(false); // switch 'wake'
break;
}
}
}

View File

@@ -0,0 +1,37 @@
#ifndef DIGITALOUTPUTABSTRACTION_H
#define DIGITALOUTPUTABSTRACTION_H
#include <QObject>
class hwinf;
class QFileSystemWatcher;
class DigitalOutputAbstraction : public QObject
{
Q_OBJECT
public:
DigitalOutputAbstraction(hwinf *dc, QObject *parent = nullptr);
bool addCCWake(const QString file);
bool addCCPower(const QString file);
bool addCCModem(const QString file);
private:
hwinf *dc;
QFileSystemWatcher *fileMonitor;
QString modemPowerPath;
QString ccPowerPath;
QString ccWakePath;
void fileChanged(const QString &path);
void private_modemPowerChanged();
void private_ccPowerChanged();
void private_ccWakeChanged();
};
#endif // DIGITALOUTPUTABSTRACTION_H

View File

@@ -40,14 +40,14 @@ DEFINES+=APP_EXTENDED_VERSION=\\\"$$EXTENDED_VERSION\\\"
SOURCES += \ SOURCES += \
CArun.cpp \ CArun.cpp \
CCWakelineAbstraction.cpp \ DigitalOutputAbstraction.cpp \
main.cpp \ main.cpp \
tslib.cpp \ tslib.cpp \
datei.cpp datei.cpp
HEADERS += \ HEADERS += \
CArun.h \ CArun.h \
CCWakelineAbstraction.h \ DigitalOutputAbstraction.h \
guidefs.h \ guidefs.h \
tslib.h \ tslib.h \
versionHistory.txt \ versionHistory.txt \

View File

@@ -63,8 +63,7 @@ V4.0 6.9.2023: activating DC-Bootloader in slve-lib (SM)
#include "shared_mem_buffer.h" #include "shared_mem_buffer.h"
#include "runProc.h" #include "runProc.h"
#include "interfaces.h" #include "interfaces.h"
#include <QScopedPointer>
#include <QFileSystemWatcher>
/* /*
* select Plugin Type here * select Plugin Type here
@@ -99,7 +98,7 @@ V4.0 6.9.2023: activating DC-Bootloader in slve-lib (SM)
//#define THIS_IS_CA_MASTER //#define THIS_IS_CA_MASTER
class QFileSystemWatcher;
class QSharedMemory; class QSharedMemory;
class DownloadThread; class DownloadThread;
class ReportingThread; class ReportingThread;
@@ -116,13 +115,7 @@ private:
QSharedMemory *m_sharedMem; QSharedMemory *m_sharedMem;
ReportingThread *m_reportingThread; ReportingThread *m_reportingThread;
DownloadThread *m_downloadThread; DownloadThread *m_downloadThread;
QScopedPointer<QFileSystemWatcher> m_fileSystemWatcher; //QTimer *hwapi_triggerBL;
QString m_powerctrl_cc;
QString m_powerctrl_modem;
private slots:
void onCCWakeGpioChanged(QString const &file);
public: public:
explicit hwapi(QObject *parent = nullptr); explicit hwapi(QObject *parent = nullptr);

View File

@@ -164,7 +164,7 @@ char T_datif::datif_cycleSend()
// supervise if DC data are valid // supervise if DC data are valid
datif_noResponseCtr++; // inc every 20ms datif_noResponseCtr++; // inc every 20ms
if (datif_noResponseCtr>50) // no life sign from device controller (DC) for about a sec if (datif_noResponseCtr>250) // no life sign from device controller (DC) for about 20ms x 250 = 5000ms = 5s
{ {
epi_resetDcDataValid(3); // DC data has not updated for >=5s -> no longer valid! epi_resetDcDataValid(3); // DC data has not updated for >=5s -> no longer valid!
datif_nowNewDyns=0; datif_nowNewDyns=0;
@@ -1204,11 +1204,10 @@ char T_datif::loadRecDataFromFrame()
uitmp=0; uitmp=0;
uit2=0; uit2=0;
} }
//if ((newInsertedAmount != lastInsertedAmount) || uit2>0 )
if (uit2==3 || uit2==5 || uit2==10 || uit2==20 || uit2==40 || uit2==50 || uit2==100 || uit2==200 || uit2==500) if ((newInsertedAmount != lastInsertedAmount) || uit2==3
{ || uit2==5 || uit2==10 || uit2==25 || uit2==40
// valid coin || uit2==50 || uit2==100 || uit2==200 || uit2==500 )
if ((newInsertedAmount != lastInsertedAmount) || uit2>0 )
{ {
gpi_storeCurrentPayment(newInsertedAmount, uitmp, uit2); gpi_storeCurrentPayment(newInsertedAmount, uitmp, uit2);
emit datif_gotNewCoin(); // OR BILL if (uitmp & 0x8000)>0 emit datif_gotNewCoin(); // OR BILL if (uitmp & 0x8000)>0
@@ -1216,7 +1215,6 @@ char T_datif::loadRecDataFromFrame()
lastInsertedAmount=newInsertedAmount; lastInsertedAmount=newInsertedAmount;
//qCritical()<<"datif 112 store and emit new coin "<<newInsertedAmount<<" "<<uitmp<<" "<<uit2; //qCritical()<<"datif 112 store and emit new coin "<<newInsertedAmount<<" "<<uitmp<<" "<<uit2;
} }
}
break; break;

View File

@@ -15,8 +15,6 @@
#include <cstring> #include <cstring>
#include <QThread> #include <QThread>
#include <QDebug> #include <QDebug>
#include <QFileSystemWatcher>
#include <QSettings>
static uint32_t hwapi_lastStartAmount; static uint32_t hwapi_lastStartAmount;
@@ -37,7 +35,6 @@ hwapi::hwapi(QObject *parent) : QObject(parent)
qCritical() << " hwapi::hwapi() APP_EXTENDED_VERSION:" << APP_EXTENDED_VERSION; qCritical() << " hwapi::hwapi() APP_EXTENDED_VERSION:" << APP_EXTENDED_VERSION;
qCritical() << "hwapi::hwapi() APP_EXTENDED_VERSION_LIB:" << APP_EXTENDED_VERSION_LIB; qCritical() << "hwapi::hwapi() APP_EXTENDED_VERSION_LIB:" << APP_EXTENDED_VERSION_LIB;
m_fileSystemWatcher.reset();
// create or attach shared memory segment // create or attach shared memory segment
m_sharedMem = SharedMem::getShm(sizeof(SharedMem)); m_sharedMem = SharedMem::getShm(sizeof(SharedMem));
@@ -59,26 +56,8 @@ hwapi::hwapi(QObject *parent) : QObject(parent)
#error "SLAVE LIB COMPILED INTO MASTER" #error "SLAVE LIB COMPILED INTO MASTER"
#endif #endif
QSettings settings("/opt/app/ATBAPP/ATBQT.ini", QSettings::IniFormat);
m_powerctrl_cc = settings.value("AsyncPOS_CCPlugin/terminal_watch_file",
"/run/powerctrl_cc").toString();
m_fileSystemWatcher.reset(new QFileSystemWatcher());
m_powerctrl_modem = "/run/powerctrl_modem";
m_fileSystemWatcher->addPath(m_powerctrl_modem);
if (!m_fileSystemWatcher->addPath(m_powerctrl_cc)) {
qCritical() << "cannot add path for" << m_powerctrl_cc;
} else {
if (connect(m_fileSystemWatcher.get(), SIGNAL(fileChanged(QString const&)),
this, SLOT(onCCWakeGpioChanged(QString const&)))) {
qCritical() << "connected file watcher with" << m_powerctrl_cc;
}
}
myDatif = new T_datif(this); // für die CAslave-Lib auskommentieren! myDatif = new T_datif(this); // für die CAslave-Lib auskommentieren!
#endif #endif
#ifdef THIS_IS_CA_SLAVE #ifdef THIS_IS_CA_SLAVE
@@ -141,62 +120,6 @@ hwapi::hwapi(QObject *parent) : QObject(parent)
connect(runProcess, SIGNAL(runProc_coinAttached()), this, SLOT(coinAttached())); connect(runProcess, SIGNAL(runProc_coinAttached()), this, SLOT(coinAttached()));
} }
void hwapi::onCCWakeGpioChanged(QString const &fileName) {
qCritical() << __func__ << ":" << __LINE__ << fileName;
if (fileName == m_powerctrl_cc) {
QFile f(m_powerctrl_cc);
if (f.exists() && f.open(QFile::ReadOnly | QFile::Text)) {
QTextStream stream(&f);
QString const &content = stream.readAll();
if (content.startsWith("0")) {
qCritical() << __func__ << ":" << __LINE__ << "switching cc-terminal off...";
credit_switchWake(false);
credit_switchPower(false);
} else
if (content.startsWith("1")) {
qCritical() << __func__ << ":" << __LINE__ << "switching cc-terminal on...";
credit_switchPower(true);
credit_switchWake(true);
} else
if (content.startsWith("2")) {
qCritical() << __func__ << ":" << __LINE__ << "switching cc-terminal off and on...";
credit_switchWake(false);
credit_switchPower(false);
QThread::sleep(1);
credit_switchPower(true);
credit_switchWake(true);
} else {
qCritical() << "switching cc-terminal watched file contained" << content;
QFile::resize(m_powerctrl_cc, 0); // empty file
}
}
}
else if (fileName == m_powerctrl_modem) {
QFile f(m_powerctrl_modem);
if (f.exists() && f.open(QFile::ReadOnly | QFile::Text)) {
QTextStream stream(&f);
QString const &content = stream.readAll();
if (content.startsWith("0")) {
qCritical() << __func__ << ":" << __LINE__ << "switching modem off...";
mod_switchWake(false);
mod_switchPower(false);
} else
if (content.startsWith("1")) {
qCritical() << __func__ << ":" << __LINE__ << "switching modem on...";
mod_switchWake(true);
mod_switchPower(true);
}
}
}
else {
qCritical() << "ERROR watching the wrong file" << fileName << m_powerctrl_cc;
}
}
void hwapi::hwapi_slotPayProc(void) void hwapi::hwapi_slotPayProc(void)
{ {