Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

@@ -0,0 +1,441 @@
/**
* @RDE_HEADER@
* Notifcation plugin for TAB connection states
* $Id$
* $HeadURL$
* $Author$
* Created by Philipp Dassow, SLST, 2017-09-19
*/
#include "nme_battery_info_dialog.h"
#include "nme_notification_gui_plugin.h"
#include "nme_shutdown_dialog.h"
#include <LtsSession/lts_session.h>
#include <LtsNotification/lts_notification.h>
#include <LtsWidgets/lts_base_layout_widget.h>
#include <QCoreApplication>
#include <QMessageBox>
#include <QPainter>
#include <QPixmap>
namespace NmeaManagement
{
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
{
return std::make_shared<InterfaceImpl>(session);
}
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
: GuiPluginBase::Interface(session, NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("NmeaGuiPlugin"))
, m_tabDtc(nullptr)
, m_tabFtc(nullptr)
, m_notiBattery(nullptr)
, m_notiOwnPosition(nullptr)
{
m_oudatedFirstBatteryTimer = new QTimer(this);
m_oudatedSecondBatteryTimer = new QTimer(this);
connect(m_oudatedFirstBatteryTimer, &QTimer::timeout, this,&InterfaceImpl::onOutdatedFirstBatteryTimerTimeout);
connect(m_oudatedSecondBatteryTimer, &QTimer::timeout, this,&InterfaceImpl::onOutdatedSecondBatteryTimerTimeout);
}
InterfaceImpl::~InterfaceImpl()
{
delete m_notiBattery;
delete m_notiOwnPosition;
}
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
{
QVector<LtsWidgets::PluginData> ret;
LtsWidgets::PluginData plData;
plData.menuGroup = menuGroup();
plData.menuText = tr("Shutdown Radio Master");
plData.identifier = QLatin1String("ShutdownRadioMaster");
plData.menuIcon = QIcon(QLatin1String("icon:application-exit.svg"));
plData.exercisePart = LtsWidgets::ExercisePart::eSpecial;
plData.directFunc = [this](const LtsWidgets::PluginData &)
{
NmeBatteryInfoDialog *batteryDialog = new NmeBatteryInfoDialog(m_currentBatteryStateForId, m_tabDtc, m_tabFtc);
m_session->addWidget(batteryDialog, menuGroup(), QStringLiteral("batteryInfo"), LtsWidgets::LayoutArea::eDialogTab);
};
if (m_notiBattery != nullptr /*|| m_notiOwnPosition != nullptr*/)
return QVector<LtsWidgets::PluginData>();
//TODO: Uncomment if necessary
// m_notiOwnPosition = m_session->createNotification(QStringLiteral("Show own position"));
// m_notiOwnPosition->setToolTip(tr("Show own position"));
// m_notiOwnPosition->setIcon(QIcon(QStringLiteral("icon:/position.svg")));
// m_notiOwnPosition->setAction([this](){
// //TODO: What to do if something like that happend
// });
m_notiBattery = m_session->createNotification(QStringLiteral("Radio Master Battery State"));
updateBatteryLevel();
m_notiBattery->setAction([this](){
NmeBatteryInfoDialog *batteryDialog = new NmeBatteryInfoDialog(m_currentBatteryStateForId, m_tabDtc, m_tabFtc);
m_session->addWidget(batteryDialog, menuGroup(), QStringLiteral("batteryInfo"), LtsWidgets::LayoutArea::eDialogTab);
});
//setToolTip();
// ret.append(plData);
return ret;
}
bool InterfaceImpl::fetchInterfaces()
{
//Dual Use while migrating from NmeaService to Nmea Tab Plugin
if (!m_session->getDtc<TrainingAreaBase::DataInterface>(m_tabDtc))
return false;
if (!m_session->getFtc<TrainingAreaBase::DataInterface>(m_tabFtc))
return false;
if(!m_tabDtc->enableBatteryInfo())
return false;
if(!m_tabDtc->enableBatteryAlarm())
return false;
if(!m_tabDtc->enableServiceControl())
return false;
if(!m_tabFtc->enableSetDevicePower())
return false;
connect(m_tabDtc.get(), &TrainingAreaBase::Interface::Dtc::batteryInfoChanged, this, &InterfaceImpl::onBatteryChanged);
connect(m_tabDtc.get(), &TrainingAreaBase::Interface::Dtc::serviceControlChanged, this, &InterfaceImpl::onShutdownStateChanged);
return true;
}
void InterfaceImpl::clearInterfaces()
{
disconnect(m_tabDtc.get(), &TrainingAreaBase::Interface::Dtc::batteryInfoChanged, this, &InterfaceImpl::onBatteryChanged);
disconnect(m_tabDtc.get(), &TrainingAreaBase::Interface::Dtc::serviceControlChanged, this, &InterfaceImpl::onShutdownStateChanged);
m_tabDtc = nullptr;
m_tabFtc = nullptr;
}
/*!
* \brief InterfaceImpl::onBatteryChanged
* \param data
* \param modType
* \details
* Receives Battery State and save them if changed
* Paints new Icon and set new tooltip
* If incoming BatteryState is under 2 (40%) and lower than last received state -> Show Warning
*/
void InterfaceImpl::onBatteryChanged(const TrainingAreaBase::BatteryInfo &dataArr, DataModification modType)
{
if(dataArr.equipmentNumber() != 1)
return;
auto data = dataArr.batteryStates().at(0);
switch (modType)
{
case DataModification::eAdded:
case DataModification::eModified:
{
if(m_hasConnection == false)
{
m_hasConnection = true;
if (m_session->baseLayout() != nullptr)
m_session->baseLayout()->showMessage(tr("The radio master is connected"), tr("Connection was successfully reestablished"), LtsWidgets::LtsNotificationBox::MessageType::Success);
}
if((data.batteryPercent() / 20) < m_currentBatteryStateForId.value(data.batteryPort()).batteryPercent() / 20 && data.batteryPercent() / 20 < 2)
{
QMessageBox batteryWarnBox;
batteryWarnBox.setWindowTitle(tr("Battery Warning"));
batteryWarnBox.setText(tr("The battery (%1) has only %2 \% left").arg(QString::fromStdString(data.serialNumber())).arg(data.batteryPercent())); //*20 = Real percentage
batteryWarnBox.exec();
}
m_currentBatteryStateForId.insert(data.batteryPort(), data);
updateBatteryLevel();
if(data.batteryPort() == 0)
m_oudatedFirstBatteryTimer->start(30000);
else if(data.batteryPort() == 1)
m_oudatedSecondBatteryTimer->start(30000);
break;
}
case DataModification::eRemoved:
{
m_currentBatteryStateForId.remove(data.batteryPort());
updateBatteryLevel();
break;
}
}
}
/*!
* \brief InterfaceImpl::onShutdownStateChanged
* \author Niklas Schmidt
* \param data
* \param modType
* \details
* Receives notification for the sthutdown state of RadioMaster
* Than show QMessageBox with shutdown state
*/
void InterfaceImpl::onShutdownStateChanged(const TrainingAreaBase::ServiceControl &data, DataModification modType)
{
if(data.equipmentNumber() != 1)
return;
switch (modType)
{
case DataModification::eAdded:
case DataModification::eModified:
{
if(data.serviceControlState().underlying() == TrainingAreaBase::ServiceControlEnum::STOP)
{
m_hasConnection = false;
if (m_session->baseLayout() != nullptr)
m_session->baseLayout()->showMessage(tr("The radio master is shut down"), tr("The batteries can be disconnected."), LtsWidgets::LtsNotificationBox::MessageType::Error);
}
//shutdownInfoBox.exec();
break;
}
case DataModification::eRemoved:
{
}
}
}
/*!
* \brief InterfaceImpl::onOutdatedFirstBatteryTimerTimeout
* \details
* Timeouted if no new incoming data is available
* Updates battery icon to unknown state
*/
void InterfaceImpl::onOutdatedFirstBatteryTimerTimeout()
{
//Default values for undefined state
if(m_currentBatteryStateForId.size() < 2)
{
m_notiBattery->setIcon(QPixmap::fromImage(renderBatteryImage()));
setToolTip();
m_currentBatteryStateForId.clear();
return;
}
m_notiBattery->setIcon(QPixmap::fromImage(renderBatteryImage(99, m_currentBatteryStateForId.value(1).batteryPercent() / 20)));
setToolTip(99, m_currentBatteryStateForId.value(1).batteryPercent() / 20);
m_currentBatteryStateForId.remove(0);
}
/*!
* \brief InterfaceImpl::onOutdatedSecondBatteryTimerTimeout
* \details
* Timeouted if no new incoming data is available
* Updates battery icon to unknown state
*/
void InterfaceImpl::onOutdatedSecondBatteryTimerTimeout()
{
if(m_currentBatteryStateForId.size() < 2)
{
m_notiBattery->setIcon(QPixmap::fromImage(renderBatteryImage()));
setToolTip();
m_currentBatteryStateForId.clear();
return;
}
//Default values for undefined state
m_notiBattery->setIcon(QPixmap::fromImage(renderBatteryImage(m_currentBatteryStateForId.value(0).batteryPercent() / 20, 99)));
setToolTip(m_currentBatteryStateForId.value(0).batteryPercent() / 20, 99);
m_currentBatteryStateForId.remove(1);
}
/*!
* \brief InterfaceImpl::setToolTip
* \param firstBattery
* \author Niklas Schmidt
* \param secondBattery
* \details Changes Tooltip for BatteryState Notification
*/
void InterfaceImpl::setToolTip(int firstBattery, int secondBattery)
{
QString tooltip;
if(firstBattery == 99)
tooltip = tr("First Battery Level: Unknown %1").arg(QStringLiteral("\n"));
else
tooltip = tr("First Battery Level: ") + QString::number(firstBattery * 20) + QStringLiteral("% \n");
if(secondBattery == 99)
tooltip += tr("Second Battery Level: Unknown");
else
tooltip += tr("Second Battery Level: ") + QString::number(secondBattery * 20) + QStringLiteral("%");
m_notiBattery->setToolTip(tooltip);
}
/*!
* \brief InterfaceImpl::renderBatteryImage
* \author Niklas Schmidt
* \param firstBatteryState
* \param secondBatteryState
* \details
* This method paints the icon for battery state
*
* Battery Unknown = Only Outline and Questionmark in middle
* Battery 0% = 5 Red Bars
* Battery 20% = 1 Red Bar
* Battery 40% = 2 Yellow Bar
* Battery 60% = 3 Green Bars
* Battery 80% = 4 Green Bras
* Battery 100% = 5 Green Bars
*
* BatteryState Int -> 0 = Empty ... 5 = Full | 99 = Unknown
* \return
*/
QImage InterfaceImpl::renderBatteryImage(int firstBatteryState, int secondBatteryState)
{
int firstBattery = firstBatteryState;
int secondBattery = secondBatteryState;
int size = 100;
QImage image(size, size, QImage::Format_ARGB32);
image.fill(Qt::transparent);
QPainter painter(&image);
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
if(firstBattery != 99)
{
painter.setBrush(QBrush(Qt::green, Qt::SolidPattern));
if(firstBattery < 3)
painter.setBrush(QBrush(Qt::yellow, Qt::SolidPattern));
if(firstBattery < 2)
painter.setBrush(QBrush(Qt::red, Qt::SolidPattern));
if(firstBattery == 0)
{
painter.setBrush(QBrush(Qt::red, Qt::SolidPattern));
firstBattery = 5; // To paint all 5 bars red
}
//For first battery (upper bar)
if (firstBattery > 0)
painter.drawRect(00, 00, 18, 40);
if (firstBattery > 1)
painter.drawRect(20, 00, 18, 40);
if (firstBattery > 2)
painter.drawRect(40, 00, 18, 40);
if (firstBattery > 3)
painter.drawRect(60, 00, 18, 40);
if (firstBattery > 4)
painter.drawRect(80, 00, 18, 40);
}
if(secondBattery != 99)
{
painter.setBrush(QBrush(Qt::green, Qt::SolidPattern));
if(secondBattery < 3)
painter.setBrush(QBrush(Qt::yellow, Qt::SolidPattern));
if(secondBattery < 2)
painter.setBrush(QBrush(Qt::red, Qt::SolidPattern));
if(secondBattery == 0)
{
painter.setBrush(QBrush(Qt::red, Qt::SolidPattern));
secondBattery = 5; // To paint all 5 bars red
}
//For second battery (lower bar)
if (secondBattery > 0)
painter.drawRect(00, 60, 18, 40);
if (secondBattery > 1)
painter.drawRect(20, 60, 18, 40);
if (secondBattery > 2)
painter.drawRect(40, 60, 18, 40);
if (secondBattery > 3)
painter.drawRect(60, 60, 18, 40);
if (secondBattery > 4)
painter.drawRect(80, 60, 18, 40);
}
QFont font = painter.font() ;
font.setPointSize(30);
painter.setFont(font);
painter.setBrush(QBrush(Qt::black, Qt::NoBrush));
if(firstBattery == 99) //If Unknown BatteryState
{
painter.setPen(Qt::black);
painter.drawText(45,35, QStringLiteral("?"));
}
// Draw Outline for whole Battery
painter.setPen(Qt::black);
painter.drawRect(00,00,100,40);
painter.setBrush(QBrush(Qt::black, Qt::NoBrush));
if(secondBattery == 99) //If Unknown BatteryState
{
painter.setPen(Qt::black);
painter.drawText(45,92, QStringLiteral("?"));
}
// Draw Outline for whole Battery
painter.setPen(Qt::black);
painter.drawRect(00,60,100,40);
// 'marking':
// painter.setPen(QPen(Qt::NoPen)); // rect with no outter line
painter.end();
return image;
}
/*!
* \brief InterfaceImpl::updateBatteryLevel
* \details Changes the icon of battery state and change Tooltip
*/
void InterfaceImpl::updateBatteryLevel()
{
if(!m_notiBattery)
return;
if(m_currentBatteryStateForId.isEmpty())
{
setToolTip();
m_notiBattery->setIcon(QPixmap::fromImage(renderBatteryImage()));
return;
}
int firstBatteryState = m_currentBatteryStateForId.value(0).batteryPercent() / 20;
int secondBatteryState = m_currentBatteryStateForId.value(1).batteryPercent() / 20;
if(m_currentBatteryStateForId.values().length() == 2)
{
setToolTip(firstBatteryState, secondBatteryState);
m_notiBattery->setIcon(QPixmap::fromImage(renderBatteryImage(firstBatteryState, secondBatteryState)));
}
else if(m_currentBatteryStateForId.values().length() == 1)
{
if(m_currentBatteryStateForId.first().batteryPort() == 0)
{
m_notiBattery->setIcon(QPixmap::fromImage(renderBatteryImage(firstBatteryState, 99)));
setToolTip(firstBatteryState, 99);
}
else if(m_currentBatteryStateForId.first().batteryPort() == 1)
{
m_notiBattery->setIcon(QPixmap::fromImage(renderBatteryImage(99,secondBatteryState)));
setToolTip(99,secondBatteryState);
}
}
}
} // namespace NmeaManagement