/** * Handler for infrastructure data * $Id$ * $HeadURL$ * $Author: * Created by hjl, SLSE, 2016-09-21 */ #include "handler_participant_event.h" #include #include "web_socket_server.h" #include "settings.h" #include #include #include #include using namespace ExerciseEventManagement; HandlerParticipantEvent::HandlerParticipantEvent(MainHandler *mainHandler, const std::shared_ptr &ddsHandler, const std::shared_ptr &db, const std::shared_ptr &eventServer) : m_ddsHandler(ddsHandler) , m_dbHandler(db) , m_eventServer(eventServer) , m_mainHandler(mainHandler) , m_logger(getLogger("HandlerParticipantEvent")) { } // end of ctor() //----------------------------------------------------------------------------- HandlerParticipantEvent::~HandlerParticipantEvent() { } // end of dtor() //----------------------------------------------------------------------------- bool HandlerParticipantEvent::init() { INFO_LOG(m_logger) << "start init() DTC CentralEffectSimulation "; // DTC CentralEffectSimulation m_cesDtc = CentralEffectSimulation::Interface::Dtc::create(m_ddsHandler->ddsConnector()); if (!m_cesDtc) { ERROR_LOG(m_logger) << "Could not create DTC CentralEffectSimulation"; return false; } // Subsribe for ParticipantEvent (for analyzing data) connect(m_cesDtc.get(), &CentralEffectSimulation::Interface::Dtc::participantEventChanged, this, &HandlerParticipantEvent::onParticipantEventChanged); if (!m_cesDtc->enableParticipantEvent() ) { ERROR_LOG(m_logger) << "init() DTC CentralEffectSimulation failed"; return false; } // DTC ProjectDataManagement m_pdmDtc = ProjectDataManagement::Interface::Dtc::create(m_ddsHandler->ddsConnector()); if (!m_pdmDtc) { ERROR_LOG(m_logger) << "Could not create DTC ProjectDataManagement"; return false; } m_pdmDtc->enableChargeType(); m_aesDtc = AreaEffectSimulation::Interface::Dtc::create(m_ddsHandler->ddsConnector()); m_aesDtc->enableAll(); connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::aesItemViewChanged, this, &HandlerParticipantEvent::onAesItemViewChanged); connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::explosionSingleChanged, this, &HandlerParticipantEvent::onExplosionSingleChanged); return true; } // end of init() //----------------------------------------------------------------------------- void HandlerParticipantEvent::onAesItemViewChanged(const AreaEffectSimulation::AesItemView &data, DataModification modType) { DEBUG_LOG(m_logger) << "AesItemId: " << data.aesItemId << ", effectState: " << data.effectStateId; Database::EemEvent eData = m_aesMap[data.id]; eData.sampleTime = data.effectStart; if (data.partyId.is_set()) eData.partyId = data.partyId.get(); switch(modType) { case DataModification::eAdded: m_itemViews.insert(data.aesItemId, data.aesTypeId); DEBUG_LOG(m_logger) << "eAdded: AesItemId: " << data.aesItemId << ", effectState: " << data.effectStateId; m_aesEffectState.insert(data.aesItemId, data.effectStateId); if (data.aesTypeId == AreaEffectSimulation::AesType::AtBorderline) { AreaEffectSimulation::AesItem aesItem; m_aesDtc->aesItemFromId(data.aesItemId, aesItem); QJsonObject obj; obj[QStringLiteral("AesId")] = QJsonValue(aesItem.id); obj[QStringLiteral("AesName")] = QJsonValue(QString::fromStdString(aesItem.name)); obj[QStringLiteral("AesType")] = QJsonValue(static_cast(data.aesTypeId)); eData.properties = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::Compact)); eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_Borderline; eData.position = LtsUtils::QPoint3D(data.boundingBoxBottomLeft.lon, data.boundingBoxBottomLeft.lat, 0.0); if (!m_dbHandler->db()->insert(eData)) ERROR_LOG(m_logger) << "Error while inserting event data from AES "; else publishData(eData); } break; case DataModification::eModified: { AreaEffectSimulation::AesEffectState effectState = m_aesEffectState.value(data.aesItemId); DEBUG_LOG(m_logger) << "eModified: AesItemId: " << data.aesItemId << ", effectState: " << data.effectStateId; DEBUG_LOG(m_logger) << "effectState: " << effectState; // insert event only once if (effectState != AreaEffectSimulation::AesEffectState::EsPrepared && (effectState == AreaEffectSimulation::AesEffectState::EsActivated && data.effectStateId != AreaEffectSimulation::AesEffectState::EsExpired)) return; INFO_LOG(m_logger) << "new/update event: aesId: " << data.aesItemId; m_aesEffectState.insert(data.aesItemId, data.effectStateId); m_itemViews.insert(data.aesItemId, data.aesTypeId); eData.position = LtsUtils::QPoint3D(data.boundingBoxBottomLeft.lon, data.boundingBoxBottomLeft.lat, 0.0); INFO_LOG(m_logger) << "aesType: " << data.aesTypeId; switch (data.aesTypeId) { case AreaEffectSimulation::AesType::AtMineArea: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_MineArea; break; case AreaEffectSimulation::AesType::AtExplosionArea: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_HitEffectSimulation; break; case AreaEffectSimulation::AesType::AtExplosionCluster: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_ExplosionCluster; break; case AreaEffectSimulation::AesType::AtMineAreaSingleMines: return; case AreaEffectSimulation::AesType::AtNContamination: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_NContamination; break; case AreaEffectSimulation::AesType::AtBCContamination: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_BCContamination; break; case AreaEffectSimulation::AesType::AtBorderline: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_Borderline; break; case AreaEffectSimulation::AesType::AtDangerArea: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_DangerArea; break; case AreaEffectSimulation::AesType::AtFunctionalArea: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_FunctionalArea; break; case AreaEffectSimulation::AesType::AtMineCorridor: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_MineCorridor; break; case AreaEffectSimulation::AesType::AtTechnicalArea: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_TechnicalArea; break; case AreaEffectSimulation::AesType::AtGasPipe: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_GasPipe; break; // No ExerciseEvent for AesType default: { INFO_LOG(m_logger) << "No ExerciseEvent for AesType:" << data.aesTypeId; return; } } AreaEffectSimulation::AesItem aesItem; m_aesDtc->aesItemFromId(data.aesItemId, aesItem); if (eData.eventTypeId == ProjectDataManagement::PdmEventType::EventType_ExplosionCluster) { ProjectDataManagement::GearClass gearClass = m_pdmDtc->gearClassFromChargeTypeId(aesItem.chargeStruct.chargeTypeId); if (gearClass == ProjectDataManagement::GearClass::GearClass_AirSupport) eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_AirSupport; } QJsonObject obj; obj[QStringLiteral("AesId")] = QJsonValue(aesItem.id); obj[QStringLiteral("AesName")] = QJsonValue(QString::fromStdString(aesItem.name)); obj[QStringLiteral("AesType")] = QJsonValue(static_cast(data.aesTypeId)); if (data.aesTypeId != AreaEffectSimulation::AesType::AtBorderline) { obj[QStringLiteral("duration")] = QJsonValue(aesItem.effectDuration); obj[QStringLiteral("ChargeTypeId")] = QJsonValue(data.chargeStruct.chargeTypeId); obj[QStringLiteral("endTime")] = QJsonValue(static_cast(data.effectStart + aesItem.effectDuration)); } eData.properties = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::Compact)); if (eData.id <= 0) { if (!m_dbHandler->db()->insert(eData)) { ERROR_LOG(m_logger) << "Error while inserting event data from AES "; break; } m_aesMap.insert(data.id, eData); } else { if (!m_dbHandler->db()->update(eData)) { ERROR_LOG(m_logger) << "Error while updating event data from AES "; break; } } publishData(eData); break; } case DataModification::eRemoved: { m_itemViews.remove(data.aesItemId); m_aesMap.remove(data.id); break; } } } //----------------------------------------------------------------------------- void HandlerParticipantEvent::onExplosionSingleChanged(const AreaEffectSimulation::ExplosionSingle &data, DataModification modType) { Database::EemEvent eData = m_aesMap[data.id]; if ( !data.effectStart.is_set()) { return; } eData.sampleTime = data.effectStart.get(); if (data.partyId.is_set()) eData.partyId = data.partyId.get(); switch(modType) { case DataModification::eAdded: m_aesEffectState.insert(data.id, data.effectStateId); break; case DataModification::eModified: { AreaEffectSimulation::AesEffectState effectState = m_aesEffectState.value(data.id); // insert event only once if (effectState != AreaEffectSimulation::AesEffectState::EsPrepared && (effectState == AreaEffectSimulation::AesEffectState::EsActivated && data.effectStateId != AreaEffectSimulation::AesEffectState::EsExpired)) return; m_aesEffectState.insert(data.id, data.effectStateId); //m_itemViews.insert(data.id(), data.aesTypeId()); eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_FireEvent; AreaEffectSimulation::AesItem aesItem; m_aesDtc->aesItemFromId(data.id, aesItem); QJsonObject obj; obj[QStringLiteral("AesId")] = QJsonValue(aesItem.id); obj[QStringLiteral("AesName")] = QJsonValue(QString::fromStdString(aesItem.name)); obj[QStringLiteral("AesType")] = QJsonValue(static_cast(AreaEffectSimulation::AesType::AtExplosionSingle)); obj[QStringLiteral("ChargeTypeId")] = QJsonValue(data.chargeStruct.chargeTypeId); obj[QStringLiteral("duration")] = QJsonValue(aesItem.effectDuration); obj[QStringLiteral("endTime")] = QJsonValue(static_cast(data.effectStart.get() + aesItem.effectDuration)); eData.properties = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::Compact)); //const Core::GeoPosition geoPosition ( data.impactPosition().lon(), data.impactPosition().lat(), 0); const LtsUtils::QPoint3D pos3D (data.impactPosition.lon, data.impactPosition.lat, 0); eData.position = pos3D; if (eData.id <= 0) { if (!m_dbHandler->db()->insert(eData)) { ERROR_LOG(m_logger) << "Error while inserting event data from AES "; break; } m_aesMap.insert(data.id, eData); } else { if (!m_dbHandler->db()->update(eData)) { ERROR_LOG(m_logger) << "Error while updating event data from AES "; break; } } publishData(eData); break; } default: DEBUG_LOG(m_logger) << "Nothing to do"; } } //----------------------------------------------------------------------------- void HandlerParticipantEvent::onParticipantEventChanged(const CentralEffectSimulation::ParticipantEvent &data, DataModification modType) { if (modType == DataModification::eRemoved) return; Database::EemEvent eData; eData.participantId = data.participantId; eData.equipmentNumber = data.equipmentNumber; eData.partyId = data.partyId; eData.sampleTime = data.eventTime; eData.position = LtsUtils::QPoint3D(data.position.lon, data.position.lat, data.position.z); DEBUG_LOG(m_logger) << " onParticipantEventChanged " << " position=" << data.position << " eData.position=" << eData.position; eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_Unknown; QJsonObject obj; obj[QStringLiteral("AesId")] = QJsonValue(data.aesItemId); obj[QStringLiteral("AesType")] = QJsonValue(static_cast(m_itemViews.value(data.aesItemId))); obj[QStringLiteral("AesName")] = QJsonValue(QString::fromStdString(data.aesName)); obj[QStringLiteral("FriendlyFire")] = QJsonValue(data.friendlyFire); switch(data.eventTypeId) { case ProjectDataManagement::PdmEventType::EventType_HitEffectSimulation: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_HitEffectSimulation; break; case ProjectDataManagement::PdmEventType::EventType_HitMine: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_HitMine; break; case ProjectDataManagement::PdmEventType::EventType_HitN: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_HitN; break; case ProjectDataManagement::PdmEventType::EventType_HitC: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_HitC; break; case ProjectDataManagement::PdmEventType::EventType_EnterDangerArea: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_EnterDangerArea; break; case ProjectDataManagement::PdmEventType::EventType_LeaveDangerArea: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_LeaveDangerArea; break; case ProjectDataManagement::PdmEventType::EventType_EnterMineArea: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_EnterMineArea; break; case ProjectDataManagement::PdmEventType::EventType_LeaveMineArea: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_LeaveMineArea; break; case ProjectDataManagement::PdmEventType::EventType_EnterNuclear: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_EnterNuclear; break; case ProjectDataManagement::PdmEventType::EventType_LeaveNuclear: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_LeaveNuclear; break; case ProjectDataManagement::PdmEventType::EventType_CrossLocalBorderline: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_CrossLocalBorderline; obj[QStringLiteral("Global")] = QJsonValue(false); break; case ProjectDataManagement::PdmEventType::EventType_CrossGlobalBorderline: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_CrossGlobalBorderline; obj[QStringLiteral("Global")] = QJsonValue(true); break; case ProjectDataManagement::PdmEventType::EventType_EnterFunctionalArea: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_EnterFunctionalArea; break; case ProjectDataManagement::PdmEventType::EventType_LeaveFunctionalArea: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_LeaveFunctionalArea; break; case ProjectDataManagement::PdmEventType::EventType_EnterHazardDistance: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_EnterHazardDistance; break; case ProjectDataManagement::PdmEventType::EventType_LeaveHazardDistance: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_LeaveHazardDistance; break; case ProjectDataManagement::PdmEventType::EventType_AirSupport: eData.eventTypeId = ProjectDataManagement::PdmEventType::EventType_AirSupport; break; default: return; } eData.properties = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::Compact)); if (!m_dbHandler->db()->insert(eData)) ERROR_LOG(m_logger) << "Error while inserting event data from CES "; else publishData(eData); } // end of onParticipantEventChanged() //----------------------------------------------------------------------------- void HandlerParticipantEvent::publishData(const Database::EemEvent &data) { m_eventServer->sendEvent(Database::toJson(data)); ExerciseEventManagement::Event ddsData = toDdsData(data); if (!m_ddsHandler->dts()->publish(ddsData)) ERROR_LOG(m_logger) << "Error publishing event-data to dds"; // take data from dds-bus after 10s, we need just to make sure the recording service got it m_mainHandler->addEventIdToRemove(ddsData.id); } ExerciseEventManagement::Event HandlerParticipantEvent::toDdsData(const Database::EemEvent &data) { ExerciseEventManagement::Event ddsData; ddsData.id = data.id; ddsData.sampleTime = data.sampleTime; ddsData.participantId = data.participantId; ddsData.partyId = data.partyId; ddsData.equipmentNumber = data.equipmentNumber; ddsData.eventTypeId = data.eventTypeId; ddsData.properties = data.properties.toStdString(); // Core::GeoPosition LtsUtils::QPoint3D Core::GeoPosition position(data.position.x(), data.position.y(),data.position.z()); ddsData.position = position; return ddsData; }