/** * Websocket C++ API for building control unit * $Id$ * $HeadURL$ * $Author$ * Created by Christian Ehrlicher, SLSE, 2017-01-30 */ #include "json_api.h" #include "web_socket_handler.h" #include "web_socket_telegrams.h" #include #include namespace BuildingControlUnit { namespace Json { Api::Api(QObject *parent) : QObject(parent) , m_webSocketHandler(new WebSocketHandler(this)) , m_logger(getLogger("Json.Api")) { connect(m_webSocketHandler, &WebSocketHandler::telegramReceived, this, &Api::onTelegramReceived); connect(m_webSocketHandler, &WebSocketHandler::webSocketConnected, this, &Api::webSocketConnected); } bool Api::init(quint16 listenPort) { return m_webSocketHandler->init(listenPort); } void Api::onHitResult(const HitResult &hitResult, const QMap &contaminationStates, bool playSound) { Q_UNUSED(playSound); sendHitResult(hitResult, contaminationStates, nullptr); } void Api::sendHitResult(const HitResult &hitResult, const QMap &contaminationStates, QWebSocket *ws) { Telegrams::HitResult tele; tele.timestamp = hitResult.effectTimeMSec; tele.hitResult.sensorId = hitResult.sensorId; tele.hitResult.originatorId = hitResult.originatorId; tele.hitResult.originatorType = hitResult.originatorType; tele.hitResult.chargeTypeId = hitResult.chargeTypeId; tele.hitResult.damagePercentOld = hitResult.damagePercentOld; tele.hitResult.damagePercentNew = hitResult.damagePercentNew; tele.hitResult.effectSoundId = hitResult.effectSoundId; tele.hitResult.damageState = hitResult.damageState; tele.hitResult.rooms.reserve(hitResult.rooms.size()); for (const HitRoom &hr : hitResult.rooms) { Telegrams::HitResult::HitRoomInfo hri; hri.roomId = hr.roomId; hri.damagePercent = hr.damagePercent; hri.remainingEffectPercent = hr.remainingEffectPercent; hri.fortifyFactor = hr.fortifyFactor; if (hr.directHit) tele.hitResult.hitOnRoomId = hr.roomId; tele.hitResult.rooms += hri; } for (const auto &cs : contaminationStates) { Telegrams::HitResult::ContaminationStateInfo csi; csi.aesId = cs.aesId; csi.rooms = cs.rooms; tele.hitResult.contaminations += csi; } DEBUG_LOG(m_logger) << LOGFUNCTION << ", tele = " << tele.toJson(); m_webSocketHandler->sendTelegram(&tele, ws); } void Api::onBsmState(const QVector &bsmStates) { sendBsmState(bsmStates, nullptr); } void Api::onRelayState(const RelayState &relayState) { sendRelayState(relayState.hostname, relayState.stateTime, relayState.offlineTime, relayState.relayStates, nullptr); } void Api::sendBsmState(const QVector &bsmStates, QWebSocket *ws) { Telegrams::BsmState tele; tele.timestamp = QDateTime::currentMSecsSinceEpoch(); tele.bsmStates.reserve(bsmStates.size()); Telegrams::BsmState::BsmStateInfo bsi; for (const BSM::BsmState &state : bsmStates) { bsi.connected = state.bConnected; bsi.hostname = state.hostname; bsi.id = state.id; bsi.port = state.port; bsi.versionInfo = state.versionInfo; tele.bsmStates += bsi; } m_webSocketHandler->sendTelegram(&tele, ws); } void Api::sendRelayState(const QString &segment, const qint64 stateTime, const qint64 offlineTime, const QVector &relayStates, QWebSocket *ws) { Telegrams::RelayState tele; tele.segment = segment; tele.stateTime = stateTime; tele.offlineTime = offlineTime; Telegrams::RelayState::RelayStateInfo rsi; for (const RelayStateInfo &state : relayStates) { rsi.id = state.id; rsi.state = state.state; tele.relayStates += rsi; } m_webSocketHandler->sendTelegram(&tele, ws); } void Api::sendEffectOverrides(const QString &segment, const qint64 stateTime, const qint64 offlineTime, const QVector &effectOverrides, QWebSocket *ws) { Telegrams::EffectOverride tele; tele.segment = segment; tele.stateTime = stateTime; tele.offlineTime = offlineTime; Telegrams::EffectOverride::OverrideInfo rsi; for (const BcuEffectState &state : effectOverrides) { rsi.id = state.id; rsi.effectOverride = state.effectOverride; tele.overrides += rsi; } m_webSocketHandler->sendTelegram(&tele, ws); } void Api::onTelegramReceived(const std::shared_ptr &tele) { DEBUG_LOG(m_logger) << "tele->telegramId(): " << tele->telegramId(); if (tele->telegramId() == Telegrams::SetDamageState::telegramId()) { Telegrams::SetDamageState *sds = static_cast(tele.get()); emit damageStateRequest(sds->originatorId, sds->damageState, sds->roomIds); return; } if (tele->telegramId() == Telegrams::ResetContaminationState::telegramId()) { emit resetContaminationRequest(); return; } if (tele->telegramId() == Telegrams::SetContaminationState::telegramId()) { Telegrams::SetContaminationState *scs = static_cast (tele.get()); emit setContaminationStateRequest(scs->contaminationStates); return; } if (tele->telegramId() == Telegrams::SetEffectStates::telegramId()) { Telegrams::SetEffectStates *sff = static_cast(tele.get()); QVector val; val.reserve(sff->effectStates.size()); for(const auto &fi : qAsConst(sff->effectStates)) { BcuEffectState ff; ff.id = fi.id; ff.type = fi.type; ff.effectOverride = fi.effectOverride; val += ff; } emit setEffectStatesRequest(sff->segment, val); return; } if (tele->telegramId() == Telegrams::SwitchRelay::telegramId()) { Telegrams::SwitchRelay *sff = static_cast(tele.get()); emit switchRelayRequest(sff->segment, sff->switchRelayValues); return; } if (tele->telegramId() == Telegrams::SetFortifyFactor::telegramId()) { Telegrams::SetFortifyFactor *sff = static_cast(tele.get()); QVector val; val.reserve(sff->fortifyFactors.size()); for(const auto &fi : qAsConst(sff->fortifyFactors)) { FortifyInfo ff; ff.roomId = fi.roomId; ff.fortifyFactor = fi.fortifyFactor; val += ff; } emit setFortifyFactorRequest(sff->originatorId, val); return; } if (tele->telegramId() == Telegrams::RelayState::telegramId()) { Telegrams::RelayState *sff = static_cast(tele.get()); QVector val; val.reserve(sff->relayStates.size()); for(const auto &fi : qAsConst(sff->relayStates)) { RelayStateInfo ff; ff.id = fi.id; ff.state = fi.state; val += ff; } emit relayStatesRequest(sff->segment, val); return; } if (tele->telegramId() == Telegrams::BsmTriggerFlashlight::telegramId()) { Telegrams::BsmTriggerFlashlight *btf = static_cast(tele.get()); emit bsmTriggerFlashlightRequest(btf->sensorId, btf->hostname, btf->numberOfFlashes, btf->pauseBetweenFlashesSec); return; } if (tele->telegramId() == Telegrams::CentralEffectSimulationHit::telegramId()) { Telegrams::CentralEffectSimulationHit *cesHit = static_cast(tele.get()); emit centralEffectSimulationHit(cesHit->effectTimeMSec, cesHit->chargeTypeId, cesHit->destructiveFactor, cesHit->penetrationFactor, cesHit->aesId, LtsUtils::QPoint3D(cesHit->relPosition.x, cesHit->relPosition.y, cesHit->relPosition.z), cesHit->properties); return; } if (tele->telegramId() == Telegrams::CentralEffectSimulationHit3D::telegramId()) { Telegrams::CentralEffectSimulationHit3D *cesHit = static_cast(tele.get()); emit centralEffectSimulationHit3D(cesHit->effectTimeMSec, cesHit->chargeTypeId, cesHit->destructiveFactor, cesHit->penetrationFactor, cesHit->aesId, LtsUtils::QPoint3D(cesHit->impactPosition.x, cesHit->impactPosition.y, cesHit->impactPosition.z), LtsUtils::QPoint3D(cesHit->detonationLocation.x, cesHit->detonationLocation.y, cesHit->detonationLocation.z), cesHit->detonationDistance, cesHit->properties); return; } if (tele->telegramId() == Telegrams::DebugSimulateBSMHit::telegramId()) { Telegrams::DebugSimulateBSMHit *bsmHit = static_cast(tele.get()); qint64 effectTimeMSec = bsmHit->effectTimeMSec ? bsmHit->effectTimeMSec : QDateTime::currentMSecsSinceEpoch(); emit simulateBSMHit(effectTimeMSec, bsmHit->sensorId, bsmHit->originatorId, bsmHit->chargeTypeId, bsmHit->deposition1, bsmHit->deposition2); return; } if (tele->telegramId() == Telegrams::GetBsmConfiguration::telegramId()) { Telegrams::GetBsmConfiguration *tel = static_cast(tele.get()); emit getBsmConfiguration(tel->sensorId); return; } if (tele->telegramId() == Telegrams::GetBsmBitTimeout::telegramId()) { Telegrams::GetBsmBitTimeout *tel = static_cast(tele.get()); emit getBsmBitTimeout(tel->sensorId); return; } if (tele->telegramId() == Telegrams::GetBsmTechnicalStatus::telegramId()) { Telegrams::GetBsmTechnicalStatus *tel = static_cast(tele.get()); emit getBsmTechnicalStatus(tel->sensorId); return; } WARNING_LOG(m_logger) << "Received unhandled telegram " << tele->telegramId(); } } // namespace Json } // namespace BuildingControlUnit