Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Services/WarehouseGuez/WsBiteInterface/bite_data_manager.cpp
T
berrux-dev c3eda18234 Migrates remaining services and plugins to generated rtiddsgen API
Converts accessor calls to plain member access across the residual service set.
2026-09-21 02:47:48 +02:00

295 lines
9.2 KiB
C++
Executable File

/**
* @RDE_HEADER@
* The DataManager class takes strucure element data from the HandlerStructureElement,
* offers an interface to get and set structure data
* $Id$
* $HeadURL$
* $Author$
* Created by Hannes Fritsche, SLSE, 2017-09-07
*/
#include "bite_data_manager.h"
#include "dds_handler.h"
#include "WsBiteInterface/Messages/message_transmitter.h"
#include <WarehouseGuez/WsBiteInterface/json_keys.h>
#include <LtsUtilsCore/outdated_position.h>
#include <nglsettings/nglsettings_connections.h>
#include <QtCore/QMap>
#include <QUuid>
#include <QJsonDocument>
namespace WarehouseGuez
{
namespace WsBiteInterface
{
using namespace JsonKeys;
DataManager::DataManager(std::shared_ptr<DdsHandler> ddsHandler)
: m_scmWebSocket(new QWebSocket)
, m_ddsHandler(ddsHandler)
, m_timer(new QTimer(this))
, m_logger(getLogger(QLatin1String("DataManager")))
{
QUrl scmUrl(QStringLiteral("ws://%1:%2").arg(NGL::Connections::hostName(NGL::Connections::eConnection::SCM_WEBSOCKET)).arg(NGL::Connections::port(NGL::Connections::eConnection::SCM_WEBSOCKET)));
connect(m_scmWebSocket, &QWebSocket::connected, this, &DataManager::onConnected);
connect(m_scmWebSocket, &QWebSocket::disconnected, this, &DataManager::closed);
m_scmWebSocket->open(scmUrl);
// DTC TrainingAreaBase
m_tabDtc = TrainingAreaBase::Interface::Dtc::create(m_ddsHandler->dds());
if (m_tabDtc == nullptr)
{
ERROR_LOG(m_logger) << "Could not create DTC TrainingAreaBase";
return;
}
#if 0
connectToTabWebSocket(8080, 42);
#endif
}
DataManager::~DataManager()
{
for ( TabData data : m_tabWebSocketMap.values())
delete data.websocket;
delete m_scmWebSocket;
}
void DataManager::onConnected()
{
DEBUG_LOG(m_logger) << "SCM websocket port connected";
connect(m_scmWebSocket, &QWebSocket::textMessageReceived, this, &DataManager::onTextMessageFromScm);
connect(m_timer, &QTimer::timeout, this, &DataManager::onTimerTimeout);
m_timer->setInterval(60000);
m_timer->start();
onTimerTimeout();
}
void DataManager::onTimerTimeout()
{
m_scmWebSocket->sendTextMessage(QStringLiteral("{\"type\":\"servicePortsInformationRequest\", \"uuid\": \"7777\"}"));
}
void DataManager::onTextMessageFromScm(const QString &message)
{
DEBUG_LOG(m_logger) << "onTextMessageFromScm from scm: " << message;
const QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8());
const QJsonArray exercises = doc.object().value(DATA()).toArray();
for (const QJsonValue &valEx : exercises)
{
const QJsonObject &exercise = valEx.toObject();
const int exerciseId = exercise.value(EXERCISE_ID()).toInt();
DEBUG_LOG(m_logger) << "textMessageFromScm from scm - exerciseId " << exerciseId;
const QJsonArray services = exercise.value(SERVICES()).toArray();
for (const QJsonValue &valSvc : services)
{
const QJsonObject &service = valSvc.toObject();
const QString svcName = service.value(NAME_ABBREVATION()).toString().toUpper();
DEBUG_LOG(m_logger) << "textMessageFromScm from scm - svcName " << svcName;
if (svcName != QStringLiteral("TAB"))
continue;
DEBUG_LOG(m_logger) << "service TAB ";
const QJsonArray ports = service.value(PORTS()).toArray();
for (const QJsonValue &valPort : ports)
{
const QJsonObject &port = valPort.toObject();
int typeId = port.value(TYPE_ID()).toInt();
if (typeId == static_cast<int>(Core::CorePortType::WebSocketServer))
{
int tabPort = port.value(NUMBER()).toInt();
DEBUG_LOG(m_logger) << "connect to TAB - port: " << tabPort;
connectToTabWebSocket(tabPort, exerciseId);
}
}
}
}
}
void DataManager::onConnectedTab()
{
DEBUG_LOG(m_logger) << "TAB connected";
}
void DataManager::connectToTabWebSocket(int port, int exerciseId)
{
if (m_tabWebSocketMap.contains(exerciseId))
{
TabData tabData = m_tabWebSocketMap.value(exerciseId);
// Websocket connection already exists?
if (tabData.port == port)
{
INFO_LOG(m_logger) << "Connection to port " << port << " already exists.";
return;
}
else
{
tabData.websocket->close();
delete tabData.websocket;
m_tabWebSocketMap.remove(exerciseId);
}
}
INFO_LOG(m_logger) << "New connection: exercise: " << exerciseId << ", port: " << port;
const QUrl url(QStringLiteral("ws://%1:%2").arg(NGL::Connections::hostName(NGL::Connections::eConnection::SCM_WEBSOCKET)).arg(port));
QWebSocket *webSocketTab = new QWebSocket;
connect(webSocketTab, &QWebSocket::connected, this, &DataManager::onConnectedTab);
connect(webSocketTab, &QWebSocket::disconnected, this, &DataManager::closedTab);
connect(webSocketTab, &QWebSocket::textMessageReceived, this, &DataManager::onTextMessageFromTab);
DEBUG_LOG(m_logger) << "Trying to connect to TAB at " << url.toString();
webSocketTab->open(url);
TabData data;
data.exerciseId = exerciseId;
data.port = port;
data.websocket = webSocketTab;
m_tabWebSocketMap.insert(exerciseId, data);
}
void DataManager::onClientDisconnect(Messages::MessageTransmitter *transmitter)
{
for (EquipData &ed : m_equipDataMap)
{
if (ed.transmitter == transmitter)
{
DEBUG_LOG(m_logger) << "removed dead transmitter";
ed.transmitter = nullptr;
}
}
}
void DataManager::onTextMessageFromTab(const QString &message)
{
INFO_LOG(m_logger) << "onTextMessageFromTab : " << message;
const QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8());
if (doc.object().value(TYPE()) != BITE_DATA() && doc.object().value(TYPE()) != POSITION_DATA())
return;
INFO_LOG(m_logger) << "TYPE: " << doc.object().value(TYPE()).toString();
QJsonObject data = doc.object().value(DATA()).toObject();
data.insert(LAST_UPDATE(), QDateTime::currentSecsSinceEpoch());
int equipNo = data.value(EQUIP_NO()).toInt();
INFO_LOG(m_logger) << "equipNo: " << equipNo;
if (equipNo <= 0)
return;
if (doc.object().value(TYPE()) == BITE_DATA())
m_equipDataMap[equipNo].biteMessage = data;
if (doc.object().value(TYPE()) == POSITION_DATA())
{
m_equipDataMap[equipNo].lastPositionUpdate = data.value(LAST_POSITION_UPDATE()).toDouble();
INFO_LOG(m_logger) << "lastPosUpdate: " << m_equipDataMap[equipNo].lastPositionUpdate;
}
if (m_equipDataMap[equipNo].boxId >= 0)
{
Messages::MessageTransmitter* transmitter = m_equipDataMap[equipNo].transmitter;
if (transmitter == nullptr)
{
ERROR_LOG(m_logger) << "transmitter for eqId " << equipNo << " no longer available";
return;
}
int &boxId = m_equipDataMap[equipNo].boxId;
QJsonObject &biteData = m_equipDataMap[equipNo].biteMessage;
biteData.insert(BOX(), boxId);
biteData.insert(LAST_POSITION_UPDATE(), m_equipDataMap[equipNo].lastPositionUpdate);
transmitter->addMessage(Messages::BiteDataMessage(biteData, m_equipDataMap[equipNo].uuid));
INFO_LOG(m_logger) << "Send Message with boxId: " << boxId << ", equipNo: " << equipNo;
if (boxId == 0)
boxId = -1; // only single request
}
}
void DataManager::setEquipNoBoxId(int equipNo, int boxId, Messages::MessageTransmitter *transmitter, const QString &uuid)
{
INFO_LOG(m_logger) << "equipNo: " << equipNo << ", boxId = " << boxId;
// erase abonnement, no further biteData telegrams
if (equipNo == 0)
{
for ( int key : m_equipDataMap.keys())
{
if (m_equipDataMap[key].boxId == boxId)
{
m_equipDataMap.remove(key);
break;
}
}
return;
}
auto &equipData = m_equipDataMap[equipNo];
// create new equipData if equipNo is not present yet
equipData.equipNo = equipNo;
equipData.boxId = boxId;
equipData.transmitter = transmitter;
equipData.uuid = uuid;
// find biteMessage and send biteData telegram if not older than 1h
if (!equipData.biteMessage.isEmpty())
{
QJsonObject &data = equipData.biteMessage;
qint64 lastUpdate = data.value(LAST_UPDATE()).toDouble();
if ( lastUpdate + 3600 > QDateTime::currentSecsSinceEpoch())
{
data.insert(BOX(), boxId);
data.insert(LAST_POSITION_UPDATE(), equipData.lastPositionUpdate);
transmitter->addMessage(Messages::BiteDataMessage(data, equipData.uuid));
INFO_LOG(m_logger) << "Send Message with boxId: " << boxId << ", equipNo: " << equipNo;
}
}
else
{
QJsonObject data;
data.insert(EQUIP_NO(), equipNo);
data.insert(BOX(), boxId);
data.insert(LAST_UPDATE(), 0);
data.insert(LAST_POSITION_UPDATE(), 0);
data.insert(IS_LICENSED(), false);
equipData.biteMessage = data;
transmitter->addMessage(Messages::BiteDataMessage(data, equipData.uuid));
INFO_LOG(m_logger) << "Send Message with boxId: " << boxId << ", equipNo: " << equipNo << ", lastUpdate 0";
// send bite request
QJsonObject biteData;
biteData.insert(DATA(), data);
biteData.insert(TYPE(), SEND_BITE_REQUEST());
biteData.insert(UUID_(), QUuid::createUuid().toString());
QString message = QString::fromStdString(QJsonDocument(biteData).toJson(QJsonDocument::Compact).toStdString());
INFO_LOG(m_logger) << "message: " << message;
for (TabData dataTab : m_tabWebSocketMap)
dataTab.websocket->sendTextMessage(message);
}
}
} // namespace WsBiteInterface
} // namespace WarehouseGuez