Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Services/AlarmManagement/handler_configure_alarms.cpp
T
2026-10-03 09:20:13 +02:00

406 lines
16 KiB
C++
Executable File

/**
* Handler for message data request
* $Id$
* $HeadURL$
* $Author$
* Created by hjl, SLSE, 2016-10-12
*/
#include "handler_configure_alarms.h"
#include <utility>
#include "initialization.h"
#include <QJsonObject>
#include <QJsonDocument>
#include <QtCore/QSet>
#include <QtCore/QTimer>
#include <ProjectDataManagement/pdm_translation.h>
#include <LtsUtilsCore/json_object.h>
namespace AlarmManagement
{
static AlarmConfig toDds(const Database::AlmConfig &data)
{
AlarmConfig almConfig;
almConfig.id = data.id;
almConfig.operatorId = data.operatorId;
if (data.participantId.isValid())
almConfig.participantId = data.participantId.toInt();
else
almConfig.participantId = 0;
almConfig.eventTypeId = data.eventTypeId;
almConfig.messageWindow = data.messageWindow;
almConfig.global = data.global;
almConfig.vulnerabilityState = data.vulnerabilityState;
almConfig.setMarker = data.setMarker;
return almConfig;
}
HandlerConfigureAlarms::HandlerConfigureAlarms(Initialization *mainHandler)
: QObject()
, ConfigureAlarmsRequestHandler(mainHandler->dds()->ftsAlm())
, m_mainHandler(mainHandler)
, m_logger(getLogger("HandlerConfigureAlarms"))
, m_windowIndex(0)
{
} // end of ctor()
//-----------------------------------------------------------------------------
HandlerConfigureAlarms::~HandlerConfigureAlarms()
{
} // end of dtor()
//-----------------------------------------------------------------------------
bool HandlerConfigureAlarms::init()
{
INFO_LOG(m_logger) << "Start HandlerConfigureAlarms.";
auto dtcEem = m_mainHandler->dds()->dtcEem();
connect(dtcEem.get(), &ExerciseEventManagement::Interface::Dtc::eventChanged,
this, &HandlerConfigureAlarms::onEventChanged);
// publish data from db-table 'alm_config'
auto cb = [this](const Database::AlmConfig & data)
{
DEBUG_LOG(m_logger) << "restore AlarmConfig from DB data: id=" << data.id
<< " operatorId=" << data.operatorId
<< " participantId=" << data.participantId.toInt()
<< " global=" << data.global
<< " eventTypeId=" << data.eventTypeId
<< " setMarker=" << data.setMarker
<< " messageWindow=" << data.messageWindow
<< " vulnerabilityState=" << data.vulnerabilityState;
m_mainHandler->dds()->dtsAlm()->publish(toDds(data));
m_alarms.insert(data.id, data);
};
if (!m_mainHandler->db()->select(cb))
{
ERROR_LOG(m_logger) << "Error reading data from database 'alm_config'!";
return false;
}
return true;
} // end init()
void HandlerConfigureAlarms::removeAlarmConfig(int operatorId,
int participantId,
int eventTypeId)
{
DEBUG_LOG(m_logger) << "removeAlarmConfig m_alarms.size=" << m_alarms.size()
<< " operatorId=" << operatorId
<< " participantId=" << participantId
<< " eventTypeId=" << eventTypeId;
// Find Key
QMapIterator<int, Database::AlmConfig> i(m_alarms);
while (i.hasNext())
{
i.next();
DEBUG_LOG(m_logger) << "key= " << i.key() << ": "
<< " operatorId=" << i.value().operatorId
<< " participantId=" << i.value().participantId.toInt()
<< " eventTypeId=" << i.value().eventTypeId;
if ((operatorId == i.value().operatorId)
&& (participantId == i.value().participantId)
&& (eventTypeId == static_cast<int>(ProjectDataManagement::PdmEventType::EventType_Unknown) || eventTypeId == static_cast<int>(i.value().eventTypeId)))
{
const int key = i.key();
DEBUG_LOG(m_logger) << "found alarm to remove: " << key << ", eventTypeId: " << eventTypeId;
m_mainHandler->db()->removeAlmConfig(key);
m_mainHandler->dds()->dtsAlm()->removeAlarmConfigByKey(key);
m_alarms.remove(key); // is ok, QMapIterator work on a copy
}
}
}
void HandlerConfigureAlarms::removeGlobalAlarmConfig(int operatorId)
{
DEBUG_LOG(m_logger) << "removeAlarmConfig m_alarms.size=" << m_alarms.size();
// Find Key
QMapIterator<int, Database::AlmConfig> i(m_alarms);
while (i.hasNext())
{
i.next();
DEBUG_LOG(m_logger) << "key= " << i.key()
<< " participantId=" << i.value().participantId.toInt();
if ((operatorId == i.value().operatorId)
&& (i.value().participantId.toInt()) == 0)
{
const int key = i.key();
DEBUG_LOG(m_logger) << "found alarm to remove: " << key;
m_mainHandler->db()->removeAlmConfig(key);
m_mainHandler->dds()->dtsAlm()->removeAlarmConfigByKey(key);
m_alarms.remove(key); // is ok, QMapIterator work on a copy
}
}
}
//-----------------------------------------------------------------------------
void HandlerConfigureAlarms::onConfigureAlarmsRequest(const rti::core::SampleIdentity &cookie,
const ConfigureAlarmsRequest &request)
{
DEBUG_LOG(m_logger) << "onConfigureAlarmsRequest " << request;
if (request.participantIds.size() == 0)
{
Core::FunctionReplyObject ret(0, tr_lts("dds", "Error adding ConfigureAlarms to database. There were no participants given."));
m_mainHandler->dds()->ftsAlm()->configureAlarmsReply(cookie, ret);
return;
}
if (request.remove)
{
// remove only this one Alarm, not all types of the participant for operator
// in DB,
// from DDS
DEBUG_LOG(m_logger) << "request.remove()";
if (request.participantIds.size() > 0 &&
request.alarms.size() > 0)
{
int participantId = request.participantIds[0];
int eventTypeId = static_cast<int>(request.alarms[0].eventTypeId);
DEBUG_LOG(m_logger) << "removeAlarmConfig(request.operatorId()=" << request.operatorId
<< " participantId=" << participantId
<< " eventTypeId=" << eventTypeId;
removeAlarmConfig(request.operatorId, participantId, eventTypeId);
}
}
else
{
// remove old configuration
for (int participantId : request.participantIds)
{
DEBUG_LOG(m_logger) << "remove old configuration participantId=" << participantId;
removeAlarmConfig(request.operatorId, participantId, 0);
}
if ( request.global)
{
removeGlobalAlarmConfig(request.operatorId);
}
for (int participantId : request.participantIds)
{
DEBUG_LOG(m_logger) << "participantId: " << participantId;
for (const AlarmManagement::AlarmAction &action : request.alarms)
{
DEBUG_LOG(m_logger) << "action: " << action;
AlarmManagement::AlarmConfig almConfig;
almConfig.operatorId = request.operatorId;
almConfig.participantId = participantId;
almConfig.eventTypeId = action.eventTypeId;
almConfig.messageWindow = action.messageWindow;
almConfig.vulnerabilityState = action.vulnerabilityState;
almConfig.setMarker = action.setMarker;
almConfig.global = request.global;
Database::AlmConfig newConfig;
newConfig.operatorId = request.operatorId;
if (participantId != 0)
newConfig.participantId = participantId;
newConfig.eventTypeId = action.eventTypeId;
newConfig.messageWindow = action.messageWindow;
newConfig.vulnerabilityState = action.vulnerabilityState;
newConfig.setMarker = action.setMarker;
newConfig.global = request.global;
if (!m_mainHandler->db()->insert(newConfig))
{
Core::FunctionReplyObject ret(0, tr_lts("dds", "Error adding ConfigureAlarms to database."));
m_mainHandler->dds()->ftsAlm()->configureAlarmsReply(cookie, ret);
}
DEBUG_LOG(m_logger) << "m_dbAlmConfig.insert id=" << newConfig.id;
almConfig.id = newConfig.id;
m_alarms.insert(newConfig.id, newConfig);
m_mainHandler->dds()->dtsAlm()->publish(almConfig);
}
}
}
m_mainHandler->dds()->ftsAlm()->configureAlarmsReply(cookie, Core::FunctionReplyObject());
} // end onConfigureAlarmsRequest()
//-----------------------------------------------------------------------------
void HandlerConfigureAlarms::onEventChanged(const ExerciseEventManagement::Event &eventData, DataModification modType)
{
DEBUG_LOG(m_logger) << "onParticipantEventChanged participantId=" << eventData.participantId;
if (modType == DataModification::eRemoved ||
modType == DataModification::eModified)
return;
DEBUG_LOG(m_logger) << "onParticipantEventChanged verarbeiten m_alarms.size =" << m_alarms.size();
ExerciseEventManagement::Event eventDatalocal = eventData;
QVector<int> participants;
QSet<int> sentEventToOperator;
// toBool() returns false if attribute does not exist
const QJsonObject eventObject = getEventProperties(eventDatalocal);
const bool friendlyFireBool = eventObject.value(QStringLiteral("FriendlyFire")).toBool();
const int vulnerabilityState = eventObject.value(QStringLiteral("vulnerabilityState")).toInt();
// Schleife ueber jede Konfiguration,
// pruefen, ob eventTypeId == EventTypeId
// Schleife ueber jeden Participant in der Konfiguration
// Vergleich Participant-ID Event mit Konfiguration Event
// Wenn ja, Alarm an operatorId schicken
for (const Database::AlmConfig &alarm : std::as_const(m_alarms))
{
{
/*DEBUG_LOG(m_logger) << " alarmConfigItem.id=" << alarm.id
<< " alarmConfigItem.participantId=" << alarm.participantId
<< " alarmConfigItem.eventTypeId=" << alarm.eventTypeId
<< " eventDatalocal.eventTypeId()=" << eventDatalocal.eventTypeId().underlying()
<< " alarm.operatorId=" << alarm.operatorId
<< " friendyFire =" << friendlyFireBool;*/
if ((alarm.eventTypeId == eventDatalocal.eventTypeId) ||
(alarm.eventTypeId == ProjectDataManagement::PdmEventType::EventType_FriendlyFire && friendlyFireBool))
{
if (friendlyFireBool && eventDatalocal.eventTypeId == ProjectDataManagement::PdmEventType::EventType_FireEvent)
eventDatalocal.eventTypeId = ProjectDataManagement::PdmEventType::EventType_FriendlyFire;
participants.clear();
if (alarm.participantId.isValid())
participants = m_mainHandler->hdlParticipant()->getRecursiveInferiorIds(alarm.participantId.toInt());
else
participants.append(0);
for (int participantId : std::as_const(participants))
{
bool allVulnerabilityStates = alarm.vulnerabilityState == -1;
bool vulnerabilityCheck = vulnerabilityState == alarm.vulnerabilityState;
bool globalAlarm = participantId == 0;
DEBUG_LOG(m_logger) << " allVulnerabilityStates=" << allVulnerabilityStates
<< " vulnerabilityCheck=" << vulnerabilityCheck
<< " participantId=" << participantId
<< " eventDatalocal.participantId=" << eventDatalocal.participantId;
if (((allVulnerabilityStates || vulnerabilityCheck) &&
(participantId == eventDatalocal.participantId)) || globalAlarm)
{
if (sentEventToOperator.contains(alarm.operatorId))
{
DEBUG_LOG(m_logger) << "Event " << eventDatalocal.eventTypeId << " already handled for Operator:" << alarm.operatorId;
continue;
}
sentEventToOperator += alarm.operatorId;
if (alarm.messageWindow)
{
DEBUG_LOG(m_logger) << "send Window to Operator:" << alarm.operatorId;
sendWindow(eventDatalocal, alarm);
}
if (alarm.setMarker)
{
DEBUG_LOG(m_logger) << "set Marker to Operator:" << alarm.operatorId;
sendMarker(eventDatalocal, alarm);
}
}
}
}
}
}
} // end onParticipantEventChanged
void HandlerConfigureAlarms::sendWindow(const ExerciseEventManagement::Event &eventData,
const Database::AlmConfig &config)
{
AlarmManagement::Notification wi;
QJsonObject eventObject = getEventProperties(eventData);
QJsonObject obj;
wi.id = m_windowIndex;
wi.operatorId = config.operatorId;
wi.time = eventData.sampleTime;
wi.eventId = eventData.id;
if (eventData.eventTypeId == ProjectDataManagement::PdmEventType::EventType_CrossGlobalBorderline
|| eventData.eventTypeId == ProjectDataManagement::PdmEventType::EventType_CrossLocalBorderline)
{
if (eventObject.contains(QStringLiteral("Global")))
obj[QStringLiteral("Global")] = eventObject.value(QStringLiteral("Global"));
}
if (eventObject.contains(QStringLiteral("FriendlyFire")))
obj[QStringLiteral("FriendlyFire")] = eventObject.value(QStringLiteral("FriendlyFire"));
if (eventObject.contains(QStringLiteral("AesId")))
wi.aesId = eventObject.value(QStringLiteral("AesId")).toInt();
// AesEvent from the radio:
int originatorType = eventObject[QStringLiteral("OriginatorType")].toInt();
if (originatorType == static_cast<int>(ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_AreaEffectSimulation)
|| originatorType == static_cast<int>(ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_FunctionalArea))
obj[QStringLiteral("aesId")] = eventObject[QStringLiteral("OriginatorId")].toInt();
wi.equipmentNumber = eventData.equipmentNumber;
wi.eventType = eventData.eventTypeId;
wi.participantId = eventData.participantId;
wi.position = eventData.position;
const QByteArray propertiesStr = QJsonDocument(obj).toJson(QJsonDocument::Compact);
wi.properties = propertiesStr.data();
m_mainHandler->dds()->dtsAlm()->publish(wi);
// take data from dds-bus after 1 min
const auto id = wi.id;
QTimer::singleShot(1 * 60 * 1000, this, [id, this]() { m_mainHandler->dds()->dtsAlm()->removeNotificationByKey(id); });
incrementWindowIndex(); // m_windowIndex++;
} // end sendWindow
QJsonObject HandlerConfigureAlarms::getEventProperties(const ExerciseEventManagement::Event &eventData)
{
return LtsUtils::JsonObject::fromJson(eventData.properties.c_str());
}
void HandlerConfigureAlarms::sendMarker(const ExerciseEventManagement::Event &eventData,
const Database::AlmConfig &config)
{
int defaultOffset = 10000;
DEBUG_LOG(m_logger) << "eventProperties =" << eventData.properties;
QString contentStr;
contentStr = QStringLiteral("Equip No.: ");
const int participantId = eventData.participantId;
const int equipNo = m_mainHandler->hdlParticipant()->participantId2EquipNo(participantId);
QJsonObject eventObject = getEventProperties(eventData);
contentStr += QString::number(equipNo);
contentStr += QStringLiteral(" ");
contentStr += ProjectDataManagement::toString(eventData.eventTypeId);
if (eventObject.contains(QStringLiteral("AesName")))
{
contentStr += QStringLiteral(" (");
contentStr += eventObject.value(QStringLiteral("AesName")).toString();
contentStr += QStringLiteral(")");
}
DEBUG_LOG(m_logger) << "contentStr=" << contentStr;
const QByteArray contentArr = contentStr.toUtf8();
MarkerManagement::MarkerDescription ma;
ma.content = contentArr.data();
ma.markerType = MarkerManagement::MarkerType::Situation;
MarkerManagement::Marker mcr;
mcr.operatorId = config.operatorId;
mcr.note = ma.content; // really?
mcr.timeStamp = eventData.sampleTime;
mcr.timeStampOffset = defaultOffset;
mcr.descriptions.push_back(ma);
mcr.position = eventData.position;
mcr.fileContentId = 0; // we cannot save an image here
m_mainHandler->dds()->ftcMrk()->markerModifyRequest(mcr, this);
} // end sendMarker
void HandlerConfigureAlarms::onMarkerModifyReply(const Core::FunctionReplyObject &replyObject)
{
Q_UNUSED(replyObject);
INFO_LOG(m_logger) << "************** onMarkerCreateReply";
} // end onMarkerCreateReply
} // namespace AlarmManagement