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

405 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 "initialization.h"
#include <QJsonObject>
#include <QJsonDocument>
#include <QSet>
#include <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.underlying();
if ((operatorId == i.value().operatorId)
&& (participantId == i.value().participantId)
&& (eventTypeId == ProjectDataManagement::EventType_def::Unknown || eventTypeId == i.value().eventTypeId.underlying()))
{
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 = request.alarms()[0].eventTypeId().underlying();
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 : qAsConst(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().underlying()) ||
(alarm.eventTypeId == ProjectDataManagement::EventType_def::FriendlyFire && friendlyFireBool))
{
if (friendlyFireBool && eventDatalocal.eventTypeId() == ProjectDataManagement::EventType_def::FireEvent)
eventDatalocal.eventTypeId(ProjectDataManagement::EventType_def::FriendlyFire);
participants.clear();
if (alarm.participantId.isValid())
participants = m_mainHandler->hdlParticipant()->getRecursiveInferiorIds(alarm.participantId.toInt());
else
participants.append(0);
for (int participantId : qAsConst(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::EventType_def::CrossGlobalBorderline
|| eventData.eventTypeId() == ProjectDataManagement::EventType_def::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 == ProjectDataManagement::StateChangeOriginator_def::AreaEffectSimulation
|| originatorType == ProjectDataManagement::StateChangeOriginator_def::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());
}
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_def::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