Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+385
@@ -0,0 +1,385 @@
|
||||
/**
|
||||
* Handle the single building instances
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2017-02-06
|
||||
*/
|
||||
|
||||
#include "building_control_handler.h"
|
||||
#include "building_process.h"
|
||||
#include "main_handler.h"
|
||||
#include <QCoreApplication>
|
||||
#include <QStandardPaths>
|
||||
#include <QDateTime>
|
||||
|
||||
#include <ngldb/nsqlquery.h>
|
||||
|
||||
#include <Buildings/bld_record_replay_plugin.h>
|
||||
#include <AssetManagement/asm.hpp>
|
||||
|
||||
namespace Buildings
|
||||
{
|
||||
BuildingControlHandler::BuildingControlHandler(MainHandler *mainHandler)
|
||||
: QObject()
|
||||
, Interface::Fts::SetBuildingStatesRequestHandler(mainHandler->ddsHandler()->fts())
|
||||
, Interface::Fts::SetBuildingContaminationStateRequestHandler(mainHandler->ddsHandler()->fts())
|
||||
, Interface::Fts::SetFortifyFactorRequestHandler(mainHandler->ddsHandler()->fts())
|
||||
, Interface::Fts::SendCesHitOnBuildingRequestHandler(mainHandler->ddsHandler()->fts())
|
||||
, Interface::Fts::SendCesHit3DonBuildingRequestHandler(mainHandler->ddsHandler()->fts())
|
||||
, Interface::Fts::TriggerBsmFlashRequestHandler(mainHandler->ddsHandler()->fts())
|
||||
, Interface::Fts::SwitchRelayRequestHandler(mainHandler->ddsHandler()->fts())
|
||||
, m_mainHandler(mainHandler)
|
||||
, m_logger(getLogger("BuildingControlHandler"))
|
||||
{}
|
||||
|
||||
BuildingControlHandler::~BuildingControlHandler()
|
||||
{
|
||||
for (BuildingProcess *bldg : qAsConst(m_buildings))
|
||||
{
|
||||
bldg->shutdown();
|
||||
delete bldg;
|
||||
}
|
||||
m_buildings.clear();
|
||||
}
|
||||
|
||||
bool BuildingControlHandler::init()
|
||||
{
|
||||
DEBUG_LOG(m_logger)<<"BuildingControlHandler::init exerciseId="<<m_mainHandler->exerciseId();
|
||||
|
||||
const QString bcuName = QStringLiteral("BuildingControlUnit");
|
||||
m_bcuExecutableName = QStandardPaths::findExecutable(bcuName, { QCoreApplication::applicationDirPath()});
|
||||
if (m_bcuExecutableName.isEmpty())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Executable " << bcuName << " not found - can not start building control unit processes!";
|
||||
return false;
|
||||
}
|
||||
if (m_mainHandler->exerciseId() > 0)
|
||||
{
|
||||
// Initialize RecordReplay to get initial participantPosition
|
||||
RecordReplayPlugin recordReplay;
|
||||
// no ddsconnector - we don't want to publish data here
|
||||
recordReplay.initDtc(nullptr, m_mainHandler->exerciseId());
|
||||
|
||||
NSqlQuery q(m_mainHandler->db()->database());
|
||||
recordReplay.readHistoryStateAt(q, QDateTime::currentMSecsSinceEpoch());
|
||||
// key is sampleTime -> multiMap
|
||||
const QMultiMap<qint64, Buildings::HistoryState> latestStates = recordReplay.getHistoryStateMap();
|
||||
|
||||
DEBUG_LOG(m_logger) << "Starting to read HistoryStatedata from record replay. Size: "
|
||||
<< latestStates.size();
|
||||
for (auto it = latestStates.begin(); it != latestStates.end(); ++it)
|
||||
{
|
||||
const Buildings::HistoryState &historyState = it.value();
|
||||
if (!m_mainHandler->ismHandler()->isElementAssignedToExercise(historyState.mseId(),m_mainHandler->exerciseId() ))
|
||||
{
|
||||
DEBUG_LOG(m_logger)<<"[INIT] [recordReplay]>>>>>>> mseId=" << historyState.mseId() << " not in execise";
|
||||
continue;
|
||||
}
|
||||
m_historyStates.insert(historyState.mseId(), historyState);
|
||||
DEBUG_LOG(m_logger)<<"[INIT] [recordReplay]>>>>>>> "<<historyState;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void BuildingControlHandler::onBuildingRemoved(int buildingId)
|
||||
{
|
||||
auto it = m_buildings.find(buildingId);
|
||||
if (it == m_buildings.end())
|
||||
return;
|
||||
BuildingProcess *bldg = it.value();
|
||||
bldg->shutdown();
|
||||
bldg->deleteLater();
|
||||
m_buildings.erase(it);
|
||||
m_historyStates.remove(buildingId);
|
||||
}
|
||||
|
||||
void BuildingControlHandler::onBuildingChanged(const BuildingInfo &buildingInfo, bool damageInit = false)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onBuildingChanged damageInit=" << damageInit
|
||||
<< " mseId=" << buildingInfo.mseId;
|
||||
auto it = m_buildings.find(buildingInfo.mseId);
|
||||
BuildingProcess *bldg = nullptr;
|
||||
if (it == m_buildings.end())
|
||||
{
|
||||
bldg = new BuildingProcess(m_mainHandler,
|
||||
m_bcuExecutableName,
|
||||
buildingInfo,
|
||||
damageInit,
|
||||
this);
|
||||
DEBUG_LOG(m_logger) << "onBuildingChanged m_buildings.insert mseId=" << buildingInfo.mseId;
|
||||
m_buildings.insert(buildingInfo.mseId, bldg);
|
||||
bldg->newRelayInfos(m_relayInfos);
|
||||
bldg->start();
|
||||
}
|
||||
else
|
||||
{
|
||||
bldg = it.value();
|
||||
bldg->setBuildingInfo(buildingInfo);
|
||||
bldg->newRelayInfos(m_relayInfos);
|
||||
}
|
||||
Buildings::HistoryState historyState;
|
||||
if ( m_historyStates.contains(buildingInfo.mseId))
|
||||
{
|
||||
historyState = m_historyStates.value(buildingInfo.mseId);
|
||||
DEBUG_LOG(m_logger) << "onBuildingChanged setHistoryState contains historyState.mseId=" << historyState.mseId()
|
||||
<< " buildingInfo.mseId=" << buildingInfo.mseId;
|
||||
}
|
||||
else
|
||||
{
|
||||
historyState.mseId (buildingInfo.mseId);
|
||||
DEBUG_LOG(m_logger) << "onBuildingChanged setHistoryState insert historyState.mseId=" << historyState.mseId()
|
||||
<< " buildingInfo.mseId=" << buildingInfo.mseId;
|
||||
m_historyStates.insert(historyState.mseId(), historyState);
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "onBuildingChanged setHistoryState historyState.mseId=" << historyState.mseId()
|
||||
<< " buildingInfo.mseId=" << buildingInfo.mseId;
|
||||
bldg->setHistoryState(m_historyStates.value(buildingInfo.mseId));
|
||||
}
|
||||
|
||||
void BuildingControlHandler::onSetBuildingContaminationStateRequest(const rti::core::SampleIdentity &cookie,
|
||||
const SetBuildingContaminationStateRequest &request)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onSetBuildingContaminationStateRequest " << request;
|
||||
const Core::FunctionReplyObject fro = onSetBuildingContaminationStateRequestInternal(request);
|
||||
if (fro.error())
|
||||
WARNING_LOG(m_logger) << fro();
|
||||
m_mainHandler->ddsHandler()->fts()->setBuildingContaminationStateReply(cookie, fro);
|
||||
}
|
||||
|
||||
void BuildingControlHandler::onSetBuildingStatesRequest(const rti::core::SampleIdentity &cookie,
|
||||
const SetBuildingStatesRequest &request)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onSetBuildingStatesRequest " << request;
|
||||
const Core::FunctionReplyObject fro = onSetBuildingStatesRequestInternal(request);
|
||||
if (fro.error())
|
||||
WARNING_LOG(m_logger) << fro();
|
||||
m_mainHandler->ddsHandler()->fts()->setBuildingStatesReply(cookie, fro);
|
||||
}
|
||||
|
||||
void BuildingControlHandler::onSetFortifyFactorRequest(const rti::core::SampleIdentity &cookie,
|
||||
const SetFortifyFactorRequest &request)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onSetFortifyFactorRequest " << request;
|
||||
const Core::FunctionReplyObject fro = onSetFortifyFactorRequestInternal(request);
|
||||
if (fro.error())
|
||||
WARNING_LOG(m_logger) << fro();
|
||||
m_mainHandler->ddsHandler()->fts()->setFortifyFactorReply(cookie, fro);
|
||||
}
|
||||
|
||||
void BuildingControlHandler::onSendCesHitOnBuildingRequest(const rti::core::SampleIdentity &cookie,
|
||||
const SendCesHitOnBuildingRequest &request)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onSendCesHitOnBuildingRequest " << request;
|
||||
const Core::FunctionReplyObject fro = onSendCesHitOnBuildingRequestInternal(request);
|
||||
if (fro.error())
|
||||
WARNING_LOG(m_logger) << fro();
|
||||
m_mainHandler->ddsHandler()->fts()->sendCesHitOnBuildingReply(cookie, fro);
|
||||
}
|
||||
|
||||
void BuildingControlHandler::onSendCesHit3DonBuildingRequest(const rti::core::SampleIdentity &cookie, const SendCesHit3DonBuildingRequest &request)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onSendCesHit3DonBuildingRequest " << request;
|
||||
const Core::FunctionReplyObject fro = onSendCesHit3DonBuildingRequestInternal(request);
|
||||
if (fro.error())
|
||||
WARNING_LOG(m_logger) << fro();
|
||||
m_mainHandler->ddsHandler()->fts()->sendCesHit3DonBuildingReply(cookie, fro);
|
||||
}
|
||||
|
||||
void BuildingControlHandler::onTriggerBsmFlashRequest(const rti::core::SampleIdentity &cookie,
|
||||
const TriggerBsmFlashRequest &request)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onTriggerBsmFlashRequest " << request;
|
||||
const Core::FunctionReplyObject fro = onTriggerBsmFlashInternal(request);
|
||||
if (fro.error())
|
||||
WARNING_LOG(m_logger) << fro();
|
||||
m_mainHandler->ddsHandler()->fts()->triggerBsmFlashReply(cookie, fro);
|
||||
}
|
||||
|
||||
|
||||
Core::FunctionReplyObject BuildingControlHandler::onSetBuildingContaminationStateRequestInternal(const SetBuildingContaminationStateRequest &data)
|
||||
{
|
||||
|
||||
const auto it = m_buildings.find(data.buildingId());
|
||||
if (it == m_buildings.end())
|
||||
return Core::FunctionReplyObject(data.buildingId(), tr_lts("dds", "Building with id %1 not found.")).arg(data.buildingId());
|
||||
|
||||
BuildingProcess *bldg = it.value();
|
||||
if (!bldg->setContaminationState(data.buildingId(), data.contaminationState()))
|
||||
return Core::FunctionReplyObject(data.buildingId(), tr_lts("dds", "Can not send contamination state to building control process."));
|
||||
|
||||
return Core::FunctionReplyObject();
|
||||
}
|
||||
|
||||
Core::FunctionReplyObject BuildingControlHandler::onSetBuildingStatesRequestInternal(const SetBuildingStatesRequest &data)
|
||||
{
|
||||
std::vector<int> roomIds; // prefer std::vector here since building.roomIds() has also std::vector, so it´s easier
|
||||
for (const auto &building : data.buildings())
|
||||
{
|
||||
const auto it = m_buildings.find(building.buildingId());
|
||||
if (it == m_buildings.end())
|
||||
return Core::FunctionReplyObject(building.buildingId(), tr_lts("dds", "Building with id %1 not found.")).arg(building.buildingId());
|
||||
|
||||
BuildingProcess *bldg = it.value();
|
||||
|
||||
if (data.resetContamination().is_set())
|
||||
{
|
||||
if (data.resetContamination().get() && !bldg->resetContaminationState())
|
||||
return Core::FunctionReplyObject(building.buildingId(), tr_lts("dds", "reset contamination of building with id %1 failed.")).arg(building.buildingId());
|
||||
}
|
||||
|
||||
if (data.vulnerabilityState() == ProjectDataManagement::VulnerabilityState::NoChange)
|
||||
continue;
|
||||
|
||||
if (data.vulnerabilityState() != ProjectDataManagement::VulnerabilityState::CatastrophicKill &&
|
||||
data.vulnerabilityState() != ProjectDataManagement::VulnerabilityState::CombatReady )
|
||||
return Core::FunctionReplyObject(building.buildingId(), tr_lts("dds", "Building with id %1 not found.")).arg(building.buildingId());
|
||||
|
||||
if (building.roomIds().is_set())
|
||||
roomIds = building.roomIds().get();
|
||||
|
||||
if (!bldg->setVulnerabilityState(data.vulnerabilityState(), roomIds))
|
||||
return Core::FunctionReplyObject(building.buildingId(), tr_lts("dds", "Can not send vulnerability state to building control process."));
|
||||
}
|
||||
return Core::FunctionReplyObject();
|
||||
}
|
||||
|
||||
Core::FunctionReplyObject BuildingControlHandler::onSetFortifyFactorRequestInternal(const SetFortifyFactorRequest &data)
|
||||
{
|
||||
auto it = m_buildings.find(data.buildingId());
|
||||
if (it == m_buildings.end())
|
||||
return Core::FunctionReplyObject(data.buildingId(), tr_lts("dds", "Building with id %1 not found.")).arg(data.buildingId());
|
||||
|
||||
BuildingProcess *bldg = it.value();
|
||||
if (!bldg->setFortifyFactors(data.fortifyFactors()))
|
||||
return Core::FunctionReplyObject(data.buildingId(), tr_lts("dds", "Can not send fortify factors to building control process."));
|
||||
|
||||
return Core::FunctionReplyObject();
|
||||
}
|
||||
|
||||
void BuildingControlHandler::setEffectStates(const int buildingId, const int assetId, const QByteArray &properties)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "BuildingControlHandler::setEffectStates"
|
||||
<< " buildingId=" << buildingId
|
||||
<< " assetId=" << assetId
|
||||
<< " properties=" << properties;
|
||||
auto it = m_buildings.find(buildingId);
|
||||
if (it == m_buildings.end())
|
||||
return;
|
||||
|
||||
BuildingProcess *bldg = it.value();
|
||||
if (bldg)
|
||||
bldg->setEffectStates( assetId, properties);
|
||||
}
|
||||
|
||||
void BuildingControlHandler::onRelayInfoChanged(const AssetManagement::RelayInfo &info, const DataModification mod)
|
||||
{
|
||||
if (mod != DataModification::eRemoved)
|
||||
m_relayInfos.insert(info.id(), info);
|
||||
else
|
||||
m_relayInfos.remove(info.id());
|
||||
|
||||
for(auto *bldg : qAsConst(m_buildings))
|
||||
bldg->newRelayInfos(m_relayInfos);
|
||||
|
||||
}
|
||||
|
||||
Core::FunctionReplyObject BuildingControlHandler::onSendCesHitOnBuildingRequestInternal(const SendCesHitOnBuildingRequest &data)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onSendCesHitOnBuildingRequestInternal";
|
||||
auto it = m_buildings.find(data.buildingId());
|
||||
if (it == m_buildings.end())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onSendCesHitOnBuildingRequestInternal return";
|
||||
return Core::FunctionReplyObject(data.buildingId(), tr_lts("dds", "Building with id %1 not found.")).arg(data.buildingId());
|
||||
}
|
||||
|
||||
BuildingProcess *bldg = it.value();
|
||||
if (!bldg->sendCesHitOnBuilding(data.effectTime(), data.chargeTypeId(), data.destructiveFactor(), data.penetrationFactor(),
|
||||
data.aesId(), data.impactPosition(),
|
||||
QString::fromStdString(data.properties())))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onSendCesHitOnBuildingRequestInternal return Can not send ces hit to building control process";
|
||||
return Core::FunctionReplyObject(data.buildingId(), tr_lts("dds", "Can not send ces hit to building control process."));
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "FunctionReplyObject";
|
||||
return Core::FunctionReplyObject();
|
||||
}
|
||||
|
||||
Core::FunctionReplyObject BuildingControlHandler::onSendCesHit3DonBuildingRequestInternal(const SendCesHit3DonBuildingRequest &data)
|
||||
{
|
||||
|
||||
DEBUG_LOG(m_logger) << "onSendCesHit3DonBuildingRequestInternal";
|
||||
auto it = m_buildings.find(data.buildingId());
|
||||
if (it == m_buildings.end())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onSendCesHit3DonBuildingRequestInternal return";
|
||||
return Core::FunctionReplyObject(data.buildingId(), tr_lts("dds", "Building with id %1 not found.")).arg(data.buildingId());
|
||||
}
|
||||
|
||||
BuildingProcess *bldg = it.value();
|
||||
if (!bldg->sendCesHit3DonBuilding(data.effectTime(), data.chargeTypeId(), data.destructiveFactor(), data.penetrationFactor(),
|
||||
data.aesId(), data.impactPosition(), data.detonationLocation(), data.detonationDistance(),
|
||||
QString::fromStdString(data.properties())))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onSendCesHit3DonBuildingRequestInternal return Can not send ces hit to building control process";
|
||||
return Core::FunctionReplyObject(data.buildingId(), tr_lts("dds", "Can not send ces hit to building control process."));
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "FunctionReplyObject";
|
||||
return Core::FunctionReplyObject();
|
||||
}
|
||||
|
||||
Core::FunctionReplyObject BuildingControlHandler::onTriggerBsmFlashInternal(const TriggerBsmFlashRequest &data)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onTriggerBsmFlashInternal";
|
||||
|
||||
|
||||
{
|
||||
|
||||
auto it = m_buildings.find(data.buildingId());
|
||||
if (it == m_buildings.end())
|
||||
return Core::FunctionReplyObject(data.buildingId(), tr_lts("dds", "Building with id %1 not found.")).arg(data.buildingId());
|
||||
|
||||
BuildingProcess *bldg = it.value();
|
||||
BuildingInfo buildingInfo= bldg->buildingInfo();
|
||||
BsmInfo bsmInfo = buildingInfo.bsms.value(data.assetId());
|
||||
|
||||
DEBUG_LOG(m_logger) << " BuildingId=" << data.buildingId()
|
||||
<< " assetId=" << bsmInfo.assetId
|
||||
<< " hostname=" << bsmInfo.hostname;
|
||||
|
||||
if (!bldg->triggerFlashlight(data))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onTriggerBsmFlashInternal return Can not send trigger flashlight to building control process";
|
||||
return Core::FunctionReplyObject(data.buildingId(), tr_lts("dds", "Can not send trigger flashlight to building control process"));
|
||||
}
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "FunctionReplyObject";
|
||||
return Core::FunctionReplyObject();
|
||||
}
|
||||
|
||||
void BuildingControlHandler::onSwitchRelayRequest(const rti::core::SampleIdentity &cookie,
|
||||
const SwitchRelayRequest &request)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "SwitchRelayRequest " << request;
|
||||
// Request als Json-Telegramm an den entsprechenden Gebaeudeprozess wer websocket weiterleiten.
|
||||
const Core::FunctionReplyObject fro = onSwitchRelayInternal(request);
|
||||
if (fro.error())
|
||||
WARNING_LOG(m_logger) << fro();
|
||||
m_mainHandler->ddsHandler()->fts()->switchRelayReply(cookie, fro);
|
||||
}
|
||||
|
||||
Core::FunctionReplyObject BuildingControlHandler::onSwitchRelayInternal(const SwitchRelayRequest &data)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onSwitchRelayInternal " << data;
|
||||
auto it = m_buildings.find(data.buildingId());
|
||||
if (it == m_buildings.end())
|
||||
return Core::FunctionReplyObject(data.buildingId(), tr_lts("dds", "Building with id %1 not found.")).arg(data.buildingId());
|
||||
BuildingProcess *bldg = it.value();
|
||||
if (!bldg->switchRelay(data))
|
||||
return Core::FunctionReplyObject(data.buildingId(), tr_lts("dds", "Can not set relay to building control process."));
|
||||
return Core::FunctionReplyObject();
|
||||
}
|
||||
|
||||
} // namespace Buildings
|
||||
Reference in new issue
Block a user