/** * Handler for message data request * $Id$ * $HeadURL$ * $Author$ * Created by hjl, SLSE, 2016-10-12 */ #include "handler_configure_alarms.h" #include "initialization.h" #include #include #include #include #include #include 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 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 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 participants; QSet 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