/** * @RDE_HEADER@ * The DataManager class takes strucure element data from the HandlerStructureElement, * offers an interface to get and set structure data * $Id$ * $HeadURL$ * $Author$ * Created by Hannes Baeuerle, SLSE, 2016-09-12 */ #include "data_manager.h" #include "Common/LtsCoordTrans/lts_coord_trans.h" #include "main_handler.h" #include "handler_main_schedule.h" #include "object_main_schedule.h" #include "handler_mounting_point_asset.h" #include "object_mounting_point_asset.h" #include "handler_instrumentation_asset.h" #include "object_instrumentation_asset.h" #include "handler_main_structure_element.h" #include "object_main_structure_element.h" #include "object_structure_element.h" #include #include #include #include #include using namespace InfrastructureManagement; using namespace InfrastructureManagement::WebSocketInterface; namespace { /** * Determine the floor number. * Currently the floor number is not part of the model. At least it is not stored in the DB. * But the floor number is encoded in the floor name, e.g. "floor_-1", * so we simply try to extract it from there. */ int determineFloorNumber(ObjectStructureElement *floor) { static const QString FLOOR_PATTERN = QStringLiteral("floor_"); Q_ASSERT(floor); Q_ASSERT(floor->getStructureElementTypeId() == StructureElementType::Floor); QString name = QString::fromStdString(floor->getData().name()).toLower(); if (!name.startsWith(FLOOR_PATTERN)) return 0; bool ok = false; int floorNumber = name.midRef(FLOOR_PATTERN.size()).toInt(&ok); if (!ok) return 0; return floorNumber; } } // anonymous namespace //--------------------------------------------------------------------------------------------------------- DataManager::DataManager(MainHandler *mainHandler) : LtsWebSocket::DataManagerBaseDl(mainHandler->db(), getLogger(QStringLiteral("DataManager"))) , m_mainHandler(mainHandler) {} //--------------------------------------------------------------------------------------------------------- bool DataManager::init() { std::shared_ptr ddsConnector = m_mainHandler->dds()->ddsConnector(); m_asmDtc = AssetManagement::Interface::Dtc::create(ddsConnector); return m_asmDtc->enableTrainingArea(); } //--------------------------------------------------------------------------------------------------------- DataManager::EinruestEssentials DataManager::getEssentials(const QString &uuid) const { using namespace Messages; EinruestEssentials result; // training areas and areas const QMap trainingAreaMap = m_asmDtc->trainingAreas(); QVector path; path.reserve(4); result.trainingAreas.reserve(trainingAreaMap.size()); result.areas.reserve(trainingAreaMap.size()); using namespace LtsCoordTrans; for (const AssetManagement::TrainingArea ¤tArea : trainingAreaMap) { TrainingAreaMessage::TrainingAreaData trainingAreaData; AreaMessage::AreaData areaData; ReplyMessage::LonLatPoint point; path.clear(); // bottom left UtmCoordinate bl(UtmCoordinate::fromGeographic({currentArea.bottomLeft().lon(), currentArea.bottomLeft().lat()})); point.lon = currentArea.bottomLeft().lon(); point.lat = currentArea.bottomLeft().lat(); trainingAreaData.path.append(point); areaData.path.append(point); // upper left UtmCoordinate ul(UtmCoordinate::fromGeographic(bl.geographic(0, currentArea.height()))); point.lon = ul.geographic().x(); point.lat = ul.geographic().y(); trainingAreaData.path.append(point); areaData.path.append(point); // upper right UtmCoordinate ur(UtmCoordinate::fromGeographic(bl.geographic(currentArea.width(), currentArea.height()))); point.lon = ur.geographic().x(); point.lat = ur.geographic().y(); trainingAreaData.path.append(point); areaData.path.append(point); // lower right UtmCoordinate lr(UtmCoordinate::fromGeographic(bl.geographic(currentArea.width(), 0))); point.lon = lr.geographic().x(); point.lat = lr.geographic().y(); trainingAreaData.path.append(point); areaData.path.append(point); trainingAreaData.designation = QString::fromStdString(currentArea.name()); trainingAreaData.id = currentArea.id(); areaData.id = currentArea.id(); areaData.trainingAreaId = currentArea.id(); areaData.designation = QString::fromStdString(currentArea.name()); result.trainingAreas.append(TrainingAreaMessage(trainingAreaData, uuid)); result.areas.append(AreaMessage(areaData, uuid)); } const auto structureElementsMap = m_mainHandler->getHandlerMainStructureElement()->getStructureElementMap(); const auto mainStructureElementMap = m_mainHandler->getHandlerMainStructureElement()->getMainStructureElementsMap(); for (auto it = structureElementsMap.begin(); it != structureElementsMap.end(); ++it) { ObjectStructureElement *currentElement = it.value(); switch (currentElement->getStructureElementTypeId().underlying()) { case StructureElementType::TrainingArea: case StructureElementType::City: case StructureElementType::Section: case StructureElementType::ApproachingPoint: case StructureElementType::RadioStation: continue; case StructureElementType::MeteoDataUnit: case StructureElementType::Bridge: case StructureElementType::Announcement: case StructureElementType::Building: { ObjectMessage::ObjectMessageData objectData; ReplyMessage::LonLatPoint refPoint; refPoint.lat = currentElement->getGeoPosition().lat(); refPoint.lon = currentElement->getGeoPosition().lon(); objectData.z = currentElement->getGeoPosition().z(); objectData.refPoint = refPoint; objectData.pathRelative = pathForStructureId(currentElement->getId()); objectData.path = relativeToGeographic(objectData.refPoint, objectData.pathRelative); objectData.designation = (currentElement->getData().displayName().size() > 0) ? QString::fromStdString(currentElement->getData().displayName()) : QString::fromStdString(currentElement->getData().name()); objectData.id = currentElement->getId(); objectData.areaId = 6; // TODO: HACK - calculate from position objectData.mseId = currentElement->getMainStructureElementId(); const ObjectMainStructureElement *mse = mainStructureElementMap.value(currentElement->getMainStructureElementId()); if (mse) { QJsonObject description = QJsonDocument::fromJson(mse->getDescription().toUtf8()).object(); objectData.street = description.value(QStringLiteral("street")).toString(); objectData.number = description.value(QStringLiteral("number")).toString(); objectData.rotationDegree = mse->getData().angle(); } result.objects.append(ObjectMessage(objectData, uuid)); break; } case StructureElementType::Floor: { LevelMessage::LevelData levelData; levelData.id = currentElement->getId(); levelData.objectid = currentElement->getPath().at(0); levelData.designation = (currentElement->getData().displayName().size() > 0) ? QString::fromStdString(currentElement->getData().displayName()) : QString::fromStdString(currentElement->getData().name()); levelData.number = determineFloorNumber(currentElement); levelData.path = pathForStructureId(currentElement->getId()); levelData.zPos = currentElement->getRelativePosition().offsetZ(); result.levels.append(LevelMessage(levelData, uuid)); break; } case StructureElementType::Room: { RoomMessage::RoomData roomData; roomData.id = currentElement->getId(); roomData.designation = (currentElement->getData().displayName().size() > 0) ? QString::fromStdString(currentElement->getData().displayName()) : QString::fromStdString(currentElement->getData().name()); roomData.path = pathForStructureId(currentElement->getId()); roomData.levelId = currentElement->getPath().at(1); result.rooms.append(RoomMessage(roomData, uuid)); break; } case StructureElementType::MountingPoint: { MountingPointMessage::MountingPointData mountingPointData; mountingPointData.id = currentElement->getId(); mountingPointData.designation = (currentElement->getData().displayName().size() > 0) ? QString::fromStdString(currentElement->getData().displayName()) : QString::fromStdString(currentElement->getData().name()); mountingPointData.tag = QString::fromStdString(currentElement->getData().barcode()); mountingPointData.objectId = currentElement->getPath().at(0); mountingPointData.levelId = currentElement->getPath().size() > 2 ? currentElement->getPath().at(1) : -1; mountingPointData.roomId = currentElement->getPath().size() > 2 ? currentElement->getPath().at(2) : -1; mountingPointData.position3d.x = currentElement->getRelativePosition().offsetX(); mountingPointData.position3d.y = currentElement->getRelativePosition().offsetY(); mountingPointData.position3d.z = currentElement->getRelativePosition().offsetZ(); mountingPointData.supportedAssetTypIds.append(currentElement->getData().mountingPointTypeId().underlying()); mountingPointData.assetId = getMountedAssetId(currentElement->getId()); result.mountingPoints.append(MountingPointMessage(mountingPointData, uuid)); break; } } } // No BuildingNetworkSwitch and no AnnouncementUnit (see GUEZE-1548/1459) AssetTypeMessage::AssetTypeData assetTypeData; for (int i = MountingPointType::Unknown; i <= MountingPointType::EffectGenerationControlUnit; ++i) { if (i == MountingPointType_def::AnnouncementUnit) continue; assetTypeData.id = i; assetTypeData.designation = toString(static_cast(i)); if (assetTypeData.designation.endsWith(QLatin1Char(')'))) continue; assetTypeData.deviceClass = 1; // device class is just a dumy value here ... result.assetTypes.append(AssetTypeMessage(assetTypeData, uuid)); } return result; } //--------------------------------------------------------------------------------------------------------- QVector DataManager::getPlannedMounting(const QString &uuid) const { using namespace Messages; const auto schedulesMap = m_mainHandler->getHandlerMainSchedule()->getMainScheduleMap(); QVector result; result.reserve(schedulesMap.size()); PlannedMountingMessage::PlannedMountingData mountingData; for (const ObjectMainSchedule *sched : schedulesMap) { const MainSchedule &data = sched->getData(); if (data.statusId() == ScheduleStatus::Inactive) continue; mountingData.areaId = areaIdForScheduleId(data.id()); mountingData.plannedMountingId = data.id(); mountingData.designation = QString::fromStdString(data.name()); mountingData.mounting = entriesForScheduleId(data.id()); result.append(PlannedMountingMessage(mountingData, uuid)); } return result; } //--------------------------------------------------------------------------------------------------------- LtsWebSocket::ReplyMessage *DataManager::getObjectMounting(int plannedMountingId, int objectId, const QString &uuid) const { // objectId = structureElementId using namespace Messages; ObjectMainSchedule *objMps = m_mainHandler->getHandlerMainSchedule()->getMainSchedule(plannedMountingId); // check if plannedMountingId exists if (!objMps) { LtsWebSocket::ErrorMessage::ErrorData errorData; errorData.errorClass = 1; errorData.errorMessage = QObject::tr("Planned mounting schedule id is invalid", "DataManager"); errorData.uuid = uuid; WARNING_LOG(m_logger) << errorData.errorMessage << " - " << plannedMountingId; LtsWebSocket::ReplyMessage *reply = new LtsWebSocket::ErrorMessage(errorData); return reply; } // check if objectId is valid ObjectStructureElement *buildingEle = m_mainHandler->getHandlerMainStructureElement()->getStructureElement(objectId); if (buildingEle == nullptr || buildingEle->getStructureElementTypeId() != StructureElementType::Building) { LtsWebSocket::ErrorMessage::ErrorData errorData; errorData.errorClass = 1; errorData.errorMessage = QObject::tr("Building id is invalid", "DataManager"); errorData.uuid = uuid; WARNING_LOG(m_logger) << errorData.errorMessage << " - " << (buildingEle ? buildingEle->getStructureElementTypeId().underlying() : -1) << ", " << plannedMountingId << ", " << objectId; LtsWebSocket::ReplyMessage *reply = new LtsWebSocket::ErrorMessage(errorData); return reply; } // check if building with ID objectId has a plan if (!isPlannedObject(objectId)) { LtsWebSocket::ErrorMessage::ErrorData errorData; errorData.errorClass = 1; errorData.errorMessage = QObject::tr("There is no planned data available for building with id %1", "DataManager"). arg(objectId); errorData.uuid = uuid; WARNING_LOG(m_logger) << errorData.errorMessage << " - " << plannedMountingId << ", " << objectId; LtsWebSocket::ReplyMessage *reply = new LtsWebSocket::ErrorMessage(errorData); return reply; } ObjectMountingMessage::ObjectMountingData objectMountingData; objectMountingData.objectId = objectId; objectMountingData.plannedMountingId = plannedMountingId; objectMountingData.planned = entriesForBuildingInSchedule(plannedMountingId, buildingEle->getMainStructureElementId()); return new ObjectMountingMessage(objectMountingData, uuid); } //--------------------------------------------------------------------------------------------------------- LtsWebSocket::ReplyMessage *DataManager::mountTag(const QString &mountingPointTag, const QString &assetTag, const QString &messageType, const QString &uuid) const { using namespace Messages; QString okMessage; std::shared_ptr mountingPointAssetHandler = m_mainHandler->getHandlerMountingPointAsset(); int32_t mountingPointId = -1; int32_t assetId = -1; // check if mountingPointTag exists if (!mountingPointTag.isEmpty()) { mountingPointId = mountingPointIdFromBarcode(mountingPointTag); if (mountingPointId == -1) { LtsWebSocket::ErrorMessage::ErrorData data; data.errorClass = 1; data.errorMessage = QObject::tr("Got invalid mounting point tag '%1'", "DataManager"). arg(mountingPointTag); data.uuid = uuid; WARNING_LOG(m_logger) << data.errorMessage; LtsWebSocket::ReplyMessage *reply = new LtsWebSocket::ErrorMessage(data); return reply; } } // check if assetTag exists if (!assetTag.isEmpty()) { assetId = assetIdFromBarcode(assetTag); if (assetId == -1) { LtsWebSocket::ErrorMessage::ErrorData data; data.errorClass = 1; data.errorMessage = QObject::tr("Got invalid instrumentation asset tag '%1'", "DataManager"). arg(assetTag); data.uuid = uuid; WARNING_LOG(m_logger) << data.errorMessage; LtsWebSocket::ReplyMessage *reply = new LtsWebSocket::ErrorMessage(data); return reply; } } if(assetId > 0) { ObjectInstrumentationAsset *asset = m_mainHandler->getHandlerInstrumentationAsset()->getAssetFromId(assetId); if(asset->getData().assetStateId() == InstrumentationAssetState::Defect) { LtsWebSocket::ErrorMessage::ErrorData data; data.errorClass = 1; data.errorMessage = QObject::tr("Got defect instrumentation asset with id '%1'", "DataManager"). arg(assetId); data.uuid = uuid; WARNING_LOG(m_logger) << data.errorMessage; LtsWebSocket::ReplyMessage *reply = new LtsWebSocket::ErrorMessage(data); return reply; } } if (mountingPointId == -1 && assetId >= 0) // unmount mounting point { if (!mountingPointAssetHandler->unmountAsset(assetId)) { LtsWebSocket::ErrorMessage::ErrorData data; data.errorClass = 1; data.errorMessage = QObject::tr("Error unmounting instrumentation asset with id %1", "DataManager"). arg(assetId); data.uuid = uuid; WARNING_LOG(m_logger) << data.errorMessage; LtsWebSocket::ReplyMessage *reply = new LtsWebSocket::ErrorMessage(data); return reply; } okMessage = QObject::tr("Successfully unmounted instrumentation asset with id %1", "DataManager"). arg(assetId); } else if (assetId == -1 && mountingPointId >= 0) // unmount asset { if (!mountingPointAssetHandler->unmountMountingPoint(mountingPointId)) { LtsWebSocket::ErrorMessage::ErrorData data; data.errorClass = 1; data.errorMessage = QObject::tr("Error unmounting mounting point with id %1", "DataManager"). arg(mountingPointId); data.uuid = uuid; WARNING_LOG(m_logger) << data.errorMessage; LtsWebSocket::ReplyMessage *reply = new LtsWebSocket::ErrorMessage(data); return reply; } okMessage = QObject::tr("Successfully unmounted mounting point with id %1", "DataManager"). arg(mountingPointId); } else if (assetId >= 0 && mountingPointId >= 0) { if (!mountingPointAssetHandler->mount(assetId, mountingPointId)) { LtsWebSocket::ErrorMessage::ErrorData data; data.errorClass = 1; data.errorMessage = QObject::tr("Error mounting instrumentation asset with id %1 on mounting point with id %2", "DataManager"). arg(assetId). arg(mountingPointId); data.uuid = uuid; WARNING_LOG(m_logger) << data.errorMessage; LtsWebSocket::ReplyMessage *reply = new LtsWebSocket::ErrorMessage(data); return reply; } } else if (assetId == -1 && mountingPointId == -1) { LtsWebSocket::ErrorMessage::ErrorData data; data.errorClass = 1; data.errorMessage = QObject::tr("Got 'mountTag' message with empty tags", "DataManager");; data.uuid = uuid; WARNING_LOG(m_logger) << data.errorMessage; LtsWebSocket::ReplyMessage *reply = new LtsWebSocket::ErrorMessage(data); return reply; } OkMessage::OkData data; if (okMessage.isEmpty()) okMessage = QObject::tr("Successfully mounted instrumentation asset with id %1 on mounting point with id %2", "DataManager"). arg(assetId). arg(mountingPointId); data.messageType = messageType; data.uuid = uuid; data.info = okMessage; return new OkMessage(data); } //--------------------------------------------------------------------------------------------------------- LtsWebSocket::ReplyMessage *DataManager::mount(int32_t mountingPointId, int32_t assetId, const QString &messageType, const QString &uuid) const { using namespace Messages; if (!m_mainHandler->getHandlerMountingPointAsset()->mount(assetId, mountingPointId)) { LtsWebSocket::ErrorMessage::ErrorData data; data.errorClass = 1; data.errorMessage = QObject::tr("Error mounting instrumentation asset with id %1 on mounting point with id %2", "DataManager"). arg(assetId). arg(mountingPointId); data.uuid = uuid; WARNING_LOG(m_logger) << data.errorMessage; LtsWebSocket::ReplyMessage *reply = new LtsWebSocket::ErrorMessage(data); return reply; } OkMessage::OkData data; data.messageType = messageType; data.uuid = uuid; data.info = QObject::tr("Successfully mounted instrumentation asset with id %1 on mounting point with id %2", "DataManager"). arg(assetId). arg(mountingPointId); return new OkMessage(data); } //--------------------------------------------------------------------------------------------------------- LtsWebSocket::ReplyMessage *DataManager::unmountAsset(int32_t assetId, const QString &messageType, const QString &uuid) const { using namespace Messages; if (!m_mainHandler->getHandlerMountingPointAsset()->unmountAsset(assetId)) { LtsWebSocket::ErrorMessage::ErrorData data; data.errorClass = 1; data.errorMessage = QObject::tr("Error unmounting instrumentation asset with id %1", "DataManager"). arg(assetId); data.uuid = uuid; WARNING_LOG(m_logger) << data.errorMessage; LtsWebSocket::ReplyMessage *reply = new LtsWebSocket::ErrorMessage(data); return reply; } OkMessage::OkData data; data.messageType = messageType; data.uuid = uuid; data.info = QObject::tr("Successfully unmounted instrumentation asset with id %1", "DataManager"). arg(assetId); return new OkMessage(data); } //--------------------------------------------------------------------------------------------------------- LtsWebSocket::ReplyMessage *DataManager::unmountMountingPoint(int32_t mountingPointId, const QString &messageType, const QString &uuid) const { using namespace Messages; if (!m_mainHandler->getHandlerMountingPointAsset()->unmountMountingPoint(mountingPointId)) { LtsWebSocket::ErrorMessage::ErrorData data; data.errorClass = 1; data.errorMessage = QObject::tr("Error unmounting mounting point with id %1", "DataManager"). arg(mountingPointId); data.uuid = uuid; WARNING_LOG(m_logger) << data.errorMessage; return new LtsWebSocket::ErrorMessage(data); } OkMessage::OkData data; data.messageType = messageType; data.uuid = uuid; data.info = QObject::tr("Successfully unmounted mounting point with id %1"). arg(mountingPointId); return new OkMessage(data); } //--------------------------------------------------------------------------------------------------------- LtsWebSocket::ReplyMessage *DataManager::unmountObject(int32_t objectId, const QString &messageType, const QString &uuid) const { using namespace Messages; ObjectStructureElement *buildingSe = m_mainHandler->getHandlerMainStructureElement()->getStructureElement(objectId); ObjectMainStructureElement *building = nullptr; if (buildingSe) building = buildingSe->getMainStructureElement(); if (building == nullptr) { LtsWebSocket::ErrorMessage::ErrorData data; data.errorClass = 1; data.errorMessage = QObject::tr("Error unmounting building - building id %1 is invalid", "DataManager"). arg(objectId); data.uuid = uuid; WARNING_LOG(m_logger) << data.errorMessage; return new LtsWebSocket::ErrorMessage(data); } QStringList errorIds; std::shared_ptr mountingPointAssetHandler = m_mainHandler->getHandlerMountingPointAsset(); const auto seElements = building->getStructureElements(); for (ObjectStructureElement *currentElement : seElements) { if (currentElement->getStructureElementTypeId() != StructureElementType::MountingPoint) continue; int32_t assetId = mountingPointAssetHandler->getMountedAssetId(currentElement->getId()); if (assetId <= 0) continue; if (!mountingPointAssetHandler->unmountMountingPoint(currentElement->getId())) errorIds.append(QString::number(currentElement->getId())); } if (!errorIds.isEmpty()) { LtsWebSocket::ErrorMessage::ErrorData data; data.errorClass = 1; data.errorMessage = QObject::tr("Error unmounting the following mounting point(s): %1", "DataManager"). arg(errorIds.join(QLatin1String(", "))); data.uuid = uuid; WARNING_LOG(m_logger) << data.errorMessage; return new LtsWebSocket::ErrorMessage(data); } OkMessage::OkData data; data.info = QObject::tr("Successfully unmounted building with id %1", "DataManager"). arg(objectId); data.messageType = messageType; data.uuid = uuid; return new OkMessage(data); } //--------------------------------------------------------------------------------------------------------- LtsWebSocket::ReplyMessage *DataManager::unmountArea(int32_t areaId, const QString &messageType, const QString &uuid) const { using namespace Messages; std::shared_ptr structEleHandler = m_mainHandler->getHandlerMainStructureElement(); std::shared_ptr mountingPointAssetHandler = m_mainHandler->getHandlerMountingPointAsset(); const auto structEleMap = structEleHandler->getStructureElementMap(); QStringList errorIds; bool isValidAreaId = false; for (const auto &seElem : structEleMap) { if (seElem->getStructureElementTypeId() == StructureElementType::MountingPoint) { if (!seElem->getData().path().size()) continue; int32_t buildingId = seElem->getData().path()[0]; if (structEleMap.value(buildingId)->getParentId() == areaId) { isValidAreaId = true; if (!mountingPointAssetHandler->unmountMountingPoint(seElem->getId())) errorIds.append(QString::number(seElem->getId())); } } } if (!isValidAreaId) { LtsWebSocket::ErrorMessage::ErrorData data; data.errorClass = 1; data.errorMessage = QObject::tr("Error unmounting training area with id %1. Id is invalid", "DataManager"). arg(areaId); data.uuid = uuid; WARNING_LOG(m_logger) << data.errorMessage; return new LtsWebSocket::ErrorMessage(data); } if (!errorIds.isEmpty()) { LtsWebSocket::ErrorMessage::ErrorData data; data.errorClass = 1; data.errorMessage = QObject::tr("Error unmounting the following mounting point(s): %1", "DataManager"). arg(errorIds.join(QLatin1String(", "))); data.uuid = uuid; WARNING_LOG(m_logger) << data.errorMessage; return new LtsWebSocket::ErrorMessage(data); } OkMessage::OkData data; data.info = QObject::tr("Successfully unmounted training area with id %1"). arg(areaId); data.messageType = messageType; data.uuid = uuid; return new OkMessage(data); } //--------------------------------------------------------------------------------------------------------- LtsWebSocket::ReplyMessage *DataManager::objectMountingReady(int32_t plannedMountingId, int32_t objectId, const QString &messageType, const QString &uuid) const { using namespace Messages; std::shared_ptr structEleHandler = m_mainHandler->getHandlerMainStructureElement(); const auto structEleMap = structEleHandler->getStructureElementMap(); const auto mountingPointPlans = m_mainHandler->getHandlerMainSchedule()->getMountingPointPlans(plannedMountingId); bool isValidObjectId = false; QStringList missingMountingPoints; missingMountingPoints.reserve(mountingPointPlans.size()); for (const auto &mpp : mountingPointPlans) { int32_t structEleId = mpp.structureElementId(); int32_t buildingId = -1; if (structEleMap.value(structEleId)->getData().path().size()) buildingId = structEleMap.value(structEleId)->getData().path()[0]; if (buildingId == objectId) { isValidObjectId = true; if (!isMounted(structEleId)) missingMountingPoints.append(QString::number(structEleId)); } } if (!isValidObjectId) { LtsWebSocket::ErrorMessage::ErrorData data; data.errorClass = 1; data.errorMessage = QObject::tr("Building with id %1 is invalid", "DataManager") .arg(objectId); data.uuid = uuid; WARNING_LOG(m_logger) << data.errorMessage; return new LtsWebSocket::ErrorMessage(data); } if (!missingMountingPoints.isEmpty()) { LtsWebSocket::ErrorMessage::ErrorData data; data.errorClass = 1; data.errorMessage = QObject::tr("The following mounting points are not ready: %1", "DataManager") .arg(missingMountingPoints.join(QStringLiteral(", "))); data.uuid = uuid; WARNING_LOG(m_logger) << data.errorMessage; return new LtsWebSocket::ErrorMessage(data); } OkMessage::OkData data; data.info = QObject::tr("Building with id %1 is ready", "DataManager") .arg(objectId); data.messageType = messageType; data.uuid = uuid; return new OkMessage(data); } //--------------------------------------------------------------------------------------------------------- LtsWebSocket::ReplyMessage *DataManager::getAssetState(int32_t assetId, const QString &assetTag, const QString &uuid) const { using namespace Messages; QString errorString; ObjectInstrumentationAsset *asset = nullptr; std::shared_ptr assetHandler = m_mainHandler->getHandlerInstrumentationAsset(); if (assetId == 0 && assetTag.isEmpty()) errorString = QObject::tr("Not possible to get instrumentation asset state for empty id and tag", "DataManager"); else if (assetId == 0) asset = assetHandler->getAssetFromBarcode(assetTag); else if (assetTag.isEmpty()) asset = assetHandler->getAssetFromId(assetId); else asset = assetHandler->getAssetFromBarcodeAndId(assetTag, assetId); if (asset == nullptr) errorString = QObject::tr("Either instrumentation asset id %1 or instrumentation asset tag %2 is invalid"). arg(assetId). arg(assetTag); if (!errorString.isEmpty()) { LtsWebSocket::ErrorMessage::ErrorData data; data.errorClass = 1; data.errorMessage = errorString; data.uuid = uuid; WARNING_LOG(m_logger) << data.errorMessage; return new LtsWebSocket::ErrorMessage(data); } return new AssetStateMessage(assetData(asset), uuid); } LtsWebSocket::ReplyMessage *DataManager::getAssets(const QSet &assetTypeIds, const QString &uuid) const { using namespace Messages; for (const int value : assetTypeIds) DEBUG_LOG(m_logger) << "getAssets assetTypeId =" << value; const auto m = m_mainHandler->getHandlerInstrumentationAsset()->getObjectInstrumentationAssetMap(); QVector assets; for (const ObjectInstrumentationAsset *asset : m) { if (assetTypeIds.contains(asset->getData().mountingPointTypeId().underlying())) assets += assetData(asset); } return new AssetsMessage(assets, uuid); } LtsWebSocket::ReplyMessage *DataManager::getBuildingState(int32_t buildingId, const QString &uuid) const { using namespace Messages; std::shared_ptr structEleHandler = m_mainHandler->getHandlerMainStructureElement(); std::shared_ptr mountingPointAssetHandler = m_mainHandler->getHandlerMountingPointAsset(); ObjectMainStructureElement *mse = nullptr; if (buildingId > 0) { const auto ose = structEleHandler->getStructureElement(buildingId); mse = ose ? structEleHandler->getMainStructureElement(ose->getMainStructureElementId()) : nullptr; } if (!mse) { LtsWebSocket::ErrorMessage::ErrorData data; data.errorClass = 1; data.errorMessage = QObject::tr("Building id %1 is invalid", "DataManager").arg(buildingId); data.uuid = uuid; WARNING_LOG(m_logger) << data.errorMessage; return new LtsWebSocket::ErrorMessage(data); } AssetStateObjectMessage::AssetStateObjectData data; AssetStateObjectMessage::AssetStatesEntry entry; data.objectId = buildingId; data.time = QDateTime::currentDateTime().toString(QStringLiteral("dd:MM:yy hh:mm")); for (const StructureElement ¤tElement : mse->getElements()) { if (currentElement.structureElementTypeId() == InfrastructureManagement::StructureElementType::MountingPoint) { int32_t assetId = mountingPointAssetHandler->getMountedAssetId(currentElement.id()); if (assetId) { const AssetData assetDat = assetData(assetId); entry.assetId = assetId; entry.assetTypeId = assetDat.assetTypeId; entry.hostname = assetDat.hostname; entry.mountingPointId = assetDat.mountingPointId; entry.state = assetDat.state; data.assetStates.append(entry); } } } return new AssetStateObjectMessage(data, uuid); } //--------------------------------------------------------------------------------------------------------- LtsWebSocket::ReplyMessage *DataManager::assetBaseData(const QString &uuid) const { return toBaseDataMessageFromDb(uuid); } //--------------------------------------------------------------------------------------------------------- LtsWebSocket::ReplyMessage *DataManager::mainStructureElementBaseData(const QString &uuid) const { return toBaseDataMessageFromDb(uuid); } //--------------------------------------------------------------------------------------------------------- LtsWebSocket::ReplyMessage *DataManager::structureElementBaseData(const QString &uuid) const { return toBaseDataMessageFromDb(uuid); } //--------------------------------------------------------------------------------------------------------- LtsWebSocket::ReplyMessage *DataManager::structureElementFootprintBaseData(const QString &uuid) const { return toBaseDataMessageFromDb(uuid); } //--------------------------------------------------------------------------------------------------------- LtsWebSocket::ReplyMessage *DataManager::mountingPointAssetBaseData(const QString &uuid) const { return toBaseDataMessageFromDb(uuid); } //--------------------------------------------------------------------------------------------------------- LtsWebSocket::ReplyMessage *DataManager::mountingPointScheduleBaseData(const QString &uuid) const { return toBaseDataMessageFromDb(uuid); } //--------------------------------------------------------------------------------------------------------- LtsWebSocket::ReplyMessage *DataManager::mountingPointPlanBaseData(const QString &uuid) const { return toBaseDataMessageFromDb(uuid); } QVector DataManager::relativeToGeographic(const Messages::ReplyMessage::LonLatPoint &pos, const QVector &relPoints) { QVector ret; ret.reserve(relPoints.size()); const LtsCoordTrans::UtmCoordinate base(LtsCoordTrans::UtmCoordinate::fromGeographic(pos.lon, pos.lat)); for (const auto &relPoint : relPoints) { const auto absPoint = base.geographic(relPoint.x, relPoint.y); Messages::ReplyMessage::LonLatPoint p; p.lon = absPoint.x(); p.lat = absPoint.y(); ret.push_back(std::move(p)); } return ret; } // ------------------------------------------------------------------------------------------------------- QVector DataManager::pathForStructureId(int32_t structureElementId) const { using namespace Messages; QVector result; // we currently only have paths for MainStructureElements (== Buildings) // -> search all buildings for structureElementId ObjectMainStructureElement *mse = nullptr; const auto objMap = m_mainHandler->getHandlerMainStructureElement()->getMainStructureElementsMap(); for (ObjectMainStructureElement *obj : objMap) { if (obj->getStructureElementId() == structureElementId) { mse = obj; break; } } if (!mse) return result; const MainFootprint &footprint = mse->getFootprint(); ReplyMessage::XYPoint newPoint; result.reserve(footprint.elements().size()); const double angleDegree = mse->getData().angle(); for (const FootprintElement &fpElem : footprint.elements()) { const QPointF offset = rotatePoint(fpElem.relPosition().offsetX(), fpElem.relPosition().offsetY(), angleDegree); newPoint.x = offset.x(); newPoint.y = offset.y(); result.append(newPoint); } return result; } //--------------------------------------------------------------------------------------------------------- QVector DataManager::entriesForScheduleId(int32_t scheduleId) const { using namespace Messages; QVector result; PlannedMountingMessage::MountingEntry entry; QSet involvedBuildingIds; std::shared_ptr structEleHandler = m_mainHandler->getHandlerMainStructureElement(); for (const MountingPointPlan ¤tPlan : m_mainHandler->getHandlerMainSchedule()->getMountingPointPlans(scheduleId)) { const auto path = structEleHandler->getStructureElement(currentPlan.structureElementId())->getPath(); int32_t buildingId = -1; if (path.size()) buildingId = path[0]; if (involvedBuildingIds.contains(buildingId)) continue; involvedBuildingIds.insert(buildingId); entry.id = buildingId; entry.state = stateForBuilding(buildingId); result.append(entry); } return result; } //--------------------------------------------------------------------------------------------------------- int32_t DataManager::areaIdForScheduleId(int32_t scheduleId) const { const auto mountingPointPlans = m_mainHandler->getHandlerMainSchedule()->getMountingPointPlans(scheduleId); std::shared_ptr structureElementHandler = m_mainHandler->getHandlerMainStructureElement(); for (const auto &data : mountingPointPlans) { int32_t buildingId = structureElementHandler->getStructureElement(data.structureElementId())->getPath()[0]; return structureElementHandler->getStructureElement(buildingId)->getParentId(); } return -1; } //--------------------------------------------------------------------------------------------------------- int32_t DataManager::stateForBuilding(int32_t buildingId) const { bool isFullyMounted = true; bool isPartlyMounted = false; ObjectMainStructureElement *objMse = m_mainHandler->getHandlerMainStructureElement()->getMainStructureElement(buildingId); if (!objMse) return -1; const auto seElements = objMse->getStructureElements(); for (ObjectStructureElement *currentElement : seElements) { if (currentElement->getStructureElementTypeId().underlying() == StructureElementType::MountingPoint) { bool isMountingPointMounted = isMounted(currentElement->getId()); isFullyMounted &= isMountingPointMounted; isPartlyMounted |= isMountingPointMounted; } } if (isFullyMounted) return 1; if (isPartlyMounted) return 0; return -1; } //--------------------------------------------------------------------------------------------------------- bool DataManager::isMounted(int32_t mountingPointId) const { return getMountedAssetId(mountingPointId) != -1; } //--------------------------------------------------------------------------------------------------------- bool DataManager::isPlannedObject(int32_t objectId) const { std::shared_ptr structEleHandler = m_mainHandler->getHandlerMainStructureElement(); for (const int mainScheduleId : m_mainHandler->getHandlerMainSchedule()->getMainScheduleMap().keys()) { for (const auto &mpp : m_mainHandler->getHandlerMainSchedule()->getMountingPointPlans(mainScheduleId)) { const auto path = structEleHandler->getStructureElement(mpp.structureElementId())->getPath(); if (!path.size()) continue; if (path[0] == objectId) return true; } } return false; } //--------------------------------------------------------------------------------------------------------- QVector DataManager::entriesForBuildingInSchedule(int32_t scheduleId, int32_t buildingId) const { using namespace Messages; QVector result; ObjectMountingMessage::PlannedEntry entry; ObjectMainStructureElement *objMse = m_mainHandler->getHandlerMainStructureElement()->getMainStructureElement(buildingId); if (!objMse) return result; const auto seElements = objMse->getStructureElements(); for (ObjectStructureElement *currentElement : seElements) { if (currentElement->getStructureElementTypeId().underlying() == StructureElementType::MountingPoint) { MountingPointState mountingPointState = getMountingPointState(currentElement->getId(), scheduleId); if (mountingPointState != MountingPointState::Idle) { entry.id = currentElement->getId(); entry.assetId = getMountedAssetId(currentElement->getId()); entry.planningState = mountingPointState == MountingPointState::Empty ? 0 : 1; result.append(entry); } } } return result; } //--------------------------------------------------------------------------------------------------------- int32_t DataManager::getMountedAssetId(int32_t mountingPointId) const { const auto mountingPointAssetMap = m_mainHandler->getHandlerMountingPointAsset()->getMountingPointAssetMap(); for (const auto &p : mountingPointAssetMap) { if (p->getStructureElementId() == mountingPointId) return p->getAssetId(); } return -1; } //--------------------------------------------------------------------------------------------------------- int32_t DataManager::mountingPointIdFromBarcode(const QString &barcode) const { const auto structEleMap = m_mainHandler->getHandlerMainStructureElement()->getStructureElementMap(); const auto barcodeStd(barcode.toStdString()); for (const auto &p : structEleMap) { if (p->getStructureElementTypeId().underlying() == StructureElementType::MountingPoint && p->getData().barcode() == barcodeStd) return p->getId(); } return -1; } //--------------------------------------------------------------------------------------------------------- int32_t DataManager::assetIdFromBarcode(const QString &barcode) const { const auto assetMap = m_mainHandler->getHandlerInstrumentationAsset()->getObjectInstrumentationAssetMap(); const auto barcodeStd(barcode.toStdString()); for (const auto &p : assetMap) { if (p->getData().barcode() == barcodeStd) return p->getId(); } return -1; } //--------------------------------------------------------------------------------------------------------- Messages::AssetData DataManager::assetData(int32_t assetId) const { return assetData(m_mainHandler->getHandlerInstrumentationAsset()->getAssetFromId(assetId)); } //--------------------------------------------------------------------------------------------------------- Messages::AssetData DataManager::assetData(const ObjectInstrumentationAsset *asset) const { Messages::AssetData result; if (asset == nullptr) return result; result.mountingPointId = -1; const auto mountingPointAssetMap = m_mainHandler->getHandlerMountingPointAsset()->getMountingPointAssetMap(); for (const auto &p : mountingPointAssetMap) { if (p->getAssetId() == asset->getId()) { result.mountingPointId = p->getStructureElementId(); break; } } result.id = asset->getId(); result.assetTypeId = asset->getData().mountingPointTypeId().underlying(); result.assetTag = QString::fromStdString(asset->getData().barcode()); result.designation = QString::fromStdString(asset->getData().name()); result.hostname = QString::fromStdString(asset->getData().hostname()); result.state = toString(asset->getData().assetStateId()); result.time = QDateTime::fromMSecsSinceEpoch(asset->getData().lastUpdated()).toString(QStringLiteral("dd:MM:yy hh:mm")); if (asset->getData().assetStateId() == InstrumentationAssetState::Defect) result.errorDescription = QObject::tr("Instrumentation asset not working properly"); return result; } //--------------------------------------------------------------------------------------------------------- MountingPointState DataManager::getMountingPointState(int32_t mountingPointId, int32_t scheduleId) const { for (const auto &data : m_mainHandler->getHandlerMainSchedule()->getMountingPointPlans(scheduleId)) { if (data.structureElementId() == mountingPointId) return data.mountingPointState(); } return MountingPointState::Idle; }