Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

+212
View File
@@ -0,0 +1,212 @@
#
# $Id$
# $HeadURL$
# $Author$
#
INCLUDE(MacroRTIDDSGen)
INCLUDE(MacroCodeGenIdl)
SET(xml_FILE ism_service.xml)
#
# --- Library svcIsmCommon --------------------------------------------------------------------------------
#
SET(SRCS_common
ism_export.h
ism_db_impl_custom.cpp
ism_db_impl_custom.h
logger.cpp
logger.h
)
# Generate ism_enums.idl / ism.idl
CODEGEN_IDL_SVC(SRCS_common ${xml_FILE})
# Generate ism_db_impl.cpp/.h, ism_db.h
CODEGEN_DATABASE(SRCS_common ${xml_FILE})
# Generate *.cpp/*.hpp from idl
RTIDDSGEN(SRCS_common ism_enums.idl)
RTIDDSGEN(SRCS_common ism.idl)
# Generate ism_dt[s,c]_types.h, ism_ft[s,c]_types.h
CODEGEN_TOPIC_TYPEDEFS(SRCS_common ${xml_FILE})
# generate ism_[d|f]tc.h
CODEGEN_CLIENT_TOPICS_IFC(SRCS_common ${xml_FILE})
NGL_ADD_LIBRARY(AAR SV WS HLA svcIsmCommon SHARED ${SRCS_common})
NGL_TARGET_INCLUDE_DIRECTORIES(svcIsmCommon
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
${CMAKE_CURRENT_BINARY_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(svcIsmCommon
PRIVATE
RTI::nddscpp2
PUBLIC
Qt5::Core
ddscore
LtsUtilsCore
ngldb
NGLLogger
)
NGL_INSTALL_TARGET(svcIsmCommon)
#
# --- Library svcIsmClient --------------------------------------------------------------------------------
#
SET(SRCS_client
ism_export.h
ism_dtc_impl_custom.cpp
ism_dtc_impl_custom.h
parse_building_xml.cpp
parse_building_xml.h
)
# generate ism_[d|f]tc_impl.[cpp|h]
CODEGEN_CLIENT_TOPICS_IMPL(SRCS_client ${xml_FILE})
NGL_ADD_LIBRARY(AAR SV WS HLA svcIsmClient SHARED ${SRCS_client})
NGL_TARGET_INCLUDE_DIRECTORIES(svcIsmClient
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
${CMAKE_CURRENT_BINARY_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(svcIsmClient
PRIVATE
RTI::nddscpp2
ddsconnector
Qt5::Xml
PUBLIC
svcIsmCommon
ddsftc
LtsCoordTrans
Qt5::Gui
)
NGL_INSTALL_TARGET(svcIsmClient)
#
# --- Library svcIsmServer --------------------------------------------------------------------------------
#
SET(SRCS_server
ism_export.h
ism_db_impl_custom.cpp
ism_db_impl_custom.h
convert_db_to_dds.h
)
# generate ism_[d|f]ts.h, ism_[d|f]ts_impl.[cpp|h]
CODEGEN_SERVER_TOPICS(SRCS_server ${xml_FILE})
NGL_ADD_LIBRARY(WS AAR SV svcIsmServer SHARED ${SRCS_server})
NGL_TARGET_INCLUDE_DIRECTORIES(svcIsmServer
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
${CMAKE_CURRENT_BINARY_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(svcIsmServer
PRIVATE
RTI::nddscpp2
ddsconnector
ddsfts
PUBLIC
svcIsmCommon
ngldb
LtsUtilsCore
LtsWebSocketServer
)
NGL_INSTALL_TARGET(svcIsmServer)
#
# --- Topic Type Plugin --------------------------------------------------------------
#
CREATE_TOPIC_TYPE_PLUGIN(${xml_FILE})
#
# --- Executable svcInfrastructureManagement (sISM) -------------------------------------------------
#
SET(SRCS_exe
base.cpp
base.h
dds_handler.cpp
dds_handler.h
handler_effect_area.cpp
handler_effect_area.h
handler_instrumentation_asset.cpp
handler_instrumentation_asset.h
handler_main_schedule.cpp
handler_main_schedule.h
handler_main_structure_element.cpp
handler_main_structure_element.h
handler_mounting_point_asset.cpp
handler_mounting_point_asset.h
handler_special_area.cpp
handler_special_area.h
main.cpp
main_handler.cpp
main_handler.h
object_effect_area.cpp
object_effect_area.h
object_instrumentation_asset.cpp
object_instrumentation_asset.h
object_main_schedule.cpp
object_main_schedule.h
object_main_structure_element.cpp
object_main_structure_element.h
object_mounting_point_asset.cpp
object_mounting_point_asset.h
object_special_area.cpp
object_special_area.h
object_structure_element.cpp
object_structure_element.h
settings.cpp
settings.h
WebSocketInterface/data_manager.cpp
WebSocketInterface/data_manager.h
WebSocketInterface/json_keys.h
WebSocketInterface/websocket_interface_handler.cpp
WebSocketInterface/websocket_interface_handler.h
WebSocketInterface/Messages/client_message.cpp
WebSocketInterface/Messages/client_message.h
WebSocketInterface/Messages/reply_message.cpp
WebSocketInterface/Messages/reply_message.h
log4cxx_ism.props
${xml_FILE}
)
# Generate ism.sql, ism.xml
CODEGEN_SQL(SRCS_exe ${xml_FILE})
NGL_ADD_SVC_ICON(SRCS_exe)
NGL_ADD_EXECUTABLE(AAR SV svcInfrastructureManagement ${SRCS_exe})
NGL_TARGET_LINK_LIBRARIES(svcInfrastructureManagement
Qt5::Core
Qt5::Xml
Qt5::Gui
svcCoreClient
svcIsmCommon
svcIsmServer
ddsconnector
nglsettings
ProjectConfig
LtsCommandLineParser
NGLLogger
nglcoreapplication
LtsCoordTrans
LtsWebSocketServer
svcAsmClient
svcExmClient
ngltools
)
NGL_INSTALL_TARGET(svcInfrastructureManagement)
NGL_INSTALL(AAR SV FILES log4cxx_ism.props DESTINATION bin)
NGL_ADD_TARGET_LINK(svcInfrastructureManagement sISM)
# Uncomment if necessary
#ADD_SUBDIRECTORY(UnitTests)
ADD_SUBDIRECTORY(ModuleTests)
ADD_SUBDIRECTORY(ImportBuildings)
@@ -0,0 +1,23 @@
#
# $Id$
# $HeadURL$
# $Author$
#
SET(SRCS_IMPORT_BUILDINGS
ism_import_buildings.cpp
ism_import_buildings.h
)
NGL_ADD_EXECUTABLE(AAR SV WS ismImportBuildings ${SRCS_IMPORT_BUILDINGS})
NGL_TARGET_LINK_LIBRARIES(ismImportBuildings
Qt5::Core
RTI::nddscpp2
svcIsmClient
LtsCommandLineParser
ddsconnector
nglcoreapplication
LtsUtilsCoreHeaderOnly
Qt5::WebSockets
)
NGL_INSTALL_TARGET(ismImportBuildings)
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,99 @@
/**
* @RDE_HEADER@
* ISM Test Import XML
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-28
*/
#pragma once
#include <InfrastructureManagement/ism_ftc.h>
#include <InfrastructureManagement/ism_dtc.h>
#include <DDS/DDSConnector/dds_connector.h>
#include <InfrastructureManagement/logger.h>
#include <QVector>
//----------------------------------------------------------------------------------------------
namespace InfrastructureManagement
{
class IsmImportBuildings : public QObject
, protected InfrastructureManagement::Interface::Ftc::MainStructureElementModifyReplyHandler
, protected InfrastructureManagement::Interface::Ftc::MainStructureElementRemoveReplyHandler
, protected InfrastructureManagement::Interface::Ftc::MountingPointAssetRemoveReplyHandler
, protected InfrastructureManagement::Interface::Ftc::MountingPointAssetModifyReplyHandler
, protected InfrastructureManagement::Interface::Ftc::MountingPointPlanModifyReplyHandler
, protected InfrastructureManagement::Interface::Ftc::StructureElementModifyReplyHandler
{
Q_OBJECT
public:
struct ImportData
{
QString xmlFileName;
QString vulFileName;
QString egcuToRoomFileName;
QString soundAreaFileName;
Core::GeoPosition geoPos;
double angleDegree = 0;
int exerciseId = 0;
int externalWlsId = 0;
int buildingId = -1;
int bauabschnitt = -1;
};
explicit IsmImportBuildings(QObject *parent = nullptr);
bool init(int domainId, const QUrl &tcpDiscoveryUrl);
void import(const ImportData &importData);
void import(const QVector<ImportData> &importData);
void remove(const QVector<int> &ids);
Q_SIGNALS:
void importDone();
void removeDone();
protected Q_SLOTS:
void doImport();
void importNext();
protected:
void onMainStructureElementModifyReply(const Core::FunctionReplyObject &replyObject) override final;
void onMainStructureElementRemoveReply(const Core::FunctionReplyObject &replyObject) override final;
void onMountingPointPlanModifyReply(const Core::FunctionReplyObject &reply) override final;
void onMountingPointAssetModifyReply(const Core::FunctionReplyObject &reply) override final;
void onMountingPointAssetRemoveReply(const Core::FunctionReplyObject &reply) override final;
void onStructureElementModifyReply(const Core::FunctionReplyObject &reply) override final;
bool handleReply(const Core::FunctionReplyObject &replyObject);
private:
void removeNext();
void remove(int buildingId);
void doRemove(int buildingId);
MainStructureElement mainStructureElementByName(const std::string &name) const;
QHash</* scheduleId */ int, std::vector<MountingPointPlan> > MountingPointPlanByScheduleOfStructureElements(const QVector<qint32> &structureElementIds) const;
QVector<MountingPointAsset> mountingsOfStructureElements(const QVector<qint32> &structureElementIds) const;
QVector<std::string> pathWithNames(const StructureElement &structureElement, const MainStructureElement &mainStructureElement) const;
std::string structureElementNameById(qint32 id, const std::vector<StructureElement> &structureElements) const;
StructureElement structureElementById(qint32 id, const MainStructureElement &mainStructureElement) const;
void createNewMainStructureElement(const MainStructureElementModifyRequest &request);
void restoreData(const MainStructureElement &oldMainStructureElement,
const QMap<qint32, QVector<std::string>>&oldNamePaths,
const QVector<MountingPointAsset>& mountings,
const QHash<int, std::vector<MountingPointPlan> > &mountingPointPlansBySchedule);
void unmountAssetsOfBuliding(qint32 buildingId);
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_dtc;
std::shared_ptr<InfrastructureManagement::Interface::Ftc> m_ftc;
QVector<int> m_idsToBeRemoved;
QVector<ImportData> m_importData;
ImportData m_currentData;
int m_curImportIdx;
bool m_hasOneRemoved = true;
bool m_isInRestoringMode = false;
LOGGER_T m_logger;
};
} // namespace InfrastructureManagement
@@ -0,0 +1,39 @@
#
# $Id$
# $HeadURL$
# $Author$
#
IF(TARGET svcIsmClient)
IF(BUILD_TESTING)
SET(SRCS_TEST
ism_tests.cpp
ism_tests.h
../settings.h
../settings.cpp
)
# Testing FunctionTopic Functionality (FTC)
ADD_EXECUTABLE(ismTests ${SRCS_TEST})
TARGET_LINK_LIBRARIES(ismTests
Qt5::Core
Qt5::Test
RTI::nddscpp2
ngldb
nglsettings
ngltools
svcIsmClient
svcIsmServer
LtsCommandLineParser
ddsconnector
nglcoreapplication
LtsUtilsCoreHeaderOnly
)
IF(NOT BUILD_RPM)
NGL_INSTALL(SV TARGETS ismTests DESTINATION bin/test)
NGL_INSTALL(SV FILES ../log4cxx_ism.props DESTINATION bin/test)
ENDIF()
ENDIF()
ENDIF()
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,26 @@
Parameters,Comment
-t 101,1. Create Main Structure Element
-t 102 -m 1,2. Modify Main Structure Element
-t 131,3. Create Instrumentation Assets
-t 132 -a 2,4. Modify Instrumentation Assets
-t 141 -s 8 -a 2,5. Create Mounting Point Asset
-t 151,6. Create Mounting Point Schedule
-t 152 -a 1,7. Modify Mounting Point Schedule
-t 161 -a 1 -m 8 -s 9,8. Create Mounting Point Plan
-t 162 -a 1 -s 9,9. Modify Mounting Point Plan
-t 163 -a 1 -s 9,10. Remove Mounting Point Plan
-t 153 -a 2,11. Remove Mounting Point Schedule (without MPPs)
-t 153 -a 1,12. Remove Mounting Point Schedule (with MPPs)
-t 143 -s 8 -a 2,13. Remove Mounting Point Asset
-t 133 -a 1,14. Remove Instrumentation Asset (1)
-t 133 -a 2,15. Remove Instrumentation Asset (2)
-t 133 -a 3,16. Remove Instrumentation Asset (3)
-t 133 -a 4,17. Remove Instrumentation Asset (4)
-t 133 -a 5,18. Remove Instrumentation Asset (5)
-t 101,19. Create Main Structure Element (prepare AVM)
-t 131,20. Create Instrumentation Assets (prepare AVM tests)
1 Parameters Comment
2 -t 101 1. Create Main Structure Element
3 -t 102 -m 1 2. Modify Main Structure Element
4 -t 131 3. Create Instrumentation Assets
5 -t 132 -a 2 4. Modify Instrumentation Assets
6 -t 141 -s 8 -a 2 5. Create Mounting Point Asset
7 -t 151 6. Create Mounting Point Schedule
8 -t 152 -a 1 7. Modify Mounting Point Schedule
9 -t 161 -a 1 -m 8 -s 9 8. Create Mounting Point Plan
10 -t 162 -a 1 -s 9 9. Modify Mounting Point Plan
11 -t 163 -a 1 -s 9 10. Remove Mounting Point Plan
12 -t 153 -a 2 11. Remove Mounting Point Schedule (without MPPs)
13 -t 153 -a 1 12. Remove Mounting Point Schedule (with MPPs)
14 -t 143 -s 8 -a 2 13. Remove Mounting Point Asset
15 -t 133 -a 1 14. Remove Instrumentation Asset (1)
16 -t 133 -a 2 15. Remove Instrumentation Asset (2)
17 -t 133 -a 3 16. Remove Instrumentation Asset (3)
18 -t 133 -a 4 17. Remove Instrumentation Asset (4)
19 -t 133 -a 5 18. Remove Instrumentation Asset (5)
20 -t 101 19. Create Main Structure Element (prepare AVM)
21 -t 131 20. Create Instrumentation Assets (prepare AVM tests)
@@ -0,0 +1,129 @@
/**
* @RDE_HEADER@
* ISM Function Topic test executable
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-28
*/
#pragma once
#include <InfrastructureManagement/ism_ftc.h>
#include <InfrastructureManagement/ism_dtc.h>
#include <InfrastructureManagement/ism_ftc_types.h>
#include <InfrastructureManagement/ism_db.h>
#include <InfrastructureManagement/ism_db_impl_custom.h>
#include <InfrastructureManagement/logger.h>
#include <DDS/DDSConnector/dds_connector.h>
#include <ngldb/db_service_handler.h>
#include <ngldb/dbconnection.h>
namespace InfrastructureManagement
{
using DbHandler = NGLDB::DbServiceHandler<DatabaseInterface>;
class IsmTests : public QObject
, protected InfrastructureManagement::Interface::Ftc::InstrumentationAssetModifyReplyHandler
, protected InfrastructureManagement::Interface::Ftc::InstrumentationAssetRemoveReplyHandler
, protected InfrastructureManagement::Interface::Ftc::MountingPointAssetModifyReplyHandler
, protected InfrastructureManagement::Interface::Ftc::MountingPointAssetRemoveReplyHandler
, protected InfrastructureManagement::Interface::Ftc::MainScheduleModifyReplyHandler
, protected InfrastructureManagement::Interface::Ftc::MainScheduleRemoveReplyHandler
, protected InfrastructureManagement::Interface::Ftc::MountingPointPlanModifyReplyHandler
, protected InfrastructureManagement::Interface::Ftc::MainStructureElementModifyReplyHandler
, protected InfrastructureManagement::Interface::Ftc::MainStructureElementModifyBridgeStatusReplyHandler
, protected InfrastructureManagement::Interface::Ftc::MainStructureElementRemoveReplyHandler
, protected InfrastructureManagement::Interface::Ftc::StructureElementModifyReplyHandler
, protected InfrastructureManagement::Interface::Ftc::InstrumentationAssetSetStateReplyHandler
{
Q_OBJECT
public:
explicit IsmTests(QObject *parent = nullptr);
~IsmTests();
bool init(int domainId, int testId, int assetId, int mainStructureElementId, int structureElementId, int indexNo);
bool testsSuccessful() const { return m_bTestsSuccessful; }
public Q_SLOTS:
void startTest();
protected Q_SLOTS:
// assets
void tryCreateAsset();
void tryModifyAsset();
void tryRemoveAsset();
void tryUnmountAsset();
// main structure elements
void tryCreateMainStructureElement();
void tryModifyMainStructureElement();
void tryRemoveMainStructureElement();
void tryCreateBridge();
void tryChangeBridgeStatus();
// mounting point assets
void tryCreateMountingPointAsset();
void tryRemoveMountingPointAsset();
// mounting point schedule
void tryCreateMainSchedule();
void tryModifyMainSchedule();
void tryRemoveMainSchedule();
void tryChangeStatusSchedule();
void tryCopySchedule();
void checkSchedule();
// mounting point plan
void tryCreateMountingPointPlan();
protected:
// assets
void onInstrumentationAssetModifyReply(const Core::FunctionReplyObject &replyObject) override final { onModifyReply(replyObject); }
void onInstrumentationAssetRemoveReply(const Core::FunctionReplyObject &replyObject) override final { onRemoveReply(replyObject); }
void onInstrumentationAssetSetStateReply(const Core::FunctionReplyObject &replyObject) override final { onRemoveReply(replyObject); }
// main structure elements
void onMainStructureElementModifyReply(const Core::FunctionReplyObject &replyObject) override final { onModifyReply(replyObject); }
void onMainStructureElementRemoveReply(const Core::FunctionReplyObject &replyObject) override final { onRemoveReply(replyObject); }
void onMainStructureElementModifyBridgeStatusReply(const Core::FunctionReplyObject &replyObject) override final { onRemoveReply(replyObject); }
// structure elements
void onStructureElementModifyReply(const Core::FunctionReplyObject &replyObject) override final { onModifyReply(replyObject); }
// mounting point assets
void onMountingPointAssetModifyReply(const Core::FunctionReplyObject &replyObject) override final { onModifyReply(replyObject); }
void onMountingPointAssetRemoveReply(const Core::FunctionReplyObject &replyObject) override final { onRemoveReply(replyObject); }
// mounting point schedule
void onMainScheduleModifyReply(const Core::FunctionReplyObject &replyObject) override final { onModifyReply(replyObject); }
void onMainScheduleRemoveReply(const Core::FunctionReplyObject &replyObject) override final { onRemoveReply(replyObject); }
// mounting point plan
void onMountingPointPlanModifyReply(const Core::FunctionReplyObject &replyObject) override final { onModifyReply(replyObject); }
// general
void onError(const QString &reason);
void onCreateReply(const Core::FunctionReplyObject &replyObject);
void onModifyReply(const Core::FunctionReplyObject &replyObject);
void onRemoveReply(const Core::FunctionReplyObject &replyObject);
void failExit();
private:
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
std::shared_ptr<InfrastructureManagement::Interface::Ftc> m_ftc;
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_dtc;
std::shared_ptr<InfrastructureManagement::DatabaseInterface> m_db;
std::shared_ptr<InfrastructureManagement::DbHandler> m_dbHandler;
// given
int m_testId;
int m_assetId; // used for mounting point schedule id as well
int m_mainStructureElementId;
int m_structureElementId;
int m_indexNo;
// found per custom dtc methods
int m_mountingPointAssetId;
int m_mountingPointPlanId;
bool m_bTestsSuccessful;
bool m_replyFinished;
LOGGER_T m_logger;
};
} // namespace InfrastructureManagement
@@ -0,0 +1,409 @@
/**
* @RDE_HEADER@
* The ClientMessage class is an abstract base class for concrete ClientMessage objects
* $Id$
* $HeadURL$
* $Author$
* Created by Hannes Baeuerle, SLSE, 2016-08-25
*/
#include "client_message.h"
#include "WebSocketInterface/Messages/reply_message.h"
#include "WebSocketInterface/json_keys.h"
#include "WebSocketInterface/data_manager.h"
#include <QtCore/QJsonDocument>
#include <QtCore/QUuid>
#include <QSet>
namespace InfrastructureManagement
{
namespace WebSocketInterface
{
namespace Messages
{
using namespace JsonKeys;
template <typename T>
static QJsonArray fillArray(const T &messages)
{
QJsonArray arr;
for (const auto &currentMsg : messages)
arr += currentMsg.json().value(LtsWebSocket::JsonKeys::DATA());
return arr;
}
// ####### ClientMessageFactory begin #######
ClientMessageFactory::ClientMessageFactory(DataManager *dataManager)
: LtsWebSocket::AbstractClientMessageFactory(getLogger("ClientMessageFactory"))
, m_dataManager(dataManager)
{}
LtsWebSocket::AbstractClientMessage *ClientMessageFactory::createMessage(LtsWebSocket::ReplyHandler *client,
const QString &message)
{
LtsWebSocket::AbstractClientMessage *result = checkAttributes(client, message);
if (result)
return result;
if (m_type == OcBaseDownload::WebSocketInterface::JsonKeys::BASE_DL_REQUEST())
result = new BaseDlRequest(m_dataManager, client, m_type, m_typeId, m_uuid);
else if (m_type == GET_ASSETS())
result = new GetAssetsMessage(m_dataManager, client, m_type, m_typeId, m_uuid, m_data);
else if (m_type == GET_ASSET_STATE())
result = new GetAssetStateMessage(m_dataManager, client, m_type, m_typeId, m_uuid, m_data);
else if (m_type == GET_BUILDING_STATE())
result = new GetBuildingStateMessage(m_dataManager, client, m_type, m_typeId, m_uuid, m_data);
else if (m_type == GET_ESSENTIALS())
result = new GetEssentialsMessage(m_dataManager, client, m_type, m_typeId, m_uuid, m_data);
else if (m_type == GET_OBJECT_MOUNTING())
result = new GetObjectMountingMessage(m_dataManager, client, m_type, m_typeId, m_uuid, m_data);
else if (m_type == GET_PLANNED_MOUNTINGS())
result = new GetPlannedMountingsMessage(m_dataManager, client, m_type, m_typeId, m_uuid);
else if (m_type == MOUNT())
result = new MountMessage(m_dataManager, client, m_type, m_typeId, m_uuid, m_data);
else if (m_type == MOUNT_TAG())
result = new MountTagMessage(m_dataManager, client, m_type, m_typeId, m_uuid, m_data);
else if (m_type == OBJECT_MOUNTING_READY())
result = new ObjectMountingReadyMessage(m_dataManager, client, m_type, m_typeId, m_uuid, m_data);
else if (m_type == UNMOUNT_AREA())
result = new UnmountAreaMessage(m_dataManager, client, m_type, m_typeId, m_uuid, m_data);
else if (m_type == UNMOUNT_ASSET())
result = new UnmountAssetMessage(m_dataManager, client, m_type, m_typeId, m_uuid, m_data);
else if (m_type == UNMOUNT_MOUNTING_POINT())
result = new UnmountMountingPointMessage(m_dataManager, client, m_type, m_typeId, m_uuid, m_data);
else if (m_type == UNMOUNT_OBJECT())
result = new UnmountObjectMessage(m_dataManager, client, m_type, m_typeId, m_uuid, m_data);
return checkResult(client, message, result);
}
// ####### ClientMessageFactory end #######
// ####### ClientMessage begin #######
ClientMessage::ClientMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data)
: LtsWebSocket::AbstractClientMessage(client, type, typeId, uuid, data)
, m_dataManager(dataManager)
{}
// ####### ClientMessage end #######
// ####### GetAssetStateMessage begin #######
void GetAssetStateMessage::process()
{
m_client->addReply(m_dataManager->getAssetState(m_data.toObject().value(ASSET_ID()).toInt(),
m_data.toObject().value(ASSET_TAG()).toString(),
m_uuid));
}
bool GetAssetStateMessage::hasValidData() const
{
// one (exclusive) value has to be set
return ((!m_data.toObject().value(ASSET_ID()).isDouble() && m_data.toObject().value(ASSET_TAG()).isString()) ||
(m_data.toObject().value(ASSET_ID()).isDouble() && !m_data.toObject().value(ASSET_TAG()).isString()));
}
GetAssetStateMessage::GetAssetStateMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data)
: ClientMessage(dataManager, client, type, typeId, uuid, data)
{
}
// ####### GetAssetStateMessage end #######
// ####### GetAssetStateMessage begin #######
void GetAssetsMessage::process()
{
const QJsonValue val = m_data.toObject().value(ASSET_TYPE_ID());
QSet<int> assetTypeIds;
if (val.isArray())
{
const QJsonArray ary = val.toArray();
assetTypeIds.reserve(ary.size());
for (const auto &ele : ary)
assetTypeIds += ele.toInt();
}
else
assetTypeIds += val.toInt();
m_client->addReply(m_dataManager->getAssets(assetTypeIds,
m_uuid));
}
bool GetAssetsMessage::hasValidData() const
{
const auto val = m_data.toObject().value(ASSET_TYPE_ID());
return val.isDouble() || val.isArray();
}
GetAssetsMessage::GetAssetsMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data)
: ClientMessage(dataManager, client, type, typeId, uuid, data)
{
}
// ####### GetAssetStateMessage end #######
// ####### GetBuildingStateMessage begin #######
void GetBuildingStateMessage::process()
{
m_client->addReply(m_dataManager->getBuildingState(m_data.toObject().value(BUILDING_ID()).toInt(),
m_uuid));
}
bool GetBuildingStateMessage::hasValidData() const
{
return m_data.toObject().value(BUILDING_ID()).isDouble();
}
GetBuildingStateMessage::GetBuildingStateMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data)
: ClientMessage(dataManager, client, type, typeId, uuid, data)
{
}
// ####### GetBuildingStateMessage end #######
class GetEssentialsReply final : public ReplyMessage
{
public:
GetEssentialsReply(const QJsonObject &obj, const QString &uuid)
: ReplyMessage(QStringLiteral("essentials"), 2, uuid) // Todo: Check whether typeId is correct
{
m_jsonRepresentation.insert(LtsWebSocket::JsonKeys::DATA(), obj);
}
};
// ####### GetEssentialsMessage begin #######
void GetEssentialsMessage::process()
{
const DataManager::EinruestEssentials data = m_dataManager->getEssentials(m_uuid);
QJsonObject obj;
obj[TRAINING_AREAS()] = fillArray(data.trainingAreas);
obj[AREAS()] = fillArray(data.areas);
obj[OBJECTS()] = fillArray(data.objects);
obj[LEVELS()] = fillArray(data.levels);
obj[ROOMS()] = fillArray(data.rooms);
obj[MOUNTING_POINTS()] = fillArray(data.mountingPoints);
obj[ASSET_TYPES()] = fillArray(data.assetTypes);
m_client->addReply(new GetEssentialsReply(obj, m_uuid));
}
bool GetEssentialsMessage::hasValidData() const
{
return true; // no data part to validate
}
GetEssentialsMessage::GetEssentialsMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data)
: ClientMessage(dataManager, client, type, typeId, uuid, data)
{
}
// ####### GetEssentialsMessage end #######
// ####### GetPlannedMountingMessage begin #######
class PlannedMountingsReply final : public ReplyMessage
{
public:
PlannedMountingsReply(const QJsonArray &arr, const QString &uuid)
: ReplyMessage(QStringLiteral("plannedMountings"), 13, uuid) // Todo: Check whether typeId is correct
{
m_jsonRepresentation.insert(LtsWebSocket::JsonKeys::DATA(), arr);
}
};
void GetPlannedMountingsMessage::process()
{
const QVector<PlannedMountingMessage> plannedMountings = m_dataManager->getPlannedMounting(m_uuid);
m_client->addReply(new PlannedMountingsReply(fillArray(plannedMountings), m_uuid));
}
bool GetPlannedMountingsMessage::hasValidData() const
{
return true; // no data part to validate
}
GetPlannedMountingsMessage::GetPlannedMountingsMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid)
: ClientMessage(dataManager, client, type, typeId, uuid)
{
}
// ####### GetPlannedMountingMessage end #######
// ####### GetObjectMountingMessage begin #######
void GetObjectMountingMessage::process()
{
m_client->addReply(m_dataManager->getObjectMounting(m_data.toObject().value(PLANNED_MOUNTING_ID()).toInt(),
m_data.toObject().value(OBJECT_ID()).toInt(),
m_uuid));
}
bool GetObjectMountingMessage::hasValidData() const
{
return m_data.toObject().value(PLANNED_MOUNTING_ID()).isDouble() &&
m_data.toObject().value(OBJECT_ID()).isDouble();
}
GetObjectMountingMessage::GetObjectMountingMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data)
: ClientMessage(dataManager, client, type, typeId, uuid, data)
{
}
// ####### GetObjectMountingMessage end #######
// ####### MountMessage begin #######
void MountMessage::process()
{
m_client->addReply(m_dataManager->mount(m_data.toObject().value(MOUNTING_POINT_ID()).toInt(),
m_data.toObject().value(ASSET_ID()).toInt(),
m_type,
m_uuid));
}
bool MountMessage::hasValidData() const
{
return m_data.toObject().value(MOUNTING_POINT_ID()).isDouble() &&
m_data.toObject().value(ASSET_ID()).isDouble();
}
MountMessage::MountMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data)
: ClientMessage(dataManager, client, type, typeId, uuid, data)
{
}
// ####### MountMessage end #######
// ####### MountTagMessage begin #######
void MountTagMessage::process()
{
m_client->addReply(m_dataManager->mountTag(m_data.toObject().value(MOUNTING_POINT_TAG()).toString(),
m_data.toObject().value(ASSET_TAG()).toString(),
m_type,
m_uuid));
}
bool MountTagMessage::hasValidData() const
{
// at least one
return m_data.toObject().value(ASSET_TAG()).isString() || m_data.toObject().value(MOUNTING_POINT_TAG()).isString();
}
MountTagMessage::MountTagMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data)
: ClientMessage(dataManager, client, type, typeId, uuid, data)
{
}
// ####### MountTagMessage end #######
// ####### ObjectMountingReadyMessage begin #######
void ObjectMountingReadyMessage::process()
{
m_client->addReply(m_dataManager->objectMountingReady(m_data.toObject().value(PLANNED_MOUNTING_ID()).toInt(),
m_data.toObject().value(OBJECT_ID()).toInt(),
m_type,
m_uuid));
}
bool ObjectMountingReadyMessage::hasValidData() const
{
return m_data.toObject().value(PLANNED_MOUNTING_ID()).isDouble() &&
m_data.toObject().value(OBJECT_ID()).isDouble();
}
ObjectMountingReadyMessage::ObjectMountingReadyMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data)
: ClientMessage(dataManager, client, type, typeId, uuid, data)
{
}
// ####### ObjectMountingReadyMessage end #######
// ####### UnmountAreaMessage begin #######
void UnmountAreaMessage::process()
{
m_client->addReply(m_dataManager->unmountArea(m_data.toObject().value(AREA_ID()).toInt(),
m_type,
m_uuid));
}
bool UnmountAreaMessage::hasValidData() const
{
return m_data.toObject().value(AREA_ID()).isDouble();
}
UnmountAreaMessage::UnmountAreaMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data)
: ClientMessage(dataManager, client, type, typeId, uuid, data)
{
}
// ####### UnmountAreaMessage end #######
// ####### UnmountAssetMessage begin #######
void UnmountAssetMessage::process()
{
m_client->addReply(m_dataManager->unmountAsset(m_data.toObject().value(ASSET_ID()).toInt(),
m_type,
m_uuid));
}
bool UnmountAssetMessage::hasValidData() const
{
return m_data.toObject().value(ASSET_ID()).isDouble();
}
UnmountAssetMessage::UnmountAssetMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data)
: ClientMessage(dataManager, client, type, typeId, uuid, data)
{
}
// ####### UnmountAssetMessage end #######
// ####### UnmountMountingPointMessage begin #######
void UnmountMountingPointMessage::process()
{
m_client->addReply(m_dataManager->unmountMountingPoint(m_data.toObject().value(MOUNTING_POINT_ID()).toInt(),
m_type,
m_uuid));
}
bool UnmountMountingPointMessage::hasValidData() const
{
return m_data.toObject().value(MOUNTING_POINT_ID()).isDouble();
}
UnmountMountingPointMessage::UnmountMountingPointMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data)
: ClientMessage(dataManager, client, type, typeId, uuid, data)
{
}
// ####### UnmountMountingPointMessage end #######
// ####### UnmountObjectMessage begin #######
void UnmountObjectMessage::process()
{
m_client->addReply(m_dataManager->unmountObject(m_data.toObject().value(OBJECT_ID()).toInt(),
m_type,
m_uuid));
}
bool UnmountObjectMessage::hasValidData() const
{
return m_data.toObject().value(OBJECT_ID()).isDouble();
}
UnmountObjectMessage::UnmountObjectMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data)
: ClientMessage(dataManager, client, type, typeId, uuid, data)
{
}
// ####### UnmountObjectMessage end #######
// ####### BaseDlRequest begin #######
BaseDlRequest::BaseDlRequest(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid)
: ClientMessage(dataManager, client, type, typeId, uuid)
{}
void BaseDlRequest::process()
{
m_client->addReply(m_dataManager->assetBaseData(m_uuid));
m_client->addReply(m_dataManager->mainStructureElementBaseData(m_uuid));
m_client->addReply(m_dataManager->structureElementBaseData(m_uuid));
m_client->addReply(m_dataManager->structureElementFootprintBaseData(m_uuid));
m_client->addReply(m_dataManager->mountingPointAssetBaseData(m_uuid));
m_client->addReply(m_dataManager->mountingPointScheduleBaseData(m_uuid));
m_client->addReply(m_dataManager->mountingPointPlanBaseData(m_uuid));
}
bool BaseDlRequest::hasValidData() const
{
return true;
}
// ####### BaseDlRequest end #######
} // namespace Messages
} // namespace WebSocketInterface
} // namespace Infrastrukture Management
@@ -0,0 +1,211 @@
/**
* @RDE_HEADER@
* The ClientMessage class is an abstract base class for concrete ClientMessage objects
* $Id$
* $HeadURL$
* $Author$
* Created by Hannes Baeuerle, SLSE, 2016-08-25
*/
#pragma once
#include <QtCore/QJsonObject>
#include <LtsWebSocket/client_message_factory.h>
#include <LtsWebSocket/client_message.h>
#include "logger.h"
namespace InfrastructureManagement
{
namespace WebSocketInterface
{
class DataManager;
namespace Messages
{
/**
* @brief The ClientMessageFactory class creates ClientMessages which will then be processed
*/
class ClientMessageFactory final : public LtsWebSocket::AbstractClientMessageFactory
{
public:
explicit ClientMessageFactory(DataManager *dataManager);
/**
* @brief create Only way to create a ClientMessage object
* @param message Text message which will be converted to a ClientMessage object
* @return A ClientMessage object, which represents a concrete ClientMessage
*/
LtsWebSocket::AbstractClientMessage *createMessage(LtsWebSocket::ReplyHandler *client,
const QString &message);
private:
DataManager *m_dataManager;
}; // class ClientMessageFactory
/**
* @brief The ClientMessage class is an abstract base class for concrete ClientMessage objects
*/
class ClientMessage : public LtsWebSocket::AbstractClientMessage
{
protected: // method
explicit ClientMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data = QJsonValue());
protected: // attributes
DataManager *m_dataManager;
}; // class ClientMessage
// the following classes are concrete implementation classes of ClientMessage
/**
* @brief The GetAssetStateMessage class represents the appropriate telegram
*/
class GetAssetStateMessage final : public ClientMessage
{
public:
explicit GetAssetStateMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data);
void process() override;
bool hasValidData() const override;
}; // class AssetStateMessage
/**
* @brief Retrieve all assets for the given asset type
*/
class GetAssetsMessage final : public ClientMessage
{
public:
GetAssetsMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data);
void process() override;
bool hasValidData() const override;
}; // class GetAssetsMessage
/**
* @brief The GetBuildingStateMessage class represents the appropriate telegram
*/
class GetBuildingStateMessage final : public ClientMessage
{
public:
explicit GetBuildingStateMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data);
void process() override;
bool hasValidData() const override;
}; // class GetBuildingStateMessage
/**
* @brief The GetEssentialsMessage class represents the appropriate telegram
*/
class GetEssentialsMessage final : public ClientMessage
{
public:
explicit GetEssentialsMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data);
void process() override;
bool hasValidData() const override;
}; // class GetEssentialsMessage
/**
* @brief The GetPlannedMountingMessage class represents the appropriate telegram
*/
class GetPlannedMountingsMessage final : public ClientMessage
{
public:
explicit GetPlannedMountingsMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid);
void process() override;
bool hasValidData() const override;
}; // class GetPlannedMountingMessage
/**
* @brief The GetObjectMountingMessage class represents the appropriate telegram
*/
class GetObjectMountingMessage final : public ClientMessage
{
public:
explicit GetObjectMountingMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data);
void process() override;
bool hasValidData() const override;
}; // class GetObjectMountingMessage
/**
* @brief The MountMessage class represents the appropriate telegram
*/
class MountMessage final : public ClientMessage
{
public:
explicit MountMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data);
void process() override;
bool hasValidData() const override;
}; // class MountMessage
/**
* @brief The MountTagMessage class represents the appropriate telegram
*/
class MountTagMessage final : public ClientMessage
{
public:
explicit MountTagMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data);
void process() override;
bool hasValidData() const override;
}; // class MountTagMessage
/**
* @brief The ObjectMountingReadyMessage class represents the appropriate telegram
*/
class ObjectMountingReadyMessage final : public ClientMessage
{
public:
ObjectMountingReadyMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data);
void process() override;
bool hasValidData() const override;
}; // class ObjectMountingReadyMessage
/**
* @brief The UnmountAreaMessage class represents the appropriate telegram
*/
class UnmountAreaMessage final : public ClientMessage
{
public:
explicit UnmountAreaMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data);
void process() override;
bool hasValidData() const override;
}; // class UnmountAreaMessage
/**
* @brief The UnmountAssetMessage class represents the appropriate telegram
*/
class UnmountAssetMessage final : public ClientMessage
{
public:
explicit UnmountAssetMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data);
void process() override;
bool hasValidData() const override;
}; // class UnmountAssetMessage
class UnmountMountingPointMessage final : public ClientMessage
{
public:
explicit UnmountMountingPointMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data);
void process() override;
bool hasValidData() const override;
}; // class UnmountMountingPointMessage
class UnmountObjectMessage final : public ClientMessage
{
public:
explicit UnmountObjectMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data);
void process() override;
bool hasValidData() const override;
}; // class UnmountObjectMessage
/**
* @brief The BaseDlRequest class handles the base DL request and sends multiple replys depending on the data requested
*/
class BaseDlRequest : public ClientMessage
{
public:
explicit BaseDlRequest(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const int typeId, const QString &uuid);
void process();
bool hasValidData() const;
}; // class BaseDlRequest
} // namespace Messages
} // namespace WebSocketInterface
} // namespace InfrastructureManagement
@@ -0,0 +1,329 @@
/**
* @RDE_HEADER@
* The ReplyMessage class is an abstract base class for all possible messages which are sent to the client
* $Id$
* $HeadURL$
* $Author$
* Created by Hannes Baeuerle, SLSE, 2016-08-25
*/
#include "reply_message.h"
#include <LtsWebSocket/json_keys.h>
#include "WebSocketInterface/json_keys.h"
#include <QtCore/QUuid>
#include <QtCore/QJsonDocument>
namespace InfrastructureManagement
{
namespace WebSocketInterface
{
namespace Messages
{
using namespace JsonKeys;
using namespace LtsWebSocket::JsonKeys;
// ####### ReplyMessage begin #######
QJsonObject ReplyMessage::LonLatPoint::toJSon() const
{
return {{LONGITUDE(), lon}, {LATITUDE(), lat}};
}
QJsonObject ReplyMessage::Point3d::toJSon() const
{
return {{X(), x}, {Y(), y}, {Z(), z}};
}
QJsonObject ReplyMessage::XYPoint::toJSon() const
{
return {{X(), x}, {Y(), y}};
}
ReplyMessage::ReplyMessage(const QString &type, const int typeId, const QString &uuid)
: LtsWebSocket::ReplyMessage(type, typeId, uuid)
{}
// ####### ReplyMessage end #######
// ####### OkMessage begin #######
OkMessage::OkMessage(const OkMessage::OkData &data)
: ReplyMessage(OK(), 1, QString()) // Todo: Check whether typeId is correct
{
m_jsonRepresentation.insert(DATA(),
QJsonObject({{UUID_(), data.uuid},
{MESSAGE_TYPE(), data.messageType},
{INFO(), data.info}
}));
}
// ####### OkMessage end #######
// ####### RoomMessage begin #######
RoomMessage::RoomMessage(const RoomMessage::RoomData &data, const QString &uuid)
: ReplyMessage(ROOM(), 3, uuid) // Todo: Check whether typeId is correct
{
m_jsonRepresentation.insert(DATA(),
QJsonObject({{PATH(), vecToPath(data.path)},
{ID(), data.id},
{DESIGNATION(), data.designation},
{LEVEL_ID(), data.levelId}
}));
}
// ####### RoomMessage end #######
// ####### AssetData begin #######
QJsonObject AssetData::toJsonObject() const
{
return QJsonObject(
{
{ID(), id},
{ERROR_DESCRIPTION(), errorDescription},
{TIME(), time},
{STATE(), state},
{IP_ADDRESS(), hostname}, // TODO: Fix ICD
{MOUNTING_POINT_ID(), mountingPointId},
{ASSET_TYPE_ID(), assetTypeId},
{ASSET_TAG(), assetTag},
{DESIGNATION(), designation}
});
}
// ####### AssetData end #######
// ####### AreaMessage begin #######
AreaMessage::AreaMessage(const AreaMessage::AreaData &data, const QString &uuid)
: ReplyMessage(AREA(), 4, uuid) // Todo: Check whether typeId is correct
{
m_jsonRepresentation.insert(DATA(),
QJsonObject({{PATH(), vecToPath(data.path)},
{ID(), data.id},
{DESIGNATION(), data.designation},
{TRAINING_AREA_ID(), data.trainingAreaId}
}));
}
// ####### AreaMessage end #######
// ####### AssetStateMessage begin #######
AssetStateMessage::AssetStateMessage(const AssetData &data, const QString &uuid)
: ReplyMessage(ASSET_STATE(), 5, uuid) // Todo: Check whether typeId is correct
{
m_jsonRepresentation.insert(DATA(), {data.toJsonObject()});
}
// ####### AssetStateMessage end #######
// ####### AssetStateMessage begin #######
AssetsMessage::AssetsMessage(const QVector<AssetData> &data,
const QString &uuid)
: ReplyMessage(ASSETS(), 6, uuid) // Todo: Check whether typeId is correct
{
QJsonArray arr;
for (const AssetData &ad : data)
arr += ad.toJsonObject();
m_jsonRepresentation.insert(DATA(), arr);
}
// ####### AssetStateMessage end #######
// ####### AssetStateObjectMessage begin #######
AssetStateObjectMessage::AssetStateObjectMessage(const AssetStateObjectMessage::AssetStateObjectData &data, const QString &uuid)
: ReplyMessage(ASSET_STATE_OBJECT(), 7, uuid) // Todo: Check whether typeId is correct
{
QJsonArray assetStates;
for (const AssetStatesEntry &currentEntry : data.assetStates)
assetStates.append(QJsonObject({{MOUNTING_POINT_ID(), currentEntry.mountingPointId},
{ASSET_ID(), currentEntry.assetId},
{ASSET_TYPE_ID(), currentEntry.assetTypeId},
{IP_ADDRESS(), currentEntry.hostname}, // TODO: Fix ICD
{STATE(), currentEntry.state}
}));
m_jsonRepresentation.insert(DATA(), QJsonObject({{ASSET_STATES(), assetStates},
{OBJECT_ID(), data.objectId},
{TIME(), data.time}
}));
}
// ####### AssetStateObjectMessage end #######
// ####### AssetTypeMessage begin #######
AssetTypeMessage::AssetTypeMessage(const AssetTypeMessage::AssetTypeData &data, const QString &uuid)
: ReplyMessage(ASSET_TYPE(), 8, uuid) // Todo: Check whether typeId is correct
{
m_jsonRepresentation.insert(DATA(), QJsonObject({{ID(), data.id},
{DESIGNATION(), data.designation},
{DEVICE_CLASS(), data.deviceClass}
}));
}
// ####### AssetTypeMessage end #######
// ####### LevelMessage end #######
LevelMessage::LevelMessage(const LevelMessage::LevelData &data, const QString &uuid)
: ReplyMessage(LEVEL(), 9, uuid) // Todo: Check whether typeId is correct
{
m_jsonRepresentation.insert(DATA(), QJsonObject({{Z_POSITION(), data.zPos},
{NUMBER(), data.number},
{OBJECT_ID(), data.objectid},
{DESIGNATION(), data.designation},
{ID(), data.id},
{PATH(), vecToPath(data.path)}
}));
}
// ####### LevelMessage end #######
// ####### MountingPointMessage begin #######
MountingPointMessage::MountingPointMessage(const MountingPointMessage::MountingPointData &data, const QString &uuid)
: ReplyMessage(MOUNTING_POINT(), 10, uuid) // Todo: Check whether typeId is correct
{
QJsonArray supportedAssetTypeIds;
for (int currentId : data.supportedAssetTypIds)
supportedAssetTypeIds.append(currentId);
m_jsonRepresentation.insert(DATA(), QJsonObject({{SUPPORTED_ASSET_TYPE_IDS(), supportedAssetTypeIds},
{POSITION_3D(), data.position3d.toJSon()},
{ID(), data.id},
{DESIGNATION(), data.designation},
{TAG(), data.tag},
{OBJECT_ID(), data.objectId},
{LEVEL_ID(), data.levelId},
{ROOM_ID(), data.roomId},
{ASSET_ID(), data.assetId}
}));
}
// ####### MountingPointMessage end #######
// ####### ObjectMessage begin #######
ObjectMessage::ObjectMessage(const ObjectMessage::ObjectMessageData &data, const QString &uuid)
: ReplyMessage(OBJECT(), 11, uuid) // Todo: Check whether typeId is correct
{
m_jsonRepresentation.insert(DATA(), QJsonObject({{NUMBER(), data.number},
{STREET(), data.street},
{AREA_ID(), data.areaId},
{DESIGNATION(), data.designation},
{ID(), data.id},
{MSE_ID(), data.mseId},
{REF_POINT(), data.refPoint.toJSon()},
{Z(), data.z},
{ROTATION_DEGREE(), data.rotationDegree},
{PATH(), vecToPath(data.path)},
{PATH_RELATIVE(), vecToPath(data.pathRelative)}
}));
}
// ####### ObjectMessage end #######
// ####### ObjectMountingMessage begin #######
ObjectMountingMessage::ObjectMountingMessage(const ObjectMountingMessage::ObjectMountingData &data, const QString &uuid)
: ReplyMessage(OBJECT_MOUNTING(), 12, uuid) // Todo: Check whether typeId is correct
{
QJsonArray planned;
for (const PlannedEntry &currentEntry : data.planned)
planned.append(QJsonObject({{ID(), currentEntry.id},
{ASSET_ID(), currentEntry.assetId},
{PLANNING_STATE(), currentEntry.planningState}
}));
m_jsonRepresentation.insert(DATA(), QJsonObject({{PLANNED(), planned},
{PLANNED_MOUNTING_ID(), data.plannedMountingId},
{OBJECT_ID(), data.objectId}
}));
}
// ####### ObjectMountingMessage end #######
// ####### PlannedMountingMessage begin #######
PlannedMountingMessage::PlannedMountingMessage(const PlannedMountingMessage::PlannedMountingData &data, const QString &uuid)
: ReplyMessage(PLANNED_MOUNTING(), 13, uuid) // Todo: Check whether typeId is correct
{
QJsonArray mounting;
for (const MountingEntry &currentEntry : data.mounting)
mounting.append(QJsonObject({{ID(), currentEntry.id},
{STATE(), currentEntry.state}
}));
m_jsonRepresentation.insert(DATA(), QJsonObject({{MOUNTING(), mounting},
{PLANNED_MOUNTING_ID(), data.plannedMountingId},
{DESIGNATION(), data.designation},
{AREA_ID(), data.areaId}
}));
}
// ####### PlannedMountingMessage end #######
// ####### TrainingAreaMessage begin #######
TrainingAreaMessage::TrainingAreaMessage(const TrainingAreaMessage::TrainingAreaData &data, const QString &uuid)
: ReplyMessage(TRAINING_AREA(), 14, uuid) // Todo: Check whether typeId is correct
{
m_jsonRepresentation.insert(DATA(), QJsonObject({{PATH(), vecToPath(data.path)},
{ID(), data.id},
{DESIGNATION(), data.designation}
}));
}
// ####### TrainingAreaMessage end #######
// ######################### base DL messages #########################
// ####### AssetBaseData begin #######
AssetBaseData::AssetBaseData(const QJsonArray &data, const QString &uuid)
: LtsWebSocket::ReplyMessage (ISM_ASSET_BASE_DATA(), 15, uuid) // Todo: Check whether typeId is correct
{
m_jsonRepresentation.insert(DATA(), data);
}
// ####### AssetBaseData end #######
// ####### MainStructureElementBaseData begin #######
MainStructureElementBaseData::MainStructureElementBaseData(const QJsonArray &data, const QString &uuid)
: LtsWebSocket::ReplyMessage (MAIN_STRUCTURE_ELEMENT_BASE_DATA(), 16, uuid) // Todo: Check whether typeId is correct
{
m_jsonRepresentation.insert(DATA(), data);
}
// ####### MainStructureElementBaseData end #######
// ####### VulnerabilityModelDataBaseData begin #######
VulnerabilityModelDataBaseData::VulnerabilityModelDataBaseData(const QJsonArray &data, const QString &uuid)
: LtsWebSocket::ReplyMessage (VULNERABILITY_MODEL_DATA_BASE_DATA(), 17, uuid) // Todo: Check whether typeId is correct
{
m_jsonRepresentation.insert(DATA(), data);
}
// ####### VulnerabilityModelDataBaseData end #######
// ####### StructureElementBaseData begin #######
StructureElementBaseData::StructureElementBaseData(const QJsonArray &data, const QString &uuid)
: LtsWebSocket::ReplyMessage (STRUCTURE_ELEMENT_BASE_DATA(), 18, uuid) // Todo: Check whether typeId is correct
{
m_jsonRepresentation.insert(DATA(), data);
}
// ####### StructureElementBaseData end #######
// ####### StructureElementFootprintBaseData begin #######
StructureElementFootprintBaseData::StructureElementFootprintBaseData(const QJsonArray &data, const QString &uuid)
: LtsWebSocket::ReplyMessage (STRUCTURE_ELEMENT_FOOTPRINT_BASE_DATA(), 19, uuid) // Todo: Check whether typeId is correct
{
m_jsonRepresentation.insert(DATA(), data);
}
// ####### StructureElementFootprintBaseData end #######
// ####### MountingPointAssetBaseData begin #######
MountingPointAssetBaseData::MountingPointAssetBaseData(const QJsonArray &data, const QString &uuid)
: LtsWebSocket::ReplyMessage (MOUNTING_POINT_ASSET_BASE_DATA(), 20, uuid) // Todo: Check whether typeId is correct
{
m_jsonRepresentation.insert(DATA(), data);
}
// ####### MountingPointAssetBaseData end #######
// ####### MountingPointPlanBaseData begin #######
MountingPointPlanBaseData::MountingPointPlanBaseData(const QJsonArray &data, const QString &uuid)
: LtsWebSocket::ReplyMessage (MOUNTING_POINT_PLAN_BASE_DATA(), 21, uuid) // Todo: Check whether typeId is correct
{
m_jsonRepresentation.insert(DATA(), data);
}
// ####### MountingPointPlanBaseData end #######
// ####### MountingPointScheduleBaseData begin #######
MountingPointScheduleBaseData::MountingPointScheduleBaseData(const QJsonArray &data, const QString &uuid)
: LtsWebSocket::ReplyMessage (MOUNTING_POINT_SCHEDULE_BASE_DATA(), 22, uuid) // Todo: Check whether typeId is correct
{
m_jsonRepresentation.insert(DATA(), data);
}
// ####### MountingPointScheduleBaseData end #######
} // namespace Messages
} // namespace WebSocketInterface
} // namespace Infrastrukture Management
@@ -0,0 +1,534 @@
/**
* @RDE_HEADER@
* The ReplyMessage class is an abstract base class for all possible messages which are sent to the client
* $Id$
* $HeadURL$
* $Author$
* Created by Hannes Baeuerle, SLSE, 2016-08-25
*/
#pragma once
#include <LtsWebSocket/client_message_factory.h>
#include <QtCore/QVector>
#include <QtCore/QJsonObject>
#include <QtCore/QJsonArray>
namespace InfrastructureManagement
{
namespace WebSocketInterface
{
namespace Messages
{
/**
* @brief The ReplyMessage class is an abstract base class for all possible messages
* which are sent to the client
*/
class ReplyMessage : public LtsWebSocket::ReplyMessage
{
public:
/**
* @brief The LonLatPoint struct represents a point in any data part which has lon lat
*/
struct LonLatPoint
{
double lon = 0.;
double lat = 0.;
QJsonObject toJSon() const;
};
/**
* @brief The Point3d struct represents a 3D point in any data part which needs it
*/
struct Point3d
{
double x = 0.;
double y = 0.;
double z = 0.;
QJsonObject toJSon() const;
};
/**
* @brief The XYPoint struct represents a 2D point in any data part which needs it
*/
struct XYPoint
{
double x = 0.;
double y = 0.;
QJsonObject toJSon() const;
};
ReplyMessage() = default;
/**
* @brief ~ReplyMessage Destructor
*/
virtual ~ReplyMessage() = default;
protected:
template<typename T>
static QJsonArray vecToPath(const QVector<T> &points)
{
QJsonArray result;
for (const T &p : points)
result.append(p.toJSon());
return result;
}
protected: // methods
explicit ReplyMessage(const QString &type, const int typeId, const QString &uuid);
}; // class Reply Message
/**
* @brief The AreaMessage class represents an area
*/
class AreaMessage final
: public ReplyMessage
{
public:
/**
* @brief The AreaData struct represents the data part of an AreaMessage object
*/
struct AreaData
{
int id = 0;
int trainingAreaId = 0;
QString designation;
QVector<LonLatPoint> path;
};
/**
* @brief AreaMessage Constructor
* @param data Data part of an AreaMessage object
*/
AreaMessage(const AreaData &data, const QString &uuid);
AreaMessage() = default;
}; // class AreaMessage
/**
* @brief The AssetStateData struct represents the data part of an AssetStateMessage(/AssetsMessage object
*/
struct AssetData
{
int id = 0;
int assetTypeId = 0;
int mountingPointId = 0;
QString assetTag;
QString designation;
QString hostname; // Hostname
QString state;
QString time; // "DD.MM.JJ hh:mm"
QString errorDescription;
QJsonObject toJsonObject() const;
};
/**
* @brief The AssetStateMessage class represents an asset state
*/
class AssetStateMessage final
: public ReplyMessage
{
public:
/**
* @brief AssetStateMessage Constructor
* @param data Data part of an AssetStateMessage object
*/
explicit AssetStateMessage(const AssetData &data, const QString &uuid);
}; // class AssetStateMessage
/**
* @brief The AssetStateMessage class represents an asset state
*/
class AssetsMessage final
: public ReplyMessage
{
public:
/**
* @brief AssetStateMessage Constructor
* @param data Data part of an AssetStateMessage object
*/
explicit AssetsMessage(const QVector<AssetData> &data, const QString &uuid);
}; // class AssetStateMessage
/**
* @brief The AssetStateObjectMessage class includes data which represents the states of all
* assets in a specific object
*/
class AssetStateObjectMessage final
: public ReplyMessage
{
public:
/**
* @brief The AssetStatesEntry struct represents an entry in AssetStateObjectData.assetStates
*/
struct AssetStatesEntry
{
int assetId = 0;
int assetTypeId = 0;
int mountingPointId = 0;
QString hostname;
QString state;
};
/**
* @brief The AssetStateObjectData struct represents the data part of an AssetStateObjectMessage object
*/
struct AssetStateObjectData
{
int objectId = 0;
QString time; // "DD.MM.JJ hh:mm"
QVector<AssetStatesEntry> assetStates;
};
/**
* @brief AssetStateObjectMessage Constructor
* @param data Data part of an AssetStateObjectMessage object
*/
explicit AssetStateObjectMessage(const AssetStateObjectData &data, const QString &uuid);
}; // class AssetStateObjectMessage
/**
* @brief The AssetTypeMessage class represents an asset type
*/
class AssetTypeMessage final
: public ReplyMessage
{
public:
/**
* @brief The AssetTypeData struct represents the data part of an AssetStateObjectMessage object
*/
struct AssetTypeData
{
int id = 0;
int deviceClass = 0;
QString designation;
};
/**
* @brief AssetTypeMessage Construcor
* @param data Data part of an AssetTypeMessage object
*/
AssetTypeMessage(const AssetTypeData &data, const QString &uuid);
AssetTypeMessage() = default;
}; // class AssetTypeMessage
/**
* @brief The LevelMessage class represents a level
*/
class LevelMessage final
: public ReplyMessage
{
public:
/**
* @brief The LevelData struct represents the data part of an LevelMessage object
*/
struct LevelData
{
int id = 0;
int objectid = 0;
int number = 0;
double zPos = 0;
QString designation;
QVector<XYPoint> path;
};
/**
* @brief LevelMessage Constructor
* @param data Data part of an LevelMessage object
*/
LevelMessage(const LevelData &data, const QString &uuid);
LevelMessage() = default;
}; // class LevelMessage
/**
* @brief The MountingPointMessage class represents a mounting point
*/
class MountingPointMessage final
: public ReplyMessage
{
public:
/**
* @brief The MountingPointData struct represents the data part of an MountingPointMessage object
*/
struct MountingPointData
{
int id = 0;
int objectId = 0;
int levelId = 0;
int roomId = 0;
int assetId = 0;
QString tag;
QString designation;
Point3d position3d;
QVector<int> supportedAssetTypIds;
};
/**
* @brief MountingPointMessage Constructor
* @param data Data part of an MountingPointMessage object
*/
MountingPointMessage(const MountingPointData &data, const QString &uuid);
MountingPointMessage() = default;
}; // class MountingPointMessage
/**
* @brief The ObjectMessage class represents an object
*/
class ObjectMessage final
: public ReplyMessage
{
public:
/**
* @brief The ObjectMessageData struct represents the data part of an ObjectMessage object
*/
struct ObjectMessageData
{
int id = 0;
int areaId = 0;
int mseId = 0; //!< not part of ICD but needed for our tools
QString number;
QString designation;
LonLatPoint refPoint;
double z; // aboveMsl
double rotationDegree;
QString street;
QVector<LonLatPoint> path;
QVector<XYPoint> pathRelative;
};
/**
* @brief ObjectMessage Constructor
* @param data Data part of an ObjectMessage object
*/
ObjectMessage(const ObjectMessageData &data, const QString &uuid);
ObjectMessage() = default;
}; // class ObjectMessage
/**
* @brief The ObjectMountingMessage class represents an object mounting plan
*/
class ObjectMountingMessage final
: public ReplyMessage
{
public:
/**
* @brief The PlannedEntry struct represents an entry in ObjectMountingData.planned
*/
struct PlannedEntry
{
int id = 0;
int assetId = 0;
int planningState = 0;
};
/**
* @brief The ObjectMountingData struct represents the data part of an ObjectMountingMessage object
*/
struct ObjectMountingData
{
int objectId = 0;
int plannedMountingId = 0;
QVector<PlannedEntry> planned;
};
/**
* @brief ObjectMountingMessage Constructor
* @param data Data part of an ObjectMountingMessage object
*/
explicit ObjectMountingMessage(const ObjectMountingData &data, const QString &uuid);
}; // class ObjectMountingMessage
/**
* @brief The OkMessage is sent when a message from a client does not need
* any concrete response and eveything is fine
*/
class OkMessage final
: public ReplyMessage
{
public:
/**
* @brief The OkData struct represents the data part of an OkMessage object
*/
struct OkData
{
QString uuid;
QString messageType;
QString info;
};
/**
* @brief OkMessage Constructor
* @param data Data part of an OkMessage object
*/
explicit OkMessage(const OkData &data);
}; // class OkMessage
/**
* @brief The PlannedMountingMessage class represents a mounting plan
*/
class PlannedMountingMessage final
: public ReplyMessage
{
public:
/**
* @brief The MountingEntry struct represents an entry in PlannedMountingData.mounting
*/
struct MountingEntry
{
int id = 0;
int state = 0;
};
/**
* @brief The PlannedMountingData struct represents the data part of an PlannedMountingMessage object
*/
struct PlannedMountingData
{
int areaId = 0;
int plannedMountingId = 0;
QString designation;
QVector<MountingEntry> mounting;
};
/**
* @brief PlannedMountingMessage Constructor
* @param data Data part of an PlannedMountingMessage object
*/
PlannedMountingMessage(const PlannedMountingData &data, const QString &uuid);
PlannedMountingMessage() = default;
}; // class PlannedMountingMessage
/**
* @brief The RoomMessage class represents a room
*/
class RoomMessage final
: public ReplyMessage
{
public:
/**
* @brief The RoomData struct represents the data part of an RoomMessage object
*/
struct RoomData
{
int id = 0;
int levelId = 0;
QString designation;
QVector<XYPoint> path;
};
/**
* @brief RoomMessage Constructor
* @param data Data part of an RoomMessage object
*/
RoomMessage(const RoomData &data, const QString &uuid);
RoomMessage() = default;
}; // RoomMessage
/**
* @brief The TrainingAreaMessage class represents a training area
*/
class TrainingAreaMessage final
: public ReplyMessage
{
public:
/**
* @brief The TrainingAreaData struct represents the data part of an TrainingAreaMessage object
*/
struct TrainingAreaData
{
int id = 0;
QString designation;
QVector<LonLatPoint> path;
};
/**
* @brief TrainingAreaMessage Constructor
* @param data Data part of an TrainingAreaMessage object
*/
explicit TrainingAreaMessage(const TrainingAreaData &data, const QString &uuid);
TrainingAreaMessage() = default;
}; // class TrainingAreaMessage
// ######################### base DL messages #########################
/**
* @brief The AssetBaseData class asset data for base DL
*/
class AssetBaseData : public LtsWebSocket::ReplyMessage
{
public:
explicit AssetBaseData(const QJsonArray &data, const QString &uuid);
}; // class AssetBaseData
/**
* @brief The MainStructureElementBaseData class main structure element data for base DL
*/
class MainStructureElementBaseData : public LtsWebSocket::ReplyMessage
{
public:
explicit MainStructureElementBaseData(const QJsonArray &data, const QString &uuid);
}; // class MainStructureElementBaseData
/**
* @brief The VulnerabilityModelDataBaseData class vulnerability model data for base DL
*/
class VulnerabilityModelDataBaseData : public LtsWebSocket::ReplyMessage
{
public:
explicit VulnerabilityModelDataBaseData(const QJsonArray &data, const QString &uuid);
}; // class VulnerabilityModelDataBaseData
/**
* @brief The StructureElementBaseData class structure element data for base DL
*/
class StructureElementBaseData : public LtsWebSocket::ReplyMessage
{
public:
explicit StructureElementBaseData(const QJsonArray &data, const QString &uuid);
}; // class StructureElementBaseData
/**
* @brief The StructureElementFootprintBaseData class structure element footprint data for base DL
*/
class StructureElementFootprintBaseData : public LtsWebSocket::ReplyMessage
{
public:
explicit StructureElementFootprintBaseData(const QJsonArray &data, const QString &uuid);
}; // class StructureElementFootprintBaseData
/**
* @brief The MountingPointAssetBaseData class mounting point asset data for base DL
*/
class MountingPointAssetBaseData : public LtsWebSocket::ReplyMessage
{
public:
explicit MountingPointAssetBaseData(const QJsonArray &data, const QString &uuid);
}; // class MountingPointAssetBaseData
/**
* @brief The MountingPointScheduleBaseData class mounting point schedule data for base DL
*/
class MountingPointScheduleBaseData : public LtsWebSocket::ReplyMessage
{
public:
explicit MountingPointScheduleBaseData(const QJsonArray &data, const QString &uuid);
}; // class MountingPointScheduleBaseData
/**
* @brief The MountingPointPlanBaseData class mounting point plan data for base DL
*/
class MountingPointPlanBaseData : public LtsWebSocket::ReplyMessage
{
public:
explicit MountingPointPlanBaseData(const QJsonArray &data, const QString &uuid);
}; // class MountingPointPlanBaseData
} // namespace Messages
} // namespace WebSocketInterfac
} // namespace InfrastructureManagement
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,171 @@
/**
* @RDE_HEADER@
* The DataManager class is a convenience class for managing structure data
* $Id$
* $HeadURL$
* $Author$
* Created by Hannes Baeuerle, SLSE, 2016-09-12
*/
#pragma once
#include <LtsWebSocket/data_manager_base_dl.h>
#include <InfrastructureManagement/ism_db.h>
#include "WebSocketInterface/Messages/reply_message.h"
#include "Messages/reply_message.h"
#include "logger.h"
namespace AssetManagement
{
namespace Interface
{
class Dtc;
} // namespace Interface
} // namespace AssetManagement
namespace InfrastructureManagement
{
class MainHandler;
class ObjectInstrumentationAsset;
namespace WebSocketInterface
{
namespace Messages
{
class TrainingAreaMessage;
class AreaMessage;
class ObjectMessage;
class LevelMessage;
class RoomMessage;
class MountingPointMessage;
class AssetTypeMessage;
} // namespace Messages
/**
* @brief The DataManager class is a convenience class for managing structure data
*/
class DataManager final : LtsWebSocket::DataManagerBaseDl<DatabaseInterface>
{
public:
/**
* @brief The EinruestEssentials struct is just there to bundle essentials data
* to a single return value
*/
struct EinruestEssentials
{
QVector<Messages::TrainingAreaMessage> trainingAreas;
QVector<Messages::AreaMessage> areas;
QVector<Messages::ObjectMessage> objects;
QVector<Messages::LevelMessage> levels;
QVector<Messages::RoomMessage> rooms;
QVector<Messages::MountingPointMessage> mountingPoints;
QVector<Messages::AssetTypeMessage> assetTypes;
};
/**
* @brief DataManager Constructor
* @param mainHandler Source for needed handlers
*/
explicit DataManager(MainHandler *mainHandler);
/**
* @brief init Initialises a DataManager object
* @return True on sucess, otherwise false
*/
bool init();
/**
* @brief getEssentials Getter for initial data
* @param uuid Identifier of the message to be responded to
* @return Initial data of type EinruestEssentials
*/
EinruestEssentials getEssentials(const QString &uuid) const;
/**
* @brief getPlannedMounting Getter for data needed in response to a getPlannedMounting Message
* @param uuid Identifier of the message to be responded to
* @return All planned mounting messages
*/
QVector<Messages::PlannedMountingMessage> getPlannedMounting(const QString &uuid) const;
/**
* @brief getObjectMounting Getter for a Messages::ObjectMessage
* @param plannedMountingId Id of the schedule
* @param objectId Id of the object/building
* @param uuid Identifier of the message to be responded to
* @return Messages::ObjectMessage if combination of plannedMountingId and objectId exists,
* otherwise Messages::ErrorMessage
*/
LtsWebSocket::ReplyMessage *getObjectMounting(int plannedMountingId, int objectId, const QString &uuid) const;
LtsWebSocket::ReplyMessage *mountTag(const QString &mountingPointTag,
const QString &assetTag,
const QString &messageType,
const QString &uuid) const;
LtsWebSocket::ReplyMessage *mount(int32_t mountingPointId,
int32_t assetId,
const QString &messageType,
const QString &uuid) const;
LtsWebSocket::ReplyMessage *unmountAsset(int32_t assetId,
const QString &messageType,
const QString &uuid) const;
LtsWebSocket::ReplyMessage *unmountMountingPoint(int32_t mountingPointId,
const QString &messageType,
const QString &uuid) const;
LtsWebSocket::ReplyMessage *unmountObject(int32_t objectId,
const QString &messageType,
const QString &uuid) const;
LtsWebSocket::ReplyMessage *unmountArea(int32_t areaId,
const QString &messageType,
const QString &uuid) const;
LtsWebSocket::ReplyMessage *objectMountingReady(int32_t plannedMountingId,
int32_t objectId,
const QString &messageType,
const QString &uuid) const;
LtsWebSocket::ReplyMessage *getAssetState(int32_t assetId,
const QString &assetTag,
const QString &uuid) const;
LtsWebSocket::ReplyMessage *getAssets(const QSet<int> &assetTypeIds,
const QString &uuid) const;
LtsWebSocket::ReplyMessage *getBuildingState(int32_t buildingId,
const QString &uuid) const;
// base DL OC
LtsWebSocket::ReplyMessage *assetBaseData(const QString &uuid) const;
LtsWebSocket::ReplyMessage *mainStructureElementBaseData(const QString &uuid) const;
LtsWebSocket::ReplyMessage *structureElementBaseData(const QString &uuid) const;
LtsWebSocket::ReplyMessage *structureElementFootprintBaseData(const QString &uuid) const;
LtsWebSocket::ReplyMessage *mountingPointAssetBaseData(const QString &uuid) const;
LtsWebSocket::ReplyMessage *mountingPointScheduleBaseData(const QString &uuid) const;
LtsWebSocket::ReplyMessage *mountingPointPlanBaseData(const QString &uuid) const;
private: //methods
static QVector<Messages::ReplyMessage::LonLatPoint> relativeToGeographic(const Messages::ReplyMessage::LonLatPoint &pos,
const QVector<Messages::ReplyMessage::XYPoint> &relPoints);
QVector<Messages::ReplyMessage::XYPoint> pathForStructureId(int32_t structureElementId) const;
QVector<Messages::PlannedMountingMessage::MountingEntry> entriesForScheduleId(int32_t scheduleId) const;
int32_t areaIdForScheduleId(int32_t scheduleId) const;
int32_t stateForBuilding(int32_t buildingId) const;
bool isMounted(int32_t mountingPointId) const;
bool isPlannedObject(int32_t objectId) const;
QVector<Messages::ObjectMountingMessage::PlannedEntry> entriesForBuildingInSchedule(int32_t scheduleId, int32_t buildingId) const;
int32_t getMountedAssetId(int32_t mountingPointId) const;
int32_t mountingPointIdFromBarcode(const QString &barcode) const;
int32_t assetIdFromBarcode(const QString &barcode) const;
Messages::AssetData assetData(int32_t assetId) const;
Messages::AssetData assetData(const ObjectInstrumentationAsset *asset) const;
MountingPointState getMountingPointState(int32_t mountingPointId, int32_t scheduleId) const;
private: // attributes
MainHandler *m_mainHandler;
std::shared_ptr<AssetManagement::Interface::Dtc> m_asmDtc;
}; // class DataManager
} // namespace WebSocketInterface
} // namespace InfrastructureManagement
@@ -0,0 +1,119 @@
/**
* @RDE_HEADER@
* Header file which holds all occuring JSON keys
* $Id$
* $HeadURL$
* $Author$
* Created by Hannes Baeuerle, SLSE, 2016-08-25
*/
#pragma once
#include <QtCore/QString>
#include <OcBaseDownload/WebSocketInterface/json_keys.h>
namespace InfrastructureManagement
{
namespace WebSocketInterface
{
/**
* @brief Namespace which holds all occuring JSON keys as const QString objects
*/
namespace JsonKeys
{
// types for client --> server messages
inline QString GET_ASSETS() { return QStringLiteral("getAssets"); }
inline QString GET_ASSET_STATE() { return QStringLiteral("getAssetState"); }
inline QString GET_BUILDING_STATE() { return QStringLiteral("getBuildingState"); }
inline QString GET_ESSENTIALS() { return QStringLiteral("getEssentials"); }
inline QString GET_OBJECT_MOUNTING() { return QStringLiteral("getObjectMounting"); }
inline QString GET_PLANNED_MOUNTINGS() { return QStringLiteral("getPlannedMountings"); }
inline QString MOUNT() { return QStringLiteral("mount"); }
inline QString MOUNT_TAG() { return QStringLiteral("mountTag"); }
inline QString OBJECT_MOUNTING_READY() { return QStringLiteral("objectMountingReady"); }
inline QString UNMOUNT_AREA() { return QStringLiteral("unmountArea"); }
inline QString UNMOUNT_ASSET() { return QStringLiteral("unmountAsset"); }
inline QString UNMOUNT_MOUNTING_POINT() { return QStringLiteral("unmountMountingPoint"); }
inline QString UNMOUNT_OBJECT() { return QStringLiteral("unmountObject"); }
// types for server --> client messages
inline QString AREA() { return QStringLiteral("area"); }
inline QString AREAS() { return QStringLiteral("areas"); }
inline QString ASSET_STATE() { return QStringLiteral("assetState"); }
inline QString ASSETS() { return QStringLiteral("assets"); }
inline QString ASSET_STATE_OBJECT() { return QStringLiteral("assetStateObject"); }
inline QString ASSET_TYPE() { return QStringLiteral("assetType"); }
inline QString ASSET_TYPES() { return QStringLiteral("assetTypes"); }
inline QString LEVEL() { return QStringLiteral("level"); }
inline QString LEVELS() { return QStringLiteral("levels"); }
inline QString MOUNTING_POINT() { return QStringLiteral("mountingPoint"); }
inline QString MOUNTING_POINTS() { return QStringLiteral("mountingPoints"); }
inline QString OBJECT() { return QStringLiteral("object"); }
inline QString OBJECTS() { return QStringLiteral("objects"); }
inline QString OBJECT_MOUNTING() { return QStringLiteral("objectMounting"); }
inline QString OK() { return QStringLiteral("ok"); }
inline QString PLANNED_MOUNTING() { return QStringLiteral("plannedMounting"); }
inline QString PLANNED_MOUNTINGS() { return QStringLiteral("plannedMountings"); }
inline QString ROOM() { return QStringLiteral("room"); }
inline QString ROOMS() { return QStringLiteral("rooms"); }
inline QString TRAINING_AREA() { return QStringLiteral("trainingArea"); }
inline QString TRAINING_AREAS() { return QStringLiteral("trainingAreas"); }
// types for server --> client messages base DL
inline QString ISM_ASSET_BASE_DATA() { return QStringLiteral("ismAssetBaseData"); }
inline QString MAIN_STRUCTURE_ELEMENT_BASE_DATA() { return QStringLiteral("mainStructureElementBaseData"); }
inline QString VULNERABILITY_MODEL_DATA_BASE_DATA() { return QStringLiteral("vulnerabilityModelDataBaseData"); }
inline QString STRUCTURE_ELEMENT_BASE_DATA() { return QStringLiteral("structureElementBaseData"); }
inline QString STRUCTURE_ELEMENT_FOOTPRINT_BASE_DATA() { return QStringLiteral("structureElementFootprintBaseData"); }
inline QString MOUNTING_POINT_ASSET_BASE_DATA() { return QStringLiteral("mountingPointAssetBaseData"); }
inline QString MOUNTING_POINT_SCHEDULE_BASE_DATA() { return QStringLiteral("mountingPointScheduleBaseData"); }
inline QString MOUNTING_POINT_PLAN_BASE_DATA() { return QStringLiteral("mountingPointPlanBaseData"); }
// data keys
inline QString AREA_ID() { return QStringLiteral("areaId"); }
inline QString ASSET_ID() { return QStringLiteral("assetId"); }
inline QString ASSET_STATES() { return QStringLiteral("assetStates"); }
inline QString ASSET_TAG() { return QStringLiteral("assetTag"); }
inline QString ASSET_TYPE_ID() { return QStringLiteral("assetTypeId"); }
inline QString BUILDING_ID() { return QStringLiteral("buildingId"); }
inline QString DESIGNATION() { return QStringLiteral("designation"); }
inline QString DEVICE_CLASS() { return QStringLiteral("deviceClass"); }
inline QString ERROR_DESCRIPTION() { return QStringLiteral("errorDescription"); }
inline QString GEO_POINT() { return QStringLiteral("geoPoint"); }
inline QString ID() { return QStringLiteral("id"); }
inline QString MSE_ID() { return QStringLiteral("mseId"); }
inline QString INFO() { return QStringLiteral("info"); }
inline QString IP_ADDRESS() { return QStringLiteral("ipAddr"); }
inline QString LATITUDE() { return QStringLiteral("lat"); }
inline QString LEVEL_ID() { return QStringLiteral("levelId"); }
inline QString LONGITUDE() { return QStringLiteral("lon"); }
inline QString MESSAGE_TYPE() { return QStringLiteral("msgType"); }
inline QString MOUNTING() { return QStringLiteral("mounting"); }
inline QString MOUNTING_POINT_ID() { return QStringLiteral("mountingPointId"); }
inline QString MOUNTING_POINT_TAG() { return QStringLiteral("mountingPointTag"); }
inline QString NUMBER() { return QStringLiteral("number"); }
inline QString OBJECT_ID() { return QStringLiteral("objectId"); }
inline QString PATH() { return QStringLiteral("path"); }
inline QString PATH_RELATIVE() { return QStringLiteral("pathRelative"); }
inline QString PLANNED() { return QStringLiteral("planned"); }
inline QString PLANNED_MOUNTING_ID() { return QStringLiteral("plannedMountingId"); }
inline QString PLANNING_STATE() { return QStringLiteral("planningState"); }
inline QString POINT() { return QStringLiteral("point"); }
inline QString POSITION_3D() { return QStringLiteral("position3d"); }
inline QString REF_POINT() { return QStringLiteral("refPoint"); }
inline QString ROTATION_DEGREE() { return QStringLiteral("rotationDegree"); }
inline QString ROOM_ID() { return QStringLiteral("roomId"); }
inline QString STATE() { return QStringLiteral("state"); }
inline QString STREET() { return QStringLiteral("street"); }
inline QString SUPPORTED_ASSET_TYPE_IDS() { return QStringLiteral("supportedAssetTypeIds"); }
inline QString TAG() { return QStringLiteral("tag"); }
inline QString TIME() { return QStringLiteral("time"); }
inline QString TRAINING_AREA_ID() { return QStringLiteral("trainingAreaId"); }
inline QString X() { return QStringLiteral("x"); }
inline QString Y() { return QStringLiteral("y"); }
inline QString Z() { return QStringLiteral("z"); }
inline QString Z_POSITION() { return QStringLiteral("zPos"); }
} // namespace JsonKeys
} // namespace WebSocketInterface
} // namespace InfrastructureManagement
@@ -0,0 +1,81 @@
/**
* @RDE_HEADER@
* Handler for the WebSocket Interface
* $Id$
* $HeadURL$
* $Author$
* Created by Hannes Baeuerle, SLSE, 2016-08-25
*/
#include "websocket_interface_handler.h"
#include "main_handler.h"
#include "data_manager.h"
#include "WebSocketInterface/Messages/client_message.h"
#include <nglsettings/nglsettings_connections.h>
#include "settings.h"
namespace InfrastructureManagement
{
namespace WebSocketInterface
{
WebSocketInterfaceHandler::WebSocketInterfaceHandler(MainHandler *mainHandler, QObject *parent)
: QObject(parent)
, m_webSocketServer(nullptr)
, m_messageFactory(nullptr)
, m_dataManager(nullptr)
, m_mainHandler(mainHandler)
, m_logger(getLogger("WebSocketInterfaceHandler"))
{
}
WebSocketInterfaceHandler::~WebSocketInterfaceHandler()
{
cleanup();
}
bool WebSocketInterfaceHandler::init()
{
cleanup();
DEBUG_LOG(m_logger) << "... ok";
DEBUG_LOG(m_logger) << "Initialising DataManager";
m_dataManager = new DataManager(m_mainHandler);
if (!m_dataManager->init())
{
ERROR_LOG(m_logger) << "Failed to initialise DataManager";
return false;
}
DEBUG_LOG(m_logger) << "... ok";
m_messageFactory = new Messages::ClientMessageFactory(m_dataManager);
m_webSocketServer = new LtsWebSocket::LtsWebSocketServer(m_messageFactory, this);
DEBUG_LOG(m_logger) << "Setting Message Delay to " << Settings::messageDelay();
m_webSocketServer->setMessageDelay(Settings::messageDelay());
DEBUG_LOG(m_logger) << "Initialising LtsWebSocketServer";
if (!m_webSocketServer->init(QStringLiteral("ISM"),
NGL::Connections::port(NGL::Connections::eConnection::ISM_WEBSOCKET)))
{
ERROR_LOG(m_logger) << "Failed to initialise LtsWebSocketServer";
return false;
}
DEBUG_LOG(m_logger) << "... ok";
DEBUG_LOG(m_logger) << "Connection signals and slots";
return true;
}
void WebSocketInterfaceHandler::cleanup()
{
delete m_webSocketServer;
delete m_messageFactory;
delete m_dataManager;
}
} // namespace WebSocketInterface
} // namespace InfrastructureManagement
@@ -0,0 +1,69 @@
/**
* @RDE_HEADER@
* Handler for the WebSocket Interface
* $Id$
* $HeadURL$
* $Author$
* Created by Hannes Baeuerle, SLSE, 2016-08-25
*/
#pragma once
#include <QtCore/QObject>
#include <LtsWebSocket/lts_web_socket_server.h>
#include <InfrastructureManagement/logger.h>
namespace InfrastructureManagement
{
class MainHandler;
namespace WebSocketInterface
{
namespace Messages
{
class ClientMessageFactory;
}
class DataManager;
/**
* @brief The WebSocketInterfaceHandler class is the main class for the WebSocketInterface
*/
class WebSocketInterfaceHandler final : public QObject
{
public:
/**
* @brief WebSocketInterfaceHandler Constructor
* @param mainHandler MainHandler to get the HandlerStructureElement from
*/
explicit WebSocketInterfaceHandler(MainHandler *mainHandler, QObject *parent = nullptr);
/**
* @brief ~WebSocketInterfaceHandler Destructor
*/
~WebSocketInterfaceHandler();
/**
* @brief init Initialises all needed classes for the WebSocketInterface
* @return True on success, otherwise false
*/
bool init();
/**
* @brief webSocketPort returns the listen port
* @return listen port
*/
unsigned short webSocketPort() { return m_webSocketServer->webSocketPort(); }
private:
void cleanup();
private:
LtsWebSocket::LtsWebSocketServer *m_webSocketServer;
Messages::ClientMessageFactory *m_messageFactory;
DataManager *m_dataManager;
MainHandler *m_mainHandler;
LOGGER_T m_logger;
}; // class WebSocketInterfaceHandler
} // namespace WebSocketInterface
} // namespace InfrastructureManagement
+42
View File
@@ -0,0 +1,42 @@
/**
* @RDE_HEADER@
* Base Class for all handler in ISM
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2016-11-18
*/
#include "base.h"
#include "main_handler.h"
namespace InfrastructureManagement
{
Base::Base(MainHandler *mainHandler, NGL::INGLLogger &logger)
: m_mainHandler(mainHandler)
, m_logger(logger)
{}
Base::~Base()
{}
std::shared_ptr<DatabaseInterface> Base::db() const
{
#ifndef ISM_OBJECT_MAIN_SCHEDULE_NO_HANDLER
return m_mainHandler->db();
#else
return nullptr;
#endif
}
std::shared_ptr<Interface::Dts> Base::dts() const
{
return m_mainHandler->dds()->dts();
}
std::shared_ptr<Interface::Fts> Base::fts() const
{
return m_mainHandler->dds()->fts();
}
} // InfrastructureManagement
+35
View File
@@ -0,0 +1,35 @@
/**
* @RDE_HEADER@
* Base Class for all handler in ISM
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2016-11-18
*/
#pragma once
#include <InfrastructureManagement/ism_db.h>
#include <InfrastructureManagement/ism_dts.h>
#include <InfrastructureManagement/ism_fts.h>
#include "logger.h"
namespace InfrastructureManagement
{
class MainHandler;
class Base : public QObject
{
Q_OBJECT
protected:
explicit Base(MainHandler *mainHandler, NGL::INGLLogger &logger);
virtual ~Base();
std::shared_ptr<DatabaseInterface> db() const;
std::shared_ptr<Interface::Dts> dts() const;
std::shared_ptr<Interface::Fts> fts() const;
protected:
MainHandler *m_mainHandler;
LOGGER_T m_logger;
};
}
+88
View File
@@ -0,0 +1,88 @@
/**
* Convert db structures to dds structures
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2017-07-20
*/
#pragma once
#include <InfrastructureManagement/ism_db.h>
#include <InfrastructureManagement/ism.hpp>
namespace InfrastructureManagement
{
namespace Database
{
inline MainStructureElement convert(const Database::IsmMainStructureElement &dbData)
{
MainStructureElement ddsData;
ddsData.id(dbData.id);
ddsData.name(dbData.name.toStdString());
ddsData.description(dbData.description.toStdString());
ddsData.geoPosition(Core::GeoPosition(dbData.geoPosition.x(), dbData.geoPosition.y(), dbData.geoPosition.z()));
ddsData.angle(dbData.angle);
ddsData.externalWlsId(dbData.externalWlsId);
ddsData.groupId(dbData.groupId);
ddsData.modelId(dbData.modelId);
ddsData.properties(dbData.properties.toStdString());
// init data not in db
ddsData.isDeleted(false);
ddsData.isUsed(false);
// TODO: fill additional data?
//ddsData.structureElementId();
//ddsData.elements();
return ddsData;
}
inline StructureElement convert(const Database::IsmStructureElement &dbData)
{
StructureElement ddsData;
ddsData.id(dbData.id);
ddsData.name(dbData.name.toStdString());
ddsData.displayName(dbData.displayName.toStdString());
ddsData.mainStructureElementId(dbData.mainStructureElementId);
ddsData.structureElementTypeId(dbData.structureElementTypeId);
ddsData.path(dbData.path());
ddsData.mountingPointId(dbData.mountingPointId);
ddsData.barcode(dbData.barcode.toStdString());
ddsData.relPosition(Core::RelativePosition(dbData.relPosition.x(),
dbData.relPosition.y(),
dbData.relPosition.z()));
ddsData.mountingPointTypeId(dbData.mountingPointTypeId);
ddsData.orientation(Core::Orientation(dbData.orientation.x(),
dbData.orientation.y(),
dbData.orientation.z()));
ddsData.properties(dbData.properties.toStdString());
// init data not in db
ddsData.isDeleted(false);
ddsData.isUsed(false);
return ddsData;
}
//--------------------------------------------------------------------------------------------------
inline MainSchedule convert(const Database::IsmMountingPointSchedule &dbData)
{
MainSchedule ddsData;
ddsData.id(dbData.id);
ddsData.name(dbData.name.toStdString());
ddsData.statusId(dbData.statusId);
ddsData.timeCreated(dbData.timeCreated.toMSecsSinceEpoch());
if (!dbData.timeStart.isNull() && dbData.timeStart.isValid())
ddsData.timeStart(dbData.timeStart.toMSecsSinceEpoch());
if (!dbData.timeEnd.isNull() && dbData.timeEnd.isValid())
ddsData.timeEnd(dbData.timeEnd.toMSecsSinceEpoch());
if (!dbData.exerciseId.isNull() && dbData.exerciseId.canConvert<unsigned int>())
ddsData.exerciseId(dbData.exerciseId.toUInt());
return ddsData;
}
} // namespace Database
} // namespace InfrastructureManagement
+63
View File
@@ -0,0 +1,63 @@
/**
* @RDE_HEADER@
* DDS Handler for ISM
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#include "dds_handler.h"
#include <DDS/Core/pacemaker.h>
namespace InfrastructureManagement
{
DdsHandler::DdsHandler(int domainId)
: m_ddsConnector(std::make_shared<DDSConnector::DdsConnector>(domainId, IDL::PartitionType::Any))
, m_logger(getLogger("DdsHandler"))
{
DEBUG_LOG(m_logger) << "DdsHandler(" << domainId << ") for partition: " << m_ddsConnector->getDefaultPartition();
}
bool DdsHandler::init(const QStringList &qosFileList)
{
if (!m_ddsConnector->init(qosFileList))
{
ERROR_LOG(m_logger) << "Error initializing dds connections - aborting";
return false;
}
// default initialize Publisher and Subscriber
m_ddsConnector->initPublisherSubscriber();
// Pacemaker
m_pacemaker = std::make_shared<Core::Pacemaker>(m_ddsConnector);
m_topicLockMaster = std::make_shared<Core::TopicLockMaster>(m_ddsConnector);
m_ddsDts = InfrastructureManagement::Interface::Dts::create(m_ddsConnector);
m_ddsFts = InfrastructureManagement::Interface::Fts::create(m_ddsConnector);
bool bRet = true;
try
{
bRet = m_ddsFts->enableAll();
INFO_LOG(m_logger) << "Fts initialised";
// erst FTS funktioniert komischer Weise nicht (seit MainStructureElementModifyRequest
// von MainStructureElement abgeleitet ist ... rti/dds - Bug?
bRet &= m_ddsDts->enableAll();
INFO_LOG(m_logger) << "Dts initialised";
}
catch (const dds::core::Exception &e)
{
ERROR_LOG(m_logger) << "Exception: " << e.what();
m_pacemaker->setNewState(Core::RunningState::StoppedError);
return false;
}
return bRet;
}
} // Namespace PDM
+63
View File
@@ -0,0 +1,63 @@
/**
* @RDE_HEADER@
* DDS Handler for ISM
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#pragma once
#include <DDS/DDSConnector/dds_connector.h>
#include <DDS/Core/topic_lock_master.h>
#include <InfrastructureManagement/ism_dts.h>
#include <InfrastructureManagement/ism_fts.h>
#include "logger.h"
namespace Core
{
class Pacemaker;
}
namespace InfrastructureManagement
{
class DdsHandler final
{
public:
explicit DdsHandler(int domainId);
~DdsHandler() = default;
bool init(const QStringList &qosFileList = QStringList());
std::shared_ptr<Core::Pacemaker> pacemaker() const
{
return m_pacemaker;
}
std::shared_ptr<Core::TopicLockMaster> topicLockMaster() const { return m_topicLockMaster; }
std::shared_ptr<InfrastructureManagement::Interface::Dts> dts() const
{
return m_ddsDts;
}
std::shared_ptr<InfrastructureManagement::Interface::Fts> fts() const
{
return m_ddsFts;
}
std::shared_ptr<DDSConnector::DdsConnector> ddsConnector() const
{
return m_ddsConnector;
}
private:
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
std::shared_ptr<Core::Pacemaker> m_pacemaker;
std::shared_ptr<Core::TopicLockMaster> m_topicLockMaster;
std::shared_ptr<InfrastructureManagement::Interface::Dts> m_ddsDts;
std::shared_ptr<InfrastructureManagement::Interface::Fts> m_ddsFts;
NGL::INGLLogger &m_logger;
};
}
@@ -0,0 +1,179 @@
/**
* @RDE_HEADER@
* ISM Handler Sound Area
* $Id$
* $HeadURL$
* $Author$
* Created by Filip Biedziak, NLE, 2020-08-05
*/
#include "handler_effect_area.h"
#include "handler_main_structure_element.h"
#include "handler_mounting_point_asset.h"
#include "object_main_structure_element.h"
#include "object_effect_area.h"
#include "main_handler.h"
#include <QDebug>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonArray>
namespace InfrastructureManagement
{
HandlerEffectArea::HandlerEffectArea(MainHandler *mainHandler)
: Base(mainHandler, getLogger("HandlerEffectArea"))
{
}
HandlerEffectArea::~HandlerEffectArea()
{
qDeleteAll(m_objectEffectAreaMap);
}
//-----------------------------------------------------------------------------------------------------------------------------
// PUBLIC MEMBER FUNCTIONS
//-----------------------------------------------------------------------------------------------------------------------------
bool HandlerEffectArea::init()
{
const QHash<int, ObjectMainStructureElement *> &objMseMap = m_mainHandler->getHandlerMainStructureElement()->getMainStructureElementsMap();
for (const auto &objMse : qAsConst(objMseMap))
{
ObjectEffectArea *effectAreaObj = createEffectAreaForMse(objMse->getData());
if (effectAreaObj)
m_objectEffectAreaMap.insert(effectAreaObj->getId(), effectAreaObj);
}
if (m_logger.isDebugEnabled())
{
DEBUG_LOG(m_logger) << "number of EffectAreas: " << m_objectEffectAreaMap.size();
for (const auto &EffectAreaObj : qAsConst(m_objectEffectAreaMap))
DEBUG_LOG(m_logger) << "EffectArea ID: " << EffectAreaObj->getId()
<< " | area EGCU ID: " << EffectAreaObj->getAreaEgcuId();
}
return true;
}
int HandlerEffectArea::getSeId(const int mountPointId, const InfrastructureManagement::MainStructureElement &mse) const
{
for ( unsigned int i = 0; i < mse.elements().size(); i++)
{
ERROR_LOG(m_logger) << "mountPointId=" << mountPointId
<< " id=" << mse.elements().at(i).id()
<< " mpId="<< mse.elements().at(i).mountingPointId();
if ( mountPointId ==mse.elements().at(i).mountingPointId() )
{
ERROR_LOG(m_logger) << "return id=" << mse.elements().at(i).id();
return mse.elements().at(i).id();
}
}
return 0;
}
ObjectEffectArea *HandlerEffectArea::createEffectAreaForMse(const InfrastructureManagement::MainStructureElement &mse)
{
std::string properties = mse.properties();
if (properties.find("soundArea") == std::string::npos) // building has no associated sound area
return nullptr;
DEBUG_LOG(m_logger) << "createEffectAreaForMse id=" << mse.id()
<< " propoerties=" << properties;
QJsonObject jsonObj = QJsonDocument::fromJson(QByteArray::fromStdString(properties)).object().value(QStringLiteral("soundArea")).toObject();
int32_t id = jsonObj.value(QStringLiteral("id")).toInt();
int32_t mainEgcuMountpoint = jsonObj.value(QStringLiteral("mainEgcuMountpoint")).toInt();
DEBUG_LOG(m_logger) << "id=" << id
<< " mainEgcuMountpoint=" << mainEgcuMountpoint;
if (m_objectEffectAreaMap.contains(id)) // SoundArea has already been created during the import of another building
{
DEBUG_LOG(m_logger) << "return nullptr";
return nullptr;
}
EffectArea effectArea;
effectArea.id(id);
int seId = getSeId(mainEgcuMountpoint, mse);
effectArea.areaEgcuId(seId);
effectArea.egcuIds(egcuIdsFromJsonObject(jsonObj, mse));
effectArea.geometry(geometryFromJsonObject(jsonObj));
DEBUG_LOG(m_logger) << "mainEgcuMountpoint=" << mainEgcuMountpoint
<< " effectArea.areaEgcuId()=" << effectArea.areaEgcuId()
<< " effectArea.egcuIds().size()=" << effectArea.egcuIds().size()
<< " effectArea.name()=" << effectArea.name();
ObjectEffectArea *effectAreaObj = new ObjectEffectArea(m_mainHandler);
effectAreaObj->createObject(effectArea);
return effectAreaObj;
}
//-----------------------------------------------------------------------------------------------------------------------------
// PRIVATE MEMBER FUNCTIONS
//-----------------------------------------------------------------------------------------------------------------------------
std::vector<int32_t> HandlerEffectArea::egcuIdsFromJsonObject(const QJsonObject &jsonObj, const InfrastructureManagement::MainStructureElement &mse ) const
{
DEBUG_LOG(m_logger) << "egcuIdsFromJsonObject";
std::vector<int32_t> egcuIds;
const QJsonArray &egcuMountPoints = jsonObj.value(QStringLiteral("egcuMountpoints")).toArray(); // qAsConst does not work with r-value
DEBUG_LOG(m_logger) << "egcuMountPoints.size=" << egcuMountPoints.size();
for (const auto &egcuMountPnt : qAsConst(egcuMountPoints))
{
QJsonObject element = egcuMountPnt.toObject();
int mountingPointId = element.value(QStringLiteral("id")).toInt();
int seId = getSeId(mountingPointId, mse);
int32_t egcuId = m_mainHandler->getHandlerMountingPointAsset()->getMountedAssetId(seId);
DEBUG_LOG(m_logger) << "egcuIdsFromJsonObject mountingPointId=" << mountingPointId
<< " seId=" << seId
<< " egcuId=" << egcuId;
if (egcuId > 0)
egcuIds.push_back(egcuId);
} // for
if (m_logger.isDebugEnabled())
{
DEBUG_LOG(m_logger) << "number of EGCUs found: " << egcuIds.size();
//qCritical() << "EGCU IDs: " << egcuIds;
} // if
return egcuIds;
}
std::vector<Core::GeoPosition2D> HandlerEffectArea::geometryFromJsonObject(const QJsonObject &jsonObj) const
{
std::vector<Core::GeoPosition2D> geometry;
Core::GeoPosition2D geoPos2D;
const QJsonArray &points = jsonObj.value(QStringLiteral("geometry")).toArray(); // qAsConst does not work with r-value
for (const auto &point : points)
{
QJsonObject pnt = point.toObject(); // 2D vertex of the polygon that defines the sound area geometry
geoPos2D.lat(pnt.value(QStringLiteral("lat")).toDouble());
geoPos2D.lon(pnt.value(QStringLiteral("lon")).toDouble());
geometry.push_back(geoPos2D);
} // for
if (m_logger.isDebugEnabled())
{
DEBUG_LOG(m_logger) << "number of vertices found: " << geometry.size();
for (const auto &geoPos : geometry)
DEBUG_LOG(m_logger) << "lat = " << geoPos.lat() << " | lon = " << geoPos.lon();
} // if
return geometry;
}
} // namespace InfrastructureManagement
@@ -0,0 +1,59 @@
/**
* @RDE_HEADER@
* ISM Handler Sound Areas
* $Id$
* $HeadURL$
* $Author$
* Created by Filip Biedziak, NLE, 2020-08-05
*/
#pragma once
#include <QHash>
#include "base.h"
namespace InfrastructureManagement
{
class ObjectEffectArea;
class MainHandler;
class HandlerEffectArea final : public Base
{
public:
explicit HandlerEffectArea(MainHandler *mainHandler);
~HandlerEffectArea();
bool init();
ObjectEffectArea *createEffectAreaForMse(const InfrastructureManagement::MainStructureElement &mse);
QHash<int, ObjectEffectArea *> getObjectEffectAreaMap() const { return m_objectEffectAreaMap; }
ObjectEffectArea *getEffectAreaFromId(int32_t id) const { return m_objectEffectAreaMap.value(id, nullptr); }
private:
int getSeId(const int mountPointId, const InfrastructureManagement::MainStructureElement &mse) const;
/**
* @brief assetIdsFromJsonArray reads the EGCU IDs of the sound area from a Json object.
* @param jsonObj Json object with an entry 'egcuMountpoints'
* @return vector with EGCU IDs
*/
std::vector<int32_t> egcuIdsFromJsonObject(const QJsonObject &jsonObj, const MainStructureElement &mse) const;
/**
* @brief geometryFromJsonArray reads the vertices of the sound area from a Json object.
* @param jsonObj Json object with an entry 'geometry'
* @return vector with 2D geo coordinates
*/
std::vector<Core::GeoPosition2D> geometryFromJsonObject(const QJsonObject &jsonObj) const;
private:
QHash<int32_t, ObjectEffectArea *> m_objectEffectAreaMap;
};
} // namespace InfrastructureManagement
@@ -0,0 +1,323 @@
/**
* @RDE_HEADER@
* ISM Handler Instrumentation Assets
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#include "handler_instrumentation_asset.h"
#include "handler_mounting_point_asset.h"
#include "object_instrumentation_asset.h"
#include "main_handler.h"
using namespace InfrastructureManagement;
//--------------------------------------------------------------------------------------------------
HandlerInstrumentationAsset::HandlerInstrumentationAsset(MainHandler *mainHandler)
: Base(mainHandler, getLogger("HandlerInstrumentationAsset"))
, Interface::Fts::InstrumentationAssetModifyRequestHandler(mainHandler->dds()->fts())
, Interface::Fts::InstrumentationAssetRemoveRequestHandler(mainHandler->dds()->fts())
, Interface::Fts::InstrumentationAssetSetStateRequestHandler(mainHandler->dds()->fts())
, Interface::Fts::InstrumentationAssetUnmountRequestHandler(mainHandler->dds()->fts())
{
}
//--------------------------------------------------------------------------------------------------
HandlerInstrumentationAsset::~HandlerInstrumentationAsset()
{
qDeleteAll(m_ObjectInstrumentationAssetMap);
}
//--------------------------------------------------------------------------------------------------
bool HandlerInstrumentationAsset::init()
{
bool bRet = true;
auto cb = [this, &bRet] (const Database::IsmAsset &data)
{
InstrumentationAsset ddsData = ObjectInstrumentationAsset::toDdsData(data);
ObjectInstrumentationAsset *ifs(new ObjectInstrumentationAsset(m_mainHandler));
Core::FunctionReplyObject ret = ifs->createObject(ddsData);
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << ret();
bRet = false;
return;
}
m_ObjectInstrumentationAssetMap.insert(ifs->getId(), ifs);
DEBUG_LOG(m_logger) << "asset id=" << ifs->getId()
<< " id=" << ifs->getData().id()
<< " mountingPointTypeId=" << ifs->getData().mountingPointTypeId()
<< " name=" << ifs->getData().name();
};
// create Asset objects
if (!db()->select(cb) || !bRet)
{
ERROR_LOG(m_logger) << "Error reading data from database!";
return false;
}
DEBUG_LOG(m_logger) << "m_ObjectInstrumentationAssetMap.size() = " << m_ObjectInstrumentationAssetMap.size();
return true;
}
//--------------------------------------------------------------------------------------------------
ObjectInstrumentationAsset *HandlerInstrumentationAsset::createInstrumentationAssetForMse(int buildingId, int structureElementId)
{
int assetId = 0;
InstrumentationAssetModifyRequest request;
request.name(QStringLiteral("Building_%1_SE_%2").arg(buildingId).arg(structureElementId).toStdString());
request.mountingPointTypeId(InfrastructureManagement::MountingPointType::BuildingControlUnit);
instrumentationAssetCreate(request, &assetId);
return m_ObjectInstrumentationAssetMap.value(assetId);
}
//--------------------------------------------------------------------------------------------------
bool HandlerInstrumentationAsset::removeInstrumentationAssetForMse(int assetId)
{
Core::RemoveElementRequest request;
request.id(assetId);
const Core::FunctionReplyObject ret = onInstrumentationAssetRemove(request);
if (ret.error())
WARNING_LOG(m_logger) << ret();
return !ret.error();
}
//--------------------------------------------------------------------------------------------------
bool HandlerInstrumentationAsset::setAssetState(int assetId, InstrumentationAssetState state)
{
ObjectInstrumentationAsset *obj = m_ObjectInstrumentationAssetMap.value(assetId);
if (!obj)
return false;
InstrumentationAsset data = obj->getData();
data.assetStateId(state);
return !obj->updateObject(data).error();
}
//--------------------------------------------------------------------------------------------------
bool HandlerInstrumentationAsset::setAssetAvailableInExercise(int32_t assetId, const std::vector<int32_t> &exercises)
{
ObjectInstrumentationAsset *obj = m_ObjectInstrumentationAssetMap.value(assetId);
if (!obj)
return false;
InstrumentationAsset data = obj->getData();
data.availableInExercise(exercises);
return !obj->updateObject(data).error();
}
//--------------------------------------------------------------------------------------------------
ObjectInstrumentationAsset *HandlerInstrumentationAsset::getAssetFromBarcode(const QString &barcode) const
{
const std::string barcodeStd = barcode.toStdString();
for (auto it = m_ObjectInstrumentationAssetMap.begin(); it != m_ObjectInstrumentationAssetMap.end(); ++it)
{
if (it.value()->getData().barcode() == barcodeStd)
return it.value();
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
ObjectInstrumentationAsset *HandlerInstrumentationAsset::getAssetFromId(int32_t assetId) const
{
return m_ObjectInstrumentationAssetMap.value(assetId);
}
//--------------------------------------------------------------------------------------------------
ObjectInstrumentationAsset *HandlerInstrumentationAsset::getAssetFromBarcodeAndId(const QString &barcode, int32_t assetId) const
{
ObjectInstrumentationAsset *result = m_ObjectInstrumentationAssetMap.value(assetId);
if (result == nullptr)
return nullptr;
if (QString::fromStdString(result->getData().barcode()) != barcode)
return nullptr;
return result;
}
//--------------------------------------------------------------------------------------------------
void HandlerInstrumentationAsset::onInstrumentationAssetModifyRequest(const rti::core::SampleIdentity &cookie,
const InstrumentationAssetModifyRequest &request)
{
DEBUG_LOG(m_logger) << "onInstrumentationAssetModifyRequest: " << request;
const Core::FunctionReplyObject ret = request.id() > 0 ? instrumentationAssetModify(request) : instrumentationAssetCreate(request);
if (ret.error())
WARNING_LOG(m_logger) << ret();
m_mainHandler->dds()->fts()->instrumentationAssetModifyReply(cookie, ret);
}
//--------------------------------------------------------------------------------------------------
static InstrumentationAsset convert(const InstrumentationAssetModifyRequest &request,
const InstrumentationAssetState &state = InstrumentationAssetState::Unmounted)
{
InstrumentationAsset newData;
newData.id(request.id());
newData.name(request.name());
newData.mountingPointTypeId(request.mountingPointTypeId());
newData.barcode(request.barcode());
newData.hostname(request.hostname());
newData.properties(request.properties());
newData.assetStateId(state);
newData.lastUpdated(QDateTime::currentMSecsSinceEpoch());
newData.availableInExercise(request.availableInExercise());
return newData;
}
//--------------------------------------------------------------------------------------------------
Core::FunctionReplyObject HandlerInstrumentationAsset::instrumentationAssetCreate(const InstrumentationAssetModifyRequest &request, int *assetId)
{
if (assetId)
*assetId = 0;
ObjectInstrumentationAsset *ifs(new ObjectInstrumentationAsset(m_mainHandler));
Core::FunctionReplyObject ret = ifs->createObject(convert(request));
if (ret.error())
{
delete ifs;
return ret;
}
if (assetId)
*assetId = ifs->getId();
m_ObjectInstrumentationAssetMap.insert(ifs->getId(), ifs);
return ret;
}
//--------------------------------------------------------------------------------------------------
Core::FunctionReplyObject HandlerInstrumentationAsset::instrumentationAssetModify(const InstrumentationAssetModifyRequest &request)
{
ObjectInstrumentationAsset *ifs = m_ObjectInstrumentationAssetMap.value(request.id());
if (ifs == nullptr)
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Asset with id %1 not found")).arg(request.id());
return ifs->updateObject(convert(request, ifs->getData().assetStateId()));
}
//--------------------------------------------------------------------------------------------------
void HandlerInstrumentationAsset::onInstrumentationAssetRemoveRequest(const rti::core::SampleIdentity &cookie,
const Core::RemoveElementRequest &request)
{
const Core::FunctionReplyObject ret = onInstrumentationAssetRemove(request);
if (ret.error())
WARNING_LOG(m_logger) << ret();
m_mainHandler->dds()->fts()->instrumentationAssetRemoveReply(cookie, ret);
}
//--------------------------------------------------------------------------------------------------
Core::FunctionReplyObject HandlerInstrumentationAsset::onInstrumentationAssetRemove(const Core::RemoveElementRequest &request)
{
ObjectInstrumentationAsset *ifs = m_ObjectInstrumentationAssetMap.value(request.id());
if (ifs == nullptr)
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Asset with id %1 not found")).arg(request.id());
if (m_mainHandler->dds()->topicLockMaster()->isLocked(ifs->getData(), m_mainHandler->exerciseId()))
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Asset '%1' is used by another user!")).arg(ifs->getName());
Core::FunctionReplyObject ret = ifs->removeObject();
DEBUG_LOG(m_logger) << "Deleted Asset id = " << request.id();
if (ret.error())
return ret;
// delete ObjectInstrumentationAsset (including Map)
delete ifs;
m_ObjectInstrumentationAssetMap.remove(request.id());
m_mainHandler->getHandlerMountingPointAsset()->unmountAsset(request.id());
return ret;
}
//--------------------------------------------------------------------------------------------------
void HandlerInstrumentationAsset::onInstrumentationAssetSetStateRequest(const rti::core::SampleIdentity &cookie,
const InstrumentationAssetSetStateRequest &request)
{
DEBUG_LOG(m_logger) << "onInstrumentationAssetSetStateRequest: " << request;
const Core::FunctionReplyObject ret = instrumentationAssetSetState(request);
if (ret.error())
WARNING_LOG(m_logger) << ret();
m_mainHandler->dds()->fts()->instrumentationAssetSetStateReply(cookie, ret);
}
//--------------------------------------------------------------------------------------------------
Core::FunctionReplyObject HandlerInstrumentationAsset::instrumentationAssetSetState(const InstrumentationAssetSetStateRequest &request)
{
Core::FunctionReplyObject ret;
if (request.id() > 0)
{
ObjectInstrumentationAsset *ifs = m_ObjectInstrumentationAssetMap.value(request.id());
if (ifs == nullptr)
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Asset with id %1 not found")).arg(request.id());
if (m_mainHandler->dds()->topicLockMaster()->isLocked(ifs->getData(), m_mainHandler->exerciseId()))
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Asset '%1' is used by another user!")).arg(ifs->getName());
// we cannot mount here
if (request.instrumentationAssetStateId() == InstrumentationAssetState::Mounted)
{
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Asset '%1' cannot be mounted by this request")).arg(ifs->getName());
}
if(request.instrumentationAssetStateId() == InstrumentationAssetState::Defect)
{
bool retUnmount = m_mainHandler->getHandlerMountingPointAsset()->unmountAsset(request.id());
WARNING_LOG(m_logger)<<"unmount Asset id ( "<< request.id()<<" )"<<" return ? "<<retUnmount;
}
// set new state (unmounted or defect)
if (!setAssetState(request.id(), request.instrumentationAssetStateId()))
{
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Could not update state for asset with id %1")).arg(request.id());
}
InstrumentationAsset data = ifs->getData();
data.assetStateId(request.instrumentationAssetStateId());
data.lastUpdated(QDateTime::currentMSecsSinceEpoch());
ret = ifs->updateObject(data);
}
return ret;
}
//--------------------------------------------------------------------------------------------------
void HandlerInstrumentationAsset::onInstrumentationAssetUnmountRequest(const rti::core::SampleIdentity &cookie, const InstrumentationAssetUnmountRequest &request)
{
DEBUG_LOG(m_logger) << "onInstrumentationAssetUnmountRequest: " << request;
const Core::FunctionReplyObject ret = instrumentationAssetUnmount(request);
if (ret.error())
WARNING_LOG(m_logger) << ret();
m_mainHandler->dds()->fts()->instrumentationAssetUnmountReply(cookie, ret);
}
//--------------------------------------------------------------------------------------------------
Core::FunctionReplyObject HandlerInstrumentationAsset::instrumentationAssetUnmount(const InstrumentationAssetUnmountRequest &request)
{
Core::FunctionReplyObject ret;
if(request.id() > 0)
{
ObjectInstrumentationAsset *ifs = m_ObjectInstrumentationAssetMap.value(request.id());
if (ifs == nullptr)
{
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Asset with id %1 not found")).arg(request.id());
}
if (m_mainHandler->dds()->topicLockMaster()->isLocked(ifs->getData(), m_mainHandler->exerciseId()))
{
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Asset '%1' is used by another user!")).arg(ifs->getName());
}
if (!m_mainHandler->getHandlerMountingPointAsset()->unmountAsset(request.id()))
{
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Error unmounting instrumentation asset with id %1")).arg(request.id());
}
}
return ret;
}
@@ -0,0 +1,63 @@
/**
* @RDE_HEADER@
* ISM Handler Instrumentation Assets
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#pragma once
#include <QHash>
#include "base.h"
//-------------------------------------------------------------------------------------------------------------
namespace InfrastructureManagement
{
class ObjectInstrumentationAsset;
class MainHandler;
class HandlerInstrumentationAsset final : public Base
, protected Interface::Fts::InstrumentationAssetModifyRequestHandler
, protected Interface::Fts::InstrumentationAssetRemoveRequestHandler
, protected Interface::Fts::InstrumentationAssetSetStateRequestHandler
, protected Interface::Fts::InstrumentationAssetUnmountRequestHandler
{
public:
explicit HandlerInstrumentationAsset(MainHandler *mainHandler);
~HandlerInstrumentationAsset();
bool init();
ObjectInstrumentationAsset *createInstrumentationAssetForMse(int buildingId, int structureElementId);
bool removeInstrumentationAssetForMse(int assetId);
bool setAssetState(int assetId, InstrumentationAssetState state);
bool setAssetAvailableInExercise(int32_t assetId, const std::vector<int32_t> &exercises);
QHash<int, ObjectInstrumentationAsset *> getObjectInstrumentationAssetMap() const
{
return m_ObjectInstrumentationAssetMap;
}
ObjectInstrumentationAsset *getAssetFromBarcode(const QString &barcode) const;
ObjectInstrumentationAsset *getAssetFromId(int32_t assetId) const ;
ObjectInstrumentationAsset *getAssetFromBarcodeAndId(const QString &barcode, int32_t assetId) const;
private:
void onInstrumentationAssetModifyRequest(const rti::core::SampleIdentity &cookie,
const InstrumentationAssetModifyRequest &request) override;
Core::FunctionReplyObject instrumentationAssetCreate(const InstrumentationAssetModifyRequest &request, int *assetId = nullptr);
Core::FunctionReplyObject instrumentationAssetModify(const InstrumentationAssetModifyRequest &request);
void onInstrumentationAssetRemoveRequest(const rti::core::SampleIdentity &cookie,
const Core::RemoveElementRequest &request) override;
Core::FunctionReplyObject onInstrumentationAssetRemove(const Core::RemoveElementRequest &request);
void onInstrumentationAssetSetStateRequest(const rti::core::SampleIdentity &cookie,
const InstrumentationAssetSetStateRequest &request) override;
Core::FunctionReplyObject instrumentationAssetSetState(const InstrumentationAssetSetStateRequest &request);
void onInstrumentationAssetUnmountRequest(const rti::core::SampleIdentity &cookie,
const InstrumentationAssetUnmountRequest &request) override;
Core::FunctionReplyObject instrumentationAssetUnmount(const InstrumentationAssetUnmountRequest &request);
private:
QHash<int, ObjectInstrumentationAsset *> m_ObjectInstrumentationAssetMap;
};
}
@@ -0,0 +1,242 @@
/**
* @RDE_HEADER@
* ISM Handler Mounting Point Schedule
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#include "handler_main_schedule.h"
#include "object_main_schedule.h"
#include "main_handler.h"
#include "convert_db_to_dds.h"
#include "handler_main_structure_element.h"
#include "object_structure_element.h"
#include <InfrastructureManagement/ism_db.h>
#include <NGLLogger/NGLLoggerBootstrap.h>
using namespace InfrastructureManagement;
//--------------------------------------------------------------------------------------------------------------------------------------------------
HandlerMainSchedule::HandlerMainSchedule(MainHandler *mainHandler)
: Base(mainHandler, getLogger("HandlerMainSchedule"))
, Interface::Fts::MainScheduleModifyRequestHandler(mainHandler->dds()->fts())
, Interface::Fts::MainScheduleCopyRequestHandler(mainHandler->dds()->fts())
, Interface::Fts::MainScheduleRemoveRequestHandler(mainHandler->dds()->fts())
, Interface::Fts::MountingPointPlanModifyRequestHandler(mainHandler->dds()->fts())
, m_mainHandler(mainHandler)
{
connect(db().get(), &DatabaseInterface::notifyInsertMainSchedule, this, &HandlerMainSchedule::onDbInsertedSchedule);
}
//--------------------------------------------------------------------------------------------------------------------------------------------------
HandlerMainSchedule::~HandlerMainSchedule()
{
qDeleteAll(m_objectMainScheduleMap);
}
//--------------------------------------------------------------------------------------------------------------------------------------------------
bool HandlerMainSchedule::init()
{
bool bRet = true;
auto cbMps = [this, &bRet] (const Database::IsmMountingPointSchedule &data)
{
InfrastructureManagement::MainSchedule ddsData = ObjectMainSchedule::toDdsData(data);
ObjectMainSchedule *ifs(new ObjectMainSchedule(m_mainHandler));
Core::FunctionReplyObject ret = ifs->createObject(ddsData);
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << ret();
bRet = false;
return;
}
m_objectMainScheduleMap.insert(ifs->getId(), ifs);
DEBUG_LOG(m_logger) << "MainSchedule Id = " << ifs->getId();
};
// create Mounting Point Schedule objects
if (!db()->select(cbMps) || !bRet)
{
ERROR_LOG(m_logger) << "Error reading data from database!";
return false;
}
for (ObjectMainSchedule * ifs : m_objectMainScheduleMap)
{
ifs->loadMountingPointPlans();
}
return true;
}
//--------------------------------------------------------------------------------------------------
void HandlerMainSchedule::onMainScheduleModifyRequest(const rti::core::SampleIdentity &cookie,
const MainScheduleModifyRequest &request)
{
DEBUG_LOG(m_logger) << "onMainScheduleModifyRequest: " << request;
const Core::FunctionReplyObject ret = request.id() > 0 ? mainScheduleModify(request) : mainScheduleCreate(request);
if (ret.error())
WARNING_LOG(m_logger) << ret();
m_mainHandler->dds()->fts()->mainScheduleModifyReply(cookie, ret);
}
//--------------------------------------------------------------------------------------------------
void HandlerMainSchedule::onMainScheduleCopyRequest(const rti::core::SampleIdentity &cookie,
const MainScheduleCopyRequest &request)
{
DEBUG_LOG(m_logger) << "onMainScheduleCopyRequest: " << request;
Core::FunctionReplyObject ret;
if (request.id() > 0)
{
ObjectMainSchedule ifs(m_mainHandler);
ret = ifs.copyObject(request.id());
onDbInsertedSchedule(ifs.getId()); // because notification is not emitted in this case
}
if (ret.error())
WARNING_LOG(m_logger) << ret();
m_mainHandler->dds()->fts()->mainScheduleCopyReply(cookie, ret);
}
//--------------------------------------------------------------------------------------------------
// ---- .elements() are explicitely NOT changed with this method ----
static MainSchedule convert(const MainScheduleModifyRequest &request)
{
MainSchedule ddsData;
ddsData.id(request.id());
ddsData.name(request.name());
ddsData.statusId(request.statusId());
ddsData.timeCreated(request.timeCreated());
ddsData.timeStart(request.timeStart());
ddsData.timeEnd(request.timeEnd());
ddsData.exerciseId(request.exerciseId());
ddsData.description(request.description());
return ddsData;
}
//--------------------------------------------------------------------------------------------------------------------------------------------------
// ---- .elements() are explicitely NOT changed with this method ----
Core::FunctionReplyObject HandlerMainSchedule::mainScheduleCreate(const InfrastructureManagement::MainScheduleModifyRequest &request)
{
ObjectMainSchedule *ifs(new ObjectMainSchedule(m_mainHandler));
Core::FunctionReplyObject ret = ifs->createObject(convert(request));
if (ret.error())
delete ifs;
else
{
ifs->loadMountingPointPlans();
m_objectMainScheduleMap.insert(ifs->getId(), ifs);
}
return ret;
}
//--------------------------------------------------------------------------------------------------------------------------------------------------
// ---- .elements() are explicitely NOT changed with this method ----
Core::FunctionReplyObject HandlerMainSchedule::mainScheduleModify(const InfrastructureManagement::MainScheduleModifyRequest &request)
{
ObjectMainSchedule *ifs = m_objectMainScheduleMap.value(request.id());
if (ifs == nullptr)
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "MainSchedule with id %1 not found")).arg(request.id());
return ifs->updateObject(convert(request));;
}
//--------------------------------------------------------------------------------------------------------------------------------------------------
void HandlerMainSchedule::onMainScheduleRemoveRequest(const rti::core::SampleIdentity &cookie,
const Core::RemoveElementRequest &request)
{
Core::FunctionReplyObject ret;
ObjectMainSchedule *ifs = m_objectMainScheduleMap.value(request.id());
if (ifs == nullptr)
{
ret = Core::FunctionReplyObject(request.id(), tr_lts("dds", "MainSchedule with id %1 not found")).arg(request.id());
m_mainHandler->dds()->fts()->mainScheduleRemoveReply(cookie, ret);
return;
}
if (m_mainHandler->dds()->topicLockMaster()->isLocked(ifs->getData(), m_mainHandler->exerciseId()))
{
ret = Core::FunctionReplyObject(request.id(), tr_lts("dds", "MainSchedule '%1' is used by another user!")).arg(ifs->getName());
m_mainHandler->dds()->fts()->mainScheduleRemoveReply(cookie, ret);
return;
}
ret = ifs->removeObject();
if (ret.error())
ERROR_LOG(m_logger) << ret();
else
{
delete ifs;
m_objectMainScheduleMap.remove(request.id());
}
m_mainHandler->dds()->fts()->mainScheduleRemoveReply(cookie, ret);
}
//--------------------------------------------------------------------------------------------------------------------------------------
void HandlerMainSchedule::onMountingPointPlanModifyRequest(const rti::core::SampleIdentity &cookie,
const InfrastructureManagement::MountingPointPlanModifyRequest &request)
{
DEBUG_LOG(m_logger) << "onMountingPointPlanModifyRequest: " << request;
const Core::FunctionReplyObject ret = mountingPointPlanModify(request);
if (ret.error())
WARNING_LOG(m_logger) << ret();
m_mainHandler->dds()->fts()->mountingPointPlanModifyReply(cookie, ret);
}
Core::FunctionReplyObject HandlerMainSchedule::mountingPointPlanModify(const InfrastructureManagement::MountingPointPlanModifyRequest &request)
{
ObjectMainSchedule *ifs = m_objectMainScheduleMap.value(request.mountingPointScheduleId());
if (ifs == nullptr)
return Core::FunctionReplyObject(request.mountingPointScheduleId(), tr_lts("dds", "MainSchedule with id %1 not found")).arg(request.mountingPointScheduleId());
return ifs->updateElements(request.mountingPointPlans());
}
//----------------------------------------------------------------------------------------------------------------------------
void HandlerMainSchedule::onDbInsertedSchedule(const QVariant &id_)
{
int id = id_.toInt();
NOTICE_LOG(m_logger) << "DB inserted Schedule with id: " << id;
if (!m_objectMainScheduleMap.contains(id))
initByDbId(id);
}
//----------------------------------------------------------------------------------------------------------------------------
bool HandlerMainSchedule::initByDbId(int dbId)
{
Database::IsmMountingPointSchedule msData;
DEBUG_LOG(m_logger) << "Reading Schedule from database!";
if (!db()->selectIsmMountingPointSchedule(dbId, msData))
{
ERROR_LOG(m_logger) << "Error reading schedule data from database: id not found " << dbId;
return false;
}
if (msData.id != dbId)
return false;
// create object
ObjectMainSchedule *ifs(new ObjectMainSchedule(m_mainHandler));
Core::FunctionReplyObject ret = ifs->createObject(Database::convert(msData));
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << ret();
return false;
}
m_objectMainScheduleMap.insert(ifs->getId(), ifs);
return true;
}
std::vector<MountingPointPlan> HandlerMainSchedule::getMountingPointPlans(int scheduleId) const
{
if (!getMainSchedule(scheduleId))
return {};
return getMainSchedule(scheduleId)->getData().elements();
}
@@ -0,0 +1,67 @@
/**
* @RDE_HEADER@
* ISM Handler Mounting Point Schedule
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#pragma once
#include <QHash>
#include "base.h"
//-------------------------------------------------------------------------------------------------------------
namespace InfrastructureManagement
{
class ObjectMainSchedule;
class MainHandler;
class HandlerMainSchedule final : public Base
, protected Interface::Fts::MainScheduleModifyRequestHandler
, protected Interface::Fts::MainScheduleCopyRequestHandler
, protected Interface::Fts::MainScheduleRemoveRequestHandler
, protected Interface::Fts::MountingPointPlanModifyRequestHandler
{
Q_OBJECT
public:
explicit HandlerMainSchedule(MainHandler *mainHandler);
~HandlerMainSchedule();
bool init();
bool initByDbId(int dbId);
std::vector<MountingPointPlan> getMountingPointPlans(int scheduleId) const;
ObjectMainSchedule *getMainSchedule(int scheduleId) const
{
return m_objectMainScheduleMap.value(scheduleId);
}
QHash<int, ObjectMainSchedule *> getMainScheduleMap() const
{
return m_objectMainScheduleMap;
}
private:
void onMainScheduleModifyRequest(const rti::core::SampleIdentity &cookie,
const MainScheduleModifyRequest &request) override final;
Core::FunctionReplyObject mainScheduleCreate(const MainScheduleModifyRequest &request);
Core::FunctionReplyObject mainScheduleModify(const MainScheduleModifyRequest &request);
void onMainScheduleCopyRequest(const rti::core::SampleIdentity &cookie,
const MainScheduleCopyRequest &request) override final;
void onMainScheduleRemoveRequest(const rti::core::SampleIdentity &cookie,
const Core::RemoveElementRequest &request) override final;
void onMountingPointPlanModifyRequest(const rti::core::SampleIdentity &cookie,
const MountingPointPlanModifyRequest &request) override final;
Core::FunctionReplyObject mountingPointPlanModify(const MountingPointPlanModifyRequest &request);
void onDbInsertedSchedule(const QVariant &id_);
private:
QHash<int, ObjectMainSchedule *> m_objectMainScheduleMap;
MainHandler *m_mainHandler;
};
}
@@ -0,0 +1,683 @@
/**
* @RDE_HEADER@
* ISM Handler Main Structure Elements
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#include "handler_main_structure_element.h"
#include "handler_mounting_point_asset.h"
#include "handler_instrumentation_asset.h"
#include "object_main_structure_element.h"
#include "object_structure_element.h"
#include "object_instrumentation_asset.h"
#include <ngldb/dbtransaction.h>
#include "convert_db_to_dds.h"
#include <QJsonObject>
#include <QJsonDocument>
namespace InfrastructureManagement
{
//---------------------------------------------------------------------------------------------------------------------------------------------------
HandlerMainStructureElement::HandlerMainStructureElement(MainHandler *mainHandler)
: Base(mainHandler, getLogger("HandlerMainStructureElement"))
, Interface::Fts::MainStructureElementModifyRequestHandler(mainHandler->dds()->fts())
, Interface::Fts::MainStructureElementModifyBridgeStatusRequestHandler(m_mainHandler->dds()->fts())
, Interface::Fts::MainStructureElementModifyPositionRequestHandler(m_mainHandler->dds()->fts())
, Interface::Fts::MainStructureElementRemoveRequestHandler(mainHandler->dds()->fts())
, Interface::Fts::StructureElementModifyRequestHandler(mainHandler->dds()->fts())
, Interface::Fts::StructureElementUpdateEffectOverrideRequestHandler(mainHandler->dds()->fts())
{
}
//---------------------------------------------------------------------------------------------------------------------------------------------------
HandlerMainStructureElement::~HandlerMainStructureElement()
{
qDeleteAll(m_objectMainStructureElementMap);
// ptr in m_objectStructureElementMap are deleted inside their corresponding MainStructureElement objects
// qDeleteAll(m_objectStructureElementMap);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------
bool HandlerMainStructureElement::init()
{
// read all MSE from database
QVector<Database::IsmMainStructureElement> dataVec;
if (!db()->select(dataVec))
{
ERROR_LOG(m_logger) << "Error reading data from database!";
return false;
}
// read all SE from database
QVector<Database::IsmStructureElement> dataVecSE;
if (!db()->select(dataVecSE))
{
ERROR_LOG(m_logger) << "Error reading data from database!";
return false;
}
// TODO: add sql 'ORDER BY foo' support
auto sortSE = [](const Database::IsmStructureElement & e1, const Database::IsmStructureElement & e2)
{
return e1.id < e2.id;
};
std::sort(dataVecSE.begin(), dataVecSE.end(), sortSE);
// create MSE objects
for (const Database::IsmMainStructureElement &dbData : qAsConst(dataVec))
{
ObjectMainStructureElement *ifs(new ObjectMainStructureElement(dbData, m_mainHandler));
m_objectMainStructureElementMap.insert(ifs->getId(), ifs);
}
DEBUG_LOG(m_logger) << "m_objectMainStructureElementMap.size() = " << m_objectMainStructureElementMap.size();
// create SE objects, add them to MSE
for (const Database::IsmStructureElement &dbData : qAsConst(dataVecSE))
{
ObjectMainStructureElement *objMse = m_objectMainStructureElementMap.value(dbData.mainStructureElementId);
if (!objMse || !objMse->isValid())
{
WARNING_LOG(m_logger) << "Cannot find Main Structure Element Id = " << dbData.mainStructureElementId
<< " for structure element " << dbData.id;
continue;
}
ObjectStructureElement *ifse = objMse->createStructureElementObject(dbData);
if (!ifse)
{
ERROR_LOG(m_logger) << "Could not create SE!";
return false;
}
}
// add structure elements to global map for lookup (e.g. in 'add Footprints to MSE objects')
for (ObjectMainStructureElement *objMse : qAsConst(m_objectMainStructureElementMap))
m_objectStructureElementMap.unite(objMse->getStructureElements());
// add Footprints to MSE objects
// read all FP from database
QMap<int, QMap<int, Database::IsmStructureElementFootprint>> footprintSorted;
{
auto cb = [&footprintSorted](const Database::IsmStructureElementFootprint & fp)
{
footprintSorted[fp.structureElementId][fp.indexNo] = fp;
};
if (!db()->select(cb))
{
ERROR_LOG(m_logger) << "Error reading data from database!";
return false;
}
}
for (const QMap<int, Database::IsmStructureElementFootprint> &cont : qAsConst(footprintSorted))
{
if (cont.empty())
continue;
const int structureElementId = cont.first().structureElementId;
const ObjectStructureElement *objSe = m_objectStructureElementMap.value(structureElementId);
ObjectMainStructureElement *objMse = objSe ? m_objectMainStructureElementMap.value(objSe->getMainStructureElementId()) : nullptr;
if (!objMse || !objMse->isValid())
{
WARNING_LOG(m_logger) << "Cannot find Main Structure Element Id = " << structureElementId
<< " for footprint element " << cont.first().id;
continue;
}
std::vector<FootprintElement> elements;
elements.reserve(cont.size());
FootprintElement elem;
for (const auto &pos : cont)
{
elem.id(pos.id);
elem.relPosition(Core::RelativePosition(pos.relPosition.x(),
pos.relPosition.y(),
pos.relPosition.z()));
elem.isGroundLevel(pos.isGroundLevel);
elements.push_back(elem);
}
objMse->setFootprintData(elements);
}
DEBUG_LOG(m_logger) << "m_objectStructureElementMap.size() = " << m_objectStructureElementMap.size();
// publish
for (auto it = m_objectMainStructureElementMap.begin(); it != m_objectMainStructureElementMap.end(); ++it)
{
const int buildingId = it.key();
publishMainStructureElement(buildingId);
it.value()->noticeNewProperties();
}
return true;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------
void HandlerMainStructureElement::onMainStructureElementModifyRequest(const rti::core::SampleIdentity &cookie,
const MainStructureElementModifyRequest &request)
{
DEBUG_LOG(m_logger) << "onMainStructureElementModifyRequest: " << request;
const Core::FunctionReplyObject ret = request.id() == 0 ? onMainStructureElementCreate(request) : onMainStructureElementModify(request);
if (ret.error())
ERROR_LOG(m_logger) << ret()
<< " request.id()=" << request.id();
m_mainHandler->dds()->fts()->mainStructureElementModifyReply(cookie, ret);
}
//---------------------------------------------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject HandlerMainStructureElement::onMainStructureElementCreate(const MainStructureElementModifyRequest &request)
{
if (request.elements().size() < 1)
return Core::FunctionReplyObject(0, tr_lts("dds", "No structure elements given"));
if (request.elements().size() != request.childParentRelations().size())
return Core::FunctionReplyObject(0, tr_lts("dds", "Structure elements do not match child - parent relations"));
const StructureElement &seBuilding = request.elements().at(0);
const InfrastructureManagement::StructureElementType &seType = seBuilding.structureElementTypeId();
if ((seType != InfrastructureManagement::StructureElementType::Building &&
seType != InfrastructureManagement::StructureElementType::Announcement &&
seType != InfrastructureManagement::StructureElementType::ApproachingPoint &&
seType != InfrastructureManagement::StructureElementType::MeteoDataUnit &&
seType != InfrastructureManagement::StructureElementType::RadioStation &&
seType != InfrastructureManagement::StructureElementType::Bridge) ||
seBuilding.mountingPointTypeId() != InfrastructureManagement::MountingPointType::Unknown)
return Core::FunctionReplyObject(0, tr_lts("dds", "First structure element is not from a top level type"));
if (request.elements().size() > 1) // Buildings must have min 2 elements
{
const StructureElement &seBuildingBCU = request.elements().at(1);
if (seBuildingBCU.structureElementTypeId() != InfrastructureManagement::StructureElementType::MountingPoint ||
seBuildingBCU.mountingPointTypeId() != InfrastructureManagement::MountingPointType::BuildingControlUnit)
return Core::FunctionReplyObject(0, tr_lts("dds", "Second structure element is not from type 'MountingPoint' for 'BuildingControlUnit'"));
}
InfrastructureManagement::ObjectMainStructureElement *ifs(new ObjectMainStructureElement(m_mainHandler));
Core::FunctionReplyObject ret = ifs->createObject(request);
if (ret.error())
{
delete ifs;
return ret;
}
// add MSE, SE in corresponding maps
const int buildingId = ifs->getId();
m_objectMainStructureElementMap.insert(buildingId, ifs);
const ObjectStructureElement *oseBcu = ifs->getMainStructureElementMountingPoint();
bool bMountSucessful = false;
if (oseBcu)
{
// after adding elements to m_objectMainStructureElementMap / m_objectStructureElementMap!
ObjectInstrumentationAsset *objAsset = m_mainHandler->getHandlerInstrumentationAsset()->createInstrumentationAssetForMse(ifs->getId(),
oseBcu->getId());
if (objAsset)
{
if (m_mainHandler->getHandlerMountingPointAsset()->mount(objAsset->getId(), oseBcu->getId()))
bMountSucessful = true;
}
}
if (!bMountSucessful)
ERROR_LOG(m_logger) << "Can not create/mount an asset for main structure element " << ifs->getId();
// publish MSE
publishMainStructureElement(buildingId);
return ret;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject HandlerMainStructureElement::onMainStructureElementModify(const MainStructureElementModifyRequest &request)
{
InfrastructureManagement::ObjectMainStructureElement *ifs = m_objectMainStructureElementMap.value(request.id());
if (ifs == nullptr)
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "MainStructureElement with id %1 not found")).arg(request.id());
Core::FunctionReplyObject ret = ifs->updateObject(request);
if (ret.error())
return ret;
// updating corresponding SE, if exists
if (ifs->getStructureElementId() > 0)
{
DEBUG_LOG(m_logger) << "Updating corresponding Structure Element id = " << ifs->getStructureElementId();
InfrastructureManagement::ObjectStructureElement *ifse = m_objectStructureElementMap.value(ifs->getStructureElementId());
if (!ifse)
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "StructureElement with id %1 not found for MainStructureElement %2"))
.arg(ifs->getStructureElementId()).arg(request.id());
InfrastructureManagement::StructureElement seData = ifse->getData();
seData.name(request.name());
seData.displayName(ifse->getData().displayName());
DEBUG_LOG(m_logger) << "Updating corresponding Structure Element id = " << ifs->getStructureElementId()
<< " seData.displayName=" << seData.displayName();
Core::FunctionReplyObject retSe = ifse->updateObject(seData);
if (retSe.error())
return retSe;
}
publishMainStructureElement(request.id());
return ret;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------
void HandlerMainStructureElement::onMainStructureElementRemoveRequest(const rti::core::SampleIdentity &cookie,
const InfrastructureManagement::MainStructureElementRemoveRequest &request)
{
Core::FunctionReplyObject ret;
int buildingId = request.id();
// gest MSE object
InfrastructureManagement::ObjectMainStructureElement *ifs = m_objectMainStructureElementMap.value(buildingId);
if (ifs == nullptr)
{
ret = Core::FunctionReplyObject(buildingId, tr_lts("dds", "MainStructureElement with id %1 not found")).arg(buildingId);
m_mainHandler->dds()->fts()->mainStructureElementRemoveReply(cookie, ret);
return;
}
if (m_mainHandler->dds()->topicLockMaster()->isLocked(ifs->getData(), m_mainHandler->exerciseId()))
{
ret = Core::FunctionReplyObject(request.id(), tr_lts("dds", "MainStructureElement '%1' is used by another user!")).arg(ifs->getName());
m_mainHandler->dds()->fts()->mainStructureElementRemoveReply(cookie, ret);
return;
}
// Unmount and remove the BuildingControlUnit which was implicitly created and mounted upon import of the Building.
const ObjectStructureElement *bcuMountingPoint = ifs->getMainStructureElementMountingPoint();
int bcuAssetId = 0;
if (bcuMountingPoint)
bcuAssetId = m_mainHandler->getHandlerMountingPointAsset()->getMountedAssetId(bcuMountingPoint->getId());
if (bcuAssetId == 0 || !m_mainHandler->getHandlerInstrumentationAsset()->removeInstrumentationAssetForMse(bcuAssetId))
WARNING_LOG(m_logger) << "Can not remove BuildingControlUnit with id " << bcuAssetId << " from main structure element which got removed: " << buildingId;
// remove MSE elements from local map and unmount the assets from mounting points
const auto seElements = ifs->getStructureElements();
for (ObjectStructureElement *ose : seElements)
{
if (ose->getStructureElementTypeId() == StructureElementType::MountingPoint)
{
int mountedAssetId = m_mainHandler->getHandlerMountingPointAsset()->getMountedAssetId(ose->getId());
if (mountedAssetId > 0)
{
DEBUG_LOG(m_logger) << "Unmounting instrumentation asset with id " << mountedAssetId << " from mounting point with id " << ose->getId();
if (!m_mainHandler->getHandlerMountingPointAsset()->unmountAsset(mountedAssetId))
WARNING_LOG(m_logger) << "Can not unmount instrumentation asset with id " << mountedAssetId << " from mounting point " << ose->getId();
}
}
m_objectStructureElementMap.remove(ose->getId());
}
DEBUG_LOG(m_logger) << "Deleting MSE id = " << buildingId;
ret = ifs->removeObject(); // removes all from db due to fk
if (ret.error())
ERROR_LOG(m_logger) << ret();
// delete ObjectMainStructureElement (including Map)
delete ifs;
m_objectMainStructureElementMap.remove(buildingId);
dts()->removeMainStructureElementByKey(buildingId);
dts()->removeMainFootprintByKey(buildingId);
m_mainHandler->dds()->fts()->mainStructureElementRemoveReply(cookie, ret);
return;
}
//-----------------------------------------------------------------------------------------------------------------------------------
void HandlerMainStructureElement::onMainStructureElementModifyPositionRequest(const rti::core::SampleIdentity &cookie,
const MainStructureElementModifyPositionRequest &request)
{
const int mseId = request.id();
Core::FunctionReplyObject ret;
InfrastructureManagement::ObjectMainStructureElement *ifs = m_objectMainStructureElementMap.value(mseId);
if (ifs == nullptr)
ret = Core::FunctionReplyObject(request.id(), tr_lts("dds", "MainStructureElement with id %1 not found")).arg(mseId);
else
{
ret = ifs->updatePosition(request.geoPosition());
if (!ret.error())
publishMainStructureElement(request.id());
}
m_mainHandler->dds()->fts()->mainStructureElementModifyPositionReply(cookie, ret);
}
//-----------------------------------------------------------------------------------------------------------------------------------
void HandlerMainStructureElement::onMainStructureElementModifyBridgeStatusRequest(const rti::core::SampleIdentity &cookie,
const MainStructureElementModifyBridgeStatusRequest &request)
{
static int s_id = 1;
const int mseId = request.id();
Core::FunctionReplyObject ret;
InfrastructureManagement::ObjectMainStructureElement *ifs = m_objectMainStructureElementMap.value(mseId);
if (ifs == nullptr)
ret = Core::FunctionReplyObject(request.id(), tr_lts("dds", "MainStructureElement with id %1 not found")).arg(mseId);
else
{
ret = ifs->setBridgeStatus(request.status());
if (!ret.error())
{
publishMainStructureElement(request.id());
// publish BridgeStatus
BridgeChangeStatus bcs;
bcs.id(s_id++);
bcs.buildingId(mseId);
bcs.sampleTime(QDateTime::currentMSecsSinceEpoch());
bcs.status(request.status());
m_mainHandler->dds()->dts()->publish(bcs);
}
}
m_mainHandler->dds()->fts()->mainStructureElementModifyBridgeStatusReply(cookie, ret);
}
//-----------------------------------------------------------------------------------------------------------------------------------
void HandlerMainStructureElement::onStructureElementModifyRequest(const rti::core::SampleIdentity &cookie,
const StructureElementModifyRequest &request)
{
const Core::FunctionReplyObject ret = onStructureElementModify(request);
if (ret.error())
ERROR_LOG(m_logger) << ret();
m_mainHandler->dds()->fts()->structureElementModifyReply(cookie, ret);
}
//-----------------------------------------------------------------------------------------------------------------------------------
void HandlerMainStructureElement::onStructureElementUpdateEffectOverrideRequest(const rti::core::SampleIdentity &cookie,
const StructureElementUpdateEffectOverrideRequest &request)
{
INFO_LOG(m_logger) << "onStructureElementUpdateEffectOverrideRequest "
<< " structureElementId=" << request.structureElementId()
<< " effectId=" << request.effectId()
<< " effectOverride=" << request.effectOverride();
if (!m_objectStructureElementMap.contains(request.structureElementId()))
{
ERROR_LOG(m_logger) << "structureElementId=" << request.structureElementId() << " not valid";
const Core::FunctionReplyObject ret = Core::FunctionReplyObject(-1, tr_lts("dds", "structureElementId %1 not valid")).arg(request.structureElementId());
m_mainHandler->dds()->fts()->structureElementUpdateEffectOverrideReply(cookie, ret);
return;
}
InfrastructureManagement::StructureElement structureElement = getStructureElement(request.structureElementId())->getData();
udpatePropertiesForRelayOverride(request.effectId(), request.effectOverride(), structureElement);
InfrastructureManagement::ObjectStructureElement *ifse = m_objectStructureElementMap.value(structureElement.id());
StructureElementModifyRequest requestSe;
int mseId = ifse->getMainStructureElementId();
//m_mainHandler->dds()->dts()->getBuildingId (structureElement.id(), mseId);
requestSe.mainStructureElementId(mseId);
requestSe.elements().resize(1);
requestSe.elements()[0] = structureElement;
const Core::FunctionReplyObject ret = onStructureElementModify(requestSe);
if (ret.error())
ERROR_LOG(m_logger) << ret();
m_mainHandler->dds()->fts()->structureElementUpdateEffectOverrideReply(cookie, ret);
}
//-----------------------------------------------------------------------------------------------------------------------------------
void HandlerMainStructureElement::changeBuildingNameinMountingPoints(const StructureElement &se, MainStructureElementModifyRequest &mseData)
{
QString oldBuildingName;
QString newBuildingName;
// search old building Display Name:
for (auto it = m_objectStructureElementMap.begin(); it != m_objectStructureElementMap.end(); ++it)
{
const int structureElementId = it.key();
const int buildingId = se.mainStructureElementId();
ObjectStructureElement *ose = it.value();
DEBUG_LOG(m_logger) << "buildingId=" << buildingId
<< " structureElementId=" << structureElementId
<< " se.id=" << se.id()
<< " id=" << ose->getId()
<< " type=" << ose->getStructureElementTypeId()
<< " displayName=" << ose->getData().displayName()
<< " MainStructureElementId=" << ose->getMainStructureElementId();
if ((buildingId == ose->getMainStructureElementId())
//&& (ose->getStructureElementTypeId() == StructureElementType::Building))
&& (ose->getData().mountingPointTypeId() == MountingPointType::BuildingControlUnit))
{
oldBuildingName = QString::fromStdString(ose->getData().displayName());
newBuildingName = QString::fromStdString(se.displayName());
DEBUG_LOG(m_logger) << "old BuildingName= " << oldBuildingName
<< " newBuildingName= " << newBuildingName;
break;
}
}
// search for mse
for (auto it = m_objectStructureElementMap.begin(); it != m_objectStructureElementMap.end(); ++it)
{
const int structureElementId = it.key();
const int buildingId = se.mainStructureElementId();
ObjectStructureElement *ose = it.value();
DEBUG_LOG(m_logger) << "buildingId=" << buildingId
<< " structureElementId=" << structureElementId
<< " se.id=" << se.id()
<< " id=" << ose->getId()
<< " type=" << ose->getStructureElementTypeId()
<< " displayName=" << ose->getData().displayName()
<< " MainStructureElementId=" << ose->getMainStructureElementId();
if ((buildingId == ose->getMainStructureElementId())
&& ((ose->getStructureElementTypeId() == StructureElementType::MountingPoint)
|| (ose->getStructureElementTypeId() == StructureElementType::Building)))
{
QString displayName = QString::fromStdString(ose->getData().displayName());
if (displayName.contains(oldBuildingName))
{
DEBUG_LOG(m_logger) << "update = displayName=" << displayName
<< " oldBuildingName=" << oldBuildingName
<< " newBuildingName=" << newBuildingName;
displayName.replace(oldBuildingName, newBuildingName);
InfrastructureManagement::StructureElement seData = ose->getData();
seData.displayName(displayName.toStdString());
// update mseData before publishing
for (size_t j = 0; j < mseData.elements().size(); ++j)
{
const StructureElement &curSe = mseData.elements().at(j);
if (curSe.id() == structureElementId)
{
DEBUG_LOG(m_logger) << "i=" << j
<< " id=" << curSe.id()
<< " displayName=" << curSe.displayName();
mseData.elements().at(j) = seData;
break;
}
}
Core::FunctionReplyObject retSe = ose->updateObject(seData);
if (retSe.error())
ERROR_LOG(m_logger) << "Error update displayName:" << displayName;
}
}
}
}
//-----------------------------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject HandlerMainStructureElement::onStructureElementModify(const StructureElementModifyRequest &request)
{
const int mseId = request.mainStructureElementId();
InfrastructureManagement::ObjectMainStructureElement *ifs = m_objectMainStructureElementMap.value(mseId);
if (ifs == nullptr)
return Core::FunctionReplyObject(request.mainStructureElementId(), tr_lts("dds", "MainStructureElement with id %1 not found")).arg(mseId);
MainStructureElementModifyRequest mseData;
// copy for lazy people ...
MainStructureElement &mse = mseData;
mse = ifs->getData();
DEBUG_LOG(m_logger) << "request.mseId: " << mseId << " #elements: " << mseData.elements().size() << "request count: " << request.elements().size();
for (const StructureElement &se : request.elements())
{
bool bFound = false;
for (size_t i = 0; i < mseData.elements().size(); ++i)
{
const StructureElement &curSe = mseData.elements().at(i);
if (se.id() == curSe.id())
{
bFound = true;
mseData.elements()[i] = se;
DEBUG_LOG(m_logger) << "StructureElement Modify = " << mseData.elements()[i];
if (se.structureElementTypeId() == StructureElementType::Building
&& se.displayName() != curSe.displayName())
changeBuildingNameinMountingPoints(se, mseData);
break;
}
}
if (!bFound)
return Core::FunctionReplyObject(mseId,
tr_lts("dds", "StructureElement with id %1 not found in MainStructure with id %2")).arg(se.id()).arg(mseId);
}
return onMainStructureElementModify(mseData);
}
//-----------------------------------------------------------------------------------------------------------------------------------
void HandlerMainStructureElement::publishMainStructureElement(int buildingId)
{
DEBUG_LOG(m_logger) << " Publishing MainStructureElement buildingId = " << buildingId;
// retrieve MSE from map
ObjectMainStructureElement *objMse = m_mainHandler->getHandlerMainStructureElement()->getMainStructureElement(buildingId);
if (!objMse || !objMse->isValid())
{
DEBUG_LOG(m_logger) << " Could not publish MainStructureElement Id = " << buildingId;
return;
}
DEBUG_LOG(m_logger) << " MSE Id = " << buildingId << " , structureElementId = " << objMse->getStructureElementId();
// publish
objMse->onPublishData();
}
//-----------------------------------------------------------------------------------------------------------------------------------
void HandlerMainStructureElement::removedStructureElements(const QMap<int, ObjectStructureElement *> &removedElements)
{
for (auto it = removedElements.begin(); it != removedElements.end(); ++it)
m_objectStructureElementMap.remove(it.key());
}
//-----------------------------------------------------------------------------------------------------------------------------------
void HandlerMainStructureElement::addedStructureElements(const QMap<int, ObjectStructureElement *> &addedElements)
{
for (auto it = addedElements.begin(); it != addedElements.end(); ++it)
m_objectStructureElementMap[it.key()] = it.value();
}
/*!
* \brief HandlerMainStructureElement::onExerciseStateChanged
* \param data
* \param mod
* \author Niklas Schmidt
* \details If the exercise, the MSE is in, were deleted, delete the exercise from MSE properties and delete recording in MSE Structure elements and send to dds
*/
void HandlerMainStructureElement::onExerciseStateChanged(const ExerciseManagement::Exercise &data, DataModification mod)
{
Q_UNUSED(mod)
if (data.state().underlying() != ExerciseManagement::ExerciseState::Terminated)
return;
for (auto mseObj : qAsConst(m_objectMainStructureElementMap))
{
const MainStructureElement &mse = mseObj->getData();
QJsonObject obj = QJsonDocument::fromJson(QByteArray::fromStdString(mse.properties())).object();
if (obj.value(QStringLiteral("available_in_exercise")).toArray().at(0).toInt() == data.id())
{
MainStructureElementModifyRequest modReq;
modReq.angle(mse.angle());
modReq.description(mse.description());
modReq.externalWlsId(mse.externalWlsId());
modReq.elements(mse.elements());
// modReq.footprint(mseObj->getFootprint());
modReq.geoPosition(mse.geoPosition());
modReq.groupId(mse.groupId());
modReq.id(mse.id());
modReq.isDeleted(mse.isDeleted());
modReq.isUsed(mse.isUsed());
modReq.modelId(mse.modelId());
modReq.name(mse.name());
std::vector<InfrastructureManagement::StructureElement> resElements;
for (auto element : qAsConst(mse.elements()))
{
QJsonDocument doc = QJsonDocument::fromJson(QByteArray::fromStdString(element.properties()));
QJsonObject objEle = doc.object();
if (objEle.contains(QStringLiteral("record")))
{
objEle[QStringLiteral("record")] = false;
element.properties(QJsonDocument(objEle).toJson().toStdString());
}
resElements.push_back(element);
}
modReq.elements(resElements);
QJsonObject root;
try
{
obj.remove(QStringLiteral("available_in_exercise"));
}
catch (...)
{
ERROR_LOG(m_logger) << "can't parse json";
Q_ASSERT(false);
}
modReq.properties(QString::fromUtf8(QJsonDocument(obj).toJson()).toStdString());
modReq.structureElementId(mse.structureElementId());
modReq.structureElementTypeId(mse.structureElementTypeId());
onMainStructureElementModify(modReq);
}
}
}
void HandlerMainStructureElement::udpatePropertiesForRelayOverride(const int relay,
const InfrastructureManagement::EffectOverride state,
InfrastructureManagement::StructureElement &se)
{
QByteArray content = QByteArray::fromStdString(se.properties());
const QJsonDocument doc(QJsonDocument::fromJson(content));
QJsonObject docObj = QJsonObject(doc.object());
QJsonObject overridesObj = docObj.value(QStringLiteral("Overrides")).toObject();
bool containsRelay = false;
QJsonArray arrRelays = overridesObj.value(QStringLiteral("relays")).toArray();
for (int i = 0; i < arrRelays.size(); ++i)
{
QJsonObject objState = arrRelays[i].toObject();
QStringList keys = objState.keys();
QString keyStr = keys.at(0);
int key = keyStr.toInt();
if (key != relay)
continue;
if (state.underlying() != InfrastructureManagement::EffectOverride_def::Automatic)
arrRelays[i] = QJsonObject({qMakePair<QString, QJsonValue>(keyStr, state.underlying())});
else
arrRelays.removeAt(i);
containsRelay = true;
break;
}
if (!containsRelay && state.underlying() != InfrastructureManagement::EffectOverride_def::Automatic)
arrRelays.append(QJsonObject({qMakePair<QString, QJsonValue>(QString::number(relay), state.underlying())}));
if (arrRelays.isEmpty())
overridesObj.remove(QStringLiteral("relays"));
else
overridesObj.insert(QStringLiteral("relays"), arrRelays);
if (overridesObj.isEmpty())
docObj.remove(QStringLiteral("Overrides"));
else
docObj.insert(QStringLiteral("Overrides"), overridesObj);
QByteArray content_neu = QJsonDocument(docObj).toJson(QJsonDocument::Compact);
se.properties(content_neu.toStdString());
}
//---------------------------------------------------------------------------------------------------------------------------------------------------
} // Namespace InfrastructureManagement
@@ -0,0 +1,96 @@
/**
* @RDE_HEADER@
* ISM Handler Main Structure Elements
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#pragma once
#include <QMap>
#include <QSet>
#include "main_handler.h"
#include "base.h"
//-------------------------------------------------------------------------------------------------------------
namespace InfrastructureManagement
{
class ObjectMainStructureElement;
class ObjectStructureElement;
class MainHandler;
class HandlerMainStructureElement : public Base
, protected Interface::Fts::MainStructureElementModifyRequestHandler
, protected Interface::Fts::MainStructureElementModifyBridgeStatusRequestHandler
, protected Interface::Fts::MainStructureElementModifyPositionRequestHandler
, protected Interface::Fts::MainStructureElementRemoveRequestHandler
, protected Interface::Fts::StructureElementModifyRequestHandler
, protected Interface::Fts::StructureElementUpdateEffectOverrideRequestHandler
{
public:
explicit HandlerMainStructureElement(MainHandler *mainHandler);
~HandlerMainStructureElement();
bool init();
QHash<int, ObjectMainStructureElement *> getMainStructureElementsMap() const
{
return m_objectMainStructureElementMap;
}
ObjectMainStructureElement *getMainStructureElement(int mseId)
{
return m_objectMainStructureElementMap.value(mseId, nullptr);
}
QMap<int, ObjectStructureElement *> getStructureElementMap() const
{
return m_objectStructureElementMap;
}
ObjectStructureElement *getStructureElement(int seId)
{
return m_objectStructureElementMap.value(seId, nullptr);
}
void publishMainStructureElement(int buildingId);
void removedStructureElements(const QMap<int, ObjectStructureElement *> &removedElements);
void addedStructureElements(const QMap<int, ObjectStructureElement *> &addedElements);
public slots:
void onExerciseStateChanged(const ExerciseManagement::Exercise &data, DataModification mod);
private:
void onMainStructureElementModifyRequest(const rti::core::SampleIdentity &cookie,
const MainStructureElementModifyRequest &request) override;
Core::FunctionReplyObject onMainStructureElementCreate(const MainStructureElementModifyRequest &request);
Core::FunctionReplyObject onMainStructureElementModify(const MainStructureElementModifyRequest &request);
Core::FunctionReplyObject onStructureElementUpdateEffectOverrideModify(const StructureElementUpdateEffectOverrideRequest &request);
void onMainStructureElementRemoveRequest(const rti::core::SampleIdentity &cookie,
const MainStructureElementRemoveRequest &request) override;
void onMainStructureElementModifyPositionRequest(const rti::core::SampleIdentity &cookie,
const MainStructureElementModifyPositionRequest &request) override;
void onMainStructureElementModifyBridgeStatusRequest(const rti::core::SampleIdentity &cookie,
const MainStructureElementModifyBridgeStatusRequest &request) override;
void onStructureElementModifyRequest(const rti::core::SampleIdentity &cookie,
const StructureElementModifyRequest &request) override;
void onStructureElementUpdateEffectOverrideRequest(const rti::core::SampleIdentity &cookie,
const StructureElementUpdateEffectOverrideRequest &request) override;
Core::FunctionReplyObject onStructureElementModify(const StructureElementModifyRequest &request);
void changeBuildingNameinMountingPoints(const StructureElement &se, MainStructureElementModifyRequest &mseData);
static void udpatePropertiesForRelayOverride(const int relay,
const InfrastructureManagement::EffectOverride state,
InfrastructureManagement::StructureElement &se);
private:
QHash<int, ObjectMainStructureElement *> m_objectMainStructureElementMap;
QMap<int, ObjectStructureElement *> m_objectStructureElementMap; // all structure element of all buildings, must be sorted!
};
}
@@ -0,0 +1,360 @@
/**
* @RDE_HEADER@
* ISM Handler Mounting Point Assets
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#include "handler_mounting_point_asset.h"
#include "object_mounting_point_asset.h"
#include "object_structure_element.h"
#include "handler_instrumentation_asset.h"
#include "handler_main_structure_element.h"
#include "object_instrumentation_asset.h"
#include "main_handler.h"
#include "settings.h"
//-------------------------------------------------------------------------------------------------------------
namespace InfrastructureManagement
{
HandlerMountingPointAsset::HandlerMountingPointAsset(MainHandler *mainHandler)
: Base(mainHandler, getLogger("HandlerMountingPointAsset"))
, Interface::Fts::MountingPointAssetModifyRequestHandler(mainHandler->dds()->fts())
, Interface::Fts::MountingPointAssetRemoveRequestHandler(mainHandler->dds()->fts())
{
}
//-------------------------------------------------------------------------------------------------------------
HandlerMountingPointAsset::~HandlerMountingPointAsset()
{
qDeleteAll(m_objectMountingPointAssetMap);
}
//-------------------------------------------------------------------------------------------------------------
bool HandlerMountingPointAsset::init()
{
bool bRet = true;
auto cb = [this, &bRet] (const Database::IsmMountingPointAsset &data)
{
InfrastructureManagement::MountingPointAsset ddsData = ObjectMountingPointAsset::toDdsData(data);
ObjectMountingPointAsset *ifs(new ObjectMountingPointAsset(m_mainHandler));
Core::FunctionReplyObject ret = ifs->createObject(ddsData);
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << ret();
bRet = false;
return;
}
m_objectMountingPointAssetMap.insert(ifs->getId(), ifs);
};
// read all Mounting Point Assets from database
if (!db()->select(cb))
{
ERROR_LOG(m_logger) << "Error reading data from database!";
return false;
}
DEBUG_LOG(m_logger) << "m_objectMountingPointAssetMap.size() = " << m_objectMountingPointAssetMap.size();
return true;
}
//--------------------------------------------------------------------------------------------------
void HandlerMountingPointAsset::onMountingPointAssetModifyRequest(const rti::core::SampleIdentity &cookie,
const MountingPointAssetModifyRequest &request)
{
DEBUG_LOG(m_logger) << "onMountingPointAssetModifyRequest: " << request;
const Core::FunctionReplyObject ret = request.id() > 0 ? mountingPointAssetModify(request) : mountingPointAssetCreate(request);
if (ret.error())
WARNING_LOG(m_logger) << ret();
m_mainHandler->dds()->fts()->mountingPointAssetModifyReply(cookie, ret);
}
//-------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject HandlerMountingPointAsset::mountingPointAssetCreate(const InfrastructureManagement::MountingPointAssetModifyRequest &request)
{
MountingPointAsset newData;
newData.structureElementId(request.structureElementId());
newData.assetId(request.assetId());
newData.name(request.name());
newData.lastUpdated(QDateTime::currentMSecsSinceEpoch());
ObjectMountingPointAsset *ifs(new ObjectMountingPointAsset(m_mainHandler));
Core::FunctionReplyObject ret = ifs->createObject(newData);
if (ret.error())
{
delete ifs;
ifs = nullptr;
return ret;
}
syncAvailableInExercise(request.structureElementId(), request.assetId());
m_objectMountingPointAssetMap.insert(ifs->getId(), ifs);
return ret;
}
//-------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject HandlerMountingPointAsset::mountingPointAssetModify(const InfrastructureManagement::MountingPointAssetModifyRequest &request)
{
ObjectMountingPointAsset *ifs = m_objectMountingPointAssetMap.value(request.id());
if (ifs == nullptr)
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "MountingPointAsset with id %1 not found")).arg(request.id());
MountingPointAsset ddsData;
ddsData.id(request.id());
ddsData.structureElementId(request.structureElementId());
ddsData.assetId(request.assetId());
ddsData.name(request.name());
ddsData.lastUpdated(QDateTime::currentMSecsSinceEpoch());
int32_t oldAssetId = ifs->getAssetId();
Core::FunctionReplyObject ret = ifs->updateObject(ddsData);
if (ret.error())
return ret;
if (oldAssetId != ifs->getAssetId())
m_mainHandler->getHandlerInstrumentationAsset()->setAssetAvailableInExercise(oldAssetId, std::vector<int32_t>());
syncAvailableInExercise(ifs->getStructureElementId(), ifs->getAssetId());
return ret;
}
//-------------------------------------------------------------------------------------------------------------
void HandlerMountingPointAsset::onMountingPointAssetRemoveRequest(const rti::core::SampleIdentity &cookie,
const Core::RemoveElementRequest &request)
{
Core::FunctionReplyObject ret;
ObjectMountingPointAsset *ifs = m_objectMountingPointAssetMap.value(request.id());
if (ifs == nullptr)
{
ret = Core::FunctionReplyObject(request.id(), tr_lts("dds", "MountingPointAsset with id %1 not found")).arg(request.id());
m_mainHandler->dds()->fts()->mountingPointAssetRemoveReply(cookie, ret);
return;
}
if (m_mainHandler->dds()->topicLockMaster()->isLocked(ifs->getData(), m_mainHandler->exerciseId()))
{
ret = Core::FunctionReplyObject(request.id(), tr_lts("dds", "MountingPointAsset id %1 is used by another user!")).arg(ifs->getId());
m_mainHandler->dds()->fts()->mountingPointAssetRemoveReply(cookie, ret);
return;
}
int32_t assetId = ifs->getAssetId();
ret = ifs->removeObject();
if (ret.error())
ERROR_LOG(m_logger) << ret();
else
{
// delete ObjectMountingPointAsset (including MapStateMachine)
delete ifs;
m_objectMountingPointAssetMap.remove(request.id());
}
m_mainHandler->dds()->fts()->mountingPointAssetRemoveReply(cookie, ret);
if (!ret.error())
m_mainHandler->getHandlerInstrumentationAsset()->setAssetAvailableInExercise(assetId, std::vector<int32_t>());
}
//-------------------------------------------------------------------------------------------------------------
int HandlerMountingPointAsset::getMountingPointAssetId(int assetId, int structureElementId) const
{
for (auto it = m_objectMountingPointAssetMap.begin(); it != m_objectMountingPointAssetMap.end(); ++it)
{
InfrastructureManagement::ObjectMountingPointAsset *mpa = it.value();
if (mpa->getAssetId() == assetId && mpa->getStructureElementId() == structureElementId)
return mpa->getId();
}
return 0;
}
//-------------------------------------------------------------------------------------------------------------
bool InfrastructureManagement::HandlerMountingPointAsset::mount(int32_t assetId, int32_t mountingPointId, const std::string &name)
{
ObjectInstrumentationAsset *asset = m_mainHandler->getHandlerInstrumentationAsset()->getAssetFromId(assetId);
if (asset == nullptr)
{
WARNING_LOG(m_logger) << "Can not find asset with id " << assetId;
return false;
}
ObjectStructureElement *mountingPoint = m_mainHandler->getHandlerMainStructureElement()->getStructureElement(mountingPointId);
if (mountingPoint == nullptr)
{
WARNING_LOG(m_logger) << "Can not find mounting point with id " << mountingPointId;
return false;
}
if (asset->getData().assetStateId() == InstrumentationAssetState::Defect )
{
WARNING_LOG(m_logger) << "Can not mount asset with DEFECT state. asset_id: " << assetId <<" name: "<<asset->getData().name();
return false;
}
if (mountingPoint->getStructureElementTypeId() != StructureElementType::MountingPoint)
{
WARNING_LOG(m_logger) << "Structure Element " << mountingPointId << " type is not mounting point: "
<< mountingPoint->getStructureElementTypeId();
return false;
}
auto assetMpType = asset->getData().mountingPointTypeId();
auto mpType = mountingPoint->getData().mountingPointTypeId();
if (!Settings::distinguishBetweenIndoorAndOutdoorIPS())
{
if (assetMpType == MountingPointType::OutdoorIPS)
assetMpType = MountingPointType::IndoorIPS;
if (mpType == MountingPointType::OutdoorIPS)
mpType = MountingPointType::IndoorIPS;
}
if (assetMpType != mpType)
{
WARNING_LOG(m_logger) << "Structure Element " << mountingPointId << " and asset " << assetId
<< " - mouting point type id do not match: "
<< mountingPoint->getData().mountingPointTypeId() << " != "
<< asset->getData().mountingPointTypeId();
return false;
}
unmountAsset(assetId);
unmountMountingPoint(mountingPointId);
MountingPointAsset data;
data.structureElementId(mountingPointId);
data.assetId(assetId);
data.name(name.empty() ? asset->getName().toStdString() : name);
data.lastUpdated(QDateTime::currentMSecsSinceEpoch());
ObjectMountingPointAsset *newMountingPointAsset = new ObjectMountingPointAsset(m_mainHandler);
if (newMountingPointAsset->createObject(data).error())
{
newMountingPointAsset->removeObject();
delete newMountingPointAsset;
newMountingPointAsset = nullptr;
return false;
}
m_mainHandler->getHandlerInstrumentationAsset()->setAssetState(assetId, InstrumentationAssetState::Mounted);
m_objectMountingPointAssetMap.insert(newMountingPointAsset->getId(), newMountingPointAsset);
syncAvailableInExercise(data.structureElementId(), data.assetId());
return true;
}
//-------------------------------------------------------------------------------------------------------------
bool InfrastructureManagement::HandlerMountingPointAsset::unmountAsset(int32_t assetId)
{
for (auto it = m_objectMountingPointAssetMap.begin(); it != m_objectMountingPointAssetMap.end(); ++it)
{
ObjectMountingPointAsset *object = it.value();
if (object->getAssetId() == assetId)
return unmount(object);
}
return false;
}
//-------------------------------------------------------------------------------------------------------------
bool InfrastructureManagement::HandlerMountingPointAsset::unmountMountingPoint(int32_t mountingPointId)
{
for (auto it = m_objectMountingPointAssetMap.begin(); it != m_objectMountingPointAssetMap.end(); ++it)
{
ObjectMountingPointAsset *object = it.value();
if (object->getStructureElementId() == mountingPointId)
return unmount(object);
}
return true; // no mounting point asset found for this mounting point means it is already unmounted
}
//-------------------------------------------------------------------------------------------------------------
bool InfrastructureManagement::HandlerMountingPointAsset::unmount(ObjectMountingPointAsset *object)
{
// remove from dds
if (!dts()->removeMountingPointAssetByKey(object->getId()))
{
ERROR_LOG(m_logger) << "Error while removing MountingPointAsset with id "
<< object->getId()
<< " from DDS";
return false;
}
// remove from database
if (!db()->removeIsmMountingPointAsset(object->getId()))
{
ERROR_LOG(m_logger) << "Error while removing MountingPointAsset with id "
<< object->getId()
<< " from database";
return false;
}
m_objectMountingPointAssetMap.remove(object->getId());
m_mainHandler->getHandlerInstrumentationAsset()->setAssetState(object->getAssetId(), InstrumentationAssetState::Unmounted);
m_mainHandler->getHandlerInstrumentationAsset()->setAssetAvailableInExercise(object->getAssetId(), std::vector<int32_t>());
delete object;
return true;
}
//-------------------------------------------------------------------------------------------------------------
bool HandlerMountingPointAsset::syncAvailableInExercise(int32_t structureElementId, int32_t assetId) const
{
ObjectStructureElement *structureElement = m_mainHandler->getHandlerMainStructureElement()->getStructureElement(structureElementId);
if (!structureElement)
return false;
ObjectMainStructureElement *mainStructureElement = structureElement->getMainStructureElement();
if (!mainStructureElement)
return false;
return m_mainHandler->getHandlerInstrumentationAsset()->setAssetAvailableInExercise(assetId, mainStructureElement->getAvailableInExercise());
}
//-------------------------------------------------------------------------------------------------------------
int32_t InfrastructureManagement::HandlerMountingPointAsset::getMountedAssetId(int32_t mountingPointId) const
{
auto it = std::find_if(m_objectMountingPointAssetMap.cbegin(),
m_objectMountingPointAssetMap.cend(),
[mountingPointId](const ObjectMountingPointAsset *mpa) { return mpa->getStructureElementId() == mountingPointId;});
return it == m_objectMountingPointAssetMap.cend() ? 0 : it.value()->getAssetId();
}
//-------------------------------------------------------------------------------------------------------------
int32_t InfrastructureManagement::HandlerMountingPointAsset::getMountedStructureElementId(int32_t assetId) const
{
auto it = std::find_if(m_objectMountingPointAssetMap.cbegin(),
m_objectMountingPointAssetMap.cend(),
[assetId](const ObjectMountingPointAsset *mpa) { return mpa->getAssetId() == assetId;});
return it == m_objectMountingPointAssetMap.cend() ? 0 : it.value()->getStructureElementId();
}
//-------------------------------------------------------------------------------------------------------------
void HandlerMountingPointAsset::setAvailableInExerciseForAssetOnMountingPoint(int32_t mountingPointId, const std::vector<int32_t> &exercises)
{
const int assetId = getMountedAssetId(mountingPointId);
if (assetId <= 0)
return;
m_mainHandler->getHandlerInstrumentationAsset()->setAssetAvailableInExercise(assetId, exercises);
}
} // Namespace InfrastructureManagement
@@ -0,0 +1,59 @@
/**
* @RDE_HEADER@
* ISM Handler Mounting Point Assets
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#pragma once
#include <QHash>
#include "base.h"
//-------------------------------------------------------------------------------------------------------------
namespace InfrastructureManagement
{
class ObjectMountingPointAsset;
class MainHandler;
class HandlerMountingPointAsset final : public Base
, protected Interface::Fts::MountingPointAssetModifyRequestHandler
, protected Interface::Fts::MountingPointAssetRemoveRequestHandler
{
public:
explicit HandlerMountingPointAsset(MainHandler *mainHandler);
~HandlerMountingPointAsset();
bool init();
int getMountingPointAssetId(int assetId, int structureElementId) const;
bool mount(int32_t assetId, int32_t mountingPointId, const std::string &name = {});
bool unmountAsset(int32_t assetId);
bool unmountMountingPoint(int32_t mountingPointId);
int32_t getMountedAssetId(int32_t mountingPointId) const;
int32_t getMountedStructureElementId(int32_t assetId) const;
QHash<int, ObjectMountingPointAsset *> getMountingPointAssetMap() const { return m_objectMountingPointAssetMap;}
void setAvailableInExerciseForAssetOnMountingPoint(int32_t mountingPointId, const std::vector<int32_t> &exercises);
private:
void onMountingPointAssetModifyRequest(const rti::core::SampleIdentity &cookie,
const MountingPointAssetModifyRequest &request) override;
Core::FunctionReplyObject mountingPointAssetCreate(const MountingPointAssetModifyRequest &request);
Core::FunctionReplyObject mountingPointAssetModify(const MountingPointAssetModifyRequest &request);
void onMountingPointAssetRemoveRequest(const rti::core::SampleIdentity &cookie,
const Core::RemoveElementRequest &request) override;
bool unmount(ObjectMountingPointAsset *object);
bool syncAvailableInExercise(int32_t structureElementId, int32_t assetId) const;
private:
QHash<int, ObjectMountingPointAsset *> m_objectMountingPointAssetMap;
};
}
@@ -0,0 +1,61 @@
/**
* @RDE_HEADER@
* ISM Handler Special Areas
* $Id$
* $HeadURL$
* $Author$
* Created by Hanna E. Rathje, 2023-07-26
*/
#include "handler_special_area.h"
#include "object_special_area.h"
namespace InfrastructureManagement {
//--------------------------------------------------------------------------------------------------------------------------------------------------
HandlerSpecialArea::HandlerSpecialArea(MainHandler *mainHandler)
: Base(mainHandler, getLogger("HandlerSpecialArea"))
{
}
//--------------------------------------------------------------------------------------------------------------------------------------------------
HandlerSpecialArea::~HandlerSpecialArea()
{
qDeleteAll(m_objectSpecialAreaMap);
}
//--------------------------------------------------------------------------------------------------
bool HandlerSpecialArea::init()
{
bool bRet = true;
auto cb = [this, &bRet] (const Database::IsmSpecialArea &data)
{
SpecialArea ddsData = ObjectSpecialArea::toDdsData(data);
ObjectSpecialArea *ifs(new ObjectSpecialArea(m_mainHandler));
Core::FunctionReplyObject ret = ifs->createObject(ddsData);
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << ret();
bRet = false;
return;
}
m_objectSpecialAreaMap.insert(ifs->getId(), ifs);
DEBUG_LOG(m_logger) << " id=" << ifs->getData().id()
<< " name=" << ifs->getData().name();
};
// create Asset objects
if (!db()->select(cb) || !bRet)
{
ERROR_LOG(m_logger) << "Error reading data from database!";
return false;
}
DEBUG_LOG(m_logger) << "m_objectSpecialAreaMap.size() = " << m_objectSpecialAreaMap.size();
return true;
}
} // namespace InfrastructureManagement
@@ -0,0 +1,32 @@
/**
* @RDE_HEADER@
* ISM Handler Special Areas
* $Id$
* $HeadURL$
* $Author$
* Created by Hanna E. Rathje, 2023-07-26
*/
#pragma once
#include <QHash>
#include "base.h"
//-------------------------------------------------------------------------------------------------------------
namespace InfrastructureManagement
{
class ObjectSpecialArea;
class MainHandler;
class HandlerSpecialArea final : public Base
{
public:
explicit HandlerSpecialArea(MainHandler *mainHandler);
~HandlerSpecialArea();
bool init();
private:
QHash<int, ObjectSpecialArea *> m_objectSpecialAreaMap;
};
}
@@ -0,0 +1,202 @@
/**
* @RDE_HEADER@
* Custom db functions (extends tab_db_impl.cpp/.h)
* $Id$
* $HeadURL$
* $Author$
*/
#include "ism_db_impl_custom.h"
#include <ngldb/nsqlquery.h>
#include <ngldb/sql_query_janitor.h>
#include <ngldb/dbtransaction.h>
namespace InfrastructureManagement
{
// custom procs, body must be implemented by user
int DatabaseInterfaceImplCustom::copySchedule(int scheduleId)
{
int newId = 0;
const QString tableSchedule = getTableName(QStringLiteral("ism_mounting_point_schedule"));
//const QString tablePlan = getTableName(QStringLiteral("ism_mounting_point_plan"));
DBTransaction trans(this->database());
trans.begin();
// get the schedule name first
const QString stmtSelectName = QStringLiteral("SELECT name FROM ") + tableSchedule + QStringLiteral(" WHERE id = :id");
DEBUG_LOG(m_logger) << "Select statement: " << stmtSelectName;
if (!m_query)
{
ERROR_LOG(m_logger) << "m_query not initialized";
return -1;
}
QString fileName;
{
SqlQueryJanitor janitor(m_query);
if (!m_query->prepare(stmtSelectName))
{
ERROR_LOG(m_logger) << "Could not prepare statement: " << stmtSelectName;
return -1;
}
m_query->bindValue(QStringLiteral(":id"), scheduleId);
if (!m_query->execAndFetch())
{
ERROR_LOG(m_logger) << "Could not execute statement: " << stmtSelectName;
return -1;
}
fileName = m_query->value(0).toString();
} // query scope
DEBUG_LOG(m_logger) << "Original Plan name = " << fileName;
fileName = fileName + tr(" (Copy)");
DEBUG_LOG(m_logger) << "New Plan name = " << fileName;
const QString stmtInsertSchedule = QStringLiteral("INSERT INTO ") + tableSchedule +
QStringLiteral(" (name, status_id, time_prepared, time_start, time_end) VALUES (:newName, 1, 0, 0, 0) RETURNING id;");
//new schedule has always status created (1) and timestampes 0, time_created has default value
DEBUG_LOG(m_logger) << "Insert schedule statment: " << stmtInsertSchedule;
{
SqlQueryJanitor janitor(m_query);
if (!m_query->prepare(stmtInsertSchedule))
{
ERROR_LOG(m_logger) << "Could not prepare statement: " << stmtInsertSchedule;
return -1;
}
m_query->bindValue(QStringLiteral(":newName"), fileName);
m_query->bindValue(QStringLiteral(":oldId"), scheduleId);
if (!m_query->exec())
{
ERROR_LOG(m_logger) << "Could not execute statement: " << stmtInsertSchedule;
return -1;
}
m_query->first();
newId = m_query->value(0).toInt();
DEBUG_LOG(m_logger) << "Inserted new schedule id = " << newId;
}
const QString stmtInsertMPP = QStringLiteral("with rows as (select ") + QString::number(newId) +
QStringLiteral(" as mounting_point_schedule_id, structure_element_id from ism.ism_mounting_point_plan where mounting_point_schedule_id = :oldId) insert into ism.ism_mounting_point_plan (mounting_point_schedule_id, structure_element_id) select * from rows;");
{
SqlQueryJanitor janitor(m_query);
if (!m_query->prepare(stmtInsertMPP))
{
ERROR_LOG(m_logger) << "Could not prepare statement: " << stmtInsertMPP;
return -1;
}
m_query->bindValue(QStringLiteral(":oldId"), scheduleId);
//m_query->bindValue(QStringLiteral(":newId"), newId);
if (!m_query->exec())
{
ERROR_LOG(m_logger) << "Could not execute statement: " << stmtInsertMPP;
return -1;
}
DEBUG_LOG(m_logger) << "Inserted MMPs";
} // query scope
trans.commit(); // rollback is not needed, is done automatically for non-commited queries
return newId;
}
bool DatabaseInterfaceImplCustom::updateMountingPointPlan(int scheduleId, int mountingPointId, MountingPointState mountingPointState)
{
SqlQueryJanitor janitor(m_query);
const QString tableName(getTableName(QStringLiteral("ism_mounting_point_plan")));
const QString stmt(QStringLiteral("UPDATE ") + tableName +
QStringLiteral(" SET mounting_point_state = ") +
QString::number(mountingPointState.underlying()) +
QStringLiteral(" WHERE mounting_point_schedule_id = ") +
QString::number(scheduleId) +
QStringLiteral(" AND structure_element_id = ") +
QString::number(mountingPointId));
if (!m_query->exec(stmt, m_bEmitMessageOnError))
{
m_lastError = m_query->lastError();
return false;
}
return true;
}
bool DatabaseInterfaceImplCustom::deleteMountingPointPlan(int scheduleId, int mountingPointId)
{
SqlQueryJanitor janitor(m_query);
const QString tableName(getTableName(QStringLiteral("ism_mounting_point_plan")));
const QString stmt(QStringLiteral("DELETE FROM ") + tableName +
QStringLiteral(" WHERE mounting_point_schedule_id = ") +
QString::number(scheduleId) +
QStringLiteral(" AND structure_element_id = ") +
QString::number(mountingPointId));
if (!m_query->exec(stmt, m_bEmitMessageOnError))
{
m_lastError = m_query->lastError();
return false;
}
return true;
}
bool DatabaseInterfaceImplCustom::insertMountingPointPlans(const std::vector<Database::IsmMountingPointPlan> &mpps)
{
SqlQueryJanitor janitor(m_query);
{
const QString tableName(getTableName(QStringLiteral("ism_mounting_point_plan")));
const QString stmt(QStringLiteral("INSERT INTO ") + tableName +
QStringLiteral(" (") +
QStringLiteral(" mounting_point_schedule_id, structure_element_id, mounting_point_state"
" ) VALUES (") +
QStringLiteral(":mounting_point_schedule_id, :structure_element_id, :mounting_point_state )"));
if (!m_query->prepare(stmt))
{
m_lastError = m_query->lastError();
return false;
}
for (const auto &data : mpps)
{
m_query->bindValue(QStringLiteral(":mounting_point_schedule_id"), data.mountingPointScheduleId);
m_query->bindValue(QStringLiteral(":structure_element_id"), data.structureElementId);
m_query->bindValue(QStringLiteral(":mounting_point_state"), static_cast<int>(data.mountingPointState.underlying()));
if (!m_query->exec(m_bEmitMessageOnError))
{
m_lastError = m_query->lastError();
return false;
}
}
}
return true;
}
}
+26
View File
@@ -0,0 +1,26 @@
/**
* @RDE_HEADER@
* Custom db functions (extends tab_db_impl.cpp/.h)
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <InfrastructureManagement/ism_db_impl.h>
namespace InfrastructureManagement
{
class DatabaseInterfaceImplCustom final : public DatabaseInterfaceImpl
{
Q_OBJECT
public:
using DatabaseInterfaceImpl::DatabaseInterfaceImpl;
int copySchedule(int scheduleId) override final;
bool updateMountingPointPlan(int scheduleId, int mountingPointId, MountingPointState mountingPointState) override final;
bool deleteMountingPointPlan(int scheduleId, int mountingPointId) override final;
bool insertMountingPointPlans(const std::vector<Database::IsmMountingPointPlan> &mpps) override final;
// QHash<int, Database::IsmMountingPointPlan> getMountingPointPlansOfSchedule(int scheduleId) override final;
};
} // namespace InfrastructureManagement
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,79 @@
/**
* @RDE_HEADER@
* ISM Custom functions (extends ism_db_impl.cpp/.h)
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#pragma once
#include <InfrastructureManagement/ism_dtc_impl.h>
//-------------------------------------------------------------------------------------------------------------
namespace InfrastructureManagement
{
namespace Interface
{
class DtcImplCustom final : public Interface::DtcImpl
{
Q_OBJECT
public:
explicit DtcImplCustom(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector);
~DtcImplCustom();
public:
long structureElementCacheSize() const;
protected:
void reloadStructureElementCacheIfEmpty();
long reloadStructureElementCache();
protected Q_SLOT:
void updateStructureElementCache(const InfrastructureManagement::MainStructureElement &data, DataModification modType);
public:
bool isElementAssignedToExercise(const MainStructureElement &mse, int exerciseId) const override;
bool getMountingPointAssetId(int structureElementId, int assetId, int &mountingPointAssetId) const override;
bool getAssetIdFromMountingPoint(int structureElementId, int mountingPointAssetId, int &assetId) const override;
int getOpsCodeFromJSon(const std::string &s) const;
int getOpticalCodeFromAssetId(int assetId) const override;
int getAssetIdFromOpticalCode(int opticalCode) const override;
int getAssetIdFromMountingPointId(int mainStructureElementId, int mountingPointId) const override;
bool getOpsDataFromMseIdAndSeId(int mainStructureElementId, int structureElementId, int &roomId, Core::GeoPosition &geoPosition) const override;
bool getStructureElementById(int structureElementId, StructureElement &structureElement) const override;
bool getStructureElementInMntPointAssetByAssetId(int assetId, StructureElement &structureElement) const override;
bool getStructureElementByBuildingIdAndMountingPointId(int mainStructureElementId, int mountingPointId, StructureElement &structureElement) override;
bool getAllAssetsPerRoom(const std::function<bool(const InstrumentationAsset &)> &predicate,
QMap<int, QVector<InstrumentationAsset> > &allAssets) override;
bool getAllAssetsPerBuilding(const std::function<bool(const InstrumentationAsset &)> &predicate,
QMap<int, QVector<InstrumentationAsset> > &allAssets) const override;
bool getBuildingId(int structureElementId, int &buildingId) const override;
QString getBuildingDisplayName(int buildingId) override;
QString getBuildingDisplayName(const MainStructureElement &mse) const override;
MountingPointPlan getMountingPointPlan(int scheduleId, int structureElementId) const override;
int getBuildingRoomsCount(int buildingId) override;
BridgeStatus getBridgeStatus(int buildingId) override;
bool checkSchedule(int scheduleId) override;
bool getScheduleDifferences(int scheduleId, QList<MountingPointPlan> &diffList) override;
int getMountedAssetId(int structureElementId) const override;
int getStructueElementIdFromAssetId(int assetId) const override;
QList<int> getSections() override;
QMap<int, MainFootprint> getFootprintsByExerciseId(int exerciseId) override;
QMap<int, QPolygonF> getUtmFootprintsByExerciseId(int exerciseId, int &zone, bool isGroundLevel) override;
QPolygonF getUtmFootprintById(int mseId, int &zoneOut, bool isGroundLevel) override;
QVector <int> getBuildingByPolygon(int exerciseId, const QPolygonF &polygon, bool completeEnclosed, bool isGroundLevel) override;
int getSurroundingBuildingByPolygon(int exerciseId, const QPolygonF &polygon, bool isGroundLevel) override;
int getBuildingIdAtPosition(int exerciseId, const QPointF &utmPos, bool isGroundLevel) override;
QVector <int> getFloorIdsFromBuilding(int buildingId) override;
QList <StructureElement> getFloorsFromBuilding(int buildingId);
double getHalfFloorHeight(int buildingId, int floorId) override;
QVector <int> getRoomIdsFromFloorId(int buildingId, int floorId) override;
QVector <int> getBuildingIdsByExercise ( int exerciseId) override;
QByteArray getVulnerabilityModelData ( int buildingId) override;
class Private;
Private *d;
};
} //Interface
} // namespace InfrastructureManagement
@@ -0,0 +1,130 @@
/**
* @RDE_HEADER@
* ISM Custom functions, private extensions
* $Id$
* $HeadURL$
* $Author$
* Created by Norbert Thoden, SLSE, 2025-01-07
*/
#pragma once
#include "ism_dtc_impl_custom.h"
#include <LtsCoordinate/lts_coord_vector.h>
#include <QHash>
#include <QPolygonF>
#include <QTransform>
//-------------------------------------------------------------------------------------------------------------
namespace InfrastructureManagement
{
namespace Interface
{
// improve QPolygonF DtcImplCustom::getUtmFootprintById(int mseId, int &zone, bool isGroundLevel)
class MainFootPrintCache
{
public:
MainFootPrintCache() = default;
void init(DtcImplCustom *dtcCustom)
{
m_dtcCustom = dtcCustom;
}
const QPolygonF &getUtmFootprintById(int mseId, bool isGroundLevel, int &zoneOut) const
{
if (!load(mseId, isGroundLevel, zoneOut))
return m_cache[{-1, true}].first; // empty
const auto &cacheData = m_cache[{mseId, isGroundLevel}];
zoneOut = cacheData.second;
return cacheData.first;
}
bool load(int mseId, bool isGroundLevel, int &zoneOut) const
{
if (m_cache.contains({mseId, isGroundLevel}))
return true;
const MainStructureElement &mse = m_dtcCustom->mainStructureElement(mseId);
if (mse.id() != mseId)
return false;
const MainFootprint &mf = m_dtcCustom->mainFootprint(mseId);
if (mf.id() != mseId)
return {};
// determine the zone (using the mse.geoPosition())
const auto &utm = LtsCoordTrans::UtmCoordinate::fromGeographic(QPointF(mse.geoPosition().lon(), mse.geoPosition().lat()));
zoneOut = utm.zone;
//
// get all elements according m_isGroundLevel
//
// relative:
const std::vector<InfrastructureManagement::FootprintElement> &mfElements = mf.elements();
QPolygonF poly;
poly.reserve(mfElements.size());
for (const InfrastructureManagement::FootprintElement &element : qAsConst(mfElements))
{
// if different, continue
if (isGroundLevel != element.isGroundLevel())
continue;
const auto &relPos = element.relPosition();
poly.push_back(QPointF(relPos.offsetX(), relPos.offsetY()));
}
// Get other footprint if groundLevel footprint is not available
if (poly.isEmpty() && isGroundLevel)
{
for (const InfrastructureManagement::FootprintElement &element : qAsConst(mfElements))
{
const auto &relPos = element.relPosition();
poly.push_back(QPointF(relPos.offsetX(), relPos.offsetY()));
}
}
// old:
// // rotate poly
// QTransform trans;
// trans.rotate(mse.angle());
// poly = trans.map(poly);
// const auto utm = LtsCoordTrans::UtmCoordinate::fromGeographic(QPointF(mse.geoPosition().lon(), mse.geoPosition().lat()), zone);
// zone = utm.zone;
// const QPointF utmFpPosition(utm.x, utm.y);
// QPolygonF retPolyUtm;
// retPolyUtm.reserve(poly.size());
// for (const QPointF &point : qAsConst(poly))
// {
// const QPointF finalUtmPoint(utmFpPosition + point);
// retPolyUtm.push_back(finalUtmPoint);
// DEBUG_LOG(m_logger) << "utmPoint x: " << finalUtmPoint.x() << " utmPoint.y : " << finalUtmPoint.y();
// }
// easier to write and without additional QPolygonF
// rotate,and translate poly
QTransform trans;
trans.translate(utm.x, utm.y);
trans.rotate(mse.angle());
poly = trans.map(poly);
// finally: store in cache
m_cache[ {mseId, isGroundLevel}] = {poly, zoneOut};
return true;
}
private:
DtcImplCustom *m_dtcCustom{nullptr};
mutable QHash<QPair<int, bool>, QPair<QPolygonF, int>> m_cache;
// mseId, ground <poly , zone>
};
} //Interface
} // namespace InfrastructureManagement
+54
View File
@@ -0,0 +1,54 @@
/**
* @RDE_HEADER@
* Export definitions
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#pragma once
#include <QtCore/qglobal.h>
#ifndef ISM_COMMON_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define ISM_COMMON_EXPORT
# else
# if defined(MAKE_SVCISMCOMMON_LIB)
# define ISM_COMMON_EXPORT Q_DECL_EXPORT
# ifndef WIN32
# ifdef NDDSUSERDllExport
# undef NDDSUSERDllExport
# endif
# define NDDSUSERDllExport Q_DECL_EXPORT
# endif
# else
# define ISM_COMMON_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
#ifndef ISM_CLIENT_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define ISM_CLIENT_EXPORT
# else
# if defined(MAKE_SVCISMCLIENT_LIB)
# define ISM_CLIENT_EXPORT Q_DECL_EXPORT
# else
# define ISM_CLIENT_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
#ifndef ISM_SERVER_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define ISM_SERVER_EXPORT
# else
# if defined(MAKE_SVCISMSERVER_LIB)
# define ISM_SERVER_EXPORT Q_DECL_EXPORT
# else
# define ISM_SERVER_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
+661
View File
@@ -0,0 +1,661 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<service namespace="InfrastructureManagement" abbreviation="ISM" procNames="InfrastructureManagement" exerciseDependency="Global" groups="Core" prio="1">
<rcs>
<Id Id="$Id$"/>
<HeadURL HeadURL="$HeadURL$"/>
<Author Author="$Author$"/>
</rcs>
<operatorRights offset="18">
<guiPlugin name="InfrastructureManagement" offset="1">
<operatorRightGroup name="Infrastructure Management" description="Edit Infrastructural Plans">
<operatorRight right="InfrastructurePlansEdit" value="1" description="Edit Infrastructural Plans"/>
<operatorRight right="InfrastructurePlansShow" value="2" description="Show Infrastructural Plans (also allows view of Assets, Mounting Points,...)"/>
<operatorRight right="InfrastructurePlansChangeStatus" value="3" description="Change status of Infrastructure Plan"/>
</operatorRightGroup>
</guiPlugin>
<guiPlugin name="ResourceManagement" offset="2">
<operatorRightGroup name="ResourceManagement" description="Edit Resource Management Data">
<operatorRight right="DatabaseAdministration" value="1" description="Database Administration"/>
</operatorRightGroup>
<operatorRightGroup name="ResourceManagementSystemConfiguration" description="Edit Resource Management System Configuration Data">
<operatorRight right="SystemConfiguration" value="1"/>
</operatorRightGroup>
</guiPlugin>
</operatorRights>
<tables>
<table name="ism_asset">
<column name="id" datatype="bigint" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="name" datatype="text"/>
<column name="mounting_point_type_id" datatype="bigint" isForeignKey="1"/>
<column name="barcode" datatype="text"/>
<column name="hostname" datatype="text"/>
<column name="properties" datatype="jsonb" default="'{}'" comment="&quot;username&quot;:&quot;ahtc&quot;, &quot;password&quot;:&quot;mout11de&quot;, &quot;hitSoundVolume&quot; : 100, &quot;activationSoundVolume&quot; : 100, &quot;fireSoundVolume&quot; : 100, &quot;effects&quot; : [ {&quot;type&quot;:&quot;Fog&quot;, &quot;damage&quot;:80, &quot;id&quot;: 1, &quot;repeat&quot;:3, &quot;pulse&quot;: 3000, &quot;delay&quot;: 1000}, {&quot;type&quot;:&quot;FireLamp&quot;, &quot;damage&quot;:80, &quot;id&quot;: 2, &quot;repeat&quot;:0}, {&quot;type&quot;:&quot;SignalLamp&quot;, i &quot;damage&quot;:80, &quot;id&quot;: 3, &quot;repeat&quot;:0}] , &quot;scenarios&quot; : [{&quot;id&quot;:1, &quot;damage&quot;: 50}] Example OPS: {&quot;opticalCode&quot;: 2201, &quot;opsTunnel&quot;: true}"/>
<column name="asset_state_id" datatype="bigint" isForeignKey="1"/>
<column name="available_in_exercise" datatype="integer[]"/>
<column name="last_updated" datatype="timestamp" default="now()"/>
<foreignKey name="FK_ism_asset_ism_mounting_point_type">
<source table="ism_asset" column="mounting_point_type_id"/>
<destination table="ism_mounting_point_type" column="id"/>
</foreignKey>
<foreignKey name="FK_ism_asset_ism_asset_state">
<source table="ism_asset" column="asset_state_id"/>
<destination table="ism_asset_state" column="id"/>
</foreignKey>
</table>
<table name="ism_asset_state">
<column name="id" datatype="bigint" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="name" datatype="text"/>
</table>
<table name="ism_main_structure_element">
<column name="id" datatype="bigint" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="name" datatype="text"/>
<column name="description" datatype="text"/>
<column name="geo_position" datatype="point_3d"/>
<column name="angle" datatype="real"/>
<column name="model_id" datatype="bigint"/>
<column name="external_wls_id" datatype="bigint"/>
<column name="group_id" datatype="integer"/>
<column name="properties" datatype="jsonb" default="'{}'"/>
<foreignKey name="FK_ism_main_structure_element_ism_building_group">
<source table="ism_main_structure_element" column="group_id"/>
<destination table="ism_building_group" column="id"/>
</foreignKey>
</table>
<table name="ism_mounting_point_asset">
<column name="id" datatype="bigint" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="asset_id" datatype="bigint" isForeignKey="1"/>
<column name="structure_element_id" datatype="bigint" isForeignKey="1"/>
<column name="name" datatype="text"/>
<column name="last_updated" datatype="timestamp" default="now()"/>
<constraint name="UQ_ism_mounting_point_asset_asset_id" type="unique">
<column name="asset_id"/>
</constraint>
<constraint name="UQ_ism_mounting_point_asset_structure_element_id" type="unique">
<column name="structure_element_id"/>
</constraint>
<foreignKey name="FK_ism_mounting_point_asset_ism_asset">
<source table="ism_mounting_point_asset" column="asset_id"/>
<destination table="ism_asset" column="id"/>
</foreignKey>
<foreignKey name="FK_ism_mounting_point_asset_ism_structure_element">
<source table="ism_mounting_point_asset" column="structure_element_id"/>
<destination table="ism_structure_element" column="id"/>
</foreignKey>
</table>
<table name="ism_mounting_point_plan">
<column name="id" datatype="bigint" isPrimaryKey="1" comment="in fact not used...">
<sequence start="1" increment="1"/>
</column>
<column name="mounting_point_schedule_id" datatype="bigint" isForeignKey="1"/>
<column name="structure_element_id" datatype="bigint" isForeignKey="1"/>
<column name="mounting_point_state" datatype="integer" default="0" isForeignKey="1" comment="(-1, 0, 1) - (Empty, Idle, Equipped)"/>
<foreignKey name="FK_ism_mounting_point_plan_ism_structure_element">
<source table="ism_mounting_point_plan" column="structure_element_id"/>
<destination table="ism_structure_element" column="id"/>
</foreignKey>
<foreignKey name="FK_ism_mp_plan_ism_mp_schedule">
<source table="ism_mounting_point_plan" column="mounting_point_schedule_id"/>
<destination table="ism_mounting_point_schedule" column="id"/>
</foreignKey>
<foreignKey name="FK_ism_mp_plan_ism_mp_state">
<source table="ism_mounting_point_plan" column="mounting_point_state"/>
<destination table="ism_mounting_point_state" column="id"/>
</foreignKey>
<constraint name="UQ_ism_mp_plan_plan_structure_element_id" type="unique">
<column name="mounting_point_schedule_id"/>
<column name="structure_element_id"/>
</constraint>
<constraint name="IDX_ism_mounting_point_plan_schedule_id" type="index">
<column name="mounting_point_schedule_id"/>
</constraint>
</table>
<table name="ism_mounting_point_schedule">
<column name="id" datatype="bigint" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="name" datatype="text"/>
<column name="status_id" datatype="integer" isForeignKey="1"/>
<column name="time_created" datatype="timestamp" default="now()"/>
<column name="time_start" datatype="timestamp" comment="time activated"/>
<column name="time_end" datatype="timestamp" comment="time expired"/>
<column name="exercise_id" datatype="bigint" isOptional="1" isForeignKey="1"/>
<foreignKey name="FK_ism_mounting_point_schedule_exercise">
<source table="ism_mounting_point_schedule" column="exercise_id"/>
<destination service="ExerciseManagement" serviceAbbr="exm" schema="exm" table="exercise" column="id"/>
</foreignKey>
<foreignKey name="FK_ism_mounting_point_schedule_schedule_status">
<source table="ism_mounting_point_schedule" column="status_id"/>
<destination table="ism_schedule_status" column="id"/>
</foreignKey>
</table>
<table name="ism_mounting_point_state">
<column name="id" datatype="bigint" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="name" datatype="text"/>
</table>
<table name="ism_mounting_point_type">
<column name="id" datatype="bigint" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="name" datatype="text"/>
</table>
<table name="ism_building_group">
<column name="id" datatype="bigint" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="name" datatype="text"/>
</table>
<table name="ism_special_area">
<column name="id" datatype="bigint" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="name" datatype="text"/>
<column name="special_type" datatype="bigint" isForeignKey="1"/>
<column name="polygon" datatype="jsonb"/>
<foreignKey name="FK_ism_special_area_ism_special_area_type">
<source table="ism_special_area" column="special_type"/>
<destination table="ism_special_area_type" column="id"/>
</foreignKey>
</table>
<table name="ism_schedule_status_change" comment="instrumentation plan status changes">
<column name="id" datatype="integer" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="schedule_id" datatype="integer" isForeignKey="1"/>
<column name="schedule_status_id" datatype="integer" isForeignKey="1"/>
<column name="changed_at" datatype="bigint"/>
<column name="operator_id" datatype="integer"/>
<column name="workstation_id" datatype="integer"/>
<foreignKey name="FK_ism_schedule_status_change_schedule_id">
<source table="ism_schedule_status_change" column="schedule_id"/>
<destination table="ism_mounting_point_schedule" column="id"/>
</foreignKey>
<foreignKey name="FK_ism_schedule_status_change_schedule_status_id">
<source table="ism_schedule_status_change" column="schedule_status_id"/>
<destination table="ism_schedule_status" column="id"/>
</foreignKey>
</table>
<table name="ism_schedule_status">
<column name="id" datatype="integer" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="name" datatype="text"/>
</table>
<table name="ism_special_area_type">
<column name="id" datatype="bigint" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="name" datatype="text"/>
</table>
<table name="ism_structure_element">
<column name="id" datatype="bigint" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="name" datatype="text"/>
<column name="main_structure_element_id" datatype="bigint" isForeignKey="1"/>
<column name="structure_element_type_id" datatype="bigint" isForeignKey="1"/>
<column name="path" datatype="integer[]"/>
<column name="mounting_point_id" datatype="integer"/>
<column name="barcode" datatype="text"/>
<column name="rel_position" datatype="point_3d"/>
<column name="mounting_point_type_id" datatype="bigint" isForeignKey="1"/>
<column name="orientation" datatype="point_3d"/>
<column name="properties" datatype="jsonb" default="'{}'"/>
<column name="display_name" datatype="text"/>
<constraint name="UQ_ism_structure_element_path" type="unique">
<column name="path"/>
</constraint>
<foreignKey name="FK_ism_structure_element_ism_se_type">
<source table="ism_structure_element" column="structure_element_type_id"/>
<destination table="ism_structure_element_type" column="id"/>
</foreignKey>
<foreignKey name="FK_ism_structure_element_ism_mounting_point_type">
<source table="ism_structure_element" column="mounting_point_type_id"/>
<destination table="ism_mounting_point_type" column="id"/>
</foreignKey>
<foreignKey name="FK_ism_structure_element_ism_se_main_id">
<source table="ism_structure_element" column="main_structure_element_id"/>
<destination table="ism_main_structure_element" column="id"/>
</foreignKey>
</table>
<table name="ism_structure_element_footprint">
<column name="id" datatype="bigint" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="structure_element_id" datatype="bigint" isForeignKey="1"/>
<column name="index_no" datatype="bigint"/>
<column name="rel_position" datatype="point_3d"/>
<column name="is_ground_level" datatype="boolean" default="false"/>
<constraint name="UQ_ism_structure_element_footprint_index_no" type="unique">
<column name="structure_element_id"/>
<column name="index_no"/>
</constraint>
<foreignKey name="FK_ism_se_footprint_ism_se_id">
<source table="ism_structure_element_footprint" column="structure_element_id"/>
<destination table="ism_structure_element" column="id"/>
</foreignKey>
</table>
<table name="ism_structure_element_type">
<column name="id" datatype="bigint" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="name" datatype="text"/>
</table>
</tables>
<views/>
<dbServiceStructs>
<serviceStruct name="IsmAsset" table="ism_asset"/>
<serviceStruct name="IsmMainStructureElement" table="ism_main_structure_element"/>
<serviceStruct name="IsmMountingPointAsset" table="ism_mounting_point_asset"/>
<serviceStruct name="IsmMountingPointPlan" table="ism_mounting_point_plan">
<function name="updateMountingPointPlan" returns="bool">
<parameter pos="1" name="scheduleId" type="int"/>
<parameter pos="2" name="mountingPointId" type="int"/>
<parameter pos="3" name="mountingPointState" type="MountingPointState"/>
</function>
<function name="deleteMountingPointPlan" returns="bool">
<parameter pos="1" name="scheduleId" type="int"/>
<parameter pos="2" name="mountingPointId" type="int"/>
</function>
<function name="insertMountingPointPlans" returns="bool">
<parameter pos="1" name="mpps" type="const std::vector&lt;Database::IsmMountingPointPlan&gt; &amp;"/>
</function>
</serviceStruct>
<serviceStruct name="IsmMountingPointSchedule" table="ism_mounting_point_schedule">
<notification name="notifyInsertMainSchedule" returns="void" notificationTypes="AfterInsert">
<parameter pos="1" name="id" type="qint64"/>
</notification>
<function name="copySchedule" returns="int">
<parameter pos="1" name="scheduleId" type="int"/>
</function>
</serviceStruct>
<serviceStruct name="IsmScheduleStatusChange" table="ism_schedule_status_change"/>
<serviceStruct name="IsmSpecialArea" table="ism_special_area"/>
<serviceStruct name="IsmStructureElement" table="ism_structure_element"/>
<serviceStruct name="IsmStructureElementFootprint" table="ism_structure_element_footprint"/>
<table name="ism_asset"/>
<table name="ism_main_structure_element"/>
<table name="ism_mounting_point_asset"/>
<table name="ism_mounting_point_plan"/>
<table name="ism_mounting_point_schedule"/>
<table name="ism_schedule_status_change"/>
<table name="ism_structure_element"/>
<table name="ism_structure_element_footprint"/>
</dbServiceStructs>
<topicTypes>
<topicType name="SpecialArea" isDataObject="1" autosubscribe="1" routeToClient="1" routeToServer="0" routeInReplay="0" baseValueType="Core::BaseEntity">
<column name="specialType" idlType="SpecialAreaType"/>
<column name="polygon" idlType="sequence&lt;Core::GeoPosition2D&gt;"/>
<column name="boundingBoxBottomLeft" idlType="Core::GeoPosition2D"/>
<column name="boundingBoxTopRight" idlType="Core::GeoPosition2D"/>
</topicType>
<topicType name="InstrumentationAsset" isDataObject="1" autosubscribe="1" routeToClient="1" routeToServer="0" routeInReplay="0" baseValueType="Core::BaseEntity">
<column name="mountingPointTypeId" idlType="MountingPointType"/>
<column name="barcode" idlType="string"/>
<column name="hostname" idlType="string"/>
<column name="properties" idlType="string"/>
<column name="assetStateId" idlType="InstrumentationAssetState"/>
<column name="lastUpdated" idlType="long long"/>
<column name="availableInExercise" idlType="sequence&lt;long&gt;"/>
</topicType>
<topicType name="InstrumentationAssetModifyRequest">
<column name="id" idlType="long"/>
<column name="name" idlType="string"/>
<column name="mountingPointTypeId" idlType="MountingPointType"/>
<column name="barcode" idlType="string"/>
<column name="hostname" idlType="string"/>
<column name="properties" idlType="string"/>
<column name="instrumentationAssetStateId" idlType="InstrumentationAssetState"/>
<column name="lastUpdated" idlType="long long"/>
<column name="availableInExercise" idlType="sequence&lt;long&gt;"/>
</topicType>
<topicType name="InstrumentationAssetSetStateRequest">
<column name="id" idlType="long"/>
<column name="instrumentationAssetStateId" idlType="InstrumentationAssetState"/>
</topicType>
<topicType name="InstrumentationAssetUnmountRequest">
<column name="id" idlType="long"/>
</topicType>
<topicType name="MainSchedule" isDataObject="1" autosubscribe="1" routeToClient="1" routeToServer="0" routeInReplay="0" baseValueType="Core::BaseEntity">
<column name="description" idlType="string"/>
<column name="statusId" idlType="ScheduleStatus"/>
<column name="timeCreated" idlType="long long"/>
<column name="timeStart" idlType="long long" isOptional="1"/>
<column name="timeEnd" idlType="long long" isOptional="1"/>
<column name="exerciseId" idlType="long" isOptional="1"/>
<column name="elements" idlType="sequence&lt;MountingPointPlan&gt;"/>
</topicType>
<topicType name="MainScheduleCopyRequest">
<column name="id" idlType="long"/>
</topicType>
<topicType name="MainScheduleModifyRequest">
<column name="id" idlType="long"/>
<column name="name" idlType="string"/>
<column name="description" idlType="string"/>
<column name="statusId" idlType="ScheduleStatus"/>
<column name="timeCreated" idlType="long long"/>
<column name="timeStart" idlType="long long" isOptional="1"/>
<column name="timeEnd" idlType="long long" isOptional="1"/>
<column name="exerciseId" idlType="long" isOptional="1"/>
<column name="elements" idlType="sequence&lt;StructureElement&gt;"/>
</topicType>
<topicType name="MountingPointAsset" isDataObject="1" autosubscribe="1" routeToClient="1" routeToServer="0" routeInReplay="0">
<column name="id" idlType="long" isKey="1"/>
<column name="structureElementId" idlType="long"/>
<column name="assetId" idlType="long"/>
<column name="name" idlType="string"/>
<column name="lastUpdated" idlType="long long"/>
</topicType>
<topicType name="MountingPointAssetModifyRequest" baseValueType="MountingPointAsset">
<column name="dummy" idlType="long"/>
</topicType>
<topicType name="MountingPointPlan">
<column name="structureElementId" idlType="long"/>
<column name="mountingPointState" idlType="MountingPointState"/>
</topicType>
<topicType name="MountingPointPlanModifyRequest">
<column name="mountingPointScheduleId" idlType="long"/>
<column name="mountingPointPlans" idlType="sequence&lt;MountingPointPlan&gt;"/>
</topicType>
<topicType name="EffectArea" isDataObject="1" autosubscribe="1" routeToClient="1" routeToServer="0" routeInReplay="0">
<column name="id" idlType="long" isKey="1"/>
<column name="name" idlType="string"/>
<column name="areaEgcuId" idlType="long"/>
<column name="egcuIds" idlType="sequence&lt;long&gt;" comment="EGCU-IDs"/>
<column name="geometry" idlType="sequence&lt;Core::GeoPosition2D&gt;"/>
</topicType>
<topicType name="FootprintElement">
<column name="id" idlType="long"/>
<column name="relPosition" idlType="Core::RelativePosition"/>
<column name="isGroundLevel" idlType="boolean"/>
</topicType>
<topicType name="MainFootprint" isDataObject="1" autosubscribe="1" routeToClient="1" routeToServer="0" routeInReplay="1" baseValueType="Core::BaseEntity">
<column name="structureElementId" idlType="long"/>
<column name="elements" idlType="sequence&lt;FootprintElement&gt;"/>
</topicType>
<topicType name="MainStructureElement" isDataObject="1" autosubscribe="1" routeToClient="1" routeToServer="0" routeInReplay="1" baseValueType="Core::BaseEntity">
<column name="description" idlType="string"/>
<column name="properties" idlType="string"/>
<column name="structureElementId" idlType="long"/>
<column name="structureElementTypeId" idlType="StructureElementType"/>
<column name="geoPosition" idlType="Core::GeoPosition"/>
<column name="angle" idlType="double"/>
<column name="modelId" idlType="long"/>
<column name="externalWlsId" idlType="long"/>
<column name="groupId" idlType="long"/>
<column name="elements" idlType="sequence&lt;StructureElement&gt;"/>
</topicType>
<topicType name="MainStructureElementModifyBridgeStatusRequest">
<column name="id" idlType="long"/>
<column name="status" idlType="BridgeStatus"/>
</topicType>
<topicType name="MainStructureElementModifyPositionRequest">
<column name="id" idlType="long"/>
<column name="geoPosition" idlType="Core::GeoPosition"/>
</topicType>
<topicType name="MainStructureElementModifyRequest" baseValueType="MainStructureElement">
<column name="childParentRelations" idlType="sequence&lt;long&gt;" comment="contains the index of the parent in the elements structure"/>
<column name="footprint" idlType="sequence&lt;FootprintElement&gt;" isOptional="1" comment="if not set -&amp;gt; no update, if empty -&amp;gt; remove"/>
</topicType>
<topicType name="MainStructureElementRemoveRequest">
<column name="id" idlType="long"/>
</topicType>
<topicType name="StructureElement" baseValueType="Core::BaseEntity">
<column name="mainStructureElementId" idlType="long"/>
<column name="structureElementTypeId" idlType="StructureElementType"/>
<column name="path" idlType="sequence&lt;long&gt;"/>
<column name="mountingPointId" idlType="long" comment="SubId from XML"/>
<column name="barcode" idlType="string"/>
<column name="relPosition" idlType="Core::RelativePosition"/>
<column name="geoPosition" idlType="Core::GeoPosition"/>
<column name="mountingPointTypeId" idlType="MountingPointType"/>
<column name="orientation" idlType="Core::Orientation"/>
<column name="properties" idlType="string" comment="Overrides: relays json array [key id des Relais 0 = aus, 1 = on, nichts bi auto-Mode], sounds:0, flash:0, (bei sounds und flash ist entwerder 0 oder nicht vorhanden)"/>
<column name="displayName" idlType="string"/>
</topicType>
<topicType name="StructureElementModifyRequest">
<column name="mainStructureElementId" idlType="long"/>
<column name="elements" idlType="sequence&lt;StructureElement&gt;"/>
</topicType>
<topicType name="StructureElementUpdateEffectOverrideRequest">
<column name="structureElementId" idlType="long"/>
<column name="effectId" idlType="long"/>
<column name="effectOverride" idlType="EffectOverride"/>
</topicType>
<topicType name="BridgeChangeStatus" isDataObject="1" autosubscribe="1" routeToClient="1" routeToServer="0" routeInReplay="0" baseValueType="Core::BaseEntityWithSampleTime">
<column name="buildingId" idlType="long"/>
<column name="status" idlType="BridgeStatus"/>
</topicType>
</topicTypes>
<functionTopics>
<functionTopic name="InstrumentationAssetModify" requestTopicType="InstrumentationAssetModifyRequest" replyTopicType="Core::FunctionReply" requestTopicName="InstrumentationAssetModifyRequest" replyTopicName="InstrumentationAssetModifyReply" routeInReplay="0"/>
<functionTopic name="InstrumentationAssetRemove" requestTopicType="Core::RemoveElementRequest" replyTopicType="Core::FunctionReply" requestTopicName="InstrumentationAssetRemoveRequest" replyTopicName="InstrumentationAssetRemoveReply" routeInReplay="0"/>
<functionTopic name="InstrumentationAssetSetState" requestTopicType="InstrumentationAssetSetStateRequest" replyTopicType="Core::FunctionReply" requestTopicName="InstrumentationAssetSetStateRequest" replyTopicName="InstrumentationAssetSetStateReply" routeInReplay="0"/>
<functionTopic name="InstrumentationAssetUnmount" requestTopicType="InstrumentationAssetUnmountRequest" replyTopicType="Core::FunctionReply" requestTopicName="InstrumentationAssetUnmountRequest" replyTopicName="InstrumentationAssetUnmountReply" routeInReplay="0"/>
<functionTopic name="MainScheduleModify" requestTopicType="MainScheduleModifyRequest" replyTopicType="Core::FunctionReply" requestTopicName="MainScheduleModifyRequest" replyTopicName="MainScheduleModifyReply" routeInReplay="0"/>
<functionTopic name="MainScheduleRemove" requestTopicType="Core::RemoveElementRequest" replyTopicType="Core::FunctionReply" requestTopicName="MainScheduleRemoveRequest" replyTopicName="MainScheduleRemoveReply" routeInReplay="0"/>
<functionTopic name="MainScheduleCopy" requestTopicType="MainScheduleCopyRequest" replyTopicType="Core::FunctionReply" requestTopicName="MainScheduleCopyRequest" replyTopicName="MainScheduleCopyReply" routeInReplay="0"/>
<functionTopic name="MountingPointAssetModify" requestTopicType="MountingPointAssetModifyRequest" replyTopicType="Core::FunctionReply" requestTopicName="MountingPointAssetModifyRequest" replyTopicName="MountingPointAssetModifyReply" routeInReplay="0"/>
<functionTopic name="MountingPointAssetRemove" requestTopicType="Core::RemoveElementRequest" replyTopicType="Core::FunctionReply" requestTopicName="MountingPointAssetRemoveRequest" replyTopicName="MountingPointAssetRemoveReply" routeInReplay="0"/>
<functionTopic name="MountingPointPlanModify" requestTopicType="MountingPointPlanModifyRequest" replyTopicType="Core::FunctionReply" requestTopicName="MountingPointPlanModifyRequest" replyTopicName="MountingPointPlanModifyReply" routeInReplay="0"/>
<functionTopic name="MainStructureElementModifyBridgeStatus" requestTopicType="MainStructureElementModifyBridgeStatusRequest" replyTopicType="Core::FunctionReply" requestTopicName="MainStructureElementModifyBridgeStatusRequest" replyTopicName="MainStructureElementModifyBridgeStatusReply" routeInReplay="0"/>
<functionTopic name="MainStructureElementModifyPosition" requestTopicType="MainStructureElementModifyPositionRequest" replyTopicType="Core::FunctionReply" requestTopicName="MainStructureElementModifyPositionRequest" replyTopicName="MainStructureElementModifyPositionReply" routeInReplay="0"/>
<functionTopic name="MainStructureElementModify" requestTopicType="MainStructureElementModifyRequest" replyTopicType="Core::FunctionReply" requestTopicName="MainStructureElementModifyRequest" replyTopicName="MainStructureElementModifyReply" routeInReplay="0"/>
<functionTopic name="MainStructureElementRemove" requestTopicType="MainStructureElementRemoveRequest" replyTopicType="Core::FunctionReply" requestTopicName="MainStructureElementRemoveRequest" replyTopicName="MainStructureElementRemoveReply" routeInReplay="0"/>
<functionTopic name="StructureElementModify" requestTopicType="StructureElementModifyRequest" replyTopicType="Core::FunctionReply" requestTopicName="StructureElementModifyRequest" replyTopicName="StructureElementModifyReply" routeInReplay="0"/>
<functionTopic name="StructureElementUpdateEffectOverride" requestTopicType="StructureElementUpdateEffectOverrideRequest" replyTopicType="Core::FunctionReply" requestTopicName="StructureElementUpdateEffectOverrideRequest" replyTopicName="StructureElementUpdateEffectOverrideReply" routeInReplay="0"/>
</functionTopics>
<customDtcFunctions>
<customDtcFunction>
<function name="getMountingPointAssetId" returns="bool" isConst="1">
<parameter pos="1" name="structureElementId" type="int"/>
<parameter pos="2" name="assetId" type="int"/>
<parameter pos="3" name="mountingPointAssetId" type="int &amp;"/>
</function>
<function name="getAssetIdFromMountingPoint" returns="bool" isConst="1">
<parameter pos="1" name="structureElementId" type="int"/>
<parameter pos="2" name="mountingPointAssetId" type="int"/>
<parameter pos="3" name="assetId" type="int &amp;"/>
</function>
<function name="getOpticalCodeFromAssetId" returns="int" isConst="1">
<parameter pos="1" name="assetId" type="int"/>
</function>
<function name="getAssetIdFromOpticalCode" returns="int" isConst="1">
<parameter pos="1" name="opticalCode" type="int"/>
</function>
<function name="getAssetIdFromMountingPointId" returns="int" isConst="1">
<parameter pos="1" name="mainStructureElementId" type="int"/>
<parameter pos="2" name="mountingPointId" type="int"/>
</function>
<function name="getOpsDataFromMseIdAndSeId" returns="bool" isConst="1">
<parameter pos="1" name="mainStructureElementId" type="int"/>
<parameter pos="2" name="structureElementId" type="int"/>
<parameter pos="3" name="roomId" type="int &amp;"/>
<parameter pos="4" name="geoPosition" type="Core::GeoPosition &amp;"/>
</function>
<function name="getStructureElementById" returns="bool" isConst="1">
<parameter pos="1" name="structureElementId" type="int"/>
<parameter pos="2" name="structureElement" type="StructureElement &amp;"/>
</function>
<function name="getStructureElementInMntPointAssetByAssetId" returns="bool" isConst="1">
<parameter pos="1" name="assetId" type="int"/>
<parameter pos="2" name="structureElement" type="StructureElement &amp;"/>
</function>
<function name="getStructureElementByBuildingIdAndMountingPointId" returns="bool" >
<parameter pos="1" name="mainStructureElementId" type="int"/>
<parameter pos="2" name="mountingPointId" type="int"/>
<parameter pos="3" name="structureElement" type="StructureElement &amp;"/>
</function>
<function name="getAllAssetsPerRoom" returns="bool" >
<parameter pos="1" name="predicate" type="const std::function&lt;bool(const InstrumentationAsset&amp;)&gt; &amp;"/>
<parameter pos="2" name="allAssets" type="QMap&lt;int, QVector&lt;InstrumentationAsset&gt; &gt; &amp;"/>
</function>
<function name="getAllAssetsPerBuilding" returns="bool" isConst="1">
<parameter pos="1" name="predicate" type="const std::function&lt;bool(const InstrumentationAsset&amp;)&gt; &amp;"/>
<parameter pos="2" name="allAssets" type="QMap&lt;int, QVector&lt;InstrumentationAsset&gt; &gt; &amp;"/>
</function>
<function name="getBuildingId" returns="bool" isConst="1">
<parameter pos="1" name="structureElementId" type="int"/>
<parameter pos="2" name="buildingId" type="int &amp;"/>
</function>
<function name="getBuildingDisplayName" returns="QString">
<parameter pos="1" name="buildingId" type="int"/>
</function>
<function name="getBuildingDisplayName" returns="QString" isConst="1">
<parameter pos="1" name="mse" type="const MainStructureElement &amp;"/>
</function>
<function name="getMountingPointPlan" returns="MountingPointPlan" isConst="1">
<parameter pos="1" name="scheduleId" type="int"/>
<parameter pos="2" name="structureElementId" type="int"/>
</function>
<function name="isElementAssignedToExercise" returns="bool" isConst="1">
<parameter pos="1" name="mse" type="const MainStructureElement&amp;"/>
<parameter pos="2" name="exerciseId" type="int"/>
</function>
<function name="getBuildingRoomsCount" returns="int">
<parameter pos="1" name="buildingId" type="int"/>
</function>
<function name="getBridgeStatus" returns="BridgeStatus">
<parameter pos="1" name="buildingId" type="int"/>
</function>
<function name="checkSchedule" returns="bool">
<parameter pos="1" name="scheduleId" type="int"/>
</function>
<function name="getScheduleDifferences" returns="bool">
<parameter pos="1" name="scheduleId" type="int"/>
<parameter pos="2" name="diffList" type="QList&lt;MountingPointPlan&gt; &amp;"/>
</function>
<function name="getMountedAssetId" returns="int" isConst="1">
<parameter pos="1" name="structureElementId" type="int"/>
</function>
<function name="getStructueElementIdFromAssetId" returns="int" isConst="1">
<parameter pos="1" name="assetId" type="int"/>
</function>
<function name="getSections" returns="QList&lt;int&gt;">
</function>
<function name="getFootprintsByExerciseId" returns="QMap&lt;int, MainFootprint&gt;">
<parameter pos="1" name="exerciseId" type="int"/>
</function>
<function name="getUtmFootprintsByExerciseId" returns="QMap&lt;int, QPolygonF&gt;">
<parameter pos="1" name="exerciseId" type="int"/>
<parameter pos="2" name="zone" type="int &amp;"/>
<parameter pos="3" name="isGroundLevel" type="bool"/>
</function>
<function name="getUtmFootprintById" returns="QPolygonF">
<parameter pos="1" name="mseId" type="int"/>
<parameter pos="2" name="zone" type="int &amp;"/>
<parameter pos="3" name="isGroundLevel" type="bool"/>
</function>
<function name="getBuildingByPolygon" returns="QVector&lt;int&gt;">
<parameter pos="1" name="exerciseId" type="int"/>
<parameter pos="2" name="polygon" type="const QPolygonF &amp;"/>
<parameter pos="3" name="completeEnclosed" type="bool"/>
<parameter pos="4" name="isGroundLevel" type="bool"/>
</function>
<function name="getSurroundingBuildingByPolygon" returns="int">
<parameter pos="1" name="exerciseId" type="int"/>
<parameter pos="2" name="polygon" type="const QPolygonF &amp;"/>
<parameter pos="3" name="isGroundLevel" type="bool"/>
</function>
<function name="getBuildingIdAtPosition" returns="int">
<parameter pos="1" name="exerciseId" type="int"/>
<parameter pos="2" name="utmPos" type="const QPointF &amp;"/>
<parameter pos="3" name="isGroundLevel" type="bool"/>
</function>
<function name="getFloorIdsFromBuilding" returns="QVector&lt;int&gt;">
<parameter pos="1" name="buildingId" type="int"/>
</function>
<function name="getHalfFloorHeight" returns="double">
<parameter pos="1" name="buildingId" type="int"/>
<parameter pos="2" name="floorId" type="int"/>
</function>
<function name="getRoomIdsFromFloorId" returns="QVector&lt;int&gt;">
<parameter pos="1" name="buildingId" type="int"/>
<parameter pos="2" name="floorId" type="int"/>
</function>
<function name="getBuildingIdsByExercise" returns="QVector&lt;int&gt;">
<parameter pos="1" name="exerciseId" type="int"/>
</function>
<function name="getVulnerabilityModelData" returns="QByteArray">
<parameter pos="1" name="buildingId" type="int"/>
</function>
</customDtcFunction>
</customDtcFunctions>
<enumerations>
<enumeration name="BuildingGroup" table="ism_building_group">
<attribute key="UnknownGroup" value="0"/>
<attribute key="OutdoorCameras" value="1"/>
<attribute key="Section0" value="2"/>
<attribute key="Section1" value="3"/>
<attribute key="Section2" value="4"/>
<attribute key="Section3" value="5"/>
<attribute key="Section4" value="6"/>
<attribute key="Salchau" value="7"/>
</enumeration>
<enumeration name="EffectOverride">
<attribute key="Automatic" value="-1"/>
<attribute key="PermanentOff" value="0"/>
<attribute key="PermanentOn" value="1"/>
</enumeration>
<enumeration name="InstrumentationAssetState" table="ism_asset_state">
<attribute key="Unmounted" value="0"/>
<attribute key="Mounted" value="1"/>
<attribute key="Defect" value="2"/>
</enumeration>
<enumeration name="MountingPointState" table="ism_mounting_point_state">
<attribute key="Empty" value="-1"/>
<attribute key="Idle" value="0"/>
<attribute key="Equipped" value="1"/>
</enumeration>
<enumeration name="MountingPointType" table="ism_mounting_point_type">
<attribute key="Unknown" value="0"/>
<attribute key="BuildingSensorModule" value="1"/>
<attribute key="BuildingControlUnit" value="2"/>
<attribute key="OutdoorCamera" value="3"/>
<attribute key="IndoorCamera" value="4"/>
<attribute key="OutdoorIPS" value="5"/>
<attribute key="IndoorIPS" value="6"/>
<attribute key="MeteoDataUnit" value="7"/>
<attribute key="AnnouncementUnit" value="10"/>
<attribute key="VirtualIPS" value="11"/>
<attribute key="EffectGenerationControlUnit" value="12"/>
<attribute key="OutdoorControlUnit" value="13"/>
<attribute key="BuildingNetworkSwitch" value="14"/>
</enumeration>
<enumeration name="ScheduleStatus" table="ism_schedule_status">
<attribute key="Active" value="0"/>
<attribute key="Inactive" value="1"/>
</enumeration>
<enumeration name="StructureElementType" table="ism_structure_element_type">
<attribute key="TrainingArea" value="0"/>
<attribute key="City" value="1"/>
<attribute key="Section" value="2"/>
<attribute key="Building" value="3"/>
<attribute key="Floor" value="4"/>
<attribute key="Room" value="5"/>
<attribute key="MountingPoint" value="6"/>
<attribute key="ApproachingPoint" value="7"/>
<attribute key="RadioStation" value="8"/>
<attribute key="MeteoDataUnit" value="9"/>
<attribute key="Announcement" value="10"/>
<attribute key="Bridge" value="11"/>
</enumeration>
<enumeration name="BridgeStatus">
<attribute key="Intact" value="0"/>
<attribute key="Broken" value="1"/>
</enumeration>
<enumeration name="SpecialAreaType" table="ism_special_area_type">
<attribute key="SatMoutArea" value="1"/>
<attribute key="SatCesArea" value="2"/>
</enumeration>
</enumerations>
</service>
+96
View File
@@ -0,0 +1,96 @@
log4j.reset=true
log4j.rootLogger=WARN, file
#log4j.logger.DDS=INFO
# Service: InfrastructureManagement
###########################################################
#log4j.logger.ISM=INFO
#log4j.logger.ISM.main=INFO
#log4j.logger.ISM.DbHandler=INFO
#log4j.logger.ISM.MainHandler=INFO
#log4j.logger.ISM.ObjectStructureElement=INFO
#log4j.logger.ISM.HandlerMainStructureElement=INFO
#log4j.logger.ISM.ObjectMainStructureElement=INFO
#log4j.logger.ISM.HandlerAsset=INFO
#log4j.logger.ISM.ObjectAsset=INFO
#log4j.logger.ISM.HandlerStructureElementFootprint=INFO
#log4j.logger.ISM.ObjectStructureElementFootprint=INFO
#log4j.logger.ISM.HandlerMountingPointAsset=INFO
#log4j.logger.ISM.ObjectMountingPointAsset=INFO
#log4j.logger.ISM.HandlerMountingPointPlan=INFO
#log4j.logger.ISM.ObjectMountingPointPlan=INFO
#log4j.logger.ISM.HandlerMainSchedule=INFO
#log4j.logger.ISM.ObjectMountingPointSchedule=INFO
#log4j.logger.ISM.Settings=INFO
#log4j.logger.ISM.Fts=INFO
#log4j.logger.ISM.Test=DEBUG
#log4j.logger.ISM.ImportXml=DEBUG
# File
###########################################################
log4j.appender.file=Lts::RollingFileAppender
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=9
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d %-5p %c |#| %m (%.50F:%L) %n
# Appnd_Console
###########################################################
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern= %d %p %c %c{1} - %m (%-.30F:%L) %n
# Appnd_Syslog
###########################################################
log4j.appender.syslog=org.apache.log4j.SyslogAppender
log4j.appender.syslog.Threshold=ERROR
log4j.appender.syslog.SysLogHost=localhost
log4j.appender.syslog.Facility=LOCAL7
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
log4j.appender.syslog.layout.ConversionPattern= %-4r %-5p %c %x - %m
log4j.appender.syslog.LevelRangeFilter.AcceptOnMatch=true
log4j.appender.syslog.LevelRangeFilter.LevelMin=INFO
log4j.appender.syslog.LevelRangeFilter.LevelMax=FATAL
###########################################################
###########################################################
###########################################################
# 1) Available Levels in LOG4CXX Version 0.10.0:
# TRACE,
# DEBUG,
# INFO,
# WARN,
# ERROR
# FATAL
#
# d = date/time
# p = priority (Level)
# c = category/channel
# m = message
# F = file
# L = line
# n = platform dependent line separator character or characters.
# ....
#
# Examples for console:
# a)
# %d %p %c #%m# (%.50F:%L)%n
# date/time
# priority
# category/channel
# #message#
# (Maximal 50Character des Filename von rechts:Line)
# line separator
#
# b)
# %d (%.15F:%L) %-5p %c |#| %m%n
# date/time
# (Maximal 15Character des Filename von rechts:Line)
# priority, Right pad with spaces if the priority name is less than 5 characters long.
# category/channel
# message
# line separator
#
# Examples for files:
+38
View File
@@ -0,0 +1,38 @@
/**
* @RDE_HEADER@
* Logging
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#include "logger.h"
#include <NGLLogger/NGLLoggerBootstrap.h>
namespace InfrastructureManagement
{
LOGGER_T getLogger(const char *name)
{
static const char ns[] = "ISM.";
std::string loggerName;
const size_t len = strlen(name);
loggerName.reserve(sizeof(ns) + len);
loggerName.append(ns, sizeof(ns) - 1);
loggerName.append(name, len);
try
{
return NGL::NGLLoggerBootstrap::getNGLRootLogger().
getNGLLogger(loggerName);
}
catch (const std::exception &ex)
{
fprintf(stderr, "Error retrieving logger: %s", ex.what());
abort();
}
}
} // namespace InfrastructureManagement
+24
View File
@@ -0,0 +1,24 @@
/**
* @RDE_HEADER@
* Logging
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#pragma once
#include <NGLLogger/INGLLogger.h>
#include "ism_export.h"
namespace InfrastructureManagement
{
using LOGGER_T = NGL::INGLLogger &;
ISM_COMMON_EXPORT LOGGER_T getLogger(const char *name);
inline LOGGER_T getLogger(const QString &loggerName)
{
return getLogger(loggerName.toUtf8().constData());
}
} // namespace InfrastructureManagement
+44
View File
@@ -0,0 +1,44 @@
/**
* @RDE_HEADER@
* main for InfrastructureManagement
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#include <nglapplication/nglcoreapplication.h>
#include <LtsCommandLineParser/LtsCommandLineParser.h>
#include "main_handler.h"
#include "logger.h"
#include "settings.h"
//-------------------------------------------------------------------------------------------------------------
int main(int argc, char **argv)
{
NGLCoreApplication app(argc, argv);
LtsCommandLineParser::LtsCommandLineParser options;
if (!options.init())
return -1;
app.createLogger("ISM", options.exerciseId());
InfrastructureManagement::Settings::setIniFile(options.iniFile());
int iRet = -1;
{
STARTUP_LOG(app.baseLogger());
std::unique_ptr<InfrastructureManagement::MainHandler> mainHandler(new InfrastructureManagement::MainHandler);
if (!mainHandler->init(options.domainId()))
return iRet;
iRet = app.exec();
SHUTDOWN_LOG(app.baseLogger());
}
return iRet;
}
+180
View File
@@ -0,0 +1,180 @@
/**
* @RDE_HEADER@
* MainHandler for InfrastructureManagement
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#include "main_handler.h"
#include "handler_main_structure_element.h"
#include "handler_instrumentation_asset.h"
#include "handler_mounting_point_asset.h"
#include "handler_effect_area.h"
#include "handler_main_schedule.h"
#include "handler_special_area.h"
#include "parse_building_xml.h"
#include "WebSocketInterface/websocket_interface_handler.h"
#include "settings.h"
#include <DDS/DDSConnector/dds_connector.h>
#include <DDS/Core/pacemaker.h>
#include <LtsCoordTrans/lts_coord_trans.h>
#include <ngldb/db_service_handler.h>
namespace InfrastructureManagement
{
//-------------------------------------------------------------------------------------------------------------
MainHandler::MainHandler()
: m_logger(getLogger("MainHandler"))
{
} // end of ctor()
//-------------------------------------------------------------------------------------------------------------
MainHandler::~MainHandler()
{
m_handlerWebSocketInterface = nullptr;
m_handlerMainSchedule = nullptr;
m_handlerMountingPointAsset = nullptr;
m_handlerInstrumentationAsset = nullptr;
m_handlerMainStructureElement = nullptr;
m_dbHandler = nullptr;
m_ddsHandler = nullptr;
m_exmDtc = nullptr;
} // end of dtor()
//-------------------------------------------------------------------------------------------------------------
bool MainHandler::init(int domainId)
{
INFO_LOG(m_logger) << "--- Start InfrastructureManagement MainHandler.";
// initialize DDS
// for InfrastructureManagement => exerciseId = partitionId
m_ddsHandler = std::make_shared<DdsHandler>(domainId);
if (!m_ddsHandler->init())
{
ERROR_LOG(m_logger) << "Initialisation DdsHandler failed.";
if (m_ddsHandler->pacemaker())
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::StartingError);
return false;
}
auto pm = m_ddsHandler->pacemaker();
// initialize database
m_dbHandler = std::make_shared<DbHandler>();
if (!m_dbHandler->init(0, Settings::settings()))
{
ERROR_LOG(m_logger) << "Initialisation DbHandler failed.";
pm->setNewState(Core::RunningState::StoppedError);
return false;
}
pm->setNewState(Core::RunningState::Starting);
QScopedPointer<DDSConnector::CoherentSet> cs(Settings::useCoherentSet() ? new DDSConnector::CoherentSet(dds()->ddsConnector()) : nullptr);
// read project specific data from database
// publish project specific data
// initialize handler MainStructureElement
m_handlerMainStructureElement = std::make_shared<HandlerMainStructureElement>(this);
if (!m_handlerMainStructureElement->init())
{
ERROR_LOG(m_logger) << "Initialisation HandlerMainStructureElement failed.";
pm->setNewState(Core::RunningState::StoppedError);
return false;
}
// pm->setNewState(Core::RunningState::Starting);
// initialize handler Asset
m_handlerInstrumentationAsset = std::make_shared<HandlerInstrumentationAsset>(this);
if (!m_handlerInstrumentationAsset->init())
{
ERROR_LOG(m_logger) << "Initialisation HandlerInstrumentationAsset failed.";
pm->setNewState(Core::RunningState::StartingError);
return false;
}
// initialize handler MountingPointAsset
m_handlerMountingPointAsset = std::make_shared<HandlerMountingPointAsset>(this);
if (!m_handlerMountingPointAsset->init())
{
ERROR_LOG(m_logger) << "Initialisation HandlerMountingPointAsset failed.";
pm->setNewState(Core::RunningState::StartingError);
return false;
}
// pm->setNewState(Core::RunningState::Starting);
// initialize handler SoundArea
m_handlerEffectArea = std::make_shared<HandlerEffectArea>(this);
if (!m_handlerEffectArea->init())
{
ERROR_LOG(m_logger) << "Initialisation HandlerEffectArea failed.";
pm->setNewState(Core::RunningState::StartingError);
return false;
}
// initialize handler SpecailArea
m_handlerSpecialArea = std::make_shared<HandlerSpecialArea>(this);
if (!m_handlerSpecialArea->init())
{
ERROR_LOG(m_logger) << "Initialisation HandlerSpecialArea failed.";
pm->setNewState(Core::RunningState::StartingError);
return false;
}
// init MainSchedule handler
m_handlerMainSchedule = std::make_shared<HandlerMainSchedule>(this);
if (!m_handlerMainSchedule->init())
{
ERROR_LOG(m_logger) << "Initialisation HandlerMainSchedule failed.";
pm->setNewState(Core::RunningState::StartingError);
return false;
}
// pm->setNewState(Core::RunningState::Starting);
m_exmDtc = ExerciseManagement::Interface::Dtc::create(m_ddsHandler->ddsConnector());
m_exmDtc->enableExercise();
QObject::connect(m_exmDtc.get(), &ExerciseManagement::Interface::Dtc::exerciseChanged, m_handlerMainStructureElement.get(), &HandlerMainStructureElement::onExerciseStateChanged);
// init WebSocketInterface
using namespace WebSocketInterface;
m_handlerWebSocketInterface = std::make_shared<WebSocketInterfaceHandler>(this);
if (!m_handlerWebSocketInterface->init())
{
ERROR_LOG(m_logger) << "Initialisation WebSocketInterface failed.";
pm->setNewState(Core::RunningState::StartingError);
return false;
}
INFO_LOG(m_logger) << "ISM MainHandler initialized.";
pm->setNewState(Core::RunningState::Running);
pm->addPort(m_handlerWebSocketInterface->webSocketPort(), Core::PortType::WebSocketServer);
return true;
} // end of init()
//-------------------------------------------------------------------------------------------------------------
std::shared_ptr<DatabaseInterface> MainHandler::db() const
{
return m_dbHandler->db();
}
//-------------------------------------------------------------------------------------------------------------
int MainHandler::exerciseId() const
{
if (dds())
return dds()->ddsConnector()->getPartitionId();
return -1;
}
//-------------------------------------------------------------------------------------------------------------
QPointF rotatePoint(const double xIn, const double yIn, double angleDegree)
{
const double angleRad = angleDegree * LtsCoordTrans::deg2rad();
const double sinAngle = sin(angleRad);
const double cosAngle = cos(angleRad);
return QPointF(xIn * cosAngle - yIn * sinAngle, xIn * sinAngle + yIn * cosAngle);
}
} // namespace InfrastructureManagement;
+93
View File
@@ -0,0 +1,93 @@
/**
* @RDE_HEADER@
* MainHandler for InfrastructureManagement
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#pragma once
#include <InfrastructureManagement/ism_db.h>
#include "dds_handler.h"
#include <ExerciseManagement/exm_dtc.h>
#include "logger.h"
//-------------------------------------------------------------------------------------------------------------
namespace NGLDB
{
template <typename DB> class DbServiceHandler;
}
namespace InfrastructureManagement
{
// Forwarddeclarations
using DbHandler = NGLDB::DbServiceHandler<DatabaseInterface>;
class HandlerMainStructureElement;
class HandlerInstrumentationAsset;
class HandlerMountingPointAsset;
class HandlerEffectArea;
class HandlerMainSchedule;
class HandlerSpecialArea;
namespace WebSocketInterface
{
class WebSocketInterfaceHandler;
}
class MainHandler
{
public:
explicit MainHandler();
~MainHandler();
bool init(int domainId);
std::shared_ptr<DdsHandler> dds() const { return m_ddsHandler; }
std::shared_ptr<DatabaseInterface> db() const;
std::shared_ptr<HandlerMainStructureElement> getHandlerMainStructureElement() const
{
return m_handlerMainStructureElement;
}
std::shared_ptr<HandlerInstrumentationAsset> getHandlerInstrumentationAsset() const
{
return m_handlerInstrumentationAsset;
}
std::shared_ptr<HandlerMountingPointAsset> getHandlerMountingPointAsset() const
{
return m_handlerMountingPointAsset;
}
std::shared_ptr<HandlerEffectArea> getHandlerEffectArea() const
{
return m_handlerEffectArea;
}
std::shared_ptr<HandlerMainSchedule> getHandlerMainSchedule() const
{
return m_handlerMainSchedule;
}
std::shared_ptr<HandlerSpecialArea> getHandlerSpecialArea() const
{
return m_handlerSpecialArea;
}
int exerciseId() const;
private: // attributes
std::shared_ptr<DbHandler> m_dbHandler;
std::shared_ptr<DdsHandler> m_ddsHandler;
std::shared_ptr<HandlerMainStructureElement> m_handlerMainStructureElement;
std::shared_ptr<HandlerInstrumentationAsset> m_handlerInstrumentationAsset;
std::shared_ptr<HandlerMountingPointAsset> m_handlerMountingPointAsset;
std::shared_ptr<HandlerEffectArea> m_handlerEffectArea;
std::shared_ptr<HandlerMainSchedule> m_handlerMainSchedule;
std::shared_ptr<HandlerSpecialArea> m_handlerSpecialArea;
std::shared_ptr<WebSocketInterface::WebSocketInterfaceHandler> m_handlerWebSocketInterface;
std::shared_ptr<ExerciseManagement::Interface::Dtc> m_exmDtc;
NGL::INGLLogger &m_logger;
};
QPointF rotatePoint(const double xIn, const double yIn, double angleDegree);
} // namespace InfrastructureManagement
@@ -0,0 +1,66 @@
/**
* @RDE_HEADER@
* ISM Object Sound Area
* $Id$
* $HeadURL$
* $Author$
* Created by Filip Biedziak, NLE, 2020-08-05
*/
#include "object_effect_area.h"
namespace InfrastructureManagement
{
ObjectEffectArea::ObjectEffectArea(MainHandler *mainHandler)
: Base(mainHandler, getLogger("ObjectEffectArea"))
{
}
ObjectEffectArea::~ObjectEffectArea()
{
}
//-----------------------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectEffectArea::createObject(const EffectArea &data)
{
m_data = data;
m_data.name("Sound Area " + std::to_string(m_data.id()));
onPublishData(); // publish data via DDS
return Core::FunctionReplyObject(m_data.id());
}
Core::FunctionReplyObject ObjectEffectArea::updateObject(const EffectArea &data)
{
m_data = data;
DEBUG_LOG(m_logger) << "Data changed for Id: " << m_data.id();
onPublishData(); // publish data via DTS
return Core::FunctionReplyObject(m_data.id());
}
Core::FunctionReplyObject ObjectEffectArea::removeObject()
{
if (!dts()->removeEffectAreaByKey(m_data.id()))
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "EffectArea with id %1 can not be removed from DDS")).arg(m_data.id());
return Core::FunctionReplyObject(m_data.id());
}
//-----------------------------------------------------------------------------------------------------------------------------
void ObjectEffectArea::onPublishData()
{
INFO_LOG(m_logger) << "Publish IsmEffectArea-data to dds (" << m_data.id() << ") ...";
if (!dts()->publish(m_data))
ERROR_LOG(m_logger) << "Error publishing IsmEffectArea-data to dds";
}
} // namespace InfrastructureManagement
+46
View File
@@ -0,0 +1,46 @@
/**
* @RDE_HEADER@
* ISM Object Sound Area
* $Id$
* $HeadURL$
* $Author$
* Created by Filip Biedziak, NLE, 2020-08-05
*/
#pragma once
#include "base.h"
#include <DDS/Core/function_reply_object.h>
#include <InfrastructureManagement/ism_db.h>
namespace InfrastructureManagement
{
class ObjectEffectArea : public Base
{
public:
explicit ObjectEffectArea(MainHandler *mainHandler);
~ObjectEffectArea();
Core::FunctionReplyObject createObject(const EffectArea &data);
Core::FunctionReplyObject updateObject(const EffectArea &data);
Core::FunctionReplyObject removeObject();
int32_t getId() const { return m_data.id(); }
int32_t getAreaEgcuId() const { return m_data.areaEgcuId(); }
std::vector<int32_t> getEgcuIds() const { return m_data.egcuIds(); }
std::vector<Core::GeoPosition2D> getGeometry() const { return m_data.geometry(); }
EffectArea getData() const { return m_data; }
protected:
void onPublishData();
private:
EffectArea m_data;
};
} // namespace InfrastructureManagement
@@ -0,0 +1,175 @@
/**
* @RDE_HEADER@
* ISM Object Instrumentation Asset
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#include "object_instrumentation_asset.h"
//-------------------------------------------------------------------------------------------------------------
namespace InfrastructureManagement
{
ObjectInstrumentationAsset::ObjectInstrumentationAsset(MainHandler *mainHandler)
: Base(mainHandler, getLogger("ObjectInstrumentationAsset"))
{
}
//-------------------------------------------------------------------------------------------------------------
ObjectInstrumentationAsset::~ObjectInstrumentationAsset()
{
}
//-------------------------------------------------------------------------------------------------------------
bool ObjectInstrumentationAsset::isValid() const
{
return m_data.id() > 0;
}
//-------------------------------------------------------------------------------------------------------------
bool ObjectInstrumentationAsset::isUsed() const
{
return m_data.isUsed();
}
//-------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectInstrumentationAsset::createObject(const InstrumentationAsset &data)
{
m_data = data;
if (m_data.id() <= 0)
{
m_data.isUsed(false);
Database::IsmAsset dbData;
dbData = toDbData(data);
dbData.id = 0;
if (!db()->insert(dbData))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting IsmAsset-data into database"));
m_data.id(dbData.id);
DEBUG_LOG(m_logger) << "New Id: " << m_data.id();
}
// Publish Data via DTS
onPublishData();
return Core::FunctionReplyObject(m_data.id());
}
//-------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectInstrumentationAsset::updateObject(const InstrumentationAsset &data)
{
if (!isValid())
return Core::FunctionReplyObject(data.id(), tr_lts("dds", "Object not valid/blocked"));
Database::IsmAsset dbData;
dbData = toDbData(data);
if (!db()->update(dbData))
return Core::FunctionReplyObject(data.id(), tr_lts("dds", "Error updating IsmAsset-data into database"));
m_data = data;
DEBUG_LOG(m_logger) << "Data changed for Id: " << m_data.id();
// Publish Data via DTS
onPublishData();
return Core::FunctionReplyObject(m_data.id());
}
//-------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectInstrumentationAsset::setUsed(bool isUsed)
{
if (!isValid())
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "Trying to update an already removed IsmAsset object"));
m_data.isUsed(isUsed);
// Publish Data via DTS
onPublishData();
return Core::FunctionReplyObject(m_data.id());
}
//-------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectInstrumentationAsset::removeObject()
{
if (isUsed())
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "Asset still in use"));
if (!db()->removeIsmAsset(m_data.id()))
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "Asset with id %1 can not be removed from DB")).arg(m_data.id());
if (!dts()->removeInstrumentationAssetByKey(m_data.id()))
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "Asset with id %1 can not be removed from DDS")).arg(m_data.id());
return Core::FunctionReplyObject(m_data.id());
}
//-------------------------------------------------------------------------------------------------------------
InfrastructureManagement::InstrumentationAsset InfrastructureManagement::ObjectInstrumentationAsset::getData() const
{
return m_data;
}
//-------------------------------------------------------------------------------------------------------------
void ObjectInstrumentationAsset::onPublishData()
{
INFO_LOG(m_logger) << "Publish IsmAsset-data to dds (" << m_data.id() << ") ...";
if (!dts()->publish(m_data))
ERROR_LOG(m_logger) << "Error publishing IsmAsset-data to dds";
}
// -------------------------------------------------------------------------------------------------------
// convert methods
// -------------------------------------------------------------------------------------------------------
// InfrastructureManagement::Asset => Database::IsmAsset
Database::IsmAsset ObjectInstrumentationAsset::toDbData(const InstrumentationAsset &ddsData)
{
Database::IsmAsset dbData;
dbData.id = ddsData.id();
dbData.name = QString::fromStdString(ddsData.name());
dbData.mountingPointTypeId = ddsData.mountingPointTypeId();
dbData.barcode = QString::fromStdString(ddsData.barcode());
dbData.hostname = QString::fromStdString(ddsData.hostname());
dbData.properties = QString::fromStdString(ddsData.properties());
dbData.assetStateId = ddsData.assetStateId();
dbData.availableInExercise = LtsUtils::IntArray(ddsData.availableInExercise());
dbData.lastUpdated = QDateTime::fromMSecsSinceEpoch(ddsData.lastUpdated());
return dbData;
}
// -------------------------------------------------------------------------------------------------------
// Database::IsmAsset => InfrastructureManagement::Asset
InstrumentationAsset ObjectInstrumentationAsset::toDdsData(const Database::IsmAsset &dbData)
{
InstrumentationAsset ddsData;
ddsData.id(dbData.id);
ddsData.name(dbData.name.toStdString());
ddsData.mountingPointTypeId(dbData.mountingPointTypeId);
ddsData.barcode(dbData.barcode.toStdString());
ddsData.hostname(dbData.hostname.toStdString());
ddsData.properties(dbData.properties.toStdString());
ddsData.assetStateId(dbData.assetStateId);
ddsData.availableInExercise(dbData.availableInExercise());
ddsData.lastUpdated(dbData.lastUpdated.toMSecsSinceEpoch());
// init data not in db
ddsData.isDeleted(false);
ddsData.isUsed(false);
return ddsData;
}
// -------------------------------------------------------------------------------------------------------
} // Namespace InfrastructureManagement
@@ -0,0 +1,51 @@
/**
* @RDE_HEADER@
* ISM Object Instrumentation Asset
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#pragma once
#include "base.h"
#include <DDS/Core/function_reply_object.h>
#include <InfrastructureManagement/ism_db.h>
//-------------------------------------------------------------------------------------------------------------
namespace InfrastructureManagement
{
class ObjectInstrumentationAsset : public Base
{
public:
explicit ObjectInstrumentationAsset(MainHandler *mainHandler);
~ObjectInstrumentationAsset();
Core::FunctionReplyObject createObject(const InstrumentationAsset &data);
Core::FunctionReplyObject updateObject(const InstrumentationAsset &data);
Core::FunctionReplyObject removeObject();
qint32 getId() const
{
return m_data.id();
}
QString getName() const { return QString::fromStdString(m_data.name()); }
InfrastructureManagement::InstrumentationAsset getData() const;
bool isValid() const;
bool isUsed() const;
Core::FunctionReplyObject setUsed(bool isUsed);
// convert methods
static Database::IsmAsset toDbData(const InstrumentationAsset &ddsData); // dds -> db
static InstrumentationAsset toDdsData(const Database::IsmAsset &dbData); // db -> dds
protected:
void onPublishData();
private:
InstrumentationAsset m_data;
};
}
@@ -0,0 +1,351 @@
/**
* @RDE_HEADER@
* ISM Object Mounting Point Schedule
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#include "object_main_schedule.h"
#include <ngldb/dbtransaction.h>
#include <QTimer>
using namespace InfrastructureManagement;
//----------------------------------------------------------------------------------------------------
ObjectMainSchedule::ObjectMainSchedule(MainHandler *mainHandler)
: Base(mainHandler, getLogger("ObjectMainSchedule"))
{
}
//----------------------------------------------------------------------------------------------------
ObjectMainSchedule::~ObjectMainSchedule()
{
}
//----------------------------------------------------------------------------------------------------
bool ObjectMainSchedule::isValid() const
{
return m_data.id() > 0;
}
//----------------------------------------------------------------------------------------------------
bool ObjectMainSchedule::isUsed() const
{
return m_data.isUsed();
}
//----------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMainSchedule::createObject(const MainSchedule &data)
{
m_data = data;
if (m_data.id() <= 0)
{
// This is a brand new Item to push into the Database
m_data.isUsed(false);
Database::IsmMountingPointSchedule dbData;
dbData = toDbData(data);
if (!db()->insert(dbData))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting IsmMainSchedule-data into database"));
m_data.id(dbData.id);
DEBUG_LOG(m_logger) << "New Id: " << m_data.id();
// Publish Data via DTS
dts()->publish(m_data);
}
// If this is a replicated item from the Database, elements() must be filled with loadMountingPointPlans()
// by the calling class!
// Cannot be done within createObject as the SQL Janitor prevents this!
// Therefore, this item is not published in this case, but within loadMountingPointPlans()!
return Core::FunctionReplyObject(m_data.id());
}
// Cannot be done within createObject as the SQL Janitor prevents this!
bool ObjectMainSchedule::loadMountingPointPlans()
{
m_data.elements().clear();
// Data from DB is pushed in here, we just need to update MPPs
auto cbMps = [this] (const Database::IsmMountingPointPlan &data)
{
MountingPointPlan ddsData = ObjectMainSchedule::toDdsData(data);
m_data.elements().push_back(ddsData);
m_mppMap.insert(ddsData.structureElementId(), ddsData);
};
// create Mounting Point Schedule objects
if (!db()->selectByMountingPointScheduleId(cbMps,m_data.id()))
return false;
return dts()->publish(m_data);
}
//----------------------------------------------------------------------------------------------------
// ---- .elements() is ignored here intentionally!!!! ----
Core::FunctionReplyObject ObjectMainSchedule::updateObject(const MainSchedule &data)
{
if (!isValid())
return Core::FunctionReplyObject(data.id(), tr_lts("dds", "Object not valid/blocked"));
Database::IsmMountingPointSchedule dbData;
dbData = toDbData(data);
if (!db()->update(dbData))
return Core::FunctionReplyObject(data.id(), tr_lts("dds", "Error updating IsmMainSchedule-data into database"));
// Change state if different
if (m_data.statusId() != data.statusId())
setScheduleStatus(data.statusId());
// If elements are not saved, a MainSchedule with 0 elements will be published.
std::vector< InfrastructureManagement::MountingPointPlan > tempElements = m_data.elements();
m_data = data;
m_data.elements(tempElements);
DEBUG_LOG(m_logger) << "Data changed for Id: " << m_data.id();
// Publish Data via DTS
dts()->publish(m_data);
return Core::FunctionReplyObject(m_data.id());
}
//----------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMainSchedule::copyObject(qint32 scheduleId)
{
int newId = db()->copySchedule(scheduleId);
if (newId <= 0)
return Core::FunctionReplyObject(0, tr_lts("dds", "Error on copy IsmMainSchedule"));
Database::IsmMountingPointSchedule dbData;
if (!db()->selectIsmMountingPointSchedule(newId, dbData))
return Core::FunctionReplyObject(newId, tr_lts("dds", "Error selecting copy id from database"));
m_data = toDdsData(dbData);
//
// An Object initialized by this method is not used, but only getId() is called afterwards (right now)
// Therefore, expensive selection of MPPs is avoided. Uncomment if needed (MD, 07.02.23)
//
// auto cbMps = [this] (const Database::IsmMountingPointPlan &data)
// {
// InfrastructureManagement::MountingPointPlan ddsData = ObjectMainSchedule::toDdsData(data);
// m_data.elements().push_back(ddsData);
// };
// // create Mounting Point Schedule objects
// if (!db()->selectByMountingPointScheduleId(cbMps,m_data.id()))
// {
// return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting IsmMountingPointPlan-data into DDS Structure"));
// }
return Core::FunctionReplyObject(newId);
}
Core::FunctionReplyObject ObjectMainSchedule::updateElements(const std::vector<MountingPointPlan> &newElements)
{
std::vector<Database::IsmMountingPointPlan> insert;
DBTransaction trans(db()->database());
bool retVal = true;
for (const MountingPointPlan &mpp : newElements)
{
int seId = mpp.structureElementId();
if (m_mppMap.contains(seId))
{
if (mpp.mountingPointState() == MountingPointState_def::Idle)
{
retVal &= db()->deleteMountingPointPlan(m_data.id(), seId);
m_mppMap.remove(seId);
}
else
{
retVal &= db()->updateMountingPointPlan(m_data.id(), seId, mpp.mountingPointState());
m_mppMap[seId] = mpp;
}
}
else
{
auto copy = toDbData(m_data.id(), mpp);
m_mppMap[seId] = mpp;
// Do this as a bulk....
insert.push_back(copy);
}
}
retVal &= db()->insertMountingPointPlans(insert);
trans.commit();
m_data.elements().clear();
m_data.elements().reserve(m_mppMap.size());
std::copy(m_mppMap.begin(), m_mppMap.end(),std::back_inserter(m_data.elements()));
QTimer::singleShot(50, [this](){dts()->publish(m_data);});
if (!retVal)
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "Error on updating MountingPoint Plans."));
return Core::FunctionReplyObject(m_data.id());
}
//----------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMainSchedule::setUsed(bool isUsed)
{
if (!isValid())
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "Trying to update an already removed IsmMainSchedule object"));
m_data.isUsed(isUsed);
// Publish Data via DTS
//onPublishData();
return Core::FunctionReplyObject(m_data.id());
}
//----------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMainSchedule::removeObject()
{
if (isUsed())
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "MainSchedule still in use"));
if (!db()->removeIsmMountingPointSchedule(m_data.id()))
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "MainSchedule with id %1 can not be removed from DB")).arg(m_data.id());
if (!dts()->removeMainScheduleByKey(m_data.id()))
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "MainSchedule with id %1 can not be removed from DDS")).arg(m_data.id());
return Core::FunctionReplyObject(m_data.id());
}
//----------------------------------------------------------------------------------------------------
bool ObjectMainSchedule::setScheduleStatus(const ScheduleStatus &status)
{
if (m_data.statusId() == status)
return true;
if (!isValid())
{
WARNING_LOG(m_logger) << "Trying to update an already removed MainSchedule object";
return false;
}
DEBUG_LOG(m_logger) << "## old status = " << m_data.statusId();
DEBUG_LOG(m_logger) << "## new status = " << status;
m_data.statusId() = status;
QDateTime changed = QDateTime::currentDateTimeUtc();
if (m_data.timeCreated() <= 0)
m_data.timeCreated() = changed.toMSecsSinceEpoch();
switch (m_data.statusId().underlying())
{
case ScheduleStatus::Active:
m_data.timeStart() = changed.toMSecsSinceEpoch();
break;
case ScheduleStatus::Inactive:
m_data.timeEnd() = changed.toMSecsSinceEpoch();
break;
default:
break;
}
Database::IsmMountingPointSchedule dbData;
dbData = toDbData(m_data);
if (!db()->update(dbData))
{
ERROR_LOG(m_logger) << "Error updating MainSchedule-data in database (ScheduleStatus) for id = " << m_data.id() << " : " << db()->getLastError().text();;
return false;
}
Database::IsmScheduleStatusChange stateChange;
stateChange.id = 0;
stateChange.scheduleId = m_data.id();
stateChange.changedAt = changed.currentMSecsSinceEpoch();
// record stateChange
if (!db()->insert(stateChange))
WARNING_LOG(m_logger) << "Recording change of ScheduleStatusChange failed: " << db()->getLastError().text();;
// Publish Data via DTS
//onPublishData();
return true;
}
// -------------------------------------------------------------------------------------------------------
// convert methods
// -------------------------------------------------------------------------------------------------------
// InfrastructureManagement::MainSchedule => Database::IsmMountingPointSchedule
//----------------------------------------------------------------------------------------------------
Database::IsmMountingPointSchedule ObjectMainSchedule::toDbData(const MainSchedule &ddsData)
{
Database::IsmMountingPointSchedule dbData;
dbData.id = ddsData.id();
dbData.name = QString::fromStdString(ddsData.name());
dbData.timeCreated = QDateTime::fromMSecsSinceEpoch(ddsData.timeCreated());
dbData.statusId = ddsData.statusId();
if (ddsData.timeStart().is_set() && ddsData.timeStart().get() > 0)
dbData.timeStart = QDateTime::fromMSecsSinceEpoch(ddsData.timeStart().get());
else
dbData.timeStart = QDateTime();
if (ddsData.timeEnd().is_set() && ddsData.timeEnd().get() > 0)
dbData.timeEnd = QDateTime::fromMSecsSinceEpoch(ddsData.timeEnd().get());
else
dbData.timeEnd = QDateTime();
if (ddsData.exerciseId().is_set() && ddsData.exerciseId().get() > 0)
dbData.exerciseId = ddsData.exerciseId().get();
return dbData;
}
// InfrastructureManagement::MountingPointPlan => Database::IsmMountingPointPlan
Database::IsmMountingPointPlan ObjectMainSchedule::toDbData(int scheduleId, const MountingPointPlan &ddsData)
{
Database::IsmMountingPointPlan dbData;
dbData.structureElementId = ddsData.structureElementId();
dbData.mountingPointScheduleId = scheduleId;
dbData.mountingPointState= ddsData.mountingPointState();
return dbData;
}
// -------------------------------------------------------------------------------------------------------
// Database::IsmMountingPointSchedule => InfrastructureManagement::MainSchedule
//----------------------------------------------------------------------------------------------------
MainSchedule ObjectMainSchedule::toDdsData(const Database::IsmMountingPointSchedule &dbData)
{
MainSchedule ddsData;
ddsData.id(dbData.id);
ddsData.name(dbData.name.toStdString());
ddsData.statusId(dbData.statusId);
if (!dbData.timeStart.isNull() && dbData.timeStart.isValid() && dbData.timeStart.toMSecsSinceEpoch() > 0)
ddsData.timeStart(dbData.timeStart.toMSecsSinceEpoch());
if (!dbData.timeEnd.isNull() && dbData.timeEnd.isValid() && dbData.timeEnd.toMSecsSinceEpoch() > 0)
ddsData.timeEnd(dbData.timeEnd.toMSecsSinceEpoch());
ddsData.timeCreated(dbData.timeCreated.toMSecsSinceEpoch());
if (!dbData.exerciseId.isNull() && dbData.exerciseId.canConvert<int>())
ddsData.exerciseId(dbData.exerciseId.toInt());
// init data not in db
ddsData.isDeleted(false);
ddsData.isUsed(false);
return ddsData;
}
MountingPointPlan ObjectMainSchedule::toDdsData(const Database::IsmMountingPointPlan &dbData)
{
MountingPointPlan ddsData;
ddsData.mountingPointState(dbData.mountingPointState);
ddsData.structureElementId(dbData.structureElementId);
return ddsData;
}
// -------------------------------------------------------------------------------------------------------
@@ -0,0 +1,58 @@
/**
* @RDE_HEADER@
* ISM Object Mounting Point Schedule
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#pragma once
#include "base.h"
#include <DDS/Core/function_reply_object.h>
#include <InfrastructureManagement/ism_db.h>
//-------------------------------------------------------------------------------------------------------------
namespace InfrastructureManagement
{
class ObjectMainSchedule : public Base
{
public:
explicit ObjectMainSchedule(MainHandler *mainHandler);
~ObjectMainSchedule();
Core::FunctionReplyObject createObject(const MainSchedule &data);
Core::FunctionReplyObject updateObject(const MainSchedule &data);
Core::FunctionReplyObject removeObject();
Core::FunctionReplyObject copyObject(qint32 scheduleId);
qint32 getId() const { return m_data.id(); }
MainSchedule getData() const { return m_data; }
QString getName() const { return QString::fromStdString(m_data.name()); }
ScheduleStatus scheduleStatus() const { return m_data.statusId(); }
Core::FunctionReplyObject updateElements(const std::vector<MountingPointPlan> &newElements);
bool isValid() const;
bool isUsed() const;
Core::FunctionReplyObject setUsed(bool isUsed);
// convert methods
static Database::IsmMountingPointPlan toDbData(int scheduleId, const MountingPointPlan &ddsData); // dds -> db
static MountingPointPlan toDdsData(const Database::IsmMountingPointPlan &dbData); // db -> dds
static Database::IsmMountingPointSchedule toDbData(const MainSchedule &ddsData); // dds -> db
static MainSchedule toDdsData(const Database::IsmMountingPointSchedule &dbData); // db -> dds
bool loadMountingPointPlans();
private:
// Used by ScheduleStatusManager (only internal)
bool setScheduleStatus(const ScheduleStatus &status);
private:
MainSchedule m_data;
QHash<int, MountingPointPlan> m_mppMap;
};
}
@@ -0,0 +1,794 @@
/**
* @RDE_HEADER@
* ISM Object Main Structure Element
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#include "object_main_structure_element.h"
#include "handler_main_structure_element.h"
#include "object_structure_element.h"
#include "main_handler.h"
#include "handler_mounting_point_asset.h"
#include "convert_db_to_dds.h"
#include <ngldb/dbtransaction.h>
#include <LtsUtilsCore/dds_vector.h>
#include <LtsUtilsCore/json_object.h>
#include <LtsCoordTrans/lts_coord_trans.h>
#include <QJsonObject>
#include <QTimer>
namespace
{
inline bool isValidJsonObject(const std::string &json)
{
return LtsUtils::JsonObject::fromJson(json).isValid();
}
inline int parentFromPath(const std::vector<int32_t> &path)
{
if (path.size() < 2)
return -1;
return path.at(path.size() - 2);
}
} // anonymous namespace
using namespace InfrastructureManagement;
//----------------------------------------------------------------------------------------------------
ObjectMainStructureElement::ObjectMainStructureElement(MainHandler *mainHandler)
: Base(mainHandler, getLogger("ObjectMainStructureElement"))
{
}
//-------------------------------------------------------------------------------------------------------------
ObjectMainStructureElement::ObjectMainStructureElement(const Database::IsmMainStructureElement &dbData,
MainHandler *mainHandler)
: Base(mainHandler, getLogger("ObjectMainStructureElement"))
, m_data(Database::convert(dbData))
{
m_data.elements().reserve(100); // sadly dds::vector has neither squeeze() nor is using over-provisioning... :(
m_footprint.id(m_data.id());
}
//------------------------------------------------------------------------------------------------------------
ObjectMainStructureElement::~ObjectMainStructureElement()
{
qDeleteAll(m_objectStructureElements);
}
//------------------------------------------------------------------------------------------------------------
bool ObjectMainStructureElement::isValid() const
{
return m_data.id() > 0;
}
//------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMainStructureElement::updatePosition(const Core::GeoPosition &position)
{
MainStructureElement data(m_data);
data.geoPosition(position);
if (!db()->update(toDbData(data)))
return Core::FunctionReplyObject(data.id(), tr_lts("dds", "Error updating IsmMainStructureElement-data into database"));
m_data = data;
DEBUG_LOG(m_logger) << "Data changed for Id: " << m_data.id();
return Core::FunctionReplyObject(m_data.id());
}
//------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMainStructureElement::setBridgeStatus(const BridgeStatus &st)
{
MainStructureElement data(m_data);
QJsonObject jsonObj;
jsonObj[QStringLiteral("bridgeStatus")] = st.underlying();
QJsonDocument doc(jsonObj);
data.properties(doc.toJson().toStdString());
if (!db()->update(toDbData(data)))
return Core::FunctionReplyObject(data.id(), tr_lts("dds", "Error updating IsmMainStructureElement-properties into database"));
m_data = data;
DEBUG_LOG(m_logger) << "Properties changed for Id: " << m_data.id();
return Core::FunctionReplyObject(m_data.id());
}
/*!
* \brief ObjectMainStructureElement::deleteEGCUOverrides
* \param data
* \param oldExerciseId
* \param newExerciseId
* \param modifiedStructureElements
* \author Niklas Schmidt
* \details If a building with egcu's change/lose their exercise, the relay information in database will be deleted,
* so the buttons in ECGU Info dialog got there initial state
* \return
*/
std::vector<StructureElement> ObjectMainStructureElement::deleteEGCUOverrides(const MainStructureElement &data, int oldExerciseId, int newExerciseId, QSet<int> &modifiedStructureElements)
{
if(oldExerciseId == newExerciseId)
return data.elements();
std::vector<InfrastructureManagement::StructureElement> resElements;
for(auto element : data.elements())
{
if (element.mountingPointTypeId() == MountingPointType::EffectGenerationControlUnit)
{
QJsonObject structureEleProps = QJsonDocument::fromJson(QByteArray::fromStdString(element.properties())).object();
if(structureEleProps.contains(QStringLiteral("Overrides")))
{
QJsonObject overrides = structureEleProps.value(QStringLiteral("Overrides")).toObject();
if(overrides.contains(QStringLiteral("relays")))
{
QJsonArray relays = overrides.value(QStringLiteral("relays")).toArray();
if(relays.size() > 0)
{
QJsonObject relaysResult;
//QJsonArray resultList;
for(int i = 0; i < relays.size(); ++i)
{
//QJsonObject resultObj = relays[i].toObject();
//resultObj.insert(resultObj.keys().at(0), 0);
//resultList.append(resultObj);
}
//relaysResult[QStringLiteral("relays")] = resultList;
structureEleProps[QStringLiteral("Overrides")] = relaysResult;
element.properties(QString::fromUtf8(QJsonDocument(structureEleProps).toJson()).toStdString());
modifiedStructureElements.insert(element.id());
}
}
}
}
resElements.push_back(element);
}
return resElements;
}
//------------------------------------------------------------------------------------------------------------
void ObjectMainStructureElement::noticeNewProperties(bool remove)
{
if (!m_mainHandler->getHandlerMountingPointAsset().get())
{
QTimer::singleShot(3000, this, [this, remove]()
{
noticeNewProperties(remove);
});
return;
}
std::vector<int32_t> exercises;
if (!remove)
exercises = getAvailableInExercise();
for (const auto &ele : m_data.elements())
{
if (ele.structureElementTypeId() == StructureElementType::MountingPoint)
m_mainHandler->getHandlerMountingPointAsset()->setAvailableInExerciseForAssetOnMountingPoint(ele.id(), exercises);
}
}
//------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMainStructureElement::createObject(const MainStructureElementModifyRequest &request)
{
if (!isValidJsonObject(request.properties()))
return Core::FunctionReplyObject(0, tr_lts("dds", "MainStructureElement with invalid JSON properties"));
m_data = MainStructureElement();
m_footprint = MainFootprint();
m_data.name(request.name());
m_data.description(request.description());
m_data.geoPosition(request.geoPosition());
m_data.angle(request.angle());
m_data.modelId(request.modelId());
m_data.externalWlsId(request.externalWlsId());
m_data.groupId(request.groupId());
m_data.elements(request.elements());
m_data.properties(request.properties());
m_data.structureElementTypeId(request.structureElementTypeId());
DBTransaction trans(db()->database());
m_data.isUsed(false);
// Insert MainStructure Element
Database::IsmMainStructureElement dbData(toDbData(m_data));
if (!db()->insert(dbData))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting IsmMainStructureElement-data into database"));
m_data.id(dbData.id);
// Insert Structure Elements
QVector<ObjectStructureElement *> objSeVec;
objSeVec.reserve(m_data.elements().size());
auto fro = createStructureElements(m_data, objSeVec);
if (fro.error())
return fro;
ObjectStructureElement *objStructureElementBuilding = objSeVec.first();
// Insert Footprint Elements
m_footprint.id(m_data.id()); // = buildingId, important for remove etc.
m_footprint.structureElementId(objStructureElementBuilding->getId());
m_footprint.name(m_data.name()); // footprint name = building name
if (request.footprint().is_set())
{
const auto &fp = request.footprint().get();
for (size_t i = 0; i < fp.size(); ++i)
{
FootprintElement fpElem = fp.at(i);
const Core::RelativePosition &relPos = fpElem.relPosition();
Database::IsmStructureElementFootprint footprint;
footprint.indexNo = i;
footprint.relPosition = LtsUtils::QPoint3D(relPos.offsetX(), relPos.offsetY(), relPos.offsetZ());
footprint.structureElementId = objStructureElementBuilding->getId();
if (!db()->insert(footprint))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting IsmStructureElementFootprint-data into database"));
fpElem.id(footprint.id);
m_footprint.elements().resize(m_footprint.elements().size()+1, fpElem);
}
}
DEBUG_LOG(m_logger) << "m_footprint.elements().size() = " << m_footprint.elements().size();
if (!db()->update(toDbData(m_data)))
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "Error updating IsmMainStructureElement-data into database"));
fro = updatePaths(m_data, objSeVec, request.childParentRelations());
if (fro.error())
return fro;
DEBUG_LOG(m_logger) << "New Id: " << m_data.id();
trans.commit();
if (m_data.properties().size())
noticeNewProperties();
m_mainHandler->getHandlerMainStructureElement()->addedStructureElements(m_objectStructureElements);
return Core::FunctionReplyObject(m_data.id());
}
//------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMainStructureElement::updateObject(const MainStructureElementModifyRequest &request)
{
if (!isValidJsonObject(request.properties()))
return Core::FunctionReplyObject(0, tr_lts("dds", "MainStructureElement with invalid JSON properties"));
if (!isValid())
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Object not valid/blocked"));
bool hasNewProps = m_data.properties() != request.properties();
MainStructureElement data(m_data);
QJsonObject objRequest = QJsonDocument::fromJson(QByteArray::fromStdString(request.properties())).object();
QJsonObject objCurrent = QJsonDocument::fromJson(QByteArray::fromStdString(data.properties())).object();
int newExerciseId = objRequest.value(QStringLiteral("available_in_exercise")).toArray().at(0).toInt();
int currentExerciseId = objCurrent.value(QStringLiteral("available_in_exercise")).toArray().at(0).toInt();
data.name(request.name());
data.description(request.description());
data.geoPosition(request.geoPosition());
data.angle(request.angle());
data.modelId(request.modelId());
data.externalWlsId(request.externalWlsId());
data.groupId(request.groupId());
data.properties(request.properties());
data.structureElementId(request.structureElementId());
data.structureElementTypeId(request.structureElementTypeId());
// when we want to allow insert / update / remove for SE:
// data.elements(request.elements());
QSet<int> modifiedStructureElements;
bool bStructureElementCountChanged = false;
std::vector<int> childParentMapping;
const auto oldStructureElements = m_objectStructureElements;
if (request.elements().size() != 0)
{
if (request.elements().size() != data.elements().size())
{
bStructureElementCountChanged = true;
QHash<int, size_t> parentId2Index;
childParentMapping.resize(request.elements().size());
data.elements(request.elements());
for (size_t i = 0; i < request.elements().size(); ++i)
{
StructureElement &newElem = data.elements().at(i);
if (!isValidJsonObject(newElem.properties()))
return Core::FunctionReplyObject(0, tr_lts("dds", "StructureElement with invalid JSON properties"));
parentId2Index[newElem.id()] = i;
childParentMapping[i] = parentId2Index.value(parentFromPath(newElem.path()));
// Do *not* modify the those
if (!isStructureElementDeletable(newElem))
continue;
newElem.id(0);
}
}
else
{
for (size_t i = 0; i < request.elements().size(); ++i)
{
const StructureElement &newElem = request.elements().at(i);
if (!isValidJsonObject(newElem.properties()))
return Core::FunctionReplyObject(0, tr_lts("dds", "StructureElement with invalid JSON properties"));
StructureElement &oldElem = data.elements()[i];
if (oldElem.id() != newElem.id() && newElem.id() != 0)
return Core::FunctionReplyObject(data.id(), tr_lts("dds", "Adding / Removing Structure elements not (yet) supported"));
if (oldElem == newElem)
continue;
modifiedStructureElements += oldElem.id();
// currently we only support modifing these values:
oldElem.displayName(newElem.displayName());
oldElem.barcode(newElem.barcode());
oldElem.mountingPointId(newElem.mountingPointId());
oldElem.mountingPointTypeId(newElem.mountingPointTypeId());
oldElem.relPosition(newElem.relPosition());
oldElem.structureElementTypeId(newElem.structureElementTypeId());
oldElem.properties(newElem.properties());
DEBUG_LOG(m_logger) << "add " << oldElem.id() << " to modifiedStructureElements" << oldElem;
}
}
}
MainFootprint mfData(m_footprint);
bool bUpdateFootprintNeeded = false;
if (request.footprint().is_set())
{
const auto &fpReq = request.footprint().get();
bUpdateFootprintNeeded = fpReq.size() != mfData.elements().size();
if (!bUpdateFootprintNeeded)
{
for (size_t i = 0; i < fpReq.size(); ++i)
{
if (fpReq.at(i) != mfData.elements().at(i))
{
bUpdateFootprintNeeded = true;
break;
}
}
}
}
//The modifiedStructureElements need to be filled
data.elements(deleteEGCUOverrides(data, currentExerciseId, newExerciseId, modifiedStructureElements));
DBTransaction trans(db()->database());
if (bStructureElementCountChanged)
{
DEBUG_LOG(m_logger) << "Re-creating structure elements for " << data.id();
QVector<ObjectStructureElement *> objSeVec;
objSeVec.reserve(data.elements().size());
auto fro = createStructureElements(data, objSeVec);
if (fro.error())
return fro;
fro = updatePaths(data, objSeVec, childParentMapping);
if (fro.error())
return fro;
}
else
{
for (const auto &dataSe : data.elements())
{
if (!modifiedStructureElements.contains(dataSe.id()))
continue;
InfrastructureManagement::ObjectStructureElement *objSe = m_objectStructureElements.value(dataSe.id());
if (!objSe)
WARNING_LOG(m_logger) << "Internal Error: can not find structure element with id " << dataSe.id();
else
objSe->updateObject(dataSe);
}
}
if (!db()->update(toDbData(data)))
return Core::FunctionReplyObject(data.id(), tr_lts("dds", "Error updating IsmMainStructureElement-data into database"));
DEBUG_LOG(m_logger) << "bUpdateFootprintNeeded = " << bUpdateFootprintNeeded;
if (bUpdateFootprintNeeded)
{
// remove old footprint data
for (const FootprintElement &elem : m_footprint.elements())
db()->removeIsmStructureElementFootprint(elem.id());
// add new footprint data
Database::IsmStructureElementFootprint sef;
sef.structureElementId = getStructureElementId();
for (size_t i = 0; i < mfData.elements().size(); ++i)
{
FootprintElement &elem = mfData.elements()[i];
const Core::RelativePosition &relPos = elem.relPosition();
sef.indexNo = i;
sef.relPosition = LtsUtils::QPoint3D(relPos.offsetX(),
relPos.offsetY(),
relPos.offsetZ());
if (!db()->insert(sef))
return Core::FunctionReplyObject(data.id(), tr_lts("dds", "Error updating IsmStructureElementFootprint-data into database"));
elem.id(sef.id);
m_footprint.elements().resize(m_footprint.elements().size()+1, elem);
}
}
DEBUG_LOG(m_logger) << "mfData.elements().size() = " << mfData.elements().size();
trans.commit();
if (bStructureElementCountChanged)
{
m_mainHandler->getHandlerMainStructureElement()->removedStructureElements(oldStructureElements);
m_mainHandler->getHandlerMainStructureElement()->addedStructureElements(m_objectStructureElements);
QMap<int, ObjectStructureElement*> newObjectStructureElements;
for (ObjectStructureElement *ose : qAsConst(m_objectStructureElements))
{
// only delete the old ones
// and also not the one for the mse and bcu
if (!oldStructureElements.contains(ose->getId()) ||
!isStructureElementDeletable(ose->getData()))
{
newObjectStructureElements[ose->getId()] = ose;
continue;
}
ose->removeObject();
delete ose;
}
m_objectStructureElements = newObjectStructureElements;
}
m_data = data;
m_footprintNeedsUpdate = (m_footprint != mfData);
m_footprint = mfData;
DEBUG_LOG(m_logger) << "Data changed for Id: " << m_data.id();
if (hasNewProps)
noticeNewProperties();
return Core::FunctionReplyObject(m_data.id());
}
//------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMainStructureElement::removeObject()
{
/* done in Handler MSE
for (auto dataSe : m_data.elements())
{
if (!db()->removeIsmStructureElement(dataSe.id()))
return Core::FunctionReplyObject(dataSe.id(), tr_lts("dds", "StructureElement %1 can not be removed from DB")).arg(dataSe.id());
}
*/
if (!db()->removeIsmMainStructureElement(m_data.id()))
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "MainStructureElement with id %1 can not be removed from DB")).arg(m_data.id());
dts()->removeMainStructureElementByKey(m_data.id());
dts()->removeMainFootprintByKey(m_footprint.id());
for (ObjectStructureElement *ose : qAsConst(m_objectStructureElements))
{
ose->removeObject();
delete ose;
}
m_objectStructureElements.clear();
m_data = MainStructureElement();
m_footprint = MainFootprint();
return Core::FunctionReplyObject(m_data.id());
}
//------------------------------------------------------------------------------------------------------------
void ObjectMainStructureElement::onPublishData()
{
INFO_LOG(m_logger) << "Publish IsmMainStructureElement-data to dds (" << m_data.id() << ") ...";
dts()->publish(m_data);
DEBUG_LOG(m_logger) << "m_footprint.elements().size() = " << m_footprint.elements().size();
if (m_footprint.elements().size() == 0)
{
if (m_footprint.id() != 0)
dts()->removeMainFootprintByKey(m_footprint.id());
}
else if (m_footprintNeedsUpdate)
dts()->publish(m_footprint);
m_footprintNeedsUpdate = false;
}
//------------------------------------------------------------------------------------------------------------
ObjectStructureElement *ObjectMainStructureElement::createStructureElementObject(const Database::IsmStructureElement &dbData)
{
ObjectStructureElement *ifs(new ObjectStructureElement(m_mainHandler, this));
Core::FunctionReplyObject ret = ifs->createObject(dbData);
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << ret();
return nullptr;
}
// top level types: Building, ApproachingPoint, Announcement, MeteoDataUnit, RadioStation, Bridge
if (isTopLevel(dbData.structureElementTypeId))
{
m_data.structureElementId(ifs->getId());
m_data.structureElementTypeId(dbData.structureElementTypeId);
if (dbData.structureElementTypeId == StructureElementType::Building)
{
m_footprintNeedsUpdate |= (m_footprint.structureElementId() != ifs->getId());
m_footprint.structureElementId(ifs->getId());
auto name = dbData.name.toStdString();
m_footprintNeedsUpdate |= (m_footprint.name() != name);
m_footprint.name(name);
}
}
ifs->updateGeoPosition();
int last = m_data.elements().size();
// ifs->getData() to retrieve the correct geo position
m_data.elements().resize(last + 1, ifs->getData());
m_objectStructureElements.insert(ifs->getId(), ifs);
return ifs;
}
//------------------------------------------------------------------------------------------------------------
const ObjectStructureElement *ObjectMainStructureElement::getMainStructureElementMountingPoint() const
{
// search for mounting point for building (direct below building)
for (const ObjectStructureElement *ose : m_objectStructureElements)
{
const auto &data = ose->getData();
if (data.structureElementTypeId() == InfrastructureManagement::StructureElementType::MountingPoint &&
data.mountingPointTypeId() == InfrastructureManagement::MountingPointType::BuildingControlUnit)
return ose;
}
return nullptr;
}
//------------------------------------------------------------------------------------------------------------
void ObjectMainStructureElement::setFootprintData(const std::vector<FootprintElement> &elements)
{
m_footprintNeedsUpdate |= (m_footprint.elements() != elements);
m_footprint.elements() = elements;
}
//------------------------------------------------------------------------------------------------------------
QJsonArray ObjectMainStructureElement::getAvailableInExerciseJsonArray() const
{
return LtsUtils::JsonObject::fromJson(m_data.properties()).object().value(QLatin1String("available_in_exercise")).toArray();
}
//------------------------------------------------------------------------------------------------------------
int ObjectMainStructureElement::getBridgeStatus() const
{
return LtsUtils::JsonObject::fromJson(m_data.properties()).object().value(QLatin1String("bridgeStatus")).toInt();
}
//------------------------------------------------------------------------------------------------------------
std::vector<int32_t> ObjectMainStructureElement::getAvailableInExercise() const
{
const QJsonArray jsonArray = getAvailableInExerciseJsonArray();
std::vector<int32_t> result;
result.reserve(jsonArray.size());
for (const auto &ele : jsonArray)
result.push_back(ele.toInt());
return result;
}
//------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMainStructureElement::createStructureElements(MainStructureElement &mse,
QVector<ObjectStructureElement *> &objSeVec)
{
if (mse.elements().size() == 0)
return Core::FunctionReplyObject(0, tr_lts("dds", "MainStructureElement without StructureElements"));
ObjectStructureElement *objStructureElementBuilding = nullptr;
int rootStructureElementId = -1;
const Core::GeoPosition &geoPositionBase = m_data.geoPosition();
const auto mseBaseCoord(LtsCoordTrans::UtmCoordinate::fromGeographic(geoPositionBase.lon(), geoPositionBase.lat()));
for (size_t i = 0; i < mse.elements().size(); ++i)
{
StructureElement &dataSe = mse.elements()[i];
if (!isValidJsonObject(dataSe.properties()))
return Core::FunctionReplyObject(0, tr_lts("dds", "StructureElement with invalid JSON properties"));
DEBUG_LOG(m_logger) << "#CreateStructureElement: " << dataSe.displayName();
Database::IsmStructureElement dbDataSe(InfrastructureManagement::ObjectStructureElement::toDbData(dataSe));
dbDataSe.mainStructureElementId = mse.id();
// id + 1 to make sure the path does not exist when we update the paths with the correct values
const int seDummyParentId = rootStructureElementId < 0 ? mse.id() : rootStructureElementId + 1;
dbDataSe.path = LtsUtils::IntArray(std::vector<int>({seDummyParentId, static_cast<int>(i)})); // dummy path for unique constraint
// DEBUG_LOG(m_logger) << "dbDataSe.path: " << mse.id() << ", " << i;
if (dataSe.id() == 0)
{
if (!db()->insert(dbDataSe))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting IsmStructureElement-data into database"));
}
else
{
if (!db()->update(dbDataSe))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting IsmStructureElement-data into database"));
}
// filled with the first inserted structure element (== building structure element)
if (rootStructureElementId < 0)
rootStructureElementId = dbDataSe.id;
ObjectStructureElement *objSe = nullptr;
if (dataSe.id() == 0)
objSe = m_objectStructureElements.value(dataSe.id());
if (!objSe)
objSe = new ObjectStructureElement(Database::convert(dbDataSe), m_mainHandler, this);
// first one is buildingSE per definition (checked outside)
if (objStructureElementBuilding == nullptr)
{
objStructureElementBuilding = objSe;
// make sure to be consistent (will be updated later when se.path is updated)
objStructureElementBuilding->getData().mountingPointTypeId(InfrastructureManagement::MountingPointType::Unknown);
}
// in two containers - need a sorted one for path updates
objSeVec += objSe;
m_objectStructureElements.insert(objSe->getId(), objSe);
// update GeoPos
objSe->updateGeoPosition(mseBaseCoord, geoPositionBase.z(), m_data.angle());
dataSe.geoPosition() = objSe->getGeoPosition();
}
if (!objStructureElementBuilding)
return Core::FunctionReplyObject(0, tr_lts("dds", "MainStructureElement without valid StructureElements"));
mse.structureElementId(objStructureElementBuilding->getId());
mse.structureElementTypeId(objStructureElementBuilding->getStructureElementTypeId());
DEBUG_LOG(m_logger) << "(Re)Created " << mse.elements().size() << " structure elements";
return Core::FunctionReplyObject();
}
//------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMainStructureElement::updatePaths(MainStructureElement &mse,
const QVector<ObjectStructureElement *> &objSeVec,
const std::vector<int> &childParentMapping)
{
// now update parent - child relations
const int buildingId = mse.id();
// update first element (building SE)
{
ObjectStructureElement *objSe = objSeVec.at(0);
StructureElement seData = objSe->getData();
seData.path().clear();
seData.path().resize(1, seData.id());
seData.mainStructureElementId(buildingId);
objSe->updateObject(seData);
DEBUG_LOG(m_logger) << "UpdatePaths Building = " << seData.displayName();
// update mse.elements
mse.elements()[0] = objSe->getData();
}
for (int i = 1; i < objSeVec.size(); ++i)
{
const int parentIdx = childParentMapping.at(i);
ObjectStructureElement *objSe = objSeVec.at(i);
// sanity check
if (parentIdx < 0 || parentIdx >= i)
return Core::FunctionReplyObject(objSe->getId(), tr_lts("dds", "Error updating path information for structure element"));
DEBUG_LOG(m_logger) << "UpdatePath for element " << objSe->getName();
// create our path
std::vector<int> path = objSeVec.at(parentIdx)->getPath();
QString p;
for (int ii : path)
p += QString::number(ii) + QStringLiteral(",");
DEBUG_LOG(m_logger) << "## Parent path = " << p ;
path.resize(path.size() + 1, objSe->getId());
p += QString::number(objSe->getId());
// update db
StructureElement seData = objSe->getData();
DEBUG_LOG(m_logger) << "Updated path for element: " << seData.displayName() << ", path = " << p;
seData.path(path);
seData.mainStructureElementId(buildingId);
const Core::FunctionReplyObject fro = objSe->updateObject(seData);
if (fro.error())
return fro;
// update mse.elements
mse.elements()[i] = objSe->getData();
}
DEBUG_LOG(m_logger) << "Updated paths for " << objSeVec.size() << " structure elements";
return Core::FunctionReplyObject();
}
//------------------------------------------------------------------------------------------------------------
bool ObjectMainStructureElement::isStructureElementDeletable(const StructureElement &se)
{
if (se.structureElementTypeId() == InfrastructureManagement::StructureElementType::Building)
return false;
if (se.structureElementTypeId() == InfrastructureManagement::StructureElementType::MountingPoint &&
se.mountingPointTypeId() == InfrastructureManagement::MountingPointType::BuildingControlUnit)
return false;
return true;
}
// -------------------------------------------------------------------------------------------------------
// convert methods
// -------------------------------------------------------------------------------------------------------
// InfrastructureManagement::MainStructureElement => Database::IsmMainStructureElement
Database::IsmMainStructureElement ObjectMainStructureElement::toDbData(const MainStructureElement &ddsData)
{
Database::IsmMainStructureElement dbData;
dbData.id = ddsData.id();
dbData.name = QString::fromStdString(ddsData.name());
dbData.description = QString::fromStdString(ddsData.description());
dbData.geoPosition = LtsUtils::QPoint3D(ddsData.geoPosition().lon(), ddsData.geoPosition().lat(), ddsData.geoPosition().z());
dbData.angle = ddsData.angle();
dbData.modelId = ddsData.modelId();
dbData.externalWlsId = ddsData.externalWlsId();
dbData.groupId = ddsData.groupId();
dbData.properties = QString::fromStdString(ddsData.properties());
return dbData;
}
//------------------------------------------------------------------------------------------------------------
bool ObjectMainStructureElement::isTopLevel(InfrastructureManagement::StructureElementType structureElementTypeId)
{
if (structureElementTypeId == StructureElementType::Building ||
structureElementTypeId == StructureElementType::ApproachingPoint ||
structureElementTypeId == StructureElementType::Announcement ||
structureElementTypeId == StructureElementType::MeteoDataUnit ||
structureElementTypeId == StructureElementType::RadioStation ||
structureElementTypeId == StructureElementType::Bridge)
return true;
return false;
}
@@ -0,0 +1,78 @@
/**
* @RDE_HEADER@
* ISM Object Main Structure Element
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#pragma once
#include <QMap>
#include <QJsonArray>
#include "base.h"
#include <DDS/Core/function_reply_object.h>
#include <InfrastructureManagement/ism_db.h>
//-------------------------------------------------------------------------------------------------------------
namespace InfrastructureManagement
{
class MainHandler;
class ObjectStructureElement;
class ObjectMainStructureElement : public Base
{
Q_OBJECT
public:
explicit ObjectMainStructureElement(MainHandler *mainHandler);
ObjectMainStructureElement(const Database::IsmMainStructureElement &dbData,
MainHandler *mainHandler);
~ObjectMainStructureElement();
Core::FunctionReplyObject createObject(const MainStructureElementModifyRequest &request);
Core::FunctionReplyObject updateObject(const MainStructureElementModifyRequest &request);
Core::FunctionReplyObject removeObject();
ObjectStructureElement *createStructureElementObject(const Database::IsmStructureElement &dbData);
qint32 getId() const { return m_data.id(); }
qint32 getStructureElementId() const { return m_data.structureElementId(); }
const ObjectStructureElement *getMainStructureElementMountingPoint() const;
QString getDescription() const { return QString::fromStdString(m_data.description()); }
QString getName() const { return QString::fromStdString(m_data.name()); }
std::vector<InfrastructureManagement::StructureElement> getElements() const { return m_data.elements(); }
QMap<int, ObjectStructureElement *> getStructureElements() const { return m_objectStructureElements; }
const MainStructureElement &getData() const { return m_data; }
const MainFootprint &getFootprint() const { return m_footprint; }
void setFootprintData(const std::vector<FootprintElement> &elements);
QJsonArray getAvailableInExerciseJsonArray() const;
int getBridgeStatus() const;
std::vector<int32_t> getAvailableInExercise() const;
bool isValid() const;
Core::FunctionReplyObject updatePosition(const Core::GeoPosition &position);
void noticeNewProperties(bool remove = false);
Core::FunctionReplyObject setBridgeStatus(const BridgeStatus &st);
std::vector<StructureElement> deleteEGCUOverrides(const MainStructureElement &data, int oldExerciseId, int newExerciseId, QSet<int> &modifiedStructureElements);
bool isTopLevel(StructureElementType structureElementTypeId);
// convert methods
static Database::IsmMainStructureElement toDbData(const MainStructureElement &ddsData); // dds -> db
void onPublishData();
private: // methods
Core::FunctionReplyObject createStructureElements(MainStructureElement &mse,
QVector<ObjectStructureElement *> &objSeVec);
Core::FunctionReplyObject updatePaths(MainStructureElement &mse,
const QVector<ObjectStructureElement *> &objSeVec,
const std::vector<int> &childParentMapping);
static bool isStructureElementDeletable(const StructureElement &se);
private: // attributes
MainStructureElement m_data;
MainFootprint m_footprint;
bool m_footprintNeedsUpdate = true;
QMap<int, ObjectStructureElement *> m_objectStructureElements; // must be sorted
};
}
@@ -0,0 +1,120 @@
/**
* @RDE_HEADER@
* ISM Object Mounting Point Asset
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#include "object_mounting_point_asset.h"
//-------------------------------------------------------------------------------------------------------------
namespace InfrastructureManagement
{
ObjectMountingPointAsset::ObjectMountingPointAsset(MainHandler *mainHandler)
: Base(mainHandler, getLogger("ObjectMountingPointAsset"))
{
}
ObjectMountingPointAsset::~ObjectMountingPointAsset()
{
}
//-----------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMountingPointAsset::createObject(const MountingPointAsset &data)
{
m_data = data;
if (m_data.id() <= 0)
{
Database::IsmMountingPointAsset dbData;
dbData = toDbData(data);
if (!db()->insert(dbData))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting IsmMountingPointAsset-data into database"));
m_data.id(dbData.id);
DEBUG_LOG(m_logger) << "New Id: " << m_data.id();
}
// Publish Data via DDS
onPublishData();
return Core::FunctionReplyObject(m_data.id());
}
//-------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMountingPointAsset::updateObject(const MountingPointAsset &data)
{
Database::IsmMountingPointAsset dbData = toDbData(data);
if (!db()->update(dbData))
return Core::FunctionReplyObject(data.id(), tr_lts("dds", "Error updating IsmMountingPointAsset-data into database"));
m_data = data;
DEBUG_LOG(m_logger) << "Data changed for Id: " << m_data.id();
// Publish Data via DTS
onPublishData();
return Core::FunctionReplyObject(m_data.id());
}
//-------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectMountingPointAsset::removeObject()
{
if (!db()->removeIsmMountingPointAsset(m_data.id()))
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "MountingPointAsset with id %1 can not be removed from DB")).arg(m_data.id());
if (!dts()->removeMountingPointAssetByKey(m_data.id()))
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "MountingPointAsset with id %1 can not be removed from DDS")).arg(m_data.id());
return Core::FunctionReplyObject(m_data.id());
}
//-------------------------------------------------------------------------------------------------------------
void ObjectMountingPointAsset::onPublishData()
{
INFO_LOG(m_logger) << "Publish IsmMountingPointAsset-data to dds (" << m_data.id() << ") ...";
if (!dts()->publish(m_data))
ERROR_LOG(m_logger) << "Error publishing IsmMountingPointAsset-data to dds";
}
// -------------------------------------------------------------------------------------------------------
// convert methods
// -------------------------------------------------------------------------------------------------------
// InfrastructureManagement::MountingPointAsset => Database::IsmMountingPointAsset
Database::IsmMountingPointAsset ObjectMountingPointAsset::toDbData(const MountingPointAsset &ddsData)
{
Database::IsmMountingPointAsset dbData;
dbData.id = ddsData.id();
dbData.assetId = ddsData.assetId();
dbData.structureElementId = ddsData.structureElementId();
dbData.name = QString::fromStdString(ddsData.name());
dbData.lastUpdated = QDateTime::fromMSecsSinceEpoch(ddsData.lastUpdated());
return dbData;
}
// -------------------------------------------------------------------------------------------------------
// Database::IsmMountingPointAsset => InfrastructureManagement::MountingPointAsset
MountingPointAsset ObjectMountingPointAsset::toDdsData(const Database::IsmMountingPointAsset &dbData)
{
MountingPointAsset ddsData;
ddsData.id(dbData.id);
ddsData.assetId(dbData.assetId);
ddsData.structureElementId(dbData.structureElementId);
ddsData.name(dbData.name.toStdString());
ddsData.lastUpdated(dbData.lastUpdated.toMSecsSinceEpoch());
return ddsData;
}
// -------------------------------------------------------------------------------------------------------
} // Namespace InfrastructureManagement
@@ -0,0 +1,57 @@
/**
* @RDE_HEADER@
* ISM Object Mounting Point Asset
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#pragma once
#include "base.h"
#include <DDS/Core/function_reply_object.h>
#include <InfrastructureManagement/ism_db.h>
//-------------------------------------------------------------------------------------------------------------
namespace InfrastructureManagement
{
class ObjectMountingPointAsset : public Base
{
public:
explicit ObjectMountingPointAsset(MainHandler *mainHandler);
~ObjectMountingPointAsset();
Core::FunctionReplyObject createObject(const MountingPointAsset &data);
Core::FunctionReplyObject updateObject(const MountingPointAsset &data);
Core::FunctionReplyObject removeObject();
qint32 getId() const
{
return m_data.id();
}
qint32 getStructureElementId() const
{
return m_data.structureElementId();
}
qint32 getAssetId() const
{
return m_data.assetId();
}
MountingPointAsset getData() const
{
return m_data;
}
// convert methods
static Database::IsmMountingPointAsset toDbData(const MountingPointAsset &ddsData); // dds -> db
static MountingPointAsset toDdsData(const Database::IsmMountingPointAsset &dbData); // db -> dds
protected:
void onPublishData();
private:
MountingPointAsset m_data;
};
}
@@ -0,0 +1,107 @@
/**
* @RDE_HEADER@
* ISM Object Sound Area
* $Id$
* $HeadURL$
* $Author$
* Created by Filip Biedziak, NLE, 2020-08-05
*/
#include "object_special_area.h"
#include <QJsonDocument>
#include <QPolygonF>
namespace InfrastructureManagement
{
ObjectSpecialArea::ObjectSpecialArea(MainHandler *mainHandler)
: Base(mainHandler, getLogger("ObjectSpecialArea"))
{
}
ObjectSpecialArea::~ObjectSpecialArea()
{
}
//-----------------------------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectSpecialArea::createObject(const SpecialArea &data)
{
m_data = data;
onPublishData(); // publish data via DDS
return Core::FunctionReplyObject(m_data.id());
}
Core::FunctionReplyObject ObjectSpecialArea::updateObject(const SpecialArea &data)
{
m_data = data;
DEBUG_LOG(m_logger) << "Data changed for Id: " << m_data.id();
onPublishData(); // publish data via DTS
return Core::FunctionReplyObject(m_data.id());
}
Core::FunctionReplyObject ObjectSpecialArea::removeObject()
{
if (!dts()->removeSpecialAreaByKey(m_data.id()))
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "SpecialArea with id %1 can not be removed from DDS")).arg(m_data.id());
return Core::FunctionReplyObject(m_data.id());
}
//-----------------------------------------------------------------------------------------------------------------------------
void ObjectSpecialArea::onPublishData()
{
INFO_LOG(m_logger) << "Publish IsmSpecialArea-data to dds (" << m_data.id() << ") ...";
if (!dts()->publish(m_data))
ERROR_LOG(m_logger) << "Error publishing IsmSpecialArea-data to dds";
}
// -------------------------------------------------------------------------------------------------------
// Database::IsmSpecialArea => InfrastructureManagement::SpecialArea
SpecialArea ObjectSpecialArea::toDdsData(const Database::IsmSpecialArea &dbData)
{
SpecialArea ddsData;
ddsData.id(dbData.id);
ddsData.name(dbData.name.toStdString());
ddsData.specialType(dbData.specialType.underlying());
const QJsonDocument doc(QJsonDocument::fromJson(dbData.polygon.toUtf8()));
const QJsonObject obj(doc.object());
const QJsonArray arrPoly = obj.value(QStringLiteral("polygon")).toArray();
ddsData.polygon().reserve(arrPoly.size());
for (const auto &ele : arrPoly)
{
const QJsonObject objSeg(ele.toObject());
Core::GeoPosition2D element;
element.lat(objSeg[QStringLiteral("lat")].toDouble());
element.lon(objSeg[QStringLiteral("lon")].toDouble());
ddsData.polygon().push_back(std::move(element));
}
//End elements
QPolygonF tmp;
tmp.reserve(ddsData.polygon().size());
for (const Core::GeoPosition2D &pos : qAsConst(ddsData.polygon()))
tmp.push_back(QPointF(pos.lon(),pos.lat()));
QRectF boundingBox = tmp.boundingRect();
ddsData.boundingBoxBottomLeft() = Core::GeoPosition2D(boundingBox.bottomLeft().x(), boundingBox.bottomLeft().y());
ddsData.boundingBoxTopRight() = Core::GeoPosition2D(boundingBox.topRight().x(), boundingBox.topRight().y());
// init data not in db
ddsData.isDeleted(false);
ddsData.isUsed(false);
return ddsData;
}
} // namespace InfrastructureManagement
@@ -0,0 +1,47 @@
/**
* @RDE_HEADER@
* ISM Object Special Area
* $Id$
* $HeadURL$
* $Author$
* Created by Filip Biedziak, NLE, 2020-08-05
*/
#pragma once
#include "base.h"
#include <DDS/Core/function_reply_object.h>
#include <InfrastructureManagement/ism_db.h>
#include <QtCore/QPointF>
#include <QString>
#include <LtsCoordTrans/lts_coord_trans.h>
namespace InfrastructureManagement
{
class ObjectSpecialArea : public Base
{
public:
explicit ObjectSpecialArea(MainHandler *mainHandler);
~ObjectSpecialArea();
Core::FunctionReplyObject createObject(const SpecialArea &data);
Core::FunctionReplyObject updateObject(const SpecialArea &data);
Core::FunctionReplyObject removeObject();
static SpecialArea toDdsData(const Database::IsmSpecialArea &dbData);
int32_t getId() const { return m_data.id(); }
SpecialArea getData() const { return m_data; }
protected:
void onPublishData();
private:
SpecialArea m_data;
};
} // namespace InfrastructureManagement
@@ -0,0 +1,166 @@
/**
* @RDE_HEADER@
* ISM Object Structure Element
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#include "main_handler.h"
#include "handler_main_structure_element.h"
#include "object_main_structure_element.h"
#include "object_structure_element.h"
#include "base.h"
#include "convert_db_to_dds.h"
#include <LtsCoordTrans/lts_coord_trans.h>
using namespace InfrastructureManagement;
// -------------------------------------------------------------------------------------------------------
ObjectStructureElement::ObjectStructureElement(MainHandler *mainHandler, ObjectMainStructureElement *objMse)
: Base(mainHandler, getLogger("ObjectStructureElement"))
, m_objMse(objMse)
{
m_data.mainStructureElementId(objMse->getId());
}
// -------------------------------------------------------------------------------------------------------
ObjectStructureElement::ObjectStructureElement(const StructureElement &data, MainHandler *mainHandler, ObjectMainStructureElement *objMse)
: Base(mainHandler, getLogger("ObjectStructureElement"))
, m_data(data)
, m_objMse(objMse)
{
m_data.mainStructureElementId(objMse->getId());
}
// -------------------------------------------------------------------------------------------------------
bool ObjectStructureElement::isValid() const
{
return m_data.id() > 0;
}
// -------------------------------------------------------------------------------------------------------
bool ObjectStructureElement::isUsed() const
{
return m_data.isUsed();
}
// -------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectStructureElement::createObject(const Database::IsmStructureElement &dbData)
{
m_data = Database::convert(dbData);
if (m_data.id() <= 0)
{
m_data.isUsed(false);
Database::IsmStructureElement dbData2(dbData);
if (!db()->insert(dbData2))
return Core::FunctionReplyObject(0, tr_lts("dds", "Error inserting IsmStructureElement-data into database"));
m_data.id(dbData2.id);
DEBUG_LOG(m_logger) << "New Id: " << m_data.id();
}
updateGeoPosition();
// Publish Data via DTS
//onPublishData();
return Core::FunctionReplyObject(m_data.id());
}
// -------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectStructureElement::updateObject(const StructureElement &data)
{
if (!isValid())
return Core::FunctionReplyObject(data.id(), tr_lts("dds", "Object not valid/blocked"));
if (!db()->update(toDbData(data)))
return Core::FunctionReplyObject(data.id(), tr_lts("dds", "Error updating StructureElement with id %1 in database")).arg(data.id());
m_data = data;
TRACE_LOG(m_logger) << "Data changed for Id: " << m_data.id();
updateGeoPosition();
// Publish Data via DTS
//onPublishData();
return Core::FunctionReplyObject(m_data.id());
}
// -------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectStructureElement::setUsed(bool isUsed)
{
if (!isValid())
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "Trying to update an already removed IsmStructureElement object"));
m_data.isUsed(isUsed);
// Publish Data via DTS
//onPublishData();
return Core::FunctionReplyObject(m_data.id());
}
// -------------------------------------------------------------------------------------------------------
Core::FunctionReplyObject ObjectStructureElement::removeObject()
{
if (isUsed())
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "StructureElement still in use"));
if (!db()->removeIsmStructureElement(m_data.id()))
return Core::FunctionReplyObject(m_data.id(), tr_lts("dds", "StructureElement with id %1 can not be removed from DB")).arg(m_data.id());
return Core::FunctionReplyObject(m_data.id());
}
// -------------------------------------------------------------------------------------------------------
void ObjectStructureElement::updateGeoPosition()
{
if (m_data.mainStructureElementId() <= 0)
return;
const Core::GeoPosition &geoPositionBase = m_objMse->getData().geoPosition();
const double angleDegree = m_objMse->getData().angle();
updateGeoPosition(LtsCoordTrans::UtmCoordinate::fromGeographic(geoPositionBase.lon(), geoPositionBase.lat()), geoPositionBase.z(), angleDegree);
}
// -------------------------------------------------------------------------------------------------------
void ObjectStructureElement::updateGeoPosition(const LtsCoordTrans::UtmCoordinate &basePoint, double zBase, double angleDeg)
{
const QPointF offset = rotatePoint(m_data.relPosition().offsetX(), m_data.relPosition().offsetY(), angleDeg);
const QPointF geoPos = basePoint.geographic(offset);
m_data.geoPosition() = Core::GeoPosition(geoPos.x(), geoPos.y(), m_data.relPosition().offsetZ() + zBase);
}
// -------------------------------------------------------------------------------------------------------
// convert methods
// -------------------------------------------------------------------------------------------------------
// InfrastructureManagement::StructureElement => Database::IsmStructureElement
Database::IsmStructureElement ObjectStructureElement::toDbData(const StructureElement &ddsData)
{
Database::IsmStructureElement dbData;
dbData.id = ddsData.id();
dbData.name = QString::fromStdString(ddsData.name());
dbData.displayName = QString::fromStdString(ddsData.displayName());
dbData.mainStructureElementId = ddsData.mainStructureElementId();
dbData.structureElementTypeId = ddsData.structureElementTypeId();
dbData.path = LtsUtils::IntArray(ddsData.path());
dbData.mountingPointId = ddsData.mountingPointId();
dbData.barcode = QString::fromStdString(ddsData.barcode());
dbData.relPosition = LtsUtils::QPoint3D(ddsData.relPosition());
dbData.mountingPointTypeId = ddsData.mountingPointTypeId();
dbData.orientation = LtsUtils::QPoint3D(ddsData.orientation().heave(),
ddsData.orientation().pitch(),
ddsData.orientation().roll());
dbData.properties = QString::fromStdString(ddsData.properties());
return dbData;
}
//-------------------------------------------------------------------------------------------------------------
@@ -0,0 +1,102 @@
/**
* @RDE_HEADER@
* ISM Object Structure Element
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#pragma once
#include "base.h"
#include <DDS/Core/function_reply_object.h>
#include <InfrastructureManagement/ism_db.h>
#include <InfrastructureManagement/object_main_structure_element.h>
namespace LtsCoordTrans
{
struct UtmCoordinate;
}
//-------------------------------------------------------------------------------------------------------------
namespace InfrastructureManagement
{
class MainHandler;
class ObjectMainStructureElement;
class ObjectStructureElement : public Base
{
public:
ObjectStructureElement(MainHandler *mainHandler, ObjectMainStructureElement *objMse);
ObjectStructureElement(const StructureElement &data, MainHandler *mainHandler, ObjectMainStructureElement *objMse);
Core::FunctionReplyObject createObject(const Database::IsmStructureElement &dbData);
Core::FunctionReplyObject updateObject(const StructureElement &data);
Core::FunctionReplyObject removeObject();
qint32 getId() const
{
return m_data.id();
}
const std::string &getName() const
{
return m_data.displayName();
}
std::vector<int32_t> getPath() const
{
return m_data.path();
}
qint32 getParentId() const
{
return m_data.path().size() > 0 ? m_data.path().at(m_data.path().size() - 1) : 0;
}
qint32 getMainStructureElementId() const
{
return m_data.mainStructureElementId();
}
InfrastructureManagement::StructureElementType getStructureElementTypeId() const
{
return m_data.structureElementTypeId();
}
InfrastructureManagement::MountingPointType getMountingPointType() const
{
return m_data.mountingPointTypeId();
}
InfrastructureManagement::StructureElement &getData()
{
return m_data;
}
const InfrastructureManagement::StructureElement &getData() const
{
return m_data;
}
const Core::RelativePosition &getRelativePosition() const
{
return m_data.relPosition();
}
const Core::GeoPosition &getGeoPosition() const
{
return m_data.geoPosition();
}
ObjectMainStructureElement *getMainStructureElement() const
{
return m_objMse;
}
bool isValid() const;
bool isUsed() const;
Core::FunctionReplyObject setUsed(bool isUsed);
// update geoPosition based on MainStructureElement
void updateGeoPosition();
void updateGeoPosition(const LtsCoordTrans::UtmCoordinate &basePoint, double zBase, double angleDeg);
// convert methods
static Database::IsmStructureElement toDbData(const StructureElement &ddsData); // dds -> db
private:
StructureElement m_data;
ObjectMainStructureElement *m_objMse;
};
}
@@ -0,0 +1,700 @@
/**
* @RDE_HEADER@
* Parse building xml file and create MainStructureElementCreateRequest for the data
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2017-02-02
*/
#include "parse_building_xml.h"
#include <QDomDocument>
#include <QFile>
#include <QPointF>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonDocument>
#include <LtsUtilsCore/dds_vector.h>
//-------------------------------------------------------------------------------------------------------------
namespace InfrastructureManagement
{
class XmlImportException : public std::exception
{
public:
explicit XmlImportException(const QString &msg) noexcept
: m_msg(msg.toUtf8().data())
{}
~XmlImportException() = default;
virtual const char *what() const noexcept
{
return m_msg.c_str();
}
private:
const std::string m_msg;
};
//-------------------------------------------------------------------------------------------------------------
template <typename T>
static inline T positionFromElement(const QDomElement &elem)
{
return T(elem.attribute(QStringLiteral("X")).toDouble(),
elem.attribute(QStringLiteral("Y")).toDouble(),
elem.attribute(QStringLiteral("Z")).toDouble());
}
//-------------------------------------------------------------------------------------------------------------
ParseBuildingXml::ParseBuildingXml(const QString &xmlFilename,
const QString &vulnerabilityFilename,
const QString &egcuToRoomFilename,
const QString &soundAreaFilename,
const Core::GeoPosition &geoPosition,
double rotationAngleDegree)
: m_xmlFilename(xmlFilename)
, m_vulnerabilityFilename(vulnerabilityFilename)
, m_egcuToRoomFilename(egcuToRoomFilename)
, m_soundAreaFilename(soundAreaFilename)
, m_geoPosition(geoPosition)
, m_rotationAngleDegree(rotationAngleDegree)
, m_logger(getLogger("ParseBuildingXml"))
{
DEBUG_LOG(m_logger) << "m_soundAreaFilename=" << m_soundAreaFilename;
}
QJsonObject ParseBuildingXml::egcusToJson() const
{
DEBUG_LOG(m_logger) << "egcusToJson";
if (m_egcus.isEmpty())
return QJsonObject();
QJsonObject egcusToRooms;
QJsonArray egcus;
QJsonArray rooms;
for (const auto &egcu : m_egcus)
{
rooms = {};
for (const int room : egcu.rooms)
rooms += room;
QJsonObject json;
json[QStringLiteral("mountpointEgcu")] = egcu.mountpointEgcu;
json[QStringLiteral("rooms")] = rooms;
egcus += json;
}
egcusToRooms[QStringLiteral("egcusToRooms")] = egcus;
return egcusToRooms;
}
QJsonObject ParseBuildingXml::soundAreaToJson() const
{
DEBUG_LOG(m_logger) << "soundAreaToJson";
QJsonObject soundArea;
QJsonObject json;
QJsonObject jsonEgcu;
QJsonArray arrayGeometry;
for (const auto &point : m_soundArea.geometry)
{
json[QStringLiteral("lat")] = point.lat();
json[QStringLiteral("lon")] = point.lon();
arrayGeometry.append(json);
}
QJsonArray arrayEgcus;
for (const auto &id : m_soundArea.egcuMountpoints)
{
jsonEgcu[QStringLiteral("id")] = id;
arrayEgcus.append(jsonEgcu);
}
soundArea[QStringLiteral("id")] = m_soundArea.id;
soundArea[QStringLiteral("geometry")] = arrayGeometry;
soundArea[QStringLiteral("mainEgcuMountpoint")] = m_soundArea.mainEgcuMountpoint;
soundArea[QStringLiteral("egcuMountpoints")] = arrayEgcus;
return soundArea;
}
//-------------------------------------------------------------------------------------------------------------
bool ParseBuildingXml::parseXml()
{
DEBUG_LOG(m_logger) << "parseXml";
m_request = MainStructureElementModifyRequest();
m_request.properties("{}");
m_lastError.clear();
bool bRet = true;
parseXmlInternal();
// try
// {
// parseXmlInternal();
// if (!m_vulnerabilityFilename.isEmpty())
// {
// QDomDocument doc = openXml(m_vulnerabilityFilename);
// if (!doc.isNull())
// {
// const QByteArray compressed = qCompress(doc.toByteArray(), 9);
// m_request.vulnerabilityData(LtsUtils::convert<std::vector<uint8_t>>(compressed));
// }
// }
// }
// catch (const std::exception &ex)
// {
// m_lastError = QString::fromUtf8(ex.what());
// WARNING_LOG(m_logger) << "Error importing building: " << ex.what();
// m_request = MainStructureElementModifyRequest();
// return false;
// }
QJsonObject properties;
parseXmlEgcus();
QJsonObject egcus = egcusToJson();
properties[QStringLiteral("egcusToRooms")] = egcus[QStringLiteral("egcusToRooms")];
DEBUG_LOG(m_logger) << "parseXml vor isEmpty";
if (!m_soundAreaFilename.isEmpty())
{
DEBUG_LOG(m_logger) << "parseXml vor parseXmlSoundArea";
parseXmlSoundArea();
properties[QStringLiteral("soundArea")] = soundAreaToJson();
}
m_request.properties(QJsonDocument(properties).toJson(QJsonDocument::Compact).toStdString());
DEBUG_LOG(m_logger) << "Finished import for file " << m_xmlFilename;
return bRet;
}
//-------------------------------------------------------------------------------------------------------------
ParseBuildingXml::Egcu ParseBuildingXml::parseEgcu(const QDomElement &domEgcu)
{
ParseBuildingXml::Egcu ret;
INFO_LOG(m_logger) << "parseEgcu Egcu: = " << domEgcu.tagName();
QDomElement mountpoint = domEgcu.firstChildElement(QStringLiteral("Mountpoint"));
INFO_LOG(m_logger) << "Mountpoint=" << mountpoint.tagName();
QDomElement mountpointSubId = mountpoint.firstChildElement(QStringLiteral("SubId"));
INFO_LOG(m_logger) << "Mountpoint=" << mountpointSubId.tagName()
<< " SubId = " << mountpointSubId.attribute(QStringLiteral("SubId"))
<< " text= " << mountpointSubId.text();
ret.mountpointEgcu = mountpointSubId.text().toInt();
QDomElement rooms = domEgcu.firstChildElement(QStringLiteral("Rooms"));
INFO_LOG(m_logger) << "Rooms=" << rooms.tagName()
<< " SubId = " << rooms.attribute(QStringLiteral("SubId"))
<< " text = " << rooms.text();
QDomElement room = rooms.firstChildElement(QStringLiteral("SubId"));
for (; !room.isNull(); room = room.nextSiblingElement(room.tagName()))
{
INFO_LOG(m_logger) << "Room=" << room.tagName()
<< " SubId = " << room.attribute(QStringLiteral("SubId"))
<< " text = " << room.text();
ret.rooms.append(room.text().toInt());
}
return ret;
}
bool ParseBuildingXml::parseXmlEgcus()
{
m_lastError.clear();
bool bRet = true;
try
{
//parseXmlInternal();
INFO_LOG(m_logger) << "parseXmlEgcus " << m_egcuToRoomFilename;
if (!m_egcuToRoomFilename.isEmpty())
{
INFO_LOG(m_logger) << "openXml";
QDomDocument doc = openXml(m_egcuToRoomFilename);
if (!doc.isNull())
{
// Evaluate xml file and modify properties in m_request
QDomElement root = doc.documentElement();
INFO_LOG(m_logger) << "root.tagName()=" << root.tagName();
if (root.tagName() != QStringLiteral("EgcusToRooms"))
{
WARNING_LOG(m_logger) << "The file is not EgcusToRooms";
return false;
}
QDomElement domEgcu = root.firstChildElement(QStringLiteral("Egcu"));
if (domEgcu.isNull())
INFO_LOG(m_logger) << "Keine EGCU's";
for (; !domEgcu.isNull(); domEgcu = domEgcu.nextSiblingElement(domEgcu.tagName()))
{
INFO_LOG(m_logger) << "parseEgcus=" << domEgcu.tagName()
<< " text=" << domEgcu.text()
<< " Name=" << domEgcu.attribute(QStringLiteral("Name"));
const Egcu egcu = parseEgcu(domEgcu);
m_egcus.append(egcu);
}
}
}
}
catch (const std::exception &ex)
{
m_lastError = QString::fromUtf8(ex.what());
WARNING_LOG(m_logger) << "Error importing building: wrong XML-File EgcuToRooms: " << ex.what();
bRet = false;
}
return bRet;
}
//-------------------------------------------------------------------------------------------------------------
bool ParseBuildingXml::parseXmlSoundArea()
{
Core::GeoPosition geoPosition;
m_lastError.clear();
bool bRet = true;
try
{
//parseXmlInternal();
INFO_LOG(m_logger) << "parseXmlSoundArea " << m_soundAreaFilename;
if (!m_soundAreaFilename.isEmpty())
{
INFO_LOG(m_logger) << "openXml";
QDomDocument doc = openXml(m_soundAreaFilename);
if (!doc.isNull())
{
// Evaluate xml file and modify properties in m_request
QDomElement root = doc.documentElement();
INFO_LOG(m_logger) << "root.tagName()=" << root.tagName();
if (root.tagName() != QStringLiteral("SoundArea"))
{
WARNING_LOG(m_logger) << "The file is not SoundArea";
return false;
}
INFO_LOG(m_logger) << "parseSoundArea SoundArea: = " << root.tagName();
// Id
m_soundArea.id = root.firstChildElement(QStringLiteral("Id")).text().toInt();
INFO_LOG(m_logger) << "Id=" << m_soundArea.id;
// Geometry
QDomElement geometry = root.firstChildElement(QStringLiteral("Geometry"));
QDomElement point = geometry.firstChildElement(QStringLiteral("Point"));
for (; !point.isNull(); point = point.nextSiblingElement(point.tagName()))
{
INFO_LOG(m_logger) << "Point=" << point.tagName()
<< " lat = " << point.firstChildElement(QStringLiteral("lat")).text().toDouble()
<< " lon = " << point.firstChildElement(QStringLiteral("lon")).text().toDouble();
geoPosition.lat(point.firstChildElement(QStringLiteral("lat")).text().toDouble());
geoPosition.lon(point.firstChildElement(QStringLiteral("lon")).text().toDouble());
m_soundArea.geometry.push_back(geoPosition);
}
// MainEgcuMountpoint
m_soundArea.mainEgcuMountpoint = root.firstChildElement(QStringLiteral("MainEgcuMountpoint")).text().toInt();
DEBUG_LOG(m_logger) << "MainEgcuMountpoint Id=" << m_soundArea.mainEgcuMountpoint;
// MountpointsEgcu
QDomElement egcuMountpoints = root.firstChildElement(QStringLiteral("EgcuMountpoints"));
QDomElement id = egcuMountpoints.firstChildElement(QStringLiteral("Id"));
for (; !id.isNull(); id = id.nextSiblingElement(id.tagName()))
{
int mountpointEgcu = id.text().toInt();
DEBUG_LOG(m_logger) << "mountpointEgcu=" << mountpointEgcu;
m_soundArea.egcuMountpoints.push_back(mountpointEgcu);
}
}
}
}
catch (const std::exception &ex)
{
m_lastError = QString::fromUtf8(ex.what());
WARNING_LOG(m_logger) << "Error importing building: wrong XML-File EgcuToRooms: " << ex.what();
bRet = false;
}
return bRet;
}
//-------------------------------------------------------------------------------------------------------------
QDomDocument ParseBuildingXml::openXml(const QString &fileName) const
{
// check filename is empty
if (fileName.isEmpty())
throw XmlImportException(tr("Empty filename!"));
// check if metaFileName is a valid xml file
QFile f(fileName);
if (f.size() == 0)
return QDomDocument();
if (!f.open(QIODevice::ReadOnly))
throw XmlImportException(tr("Error opening file %1: %2").arg(fileName, f.errorString()));
// read Xml file
QDomDocument metaDoc;
int errLine = 0, errColumn = 0;
QString err;
if (!metaDoc.setContent(&f, &err, &errLine, &errColumn))
throw XmlImportException(tr("Error parsing file content: %1 at %2.%3").arg(err).arg(errLine).arg(errColumn));
// close metaFile
f.close();
return metaDoc;
}
//-------------------------------------------------------------------------------------------------------------
QVector<ParseBuildingXml::BuildingMetaInfo> ParseBuildingXml::parseMetaXml(const QString &metaXml) const
{
QVector<ParseBuildingXml::BuildingMetaInfo> ret;
const QDomDocument metaDoc = openXml(metaXml);
if (metaDoc.isNull())
return ret;
// parse metaDoc for building elements MetaData/Tag/Group/Feature+Orientation+Position+File
const QDomElement metaElem = getChildElement(metaDoc, QStringLiteral("MetaData"));
const QDomElement tagElem = getChildElement(metaElem, QStringLiteral("Tag"));
const QDomElement groupElem = getChildElement(tagElem, QStringLiteral("Group"));
QDomElement modelElem = getChildElement(groupElem, QStringLiteral("Model"));
for (; !modelElem.isNull(); modelElem = modelElem.nextSiblingElement(modelElem.tagName()))
{
const QDomElement orientationElem = getChildElement(modelElem, QStringLiteral("Orientation"));
const QDomElement posElem = getChildElement(modelElem, QStringLiteral("Position"));
const QDomElement streifElem = getChildElement(modelElem, QStringLiteral("STREIF"));
// read building file name, name, angle, position
ParseBuildingXml::BuildingMetaInfo info;
info.filename = streifElem.attribute(QLatin1String("Name"));
if (info.filename.isEmpty())
{
WARNING_LOG(m_logger) << "Empty filename (building)!";
continue;
}
info.rotationAngleDegree = orientationElem.attribute(QLatin1String("Angle")).toDouble(); // correct rotation?
INFO_LOG(m_logger) << "Found Building angle: " << info.rotationAngleDegree;
info.geoPosition = positionFromElement<Core::GeoPosition>(posElem);
INFO_LOG(m_logger) << "Found Building position: (" << info.geoPosition.lon() << ", ("
<< info.geoPosition.lat() << ", ("
<< info.geoPosition.z() << ")";
ret += info;
}
return ret;
}
//-------------------------------------------------------------------------------------------------------------
void ParseBuildingXml::parseXmlInternal()
{
const QDomDocument objDoc = openXml(m_xmlFilename);
if (objDoc.isNull())
throw XmlImportException(tr("xml file %1 is empty").arg(m_xmlFilename));
const QDomElement rootElem = objDoc.documentElement(); // STREIF
const QDomElement headerElem = getChildElement(rootElem, QStringLiteral("Header"));
const QDomElement baseGroupElem = getChildElement(headerElem, QStringLiteral("Group"));
DEBUG_LOG(m_logger) << "Start import for file " << m_xmlFilename;
m_request.angle(m_rotationAngleDegree);
m_request.geoPosition(m_geoPosition);
m_request.modelId(getInteger(getChildElement(baseGroupElem, QStringLiteral("ModelId")), QStringLiteral("Id")));
m_request.name(getChildElement(baseGroupElem, QStringLiteral("Name")).text().toStdString());
m_request.description(m_request.name());
INFO_LOG(m_logger) << "Importing building with name: " << m_request.name();
InfrastructureManagement::StructureElement seBuilding;
seBuilding.name(m_request.name());
seBuilding.displayName(m_request.name());
seBuilding.structureElementTypeId(InfrastructureManagement::StructureElementType::Building);
seBuilding.mountingPointTypeId(InfrastructureManagement::MountingPointType::Unknown);
seBuilding.properties("{}");
addElementToRequest(seBuilding, -1);
InfrastructureManagement::StructureElement seMPBuilding;
seMPBuilding.name(m_request.name());
seMPBuilding.displayName(m_request.name());
m_buildingName = QString::fromStdString(seBuilding.displayName());
seMPBuilding.structureElementTypeId(InfrastructureManagement::StructureElementType::MountingPoint);
seMPBuilding.mountingPointTypeId(InfrastructureManagement::MountingPointType::BuildingControlUnit);
seMPBuilding.properties("{}");
addElementToRequest(seMPBuilding, 0);
//SWPA 2/22 - GUEZE-1459 - IO 2022.11.10 - do not import GV for new Guez Buildings
#ifndef GUEZ_MODE
InfrastructureManagement::StructureElement seGVBuilding;
seGVBuilding.name(m_request.name()+std::string("_gv"));
seGVBuilding.displayName(m_request.name()+std::string("_gv"));
seGVBuilding.structureElementTypeId(InfrastructureManagement::StructureElementType::MountingPoint);
seGVBuilding.mountingPointTypeId(InfrastructureManagement::MountingPointType::BuildingNetworkSwitch);
seGVBuilding.properties("{}");
addElementToRequest(seGVBuilding, 0);
#endif
// all below building, not below building bcu mounting point
const int parentIdx = 0;
importFootprint(baseGroupElem);
importExternalReferences(baseGroupElem, parentIdx);
importFloors(baseGroupElem, parentIdx);
}
//-------------------------------------------------------------------------------------------------------------
void ParseBuildingXml::importFootprint(const QDomElement &parent)
{
QDomElement groupElem = parent.firstChildElement(QStringLiteral("Group"));
std::vector<InfrastructureManagement::FootprintElement> fp;
for (; !groupElem.isNull(); groupElem = groupElem.nextSiblingElement(groupElem.tagName()))
{
const QDomElement nameElement = getChildElement(groupElem, QStringLiteral("Name"), false);
if (!nameElement.text().startsWith(QLatin1String("FOOTPRINT"), Qt::CaseInsensitive))
continue;
const QDomElement polygonElem = getChildElement(groupElem, QStringLiteral("Polygon"), false);
if (polygonElem.isNull())
continue;
QDomElement vertexElem = polygonElem.firstChildElement(QStringLiteral("Vertex"));
for (; !vertexElem.isNull(); vertexElem = vertexElem.nextSiblingElement(vertexElem.tagName()))
{
// TODO: xml hat keine Reihenfolge! Man kann es anhand der Namen sortieren
const QDomElement coordElem = vertexElem.firstChildElement(QStringLiteral("Coord"));
if (coordElem.isNull())
continue;
FootprintElement fpElem;
fpElem.relPosition() = positionFromElement<Core::RelativePosition>(coordElem);
fp.resize(fp.size() + 1, fpElem);
}
break;
}
if (fp.size() > 0)
m_request.footprint(std::move(fp));
}
//-------------------------------------------------------------------------------------------------------------
void ParseBuildingXml::importExternalReferences(const QDomElement &parent,
int parentIdx)
{
QDomElement extRefElem = parent.firstChildElement(QStringLiteral("External_Reference"));
for (; !extRefElem.isNull(); extRefElem = extRefElem.nextSiblingElement(extRefElem.tagName()))
{
const StructureElement se = getStructureElement(extRefElem);
// we don't care about BCU Mounting positions inside xml file - we create our own
if (se.mountingPointTypeId() == MountingPointType::BuildingControlUnit)
{
INFO_LOG(m_logger) << "Ignoring xml-internal BuildingControl mounting point - not needed";
continue;
}
if (se.mountingPointTypeId() == MountingPointType::Unknown)
{
INFO_LOG(m_logger) << "Ignoring unknown mounting point type with subId " << se.mountingPointId();
continue;
}
INFO_LOG(m_logger) << "importExternalReferences: " << se.displayName() << ", parentIdx = " << parentIdx;
addElementToRequest(se, parentIdx);
}
}
//-------------------------------------------------------------------------------------------------------------
void ParseBuildingXml::importFloors(const QDomElement &parent,
int parentIdx)
{
QDomElement floorElem = parent.firstChildElement(QStringLiteral("Group"));
for (; !floorElem.isNull(); floorElem = floorElem.nextSiblingElement(floorElem.tagName()))
{
const QDomElement nameElement = getChildElement(floorElem, QStringLiteral("Name"), false);
if (!nameElement.text().startsWith(QLatin1String("floor_"), Qt::CaseInsensitive))
continue;
INFO_LOG(m_logger) << "importFloors: " << nameElement.text() << ", parentIdx = " << parentIdx;
StructureElement se;
se.name(nameElement.text().simplified().toStdString());
se.displayName(se.name());
se.structureElementTypeId(InfrastructureManagement::StructureElementType::Floor);
se.mountingPointTypeId(InfrastructureManagement::MountingPointType::Unknown);
se.properties("{}");
// read base height from xml comment
const QDomElement commentElement = getChildElement(floorElem, QStringLiteral("Comment"), false);
DEBUG_LOG(m_logger) << "Comment = " << commentElement.text();
const QStringList comm = commentElement.text().split(QLatin1Char('='));
double baseHeight = 0.00;
if (comm.at(0) == QStringLiteral("base_height"))
baseHeight = comm.at(1).toDouble();
DEBUG_LOG(m_logger) << "base_height = " << baseHeight;
se.relPosition().offsetZ(baseHeight);
addElementToRequest(se, parentIdx);
const int curIdx = m_request.elements().size() - 1;
importRooms(floorElem, curIdx);
}
}
//-------------------------------------------------------------------------------------------------------------
void ParseBuildingXml::importRooms(const QDomElement &parent,
int parentIdx)
{
QDomElement roomElem = parent.firstChildElement(QStringLiteral("Switch"));
for (; !roomElem.isNull(); roomElem = roomElem.nextSiblingElement(roomElem.tagName()))
{
const QDomElement nameElement = getChildElement(roomElem, QStringLiteral("Name"), false);
if (!nameElement.text().startsWith(QLatin1String("SW_room_"), Qt::CaseInsensitive))
continue;
const int subId = getInteger(getChildElement(roomElem, QStringLiteral("SubId")), QStringLiteral("ID"));
StructureElement se;
se.name(nameElement.text().simplified().toStdString());
QString roomName = QString::fromStdString(se.name());
// displayed room names are too long
roomName.replace(QStringLiteral("SW_room"), QStringLiteral("R"));
INFO_LOG(m_logger) << "importRooms: " << roomName << ", parentIdx = " << parentIdx;
se.displayName(roomName.toStdString());
se.mountingPointId(subId);
se.structureElementTypeId(InfrastructureManagement::StructureElementType::Room);
se.mountingPointTypeId(InfrastructureManagement::MountingPointType::Unknown);
se.properties("{}");
QDomElement subRoomElem = roomElem.firstChildElement(QStringLiteral("Group"));
if (!subRoomElem.isNull())
{
tryGetRoomBoundingBox(subRoomElem, se);
addElementToRequest(se, parentIdx);
const int curIdx = m_request.elements().size() - 1;
importExternalReferences(subRoomElem, curIdx);
DEBUG_LOG(m_logger) << "Room=" << se.name()
<< " Id=" << se.id()
<< " mountingPointId=" << se.mountingPointId();
}
else
{
addElementToRequest(se, parentIdx);
}
}
}
//-------------------------------------------------------------------------------------------------------------
void ParseBuildingXml::tryGetRoomBoundingBox(const QDomElement &subRoomElem, StructureElement &se)
{
const QDomElement min = getChildElement(subRoomElem, QStringLiteral("BBox_Min"));
const QDomElement max = getChildElement(subRoomElem, QStringLiteral("BBox_Max"));
if (min.isNull() || max.isNull())
return;
const auto minPos(positionFromElement<Core::RelativePosition>(min));
const auto maxPos(positionFromElement<Core::RelativePosition>(min));
se.relPosition(Core::RelativePosition((minPos.offsetX() + maxPos.offsetX()) / 2,
(minPos.offsetY() + maxPos.offsetY()) / 2,
(minPos.offsetZ() + maxPos.offsetZ()) / 2));
}
//-------------------------------------------------------------------------------------------------------------
void ParseBuildingXml::addElementToRequest(const StructureElement &se,
int parentIdx)
{
const size_t size = m_request.elements().size();
m_request.elements().resize(size + 1, se);
m_request.childParentRelations().resize(size + 1, parentIdx);
}
//-------------------------------------------------------------------------------------------------------------
InfrastructureManagement::MountingPointType ParseBuildingXml::mptFromSubId(int subId)
{
enum ExternalReference
{
NONE = 0,
REF_MOD = 11000,
ZEG = 12000,
CAMERA_OUT = 13000,
CAMERA_IN = 14000,
IPS_OUT = 15000,
IPS_IN = 16000,
Unknown1 = 17000,
ANNOUNCEMENT_Unit = 26000,
EGCU = 27000,
Unknown2 = 28000
};
if (subId > Unknown2)
return MountingPointType::Unknown;
if (subId > EGCU)
return MountingPointType::EffectGenerationControlUnit;
if (subId > ANNOUNCEMENT_Unit)
return MountingPointType::AnnouncementUnit;
if (subId > Unknown1)
return MountingPointType::Unknown;
if (subId > IPS_IN)
return MountingPointType::IndoorIPS;
if (subId > IPS_OUT)
return MountingPointType::OutdoorIPS;
if (subId > CAMERA_IN)
return MountingPointType::IndoorCamera;
if (subId > CAMERA_OUT)
return MountingPointType::OutdoorCamera;
if (subId > ZEG)
return MountingPointType::BuildingControlUnit;
if (subId > REF_MOD)
return MountingPointType::BuildingSensorModule;
return MountingPointType::Unknown;
}
//-------------------------------------------------------------------------------------------------------------
StructureElement ParseBuildingXml::getStructureElement(const QDomElement &element) const
{
const int subId = getInteger(getChildElement(element, QStringLiteral("SubId")), QStringLiteral("ID"));
StructureElement se;
se.relPosition(positionFromElement<Core::RelativePosition>(getChildElement(element, QStringLiteral("Coord"))));
se.orientation(positionFromElement<Core::Orientation>(getChildElement(element, QStringLiteral("Dir")))); // xyz=hpr?
se.mountingPointTypeId(mptFromSubId(subId));
se.structureElementTypeId(InfrastructureManagement::StructureElementType::MountingPoint);
se.name(element.firstChildElement(QStringLiteral("Name")).text().simplified().toStdString());
QString displayName = m_buildingName;
displayName.append(QLatin1String(" - "));
displayName.append(QString::fromStdString(se.name()));
se.displayName(displayName.toStdString());
se.mountingPointId(subId);
se.properties("{}");
return se;
}
//-------------------------------------------------------------------------------------------------------------
template <typename T>
QDomElement ParseBuildingXml::getChildElement(const T &parent, const QString &childTag, bool bThrow) const
{
const QDomElement ret = parent.firstChildElement(childTag);
if (ret.isNull() && bThrow)
throw XmlImportException(tr("Invalid XML Structure - no '%1' tag (line %2:%3)")
.arg(childTag).arg(parent.lineNumber()).arg(parent.columnNumber()));
return ret;
}
//-------------------------------------------------------------------------------------------------------------
int ParseBuildingXml::getInteger(const QDomElement &element, const QString &attribute) const
{
bool bOk = true;
const int ret = element.attribute(attribute).toInt(&bOk);
if (!bOk)
throw XmlImportException(tr("Can not find attribute %1 in xml element %2 (line %3:%4)")
.arg(attribute, element.tagName()).arg(element.lineNumber()).arg(element.columnNumber()));
return ret;
}
} // namespace InfrastructureManagement
+97
View File
@@ -0,0 +1,97 @@
/**
* @RDE_HEADER@
* Parse building xml file and create MainStructureElementCreateRequest for the data
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2017-02-02
*/
#pragma once
#include "ism_export.h"
#include <QObject>
#include <QVector>
#include <InfrastructureManagement/ism_dtc.h>
#include "logger.h"
class QDomElement;
class QDomDocument;
namespace InfrastructureManagement
{
class ISM_CLIENT_EXPORT ParseBuildingXml : public QObject
{
Q_OBJECT
public:
struct BuildingMetaInfo
{
QString filename;
Core::GeoPosition geoPosition;
double rotationAngleDegree = 0;
};
struct Egcu
{
int mountpointEgcu = 0;
QVector<int> rooms;
};
struct SoundArea
{
int id{-1};
std::vector <Core::GeoPosition> geometry ;
int mainEgcuMountpoint{-1};
std::vector <int> egcuMountpoints;
};
ParseBuildingXml(const QString &xmlFilename,
const QString &vulnerabilityFilename,
const QString &egcuToRoomFilename,
const QString &soundAreaFilename,
const Core::GeoPosition &geoPosition,
double rotationAngleDegree);
bool parseXml();
QString lastError() const { return m_lastError; }
QVector<BuildingMetaInfo> parseMetaXml(const QString &metaXml) const;
const MainStructureElementModifyRequest &parsedRequest() const { return m_request; }
private:
QDomDocument openXml(const QString &fileName) const;
void parseXmlInternal();
Egcu parseEgcu(const QDomElement &domEgcu);
bool parseXmlEgcus();
bool parseXmlSoundArea();
QJsonObject egcusToJson() const;
QJsonObject soundAreaToJson() const;
void importFootprint(const QDomElement &parent);
void importExternalReferences(const QDomElement &parent,
int parentIdx);
void importFloors(const QDomElement &parent,
int parentIdx);
void importRooms(const QDomElement &parent,
int parentIdx);
void tryGetRoomBoundingBox(const QDomElement &subRoomElem, StructureElement &se);
void addElementToRequest(const StructureElement &se,
int parentIdx);
static InfrastructureManagement::MountingPointType mptFromSubId(int subId);
StructureElement getStructureElement(const QDomElement &element) const;
template <typename T>
QDomElement getChildElement(const T &parent, const QString &childTag, bool bThrow = true) const;
int getInteger(const QDomElement &element, const QString &attribute) const;
private:
QString m_xmlFilename;
QString m_vulnerabilityFilename;
QString m_egcuToRoomFilename;
QString m_soundAreaFilename;
Core::GeoPosition m_geoPosition;
double m_rotationAngleDegree;
MainStructureElementModifyRequest m_request;
QString m_buildingName;
QString m_lastError;
QVector<Egcu> m_egcus;
SoundArea m_soundArea;
LOGGER_T m_logger;
};
} // namespace InfraStructureManagement
@@ -0,0 +1,83 @@
/**
* @RDE_HEADER@
* Base for ScheduleStatus
* $Id$
* $HeadURL$
* $Author$
*/
#include "schedule_status_base.h"
#include "logger.h"
//#include <time.h>
namespace InfrastructureManagement
{
//----------------------------------------
ScheduleStatusBase::ScheduleStatusBase(const QString &objectName, const ScheduleStatus &scheduleStatus, ObjectMainSchedule *objSchedule)
: QState()
, m_schedule(objSchedule)
, m_logger(getLogger(QLatin1String("State.") + objectName))
, m_scheduleStatus(scheduleStatus)
{
setObjectName(QLatin1String("State.") + objectName);
}
void ScheduleStatusBase::onEntry(QEvent *event)
{
QState::onEntry(event);
DEBUG_LOG(m_logger) << "Schedule " << scheduleId() << ": onEntry Base: write ScheduleStatus: " << m_scheduleStatus;
// write ScheduleStatus to db
m_schedule->setScheduleStatus(m_scheduleStatus);
}
//----------------------------------------
Unknown::Unknown(ObjectMainSchedule *objSchedule)
: ScheduleStatusBase(QLatin1String("Unknown"), ScheduleStatus::Unknown, objSchedule)
{}
//----------------------------------------
Creation::Creation(ObjectMainSchedule *objSchedule)
: ScheduleStatusBase(QLatin1String("Creation"), ScheduleStatus::Created, objSchedule)
{}
void Creation::onEntry(QEvent *event)
{
DEBUG_LOG(m_logger) << "Schedule " << scheduleId() << ": onEntry Creation ";
ScheduleStatusBase::onEntry(event);
}
//----------------------------------------
Preparation::Preparation(ObjectMainSchedule *objSchedule)
: ScheduleStatusBase(QLatin1String("Preparation"), ScheduleStatus::Prepared, objSchedule)
{}
//----------------------------------------
Activation::Activation(ObjectMainSchedule *objSchedule)
: ScheduleStatusBase(QLatin1String("Activation"), ScheduleStatus::Activated, objSchedule)
{}
void Activation::onEntry(QEvent *event)
{
DEBUG_LOG(m_logger) << "Schedule " << scheduleId() << ": onEntry Activation: write ScheduleStatus:Activated";
ScheduleStatusBase::onEntry(event);
}
//-----------------------------------------------------------------------------------------------------
Expiration::Expiration(ObjectMainSchedule *objSchedule)
: ScheduleStatusBase(QLatin1String("Expiration"), ScheduleStatus::Expired, objSchedule)
{}
void Expiration::onEntry(QEvent *event)
{
DEBUG_LOG(m_logger) << "Schedule " << scheduleId() << ": onEntry Expiration ";
ScheduleStatusBase::onEntry(event);
}
//-----------------------------------------------------------------------------------------------------
Removing::Removing(ObjectMainSchedule *objSchedule)
: ScheduleStatusBase(QLatin1String("Removing"), ScheduleStatus::Removed, objSchedule)
{}
} // namespace InfrastructureManagement
@@ -0,0 +1,88 @@
/**
* @RDE_HEADER@
* Base for ScheduleStatus
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <QState>
#include <InfrastructureManagement/ism_enums.hpp>
#include "object_main_schedule.h"
namespace InfrastructureManagement
{
class ScheduleStatusBase : public QState
{
Q_OBJECT
public:
InfrastructureManagement::ScheduleStatus scheduleStatus() const { return m_scheduleStatus; }
protected:
ScheduleStatusBase(const QString &objectName, const ScheduleStatus &scheduleStatus, ObjectMainSchedule* objSchedule);
void onEntry(QEvent *event);
int scheduleId() const { return m_schedule ? m_schedule->getId() : -1; }
protected:
ObjectMainSchedule *m_schedule;
NGL::INGLLogger &m_logger;
private:
const InfrastructureManagement::ScheduleStatus m_scheduleStatus;
};
class Unknown : public ScheduleStatusBase
{
Q_OBJECT
public:
explicit Unknown(ObjectMainSchedule *objSchedule);
};
class Creation : public ScheduleStatusBase
{
Q_OBJECT
public:
explicit Creation(ObjectMainSchedule *objSchedule);
protected:
void onEntry(QEvent *event);
};
class Preparation : public ScheduleStatusBase
{
Q_OBJECT
public:
explicit Preparation(ObjectMainSchedule *objSchedule);
};
class Activation : public ScheduleStatusBase
{
Q_OBJECT
public:
explicit Activation(ObjectMainSchedule *objSchedule);
protected:
void onEntry(QEvent *event);
};
class Expiration : public ScheduleStatusBase
{
Q_OBJECT
public:
explicit Expiration(ObjectMainSchedule *objSchedule);
protected:
void onEntry(QEvent *event);
};
class Removing : public ScheduleStatusBase
{
Q_OBJECT
public:
explicit Removing(ObjectMainSchedule *objSchedule);
};
} // namespace InfrastructureManagement
@@ -0,0 +1,97 @@
/**
* @RDE_HEADER@
* ScheduleStatusManager / Manages the state of an exercise
* $Id$
* $HeadURL$
* $Author$
*
* Created by Iuliana Ojog, SLTE
*/
#include "schedule_status_manager.h"
#include "object_main_schedule.h"
#include "logger.h"
namespace InfrastructureManagement
{
ScheduleStatusManager::ScheduleStatusManager(ObjectMainSchedule *objSchedule, QObject *parent)
: QObject(parent)
, m_ScheduleStatus(ScheduleStatus::Unknown)
, m_schedule(objSchedule)
, m_logger(getLogger("ScheduleStatusManager"))
{
m_stateSignals[ScheduleStatus::Unknown] = [&]() { emit stateUnknown(); };
m_stateSignals[ScheduleStatus::Created] = [&]() { emit stateCreated(); };
m_stateSignals[ScheduleStatus::Prepared] = [&]() { emit statePrepared(); };
m_stateSignals[ScheduleStatus::Activated] = [&]() { emit stateActivated(); };
m_stateSignals[ScheduleStatus::Expired] = [&]() { emit stateExpired(); };
m_stateSignals[ScheduleStatus::Removed] = [&]() { emit stateRemoved(); };
}
bool ScheduleStatusManager::triggerSwitchState(InfrastructureManagement::ScheduleStatus state)
{
INFO_LOG(m_logger) << "Schedule " << scheduleId() << ": Trying to switch to state " << toString(state);
std::function<void()> f = m_stateSignals.value(state);
if (f)
{
//DEBUG_LOG(m_logger) << "function: emit signal";
emit f();
}
return (f != nullptr);
}
bool ScheduleStatusManager::isValid(InfrastructureManagement::ScheduleStatus state) const
{
return m_stateSignals.contains(state);
}
void ScheduleStatusManager::setCurrent(InfrastructureManagement::ScheduleStatus state)
{
setStateInternal(state);
}
void ScheduleStatusManager::setInitial(InfrastructureManagement::ScheduleStatus state)
{
setStateInternal(state);
}
QString ScheduleStatusManager::toString(InfrastructureManagement::ScheduleStatus state)
{
switch (state.underlying())
{
case ScheduleStatus::Unknown:
return tr("UNKNOWN");
case ScheduleStatus::Created:
return tr("CREATED");
case ScheduleStatus::Prepared:
return tr("PREPARED");
case ScheduleStatus::Activated:
return tr("ACTIVATED");
case ScheduleStatus::Expired:
return tr("EXPIRED");
case ScheduleStatus::Removed:
return tr("REMOVED");
}
return tr("Unknown State: (%1)").arg(state.underlying());
}
void ScheduleStatusManager::setStateInternal(InfrastructureManagement::ScheduleStatus state)
{
INFO_LOG(m_logger) << "Schedule " << scheduleId() << ": In setStateInternal: new state " << toString(state);
if(m_ScheduleStatus == state)
return;
m_ScheduleStatus = state;
INFO_LOG(m_logger) << "Schedule " << scheduleId() << ": Changed schedule state to " << toString(state);
}
int ScheduleStatusManager::scheduleId() const
{
return m_schedule ? m_schedule->getId() : -1;
}
} // namespace InfrastructureManagement
@@ -0,0 +1,58 @@
/**
* @RDE_HEADER@
* ScheduleStatusManager / Manages the state of an exercise
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <QObject>
#include <QMap>
#include <InfrastructureManagement/ism_enums.hpp>
namespace NGL
{
class INGLLogger;
}
namespace InfrastructureManagement
{
class ObjectMainSchedule;
class ScheduleStatusManager : public QObject
{
Q_OBJECT
public:
explicit ScheduleStatusManager(ObjectMainSchedule* objSchedule, QObject *parent = nullptr);
bool triggerSwitchState(InfrastructureManagement::ScheduleStatus state);
bool isValid(InfrastructureManagement::ScheduleStatus state) const;
void setCurrent(InfrastructureManagement::ScheduleStatus state);
void setInitial(InfrastructureManagement::ScheduleStatus state);
static QString toString(InfrastructureManagement::ScheduleStatus state);
Q_SIGNALS:
void stateUnknown();
void stateCreated();
void statePrepared();
void stateActivated();
void stateExpired();
void stateRemoved();
void stateFalse();
private:
void setStateInternal(InfrastructureManagement::ScheduleStatus state);
int scheduleId() const;
QMap<InfrastructureManagement::ScheduleStatus, std::function<void()> > m_stateSignals;
InfrastructureManagement::ScheduleStatus m_ScheduleStatus;
ObjectMainSchedule *m_schedule;
NGL::INGLLogger &m_logger;
};
} // namespace InfrastructureManagement
@@ -0,0 +1,156 @@
/**
* @RDE_HEADER@
* State Machine handler for Exercise Control
* $Id$
* $HeadURL$
* $Author$
*/
#include "schedule_status_state_machine.h"
#include "schedule_status_manager.h"
#include "schedule_status_base.h"
#include "object_main_schedule.h"
#include "settings.h"
#include "logger.h"
namespace InfrastructureManagement
{
ScheduleStatusMachine::ScheduleStatusMachine(ObjectMainSchedule* objSchedule, QObject *parent)
: QObject(parent)
, m_stateManager(new ScheduleStatusManager(objSchedule, this))
, m_stateMachine(new QStateMachine(this))
, m_schedule(objSchedule)
, m_logger(getLogger("ScheduleStatusMachine"))
{
qRegisterMetaType<InfrastructureManagement::ScheduleStatus>("InfrastructureManagement::ScheduleStatus");
m_ScheduleStatuses.insert(ScheduleStatus::Unknown, new Unknown(m_schedule));
m_ScheduleStatuses.insert(ScheduleStatus::Created, new Creation(m_schedule));
m_ScheduleStatuses.insert(ScheduleStatus::Prepared, new Preparation(m_schedule));
m_ScheduleStatuses.insert(ScheduleStatus::Activated, new Activation(m_schedule));
m_ScheduleStatuses.insert(ScheduleStatus::Expired, new Expiration(m_schedule));
m_ScheduleStatuses.insert(ScheduleStatus::Removed, new Removing(m_schedule));
// Define transitions from one state to the other
// ----------------------------------------------------------------------------------------------------------
// ** Unknown
// => Created
m_ScheduleStatuses[ScheduleStatus::Unknown]->addTransition(m_stateManager, &ScheduleStatusManager::stateCreated,
m_ScheduleStatuses[ScheduleStatus::Created]);
// ** Created
// => Prepared
m_ScheduleStatuses[ScheduleStatus::Created]->addTransition(m_stateManager, &ScheduleStatusManager::statePrepared,
m_ScheduleStatuses[ScheduleStatus::Prepared]);
// ** Created
// => Removed
m_ScheduleStatuses[ScheduleStatus::Created]->addTransition(m_stateManager, &ScheduleStatusManager::stateRemoved,
m_ScheduleStatuses[ScheduleStatus::Removed]);
// ** Prepared
// => Created
m_ScheduleStatuses[ScheduleStatus::Prepared]->addTransition(m_stateManager, &ScheduleStatusManager::stateCreated,
m_ScheduleStatuses[ScheduleStatus::Created]);
// ** Prepared
// => Activated
m_ScheduleStatuses[ScheduleStatus::Prepared]->addTransition(m_stateManager, &ScheduleStatusManager::stateActivated,
m_ScheduleStatuses[ScheduleStatus::Activated]);
// ** Activated
// => Expired
m_ScheduleStatuses[ScheduleStatus::Activated]->addTransition(m_stateManager, &ScheduleStatusManager::stateExpired,
m_ScheduleStatuses[ScheduleStatus::Expired]);
// ** Activated
// => Prepared
m_ScheduleStatuses[ScheduleStatus::Activated]->addTransition(m_stateManager, &ScheduleStatusManager::statePrepared,
m_ScheduleStatuses[ScheduleStatus::Prepared]);
// ** Expired
// => Activated
m_ScheduleStatuses[ScheduleStatus::Expired]->addTransition(m_stateManager, &ScheduleStatusManager::stateActivated,
m_ScheduleStatuses[ScheduleStatus::Activated]);
// ** Expired
// => Removed
m_ScheduleStatuses[ScheduleStatus::Expired]->addTransition(m_stateManager, &ScheduleStatusManager::stateRemoved,
m_ScheduleStatuses[ScheduleStatus::Removed]);
// ----------------------------------------------------------------------------------------------------------
//States zur StateMachine hinzufügen
for (ScheduleStatusBase *state : qAsConst(m_ScheduleStatuses))
{
DEBUG_LOG(m_logger) << "Schedule " << scheduleId() << ": state: " << state->scheduleStatus();
m_stateMachine->addState(state);
connect(state, &ScheduleStatusBase::entered, this, &ScheduleStatusMachine::onEnteredState);
}
DEBUG_LOG(m_logger) << "Schedule " << scheduleId() << ": Constructor ScheduleStatusMachine: size m_ScheduleStatuses = " << m_ScheduleStatuses.size();
}
ScheduleStatusMachine::~ScheduleStatusMachine()
{
qDeleteAll(m_ScheduleStatuses);
delete m_stateManager;
delete m_stateMachine;
}
bool ScheduleStatusMachine::init()
{
if (m_stateMachine->isRunning())
return false;
DEBUG_LOG(m_logger) << "Schedule " << scheduleId() << ": Init ScheduleStatusMachine ";
// initialise current ScheduleStatus
ScheduleStatusBase *currentScheduleStatus = getStateFromId(m_schedule->scheduleStatus());
DEBUG_LOG(m_logger) << "Schedule " << scheduleId() << ": State = "
<< ScheduleStatusManager::toString(m_schedule->scheduleStatus());
m_stateMachine->setInitialState(currentScheduleStatus);
m_stateMachine->start();
m_stateManager->setInitial(m_schedule->scheduleStatus());
DEBUG_LOG(m_logger) << "Schedule " << scheduleId() << ": ==> Done Init ScheduleStatusMachine ";
return true;
}
InfrastructureManagement::ScheduleStatus ScheduleStatusMachine::getCurrentState()
{
return m_schedule->scheduleStatus();
}
bool ScheduleStatusMachine::switchToState(ScheduleStatus newScheduleStatus)
{
return m_stateManager->triggerSwitchState(newScheduleStatus);
}
void ScheduleStatusMachine::onEnteredState()
{
DEBUG_LOG(m_logger) << "Schedule " << scheduleId() << ": ScheduleStatusMachine - onEnteredState";
ScheduleStatusBase *s = qobject_cast<ScheduleStatusBase*>(sender());
if (!s)
return;
DEBUG_LOG(m_logger) << "Schedule " << scheduleId() << ": ScheduleStatusBase : " << s->scheduleStatus();
m_stateManager->setCurrent(s->scheduleStatus());
emit ScheduleStatusChanged(s->scheduleStatus());
}
//----------------------------------------
ScheduleStatusBase* ScheduleStatusMachine::getStateFromId(ScheduleStatus ScheduleStatus)
{
ScheduleStatusBase *s = m_ScheduleStatuses.value(ScheduleStatus);
if (!s)
s = m_ScheduleStatuses.value(ScheduleStatus::Unknown);
return s;
}
//----------------------------------------
int ScheduleStatusMachine::scheduleId() const
{
return m_schedule ? m_schedule->getId() : -1;
}
} // namespace InfrastructureManagement
@@ -0,0 +1,60 @@
/**
* @RDE_HEADER@
* State Machine handler for Exercise Object
* $Id$
* $HeadURL$
* $Author$
*
* Created by Iuliana Ojog, SLTE
*/
#pragma once
#include <QObject>
#include <QStateMachine>
#include <InfrastructureManagement/ism_enums.hpp>
namespace NGL
{
class INGLLogger;
}
namespace InfrastructureManagement
{
class ScheduleStatusManager;
class ScheduleStatusBase;
class ObjectMainSchedule;
class ScheduleStatusMachine : public QObject
{
Q_OBJECT
public:
explicit ScheduleStatusMachine(InfrastructureManagement::ObjectMainSchedule *objSchedule, QObject *parent = nullptr);
~ScheduleStatusMachine();
bool init();
bool switchToState(InfrastructureManagement::ScheduleStatus newScheduleStatus);
InfrastructureManagement::ScheduleStatus getCurrentState();
Q_SIGNALS:
void finished();
void ScheduleStatusChanged(InfrastructureManagement::ScheduleStatus ScheduleStatus);
public Q_SLOTS:
void onEnteredState();
private:
ScheduleStatusBase *getStateFromId(InfrastructureManagement::ScheduleStatus ScheduleStatus);
int scheduleId() const;
ScheduleStatusManager *m_stateManager;
QStateMachine *m_stateMachine;
QMap<InfrastructureManagement::ScheduleStatus, ScheduleStatusBase*> m_ScheduleStatuses;
ObjectMainSchedule *m_schedule;
NGL::INGLLogger &m_logger;
};
} // namespace InfrastructureManagement
+61
View File
@@ -0,0 +1,61 @@
/**
* @RDE_HEADER@
* Settings for InfrastructureManagement
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#include "settings.h"
#include <QSettings>
#include <QVariant>
#include <nglsettings/nglsettings_settings.h>
#include <ngltools/ngltools_filesystem.h>
namespace InfrastructureManagement
{
class NGLSettingsClass : public NGL::Settings
{
public:
NGLSettingsClass()
: NGL::Settings(s_iniFile.isEmpty() ? NGL::findProjectConfigFile() : s_iniFile)
{}
static void setIniFile(const QString &fn)
{
s_iniFile = fn;
}
static QString s_iniFile;
};
QString NGLSettingsClass::s_iniFile;
Q_GLOBAL_STATIC(NGLSettingsClass, s)
//-----------------------------------------------------------------------------
NGL::Settings *Settings::settings()
{
return s();
}
//-----------------------------------------------------------------------------
void Settings::setIniFile(const QString &ini)
{
NGLSettingsClass::setIniFile(ini);
}
bool Settings::distinguishBetweenIndoorAndOutdoorIPS()
{
return s()->settings()->value(QStringLiteral("IPS/distinguishBetweenIndoorAndOutdoorIPS"), false).toBool();
}
bool Settings::useCoherentSet()
{
return s()->settings()->value(QStringLiteral("CoherentSets/ISM"), false).toBool();
}
qint32 Settings::messageDelay()
{
return s()->settings()->value(QStringLiteral("ISM/MessageDelay"), 0).toInt();
}
} // namespace InfrastructureManagement
+32
View File
@@ -0,0 +1,32 @@
/**
* @RDE_HEADER@
* Settings for InfrastructureManagement
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, SLSE, 2016-11-26
*/
#pragma once
#include <QString>
namespace NGL
{
class Settings;
}
namespace InfrastructureManagement
{
namespace Settings
{
//!< The real NGL::Settings - object
NGL::Settings *settings();
void setIniFile(const QString &ini);
// if false, MountingPointType::IndoorIPS and MountingPointType::OutdoorIPS will be treated as the same type
// e.g. for GUEZ, default: false
bool distinguishBetweenIndoorAndOutdoorIPS();
bool useCoherentSet();
qint32 messageDelay();
}
} // namespace InfrastructureManagement