/** * @RDE_HEADER@ * Building State Store * $Id$ * $HeadURL$ * $Author$ * Created by Gerlinde Rudolphus, SLSA, 2017-01-15 */ #include "vwm_state_store.h" #include #include #include #include #include #include #include #include namespace BuildingControlUnit { namespace VWM { namespace StateStore { static NGL::INGLLogger &logger() { return BuildingControlUnit::getLogger("VWM.StateStore"); } static QJsonObject writeBuilding(const Building &building) { const QMap &rooms = building.rooms(); QJsonArray arrRooms; for (auto it = rooms.begin(); it != rooms.end(); ++it) { QJsonArray arrOw; const Room &room = it.value(); for (auto itW = room.outerWalls().begin(); itW != room.outerWalls().end(); ++itW) { QJsonArray arrEz; const OuterWall &ow = (*itW); for (auto itE = ow.exclusionZones().begin(); itE != ow.exclusionZones().end(); ++itE) { const ExclusionZone &ez = (*itE); arrEz.append(QJsonObject({{QStringLiteral("ExclusionZoneProtection"), ez.protection()}})); } arrOw.append(QJsonObject({{QStringLiteral("OuterWallProtection"), ow.protection()}, {QStringLiteral("Ez"), arrEz} })); } arrRooms.append(QJsonObject({{QStringLiteral("OuterWalls"), arrOw}, {QStringLiteral("room"), room.id()}, {QStringLiteral("fortifyFactor"), room.fortifyFactor()}, {QStringLiteral("remainingEffect"), room.remainingEffect()}})); } const QMap &egcuProperties = building.segmentPropertyMap(); QJsonArray arrEgcuProperties; for (auto it = egcuProperties.begin(); it != egcuProperties.end(); ++it) { arrEgcuProperties.append(QJsonObject({{QStringLiteral("Hostname"), it.key()}, {QStringLiteral("Properties"), it.value()} })); } return QJsonObject({{QStringLiteral("BuildingName"), building.name()}, {QStringLiteral("Rooms"), arrRooms}, {QStringLiteral("SegmentProperties"), arrEgcuProperties}, {QStringLiteral("BuildingProperties"), building.buildingProperties()}}); } static inline QJsonObject writeHitResult(const HitResult &hitResult) { return QJsonObject({{QStringLiteral("sensorId"), hitResult.sensorId}, {QStringLiteral("originatorId"), hitResult.originatorId}, {QStringLiteral("originatorType"),static_cast(hitResult.originatorType)}, {QStringLiteral("chargeTypeId"), hitResult.chargeTypeId}, {QStringLiteral("damagePercentOld"), hitResult.damagePercentOld}, {QStringLiteral("damagePercentNew"), hitResult.damagePercentNew}, {QStringLiteral("effectSoundId"), hitResult.effectSoundId}, {QStringLiteral("effectTimeMSec"), hitResult.effectTimeMSec}}); } static inline QJsonArray writeContaminationStates(const QMap & contaminationStates ) { QJsonArray contaminationArr; for (const auto &value : contaminationStates.values() ) { QJsonArray roomArr; for (const auto & roomId : qAsConst(value.rooms)) roomArr.append(QJsonValue(roomId)); contaminationArr.append(QJsonObject({ {QStringLiteral("aesId") , value.aesId}, {QStringLiteral("rooms"), roomArr}})); } return contaminationArr; } static void readEz(const QJsonObject &json, int ezIndex, OuterWall &outerWall) { if (ezIndex >= outerWall.exclusionZones().size()) return; double protection = json[QStringLiteral("ExclusionZoneProtection")].toDouble(); outerWall.exclusionZones()[ezIndex].setProtection(protection); } static void readOw(const QJsonObject &json, OuterWall &outerWall) { int outerWallProtection = static_cast( json[QStringLiteral("OuterWallProtection")].toDouble()); outerWall.setProtection(outerWallProtection); QJsonArray ezArray = json[QStringLiteral("Ez")].toArray(); for (int ezIndex = 0; ezIndex < ezArray.size(); ++ezIndex) { QJsonObject ezObject = ezArray[ezIndex].toObject(); readEz(ezObject, ezIndex, outerWall); } } static void readRoom(const QJsonObject &json, Building &building) { //QMap rooms = building.rooms(); int id = json[QStringLiteral("room")].toInt(); auto room = building.rooms().find(id); if (room == building.rooms().end()) return; room.value().setRemainingEffect(json[QStringLiteral("remainingEffect")].toDouble()); room.value().setFortifyFactor(json[QStringLiteral("fortifyFactor")].toDouble()); QJsonArray owArray = json[QStringLiteral("OuterWalls")].toArray(); for (int owIndex = 0; owIndex < owArray.size(); ++owIndex) { if (owIndex >= room.value().outerWalls().size()) break; QJsonObject owObject = owArray[owIndex].toObject(); if (room.value().outerWalls().size() > owIndex) readOw(owObject, room.value().outerWalls()[owIndex]); } } static void readBuilding(const QJsonObject &json, Building &building) { //QString name = json[QStringLiteral("BuildingName")].toString(); QJsonArray roomArray = json[QStringLiteral("Rooms")].toArray(); for (int roomIndex = 0; roomIndex < roomArray.size(); ++roomIndex) { QJsonObject roomObject = roomArray[roomIndex].toObject(); readRoom(roomObject, building); } building.clearSegmentProperties(); QJsonArray segmentArray = json[QStringLiteral("SegmentProperties")].toArray(); for (int segmentIndex = 0; segmentIndex < segmentArray.size(); ++segmentIndex) { QJsonObject segmentObject = segmentArray[segmentIndex].toObject(); QString hostname = segmentObject[QStringLiteral("Hostname")].toString(); QString properties = segmentObject[QStringLiteral("Properties")].toString(); building.setSegmentProperties(hostname,properties); } building.setBuildingProperties(json[QStringLiteral("BuildingProperties")].toString()); } static void readHitResult(const QJsonObject &json, HitResult &hitResult) { hitResult.sensorId = json.value(QStringLiteral("sensorId")).toInt(); hitResult.originatorId = json.value(QStringLiteral("originatorId")).toInt(); hitResult.originatorType = static_cast(json.value(QStringLiteral("originatorType")).toInt()); hitResult.chargeTypeId = json.value(QStringLiteral("chargeTypeId")).toInt(); hitResult.damagePercentOld = json.value(QStringLiteral("damagePercentOld")).toInt(); hitResult.damagePercentNew = json.value(QStringLiteral("damagePercentNew")).toInt(); hitResult.effectSoundId = json.value(QStringLiteral("effectSoundId")).toInt(); hitResult.effectTimeMSec = json.value(QStringLiteral("effectTimeMSec")).toDouble(); } static void readContaminationStates(const QJsonArray &jsArr, QMap &contaminationStates) { for (auto index : jsArr) { const QJsonObject &inObj = index.toObject(); ContaminationState contStates; contStates.aesId = inObj[QStringLiteral("aesId")].toInt(); const QJsonArray &idsArr = inObj[QStringLiteral("rooms")].toArray(); contStates.rooms.reserve(idsArr.count()); for (const auto & id : idsArr) contStates.rooms.push_back(id.toInt()); contaminationStates.insert(contStates.aesId, contStates); } } static QString getStateFilename(const QString &name) { // Linux: QStandardPaths::CacheLocation -> ~/.cache/BuildingControlUnit const QString folder = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1Char('/'); if (!QDir(folder).exists()) QDir().mkpath(folder); return folder + name; } bool saveState(const Building &building, const HitResult &hitResult,const QMap &contaminationStates) { DEBUG_LOG(logger()) << "**********************"; DEBUG_LOG(logger()) << "*** SAVE STATE *** "<< getStateFilename(building.name()); DEBUG_LOG(logger()) << "**********************"; QFile saveFile(getStateFilename(building.name())); if (!saveFile.open(QIODevice::WriteOnly)) { WARNING_LOG(logger()) << "Couldn't open State file. " << getStateFilename(building.name()); return false; } QJsonObject saveObject; saveObject[QStringLiteral("Building")] = writeBuilding(building); saveObject[QStringLiteral("HitResult")] = writeHitResult(hitResult); saveObject[QStringLiteral("contaminationStates")] = writeContaminationStates(contaminationStates); const QJsonDocument saveDoc(saveObject); saveFile.write(saveDoc.toJson()); return true; } bool loadState(Building &building, HitResult &hitResult, QMap &contaminationStates) { DEBUG_LOG(logger()) << "**********************"; DEBUG_LOG(logger()) << "*** LOAD STATE *** "<< getStateFilename(building.name()); DEBUG_LOG(logger()) << "**********************"; QFile loadFile(getStateFilename(building.name())); if (!loadFile.open(QIODevice::ReadOnly)) { WARNING_LOG(logger()) << "Couldn't open State file. " << getStateFilename(building.name()); return false; } QByteArray saveData = loadFile.readAll(); QJsonDocument loadDoc(QJsonDocument::fromJson(saveData)); readBuilding(loadDoc.object().value(QStringLiteral("Building")).toObject(), building); readHitResult(loadDoc.object().value(QStringLiteral("HitResult")).toObject(), hitResult); readContaminationStates(loadDoc.object().value(QStringLiteral("contaminationStates")).toArray(), contaminationStates); return true; } } // namespace StateStore } // namespace VWM } // namespace BuildingControlUnit