405 lines
16 KiB
C++
Executable File
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
|