Converts accessor calls to plain member access across the residual service set.
295 lines
9.2 KiB
C++
Executable File
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
|