Files
qt5-legatus-legacy/Lts/Services/EffectShowClient/control_unit_handler.cpp
T
2026-08-13 18:33:10 +02:00

293 lines
8.7 KiB
C++
Executable File

/**
* Controler interface for the DMF vehicle terminal
* $Id$
* $HeadURL$
* $Author$
* Created by Florian Schult, NLSE, 2018-06-06
*/
#include "control_unit_handler.h"
#include "connection_handler.h"
namespace EffectShowClient
{
ControlUnitHandler::ControlUnitHandler(QObject *parent)
: QObject(parent)
, m_connectionHandler(new ConnectionHandler(this))
, m_timer(new QTimer(this))
, m_feature(EffectShowManagement::Feature_e::NotSpecified)
, m_logger(getLogger("ControlUnitHandler"))
{
m_timer->setInterval(10000);
connect(m_timer, &QTimer::timeout, this, &ControlUnitHandler::onConnectedToSerialConveter);
m_timer->start();
}
ControlUnitHandler::~ControlUnitHandler()
{
delete m_connectionHandler;
}
bool ControlUnitHandler::init()
{
if (!m_connectionHandler->init())
{
DEBUG_LOG(m_logger) << "Could not init ConnectionHandler";
return false;
}
connect(m_connectionHandler, &ConnectionHandler::received, this, &ControlUnitHandler::onDataReceived);
connect(m_connectionHandler, &ConnectionHandler::connectedToSerialConverter, this, &ControlUnitHandler::onConnectedToSerialConveter);
connect(m_connectionHandler, &ConnectionHandler::connectedToSerialConverter, this, &ControlUnitHandler::vehicleConnected);
connect(m_connectionHandler, &ConnectionHandler::disconnectedFromSerialConverter, this, &ControlUnitHandler::onDisconnectedFromSerialConveter);
send(CommandSignal::FT_SE_CB_FZRSTYP);
return true;
}
bool ControlUnitHandler::send(const CommandSignal command, const unsigned int roundCount)
{
unsigned int commandByte = 0;
// Check and use input
switch (command)
{
case CommandSignal::FT_SE_CB_WERFER_STATUS:
{
if (roundCount <= 48)
commandByte = command + roundCount;
else
{
DEBUG_LOG(m_logger) << "Bad round count for command FT_SE_CB_WERFER_STATUS";
return false;
}
break;
}
case CommandSignal::FT_SE_CB_WERFER_MUNITION:
{
if (roundCount <= 48)
commandByte = command + roundCount;
else
{
DEBUG_LOG(m_logger) << "Bad round count for command FT_SE_CB_WERFER_MUNITION";
return false;
}
break;
}
default:
{
commandByte = command;
break;
}
}
DEBUG_LOG(m_logger) << "Sending int/byte to connectionHandler: " << commandByte << QString::number(commandByte, 2); // todorm
// emit sending(QString(QStringLiteral("%1 - %2")).arg(QString::number(commandByte, 2).rightJustified(8, QLatin1Char('0'))).arg(commandByte));
QByteArray data;
data.append(commandByte & 0xFF);
data.resize(1);
// emit hasWarnings();
return m_connectionHandler->send(data);
}
void ControlUnitHandler::onDataReceived(const QByteArray &ba)
{
if (ba.size() >= 1)
{
TRACE_LOG(m_logger) << "ControlUnitHandler::onDataReceived ba.at(0) " << (ba.at(0));
TRACE_LOG(m_logger) << "ControlUnitHandler::onDataReceived ba.at(0) & 0xFF " << (ba.at(0) & 0xFF);
}
else
{
DEBUG_LOG(m_logger) << "ControlUnitHandler::onDataReceived ba is empty";
return;
}
if (ba.size() >= 2)
{
TRACE_LOG(m_logger) << "ControlUnitHandler::onDataReceived ba.at(1) " << (ba.at(1));
TRACE_LOG(m_logger) << "ControlUnitHandler::onDataReceived ba.at(1) & 0xFF " << (ba.at(1) & 0xFF);
}
const unsigned int data = ba.at(0);
if (data >= SE_FT_CB_WERFER_MUNITION && data < 93)
{
DEBUG_LOG(m_logger) << "ControlUnitHandler::SE_FT_CB_WERFER_MUNITION: " << data;
DEBUG_LOG(m_logger) << "ControlUnitHandler::SE_FT_CB_WERFER_MUNITION real: " << data - SE_FT_CB_WERFER_MUNITION;
emit vehicleRoundCount(data - SE_FT_CB_WERFER_MUNITION);
return;
}
// todo catch exception SE_FT_CB_WERFER_MUNITION, it does not have any payload... ->
// What a shitty design... seriously :/
/*
* variable 'byte' has 32 bits: XXXX XXXX XXXX XXXX
* command part: XXXX XXXX
* payload: XXXX XXXX
*
* we copy the left 8 bit to a new variable 'commandByte' to check it against
* our defined ReturningSignals enum.
*/
TRACE_LOG(m_logger) << "ControlUnitHandler::onDataReceived ba " << ba;
const unsigned int commandByte = ba.at(0) & 0xFF;
TRACE_LOG(m_logger) << "ControlUnitHandler::onDataReceived byte " << commandByte;
const unsigned int byte = ba.at(1) & 0xFF;
TRACE_LOG(m_logger) << "ControlUnitHandler::onDataReceived cmdbyte" << byte;
TRACE_LOG(m_logger) << "onDataReceived byte: " << byte << " commandByte: " << commandByte;
switch (commandByte)
{
case ReturningSignal::SE_FT_CB_SCHALTER_STATUS:
{
SafetyStatus sst;
sst.loadingBoardWall = !(byte & BIT_POSITION_3);
// sst.loadingBoardWall = byte & BIT_POSITION_3;
if (m_feature != EffectShowManagement::Feature_e::Smoke)
sst.loadingBoardWall = false;
sst.safetyWarning = byte & BIT_POSITION_4;
sst.temperaturWarning = byte & BIT_POSITION_5;
sst.emergencyStop = byte & BIT_POSITION_6;
sst.safetyOn = byte & BIT_POSITION_7;
if (sst.safetyOn && !sst.safetyWarning && !sst.temperaturWarning && !sst.emergencyStop)
emit safetyStatus(SafetyConfirmation_e::SafetyConfirmed);
else if (sst.safetyWarning && !sst.temperaturWarning && !sst.emergencyStop)
emit safetyStatus(SafetyConfirmation_e::SafetyExpiring);
else
emit safetyStatus(SafetyConfirmation_e::SafetyNotConfirmed);
DEBUG_LOG(m_logger) << "safety warning ";
emit safetyWarnings(sst);
break;
}
case ReturningSignal::SE_FT_CB_FZRSTYP:
{
if (byte & BIT_POSITION_5)
m_feature = EffectShowManagement::Feature_e::Explosion24;
else if (byte & BIT_POSITION_6)
m_feature = EffectShowManagement::Feature_e::Explosion48;
else if (byte & BIT_POSITION_7)
m_feature = EffectShowManagement::Feature_e::Smoke;
else
m_feature = EffectShowManagement::Feature_e::NotSpecified;
DEBUG_LOG(m_logger) << "Got Vehicle Type " << m_feature;
emit vehicleType(m_feature);
break;
}
case ReturningSignal::SE_FT_CB_ERROR_STATUS: //tne fehler
{
CardRidges scr;
scr.cardrige1 = byte & BIT_POSITION_7;
scr.cardrige2 = byte & BIT_POSITION_6;
scr.cardrige3 = byte & BIT_POSITION_5;
scr.cardrige4 = byte & BIT_POSITION_4;
scr.cardrige5 = byte & BIT_POSITION_3;
DEBUG_LOG(m_logger) << " CB STATUS FEUER " << byte;
emit vehicleErrorStatus(scr);
break;
}
case ReturningSignal::SE_FT_CB_UBATT: // Followed by 0-255 = 0V - 51V | dez * 0,2 = V
{
emit vehicleBattery((double)byte * 0.2);
break;
}
case ReturningSignal::SE_FT_CB_WERFER_STATUS:
{
CardRidges scr;
scr.cardrige1 = byte & BIT_POSITION_7;
scr.cardrige2 = byte & BIT_POSITION_6;
scr.cardrige3 = byte & BIT_POSITION_5;
scr.cardrige4 = byte & BIT_POSITION_4;
scr.cardrige5 = byte & BIT_POSITION_3;
//emit vehicleSmokeCardridgesStatus(scr);
DEBUG_LOG(m_logger) << " WERFER STATUS ";
emit vehicleFireUnits(scr);
break;
}
case ReturningSignal::SE_FT_CB_NK_STATUS:
{
CardRidges scr;
scr.cardrige1 = byte & BIT_POSITION_7;
scr.cardrige2 = byte & BIT_POSITION_6;
scr.cardrige3 = byte & BIT_POSITION_5;
scr.cardrige4 = byte & BIT_POSITION_4;
scr.cardrige5 = byte & BIT_POSITION_3;
DEBUG_LOG(m_logger) << " NB STATUS ";
emit vehicleSmokeCardridgesStatus(scr);
break;
}
case ReturningSignal::SE_FT_CB_NK_ZUENDUNGS_STATUS:
{
CardRidges scr;
scr.cardrige1 = byte & BIT_POSITION_7;
scr.cardrige2 = byte & BIT_POSITION_6;
scr.cardrige3 = byte & BIT_POSITION_5;
scr.cardrige4 = byte & BIT_POSITION_4;
scr.cardrige5 = byte & BIT_POSITION_3;
emit vehicleSmokeCardridgesFireStatus(scr);
break;
}
case ReturningSignal::SE_FT_CB_RECHNER_BEENDEN:
{
emit vehicleShutDown();
break;
}
case ReturningSignal::SE_FT_CB_SALVE_ERLEDIGT:
{
DEBUG_LOG(m_logger) << "Volley Done";
emit vehicleFinshedVolley(byte);
break;
}
case ReturningSignal::SE_FT_CB_SALVE_UNTERBROCHEN:
{
DEBUG_LOG(m_logger) << "Volley Stopped!!";
emit vehicleStoppedVolley(byte);
//add error to ui
CardRidges scr;
scr.cardrige2 = true;
emit vehicleErrorStatus(scr);
break;
}
case ReturningSignal::SE_FT_CB_SICHERHEIT_WIDERRUFEN:
{
DEBUG_LOG(m_logger) << "Sicherheit widerrufen!!";
emit vehicleSafetyRevoked();
break;
}
default:
{
DEBUG_LOG(m_logger) << "onDataReceived switch default";
break;
}
}
TRACE_LOG(m_logger) << "end of onDataReceived";
}
void ControlUnitHandler::onConnectedToSerialConveter()
{
DEBUG_LOG(m_logger) << "Send Type Request";
send(CommandSignal::FT_SE_CB_FZRSTYP);
}
void ControlUnitHandler::onDisconnectedFromSerialConveter()
{
m_feature = EffectShowManagement::Feature_e::NotSpecified;
emit vehicleType(m_feature);
emit vehicleStoppedVolley(0); //abbort fire just in case
}
} // namespace EffectShowClient