Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
@@ -0,0 +1,54 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
|
||||
SET(bsm_SRCS
|
||||
bsm_api.cpp
|
||||
bsm_api.h
|
||||
bsm_socket.cpp
|
||||
bsm_socket.h
|
||||
bsm_socket_handler.cpp
|
||||
bsm_socket_handler.h
|
||||
bsm_telegrams_alive.h
|
||||
bsm_telegrams_base.cpp
|
||||
bsm_telegrams_base.h
|
||||
bsm_telegrams_bit_timeout_report.cpp
|
||||
bsm_telegrams_bit_timeout_report.h
|
||||
bsm_telegrams_bit_timeout_request.h
|
||||
bsm_telegrams_chopped_signal_flash.cpp
|
||||
bsm_telegrams_chopped_signal_flash.h
|
||||
bsm_telegrams_configuration_report.cpp
|
||||
bsm_telegrams_configuration_report.h
|
||||
bsm_telegrams_configuration_request.h
|
||||
bsm_telegrams_configuration_setup.cpp
|
||||
bsm_telegrams_configuration_setup.h
|
||||
bsm_telegrams_direct_fire.cpp
|
||||
bsm_telegrams_direct_fire.h
|
||||
bsm_telegrams_observer_controller.cpp
|
||||
bsm_telegrams_observer_controller.h
|
||||
bsm_telegrams_sw_version_report.cpp
|
||||
bsm_telegrams_sw_version_report.h
|
||||
bsm_telegrams_sw_version_request.h
|
||||
bsm_telegrams_technical_status.cpp
|
||||
bsm_telegrams_technical_status.h
|
||||
bsm_telegrams_technical_status_request.h
|
||||
bsm_types.h
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY2(AAR SV BuildingControlBsm SHARED ${bsm_SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(BuildingControlBsm
|
||||
PRIVATE
|
||||
NGLLogger
|
||||
PUBLIC
|
||||
Qt5::Core
|
||||
Qt5::Network
|
||||
BuildingControlCommon
|
||||
)
|
||||
|
||||
NGL_ADD_EXECUTABLE(AAR SV BuildingControlTestBsm bsm_test_main.cpp)
|
||||
NGL_TARGET_LINK_LIBRARIES(BuildingControlTestBsm
|
||||
BuildingControlBsm
|
||||
nglcoreapplication
|
||||
)
|
||||
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Api for BSM access
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2017-01-26
|
||||
*/
|
||||
|
||||
#include "bsm_api.h"
|
||||
#include "bsm_socket_handler.h"
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
Api::Api(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_socketHandler(new SocketHandler(this))
|
||||
, m_logger(BuildingControlUnit::getLogger("BSM.Api"))
|
||||
{
|
||||
connect(m_socketHandler, &SocketHandler::opticalShot,
|
||||
this, &Api::opticalShot);
|
||||
connect(m_socketHandler, &SocketHandler::opticalShotOC,
|
||||
this, &Api::opticalShotOC);
|
||||
connect(m_socketHandler, &SocketHandler::bsmStateChanged,
|
||||
this, &Api::bsmStateChanged);
|
||||
}
|
||||
|
||||
Api::~Api()
|
||||
{
|
||||
delete m_socketHandler;
|
||||
}
|
||||
|
||||
bool Api::init(const BuildingBsmConfig &bsmConfig)
|
||||
{
|
||||
return m_socketHandler->init(bsmConfig);
|
||||
}
|
||||
|
||||
bool Api::triggerFlashlight(int bsmId, const QString &hostname, int numberOfFlashes, int pauseBetweenFlashesSec)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "triggerFlashlight bsmId=" << bsmId
|
||||
<< " hostname=" << hostname
|
||||
<< " numberOfFlashes=" << numberOfFlashes
|
||||
<< " pauseBetweenFlashesSec=" << pauseBetweenFlashesSec;
|
||||
return m_socketHandler->triggerFlashlight(bsmId, hostname, numberOfFlashes, pauseBetweenFlashesSec);
|
||||
}
|
||||
|
||||
bool Api::triggerFlashlightPulse(int bsmId, const QString &hostname,
|
||||
int numberOfFlashes,
|
||||
int pauseDuration,
|
||||
int choppedConfiguration,
|
||||
int flashDuration)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "triggerFlashlightPulse bsmId=" << bsmId
|
||||
<< " hostname=" << hostname
|
||||
<< " numberOfFlashes=" << numberOfFlashes
|
||||
<< " pauseDuration=" << pauseDuration
|
||||
<< " choppedConfiguration=" << choppedConfiguration
|
||||
<< " flashDuration=" << flashDuration;
|
||||
return m_socketHandler->triggerFlashlightPulse(bsmId, hostname, numberOfFlashes, pauseDuration, choppedConfiguration, flashDuration);
|
||||
}
|
||||
|
||||
bool Api::triggerFlashlights( int numberOfFlashes,
|
||||
int pauseDuration,
|
||||
int choppedConfiguration,
|
||||
int flashDuration)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "triggerFlashlights numberOfFlashes=" << numberOfFlashes
|
||||
<< " pauseDuration=" << pauseDuration
|
||||
<< " choppedConfiguration" << choppedConfiguration
|
||||
<< " flashDuration=" << flashDuration;
|
||||
return m_socketHandler->triggerFlashlights( numberOfFlashes, pauseDuration, choppedConfiguration, flashDuration);
|
||||
}
|
||||
|
||||
|
||||
QVector<BsmState> Api::bsmStates() const
|
||||
{
|
||||
return m_socketHandler->bsmStates();
|
||||
}
|
||||
|
||||
bool Api::getBsmConfiguration(int bsmId)
|
||||
{
|
||||
return m_socketHandler->getBsmConfiguration(bsmId);
|
||||
}
|
||||
|
||||
bool Api::getBsmBitTimeout(int bsmId)
|
||||
{
|
||||
return m_socketHandler->getBsmBitTimeout(bsmId);
|
||||
}
|
||||
|
||||
bool Api::getBsmTechnicalStatus(int bsmId)
|
||||
{
|
||||
return m_socketHandler->getBsmTechnicalStatus(bsmId);
|
||||
}
|
||||
|
||||
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Api for BSM access
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2017-01-26
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <BSM/buildingcontrolbsm_export.h>
|
||||
#include <QObject>
|
||||
#include <logger.h>
|
||||
#include "bsm_types.h"
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
class SocketHandler;
|
||||
class BUILDINGCONTROLBSM_EXPORT Api : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Api(QObject *parent = nullptr);
|
||||
~Api();
|
||||
|
||||
QVector<BsmState> bsmStates() const;
|
||||
bool init(const BuildingBsmConfig &bsmConfig);
|
||||
public Q_SLOTS:
|
||||
bool triggerFlashlight(int bsmId, const QString &hostname = QString(), int numberOfFlashes = 1, int pauseBetweenFlashesSec = 1);
|
||||
bool triggerFlashlightPulse(int bsmId, const QString &hostname = QString(),
|
||||
int numberOfFlashes = 1,
|
||||
int pauseDuration = 1,
|
||||
int choppedConfiguration = 10,
|
||||
int flashDuration = 30);
|
||||
bool triggerFlashlights(int numberOfFlashes,
|
||||
int pauseDuration,
|
||||
int choppedConfiguration,
|
||||
int flashDuration);
|
||||
bool getBsmConfiguration(int bsmId);
|
||||
bool getBsmBitTimeout(int bsmId);
|
||||
bool getBsmTechnicalStatus(int bsmId);
|
||||
|
||||
Q_SIGNALS:
|
||||
void opticalShot(qint64 timeMSec,
|
||||
int sensorId,
|
||||
int originatorId,
|
||||
int ammunitionId,
|
||||
int deposition1,
|
||||
int deposition2);
|
||||
void opticalShotOC(qint64 timeMSec,
|
||||
int sensorId,
|
||||
int originatorId,
|
||||
int ammunitionId,
|
||||
DamageState damageState);
|
||||
void bsmStateChanged(const QVector<BsmState> &bsmStates);
|
||||
private:
|
||||
SocketHandler *m_socketHandler;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* One connection to a bsm
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2017-01-18
|
||||
*/
|
||||
|
||||
|
||||
#include "bsm_socket.h"
|
||||
#include "bsm_telegrams_configuration_setup.h"
|
||||
#include <QTimer>
|
||||
#include <QHostAddress>
|
||||
|
||||
static const int s_aliveTimeout = 10; // 10 seconds
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
Socket::Socket(const Bsm &cfg, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_config(cfg)
|
||||
, m_tcpSocket(new QTcpSocket(this))
|
||||
, m_reconnectTimer(nullptr)
|
||||
, m_aliveTimer(new QTimer(this))
|
||||
, m_logger(BuildingControlUnit::getLogger("BSM.Socket"))
|
||||
{
|
||||
m_aliveTimer->setTimerType(Qt::VeryCoarseTimer);
|
||||
m_aliveTimer->setSingleShot(true);
|
||||
m_aliveTimer->setInterval(s_aliveTimeout * 2 * 1000);
|
||||
connect(m_aliveTimer, &QTimer::timeout, this, &Socket::onAliveTimeout);
|
||||
|
||||
connect(m_tcpSocket, &QTcpSocket::connected,
|
||||
this, &Socket::onConnected);
|
||||
connect(m_tcpSocket, &QTcpSocket::disconnected,
|
||||
this, &Socket::onDisconnected);
|
||||
connect(m_tcpSocket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error),
|
||||
this, &Socket::onError);
|
||||
connect(m_tcpSocket, &QTcpSocket::readyRead,
|
||||
this, &Socket::onReadyRead);
|
||||
onConnect();
|
||||
}
|
||||
|
||||
bool Socket::isConnected() const
|
||||
{
|
||||
return m_tcpSocket && (m_tcpSocket->state() == QAbstractSocket::ConnectedState);
|
||||
}
|
||||
|
||||
bool Socket::sendData(const QByteArray &data)
|
||||
{
|
||||
if (!isConnected())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "BSM " << m_config.id << ": Trying to send data but not connected!";
|
||||
return false;
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "BSM " << m_config.id << ": sending data: 0x" << data.toHex();
|
||||
m_tcpSocket->write(data);
|
||||
m_tcpSocket->flush();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Socket::setVersionInformation(int verMajor, int verMinor, int verRev, const QString &manufacturer)
|
||||
{
|
||||
m_versionInfo = QStringLiteral("%1.%2-%3 (%4)").arg(verMajor).arg(verMinor).arg(verRev).arg(manufacturer);
|
||||
INFO_LOG(m_logger) << "BSM " << m_config.id
|
||||
<< ": version = " << m_versionInfo;
|
||||
}
|
||||
|
||||
void Socket::gotAlive()
|
||||
{
|
||||
// restart timer
|
||||
if (m_aliveTimer)
|
||||
m_aliveTimer->start();
|
||||
}
|
||||
|
||||
|
||||
void Socket::onConnected()
|
||||
{
|
||||
INFO_LOG(m_logger) << "BSM " << m_config.id << " is connected to "
|
||||
<< m_tcpSocket->peerAddress().toString() << ":" << m_tcpSocket->peerPort();
|
||||
Telegrams::PanConfigurationSetup tele;
|
||||
tele.m_aliveMessage = s_aliveTimeout;
|
||||
sendData(tele.toBytestream());
|
||||
m_aliveTimer->start();
|
||||
|
||||
emit connected(m_config.id);
|
||||
}
|
||||
|
||||
void Socket::onDisconnected()
|
||||
{
|
||||
INFO_LOG(m_logger) << "BSM " << m_config.id << " is disconnected";
|
||||
m_versionInfo.clear();
|
||||
startReconnectTimer();
|
||||
emit disconnected(m_config.id);
|
||||
}
|
||||
|
||||
void Socket::onError(QAbstractSocket::SocketError error)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "BSM " << m_config.id
|
||||
<< " can not connect to " << m_config.hostname << ":" << m_config.port
|
||||
<< ": " << m_tcpSocket->errorString()
|
||||
<< " (" << error << ");";
|
||||
startReconnectTimer();
|
||||
}
|
||||
|
||||
void Socket::onConnect()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "BSM " << m_config.id
|
||||
<< " trying to connect to " << m_config.hostname << ":" << m_config.port;
|
||||
m_tcpSocket->connectToHost(m_config.hostname, m_config.port);
|
||||
}
|
||||
|
||||
void Socket::onReadyRead()
|
||||
{
|
||||
emit dataAvailable(m_config.id, m_tcpSocket->readAll());
|
||||
}
|
||||
|
||||
void Socket::onAliveTimeout()
|
||||
{
|
||||
WARNING_LOG(m_logger) << "BSM " << m_config.id
|
||||
<< " alive timeout! Reconnecting";
|
||||
//m_tcpSocket->disconnectFromHost();
|
||||
}
|
||||
|
||||
void Socket::startReconnectTimer()
|
||||
{
|
||||
if (!m_reconnectTimer)
|
||||
{
|
||||
m_reconnectTimer = new QTimer(this);
|
||||
m_reconnectTimer->setTimerType(Qt::VeryCoarseTimer);
|
||||
m_reconnectTimer->setSingleShot(true);
|
||||
connect(m_reconnectTimer, &QTimer::timeout, this, &Socket::onConnect);
|
||||
}
|
||||
m_reconnectTimer->start(2000); // after 2sec
|
||||
if (m_aliveTimer)
|
||||
m_aliveTimer->stop();
|
||||
}
|
||||
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* One connection to a bsm
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2017-01-18
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QHostAddress>
|
||||
#include <QTcpSocket>
|
||||
#include <logger.h>
|
||||
#include "bsm_types.h"
|
||||
|
||||
class QTimer;
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
class Socket : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Socket(const BuildingControlUnit::Bsm &cfg, QObject *parent = nullptr);
|
||||
|
||||
bool isConnected() const;
|
||||
bool sendData(const QByteArray &data);
|
||||
const BuildingControlUnit::Bsm &bsmConfig() const { return m_config; }
|
||||
|
||||
QString versionInfo() const { return m_versionInfo; }
|
||||
void setVersionInformation(int verMajor, int verMinor, int verRev, const QString &manufacturer);
|
||||
void gotAlive();
|
||||
QHostAddress peerAddress() const { return m_tcpSocket->peerAddress(); }
|
||||
Q_SIGNALS:
|
||||
void dataAvailable(int id, const QByteArray &data);
|
||||
void connected(int id);
|
||||
void disconnected(int id);
|
||||
private Q_SLOTS:
|
||||
void onConnected();
|
||||
void onDisconnected();
|
||||
void onError(QAbstractSocket::SocketError error);
|
||||
void onConnect();
|
||||
void onReadyRead();
|
||||
void onAliveTimeout();
|
||||
private:
|
||||
void startReconnectTimer();
|
||||
private:
|
||||
BuildingControlUnit::Bsm m_config;
|
||||
QTcpSocket *m_tcpSocket;
|
||||
QTimer *m_reconnectTimer;
|
||||
QTimer *m_aliveTimer;
|
||||
QString m_versionInfo;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
@@ -0,0 +1,469 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Handle incoming/outgoing data from/to all BSMs of one building
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2017-01-18
|
||||
*/
|
||||
|
||||
#include "bsm_socket_handler.h"
|
||||
#include "bsm_telegrams_base.h"
|
||||
#include "bsm_telegrams_bit_timeout_request.h"
|
||||
#include "bsm_telegrams_chopped_signal_flash.h"
|
||||
#include "bsm_telegrams_configuration_request.h"
|
||||
#include "bsm_telegrams_direct_fire.h"
|
||||
#include "bsm_telegrams_observer_controller.h"
|
||||
#include "bsm_telegrams_sw_version_report.h"
|
||||
#include "bsm_telegrams_sw_version_request.h"
|
||||
#include "bsm_telegrams_technical_status_request.h"
|
||||
#include <QDateTime>
|
||||
#include <QHostInfo>
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
static const qint64 s_opticalTimeSlot = 100;
|
||||
|
||||
SocketHandler::SocketHandler(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_logger(BuildingControlUnit::getLogger("BSM.SocketHandler"))
|
||||
{
|
||||
connect(&m_cleanupQueueTimer, &QTimer::timeout,
|
||||
this, &SocketHandler::onCleanupQueue);
|
||||
|
||||
m_cleanupQueueTimer.setSingleShot(false);
|
||||
m_cleanupQueueTimer.setInterval(10000);
|
||||
m_cleanupQueueTimer.setTimerType(Qt::VeryCoarseTimer);
|
||||
m_cleanupQueueTimer.start();
|
||||
|
||||
|
||||
connect(&m_bsmStateTimer, &QTimer::timeout, this, &SocketHandler::onBsmStateTimerTimeOut);
|
||||
m_bsmStateTimer.setSingleShot(true);
|
||||
m_bsmStateTimer.setInterval(500);
|
||||
m_bsmStateTimer.setTimerType(Qt::VeryCoarseTimer);
|
||||
}
|
||||
|
||||
bool SocketHandler::init(const BuildingBsmConfig &bsmConfig)
|
||||
{
|
||||
// remove old sockets (should never happen)
|
||||
qDeleteAll(m_sockets);
|
||||
m_sockets.clear();
|
||||
m_socketData.clear();
|
||||
for (const Bsm &c : bsmConfig.bsmMap)
|
||||
{
|
||||
Socket *s = new Socket(c, this);//THIS
|
||||
|
||||
connect(s, &Socket::dataAvailable,
|
||||
this, &SocketHandler::onDataAvailable);
|
||||
connect(s, &Socket::disconnected,
|
||||
this, &SocketHandler::onSocketDisconnected);
|
||||
connect(s, &Socket::connected,
|
||||
this, &SocketHandler::onSocketConnected);
|
||||
m_sockets[c.id] = s;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SocketHandler::triggerFlashlight(int bsmId, const QString &hostname, int numberOfFlashes, int pauseBetweenFlashesSec)
|
||||
{
|
||||
Socket *s = hostname.isEmpty() ? getSocketForBsm(bsmId) : getSocketForBsm(hostname);
|
||||
if (!s)
|
||||
return false;
|
||||
DEBUG_LOG(m_logger) << "triggerFlashlight BSM Socket with socketId " << bsmId;
|
||||
Telegrams::PanChoppedSignalFlashlight flash;
|
||||
flash.m_noOfFlashes = qBound(0, numberOfFlashes, 255);
|
||||
flash.m_pauseDuration = qBound(1, pauseBetweenFlashesSec, 10);
|
||||
flash.m_flashDuration = 1;
|
||||
return s->sendData(flash.toBytestream());
|
||||
}
|
||||
|
||||
bool SocketHandler::triggerFlashlightPulse(int bsmId, const QString &hostname,
|
||||
int numberOfFlashes,
|
||||
int pauseDuration,
|
||||
int choppedConfiguration,
|
||||
int flashDuration)
|
||||
{
|
||||
Socket *s = hostname.isEmpty() ? getSocketForBsm(bsmId) : getSocketForBsm(hostname);
|
||||
if (!s)
|
||||
return false;
|
||||
DEBUG_LOG(m_logger) << "triggerFlashlightPulse BSM Socket with socketId " << bsmId
|
||||
<< " hostname=" << hostname
|
||||
<< " numberOfFlashes=" << numberOfFlashes
|
||||
<< " pauseDuration=" << pauseDuration
|
||||
<< " choppedConfiguration=" << choppedConfiguration
|
||||
<< " flashDuration=" << flashDuration;
|
||||
Telegrams::PanChoppedSignalFlashlight flash;
|
||||
flash.m_noOfFlashes = qBound(0, numberOfFlashes, 255);
|
||||
flash.m_pauseDuration = qBound(1, pauseDuration, 10);
|
||||
flash.m_choppedFlashConfig = qBound(2, choppedConfiguration, 10);
|
||||
flash.m_flashDuration = flashDuration;
|
||||
return s->sendData(flash.toBytestream());
|
||||
}
|
||||
|
||||
|
||||
bool SocketHandler::triggerFlashlights(int numberOfFlashes,
|
||||
int pauseDuration,
|
||||
int choppedConfiguration,
|
||||
int flashDuration)
|
||||
{
|
||||
int cntSocketsActive = 0;
|
||||
Telegrams::PanChoppedSignalFlashlight flash;
|
||||
flash.m_noOfFlashes = qBound(0, numberOfFlashes, 255);
|
||||
flash.m_pauseDuration = qBound(1, pauseDuration, 10);
|
||||
flash.m_choppedFlashConfig = qBound(2, choppedConfiguration, 10);
|
||||
flash.m_flashDuration = flashDuration;
|
||||
const QByteArray data = flash.toBytestream();
|
||||
for (Socket *s : qAsConst(m_sockets))
|
||||
{
|
||||
if (s->isConnected())
|
||||
{
|
||||
if (s->sendData(data))
|
||||
++cntSocketsActive;
|
||||
}
|
||||
else
|
||||
WARNING_LOG(m_logger) << "BSM " << s->bsmConfig().id
|
||||
<< " is not connected - can not activate flash light";
|
||||
}
|
||||
if (cntSocketsActive == 0)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "No active bsm - can not trigger flash light for all bsm";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SocketHandler::getBsmConfiguration(int bsmId)
|
||||
{
|
||||
Socket *s = getSocketForBsm(bsmId);
|
||||
if (!s)
|
||||
return false;
|
||||
Telegrams::PanConfigurationRequest req;
|
||||
return s->sendData(req.toBytestream());
|
||||
}
|
||||
|
||||
bool SocketHandler::getBsmBitTimeout(int bsmId)
|
||||
{
|
||||
Socket *s = getSocketForBsm(bsmId);
|
||||
if (!s)
|
||||
return false;
|
||||
Telegrams::PanBitTimeoutRequest req;
|
||||
return s->sendData(req.toBytestream());
|
||||
}
|
||||
|
||||
bool SocketHandler::getBsmTechnicalStatus(int bsmId)
|
||||
{
|
||||
Socket *s = getSocketForBsm(bsmId);
|
||||
if (!s)
|
||||
return false;
|
||||
Telegrams::PanTechnicalStatusRequest req;
|
||||
return s->sendData(req.toBytestream());
|
||||
}
|
||||
|
||||
QVector<BsmState> SocketHandler::bsmStates() const
|
||||
{
|
||||
QVector<BsmState> ret;
|
||||
ret.reserve(m_sockets.size());
|
||||
for (const Socket *s : m_sockets)
|
||||
{
|
||||
BsmState bs(s->bsmConfig());
|
||||
bs.bConnected = s->isConnected();
|
||||
bs.versionInfo = s->versionInfo();
|
||||
ret += bs;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SocketHandler::onBsmStateTimerTimeOut()
|
||||
{
|
||||
emit bsmStateChanged(bsmStates());
|
||||
}
|
||||
|
||||
void SocketHandler::onDataAvailable(int id, const QByteArray &data)
|
||||
{
|
||||
m_socketData[id] = parseBuffer(id, m_socketData[id] + data);
|
||||
}
|
||||
|
||||
void SocketHandler::onSocketConnected(int id)
|
||||
{
|
||||
requestVersion(id); // hopefully 500ms are enough for a version request
|
||||
DEBUG_LOG(m_logger) << "BSM Socket with id " << id << " connected";
|
||||
m_bsmStateTimer.start();
|
||||
}
|
||||
|
||||
void SocketHandler::onSocketDisconnected(int id)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "BSM Socket with id " << id << " disconnected";
|
||||
m_socketData[id].clear();
|
||||
m_bsmStateTimer.start();
|
||||
}
|
||||
|
||||
|
||||
void SocketHandler::onCleanupQueue()
|
||||
{
|
||||
if (m_lastShots.isEmpty())
|
||||
return;
|
||||
QVector<OpticalShot> activeShots;
|
||||
qint64 tNow = QDateTime::currentMSecsSinceEpoch();
|
||||
for (const OpticalShot &os : qAsConst(m_lastShots))
|
||||
{
|
||||
if (os.timeStampMSec < tNow - s_opticalTimeSlot)
|
||||
continue;
|
||||
activeShots += os;
|
||||
}
|
||||
m_lastShots = activeShots;
|
||||
}
|
||||
|
||||
Socket *SocketHandler::getSocketForBsm(int bsmId)
|
||||
{
|
||||
Socket *s = m_sockets.value(bsmId);
|
||||
if (!s)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Got invalid bsm id (" << bsmId << ") to trigger flashlight";
|
||||
return nullptr;
|
||||
}
|
||||
if (!s->isConnected())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Bsm with id " << bsmId
|
||||
<< " is not connected - can not activate flash light";
|
||||
return nullptr;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
Socket *SocketHandler::getSocketForBsm(const QString &hostname)
|
||||
{
|
||||
const QHostInfo hi = QHostInfo::fromName(hostname);
|
||||
const auto addresses = hi.addresses();
|
||||
if (addresses.isEmpty())
|
||||
return nullptr;
|
||||
for (const QHostAddress &ha : addresses)
|
||||
{
|
||||
if (ha.isLoopback())
|
||||
continue;
|
||||
for (Socket *s : qAsConst(m_sockets))
|
||||
{
|
||||
if (s->peerAddress() == ha)
|
||||
return s;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
QByteArray SocketHandler::parseBuffer(int id, const QByteArray &buffer)
|
||||
{
|
||||
int iEndPos = 0;
|
||||
int iCurReadPos = 0;
|
||||
while (findNextSyncStartByte(buffer, iCurReadPos))
|
||||
{
|
||||
const int iStartPos = iCurReadPos;
|
||||
if (!findNextSyncEndByte(buffer, iCurReadPos))
|
||||
break;
|
||||
iEndPos = iCurReadPos;
|
||||
parseBsmTelegram(id, buffer.mid(iStartPos + 1, iEndPos - iStartPos - 1));
|
||||
}
|
||||
return buffer.mid(iEndPos);
|
||||
}
|
||||
|
||||
void SocketHandler::parseBsmTelegram(int id, const QByteArray &baTele)
|
||||
{
|
||||
Telegrams::Telegram *tele = Telegrams::Telegram::telegramFromBytestream(baTele);
|
||||
if (!tele)
|
||||
return;
|
||||
if (tele->telId() != Telegrams::PanTelegramId::ALIVE)
|
||||
DEBUG_LOG(m_logger) << "Got tele from bsm with id " << id << ": " << tele->print();
|
||||
switch (tele->telId())
|
||||
{
|
||||
case Telegrams::PanTelegramId::ALIVE:
|
||||
{
|
||||
Socket *s = m_sockets.value(id);
|
||||
if (s)
|
||||
s->gotAlive();
|
||||
break;
|
||||
}
|
||||
case Telegrams::PanTelegramId::REQ_BIT_TIMEOUT:
|
||||
case Telegrams::PanTelegramId::BIT_TIMEOUT_REPORT:
|
||||
case Telegrams::PanTelegramId::REQ_SW_VERSION:
|
||||
case Telegrams::PanTelegramId::CONFIGURATION_SETUP:
|
||||
case Telegrams::PanTelegramId::REQ_CONFIGURATION:
|
||||
case Telegrams::PanTelegramId::REQ_TECHNICAL_STATUS:
|
||||
case Telegrams::PanTelegramId::TECHNICAL_STATUS:
|
||||
case Telegrams::PanTelegramId::SIGNAL_FLASHLIGHT:
|
||||
case Telegrams::PanTelegramId::CHOPPED_SIGNAL_FLASH:
|
||||
break;
|
||||
case Telegrams::PanTelegramId::CONFIGURATION_REPORT:
|
||||
// request version
|
||||
//requestVersion(id);
|
||||
break;
|
||||
case Telegrams::PanTelegramId::SW_VERSION_REPORT:
|
||||
{
|
||||
Telegrams::PanSwVersionReport *rep = static_cast<Telegrams::PanSwVersionReport *>(tele);
|
||||
Socket *s = m_sockets.value(id);
|
||||
if (s)
|
||||
s->setVersionInformation(rep->m_mainVersion,
|
||||
rep->m_subVersion,
|
||||
rep->m_revision,
|
||||
QString::fromLatin1(rep->m_manufacturer));
|
||||
break;
|
||||
}
|
||||
case Telegrams::PanTelegramId::ER_DIRECT_FIRE:
|
||||
handleDirectFire(id, static_cast<Telegrams::PanDirectFire *>(tele));
|
||||
break;
|
||||
case Telegrams::PanTelegramId::ER_OBSERVER_CONTR:
|
||||
handleObserverController(id, static_cast<Telegrams::PanObserverController *>(tele));
|
||||
break;
|
||||
}
|
||||
delete tele;
|
||||
}
|
||||
|
||||
|
||||
bool SocketHandler::requestVersion(int id)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Requesting version for BSM " << id;
|
||||
Socket *s = m_sockets.value(id);
|
||||
if (!s || !s->isConnected())
|
||||
return false;
|
||||
|
||||
Telegrams::PanSwVersionRequest tele;
|
||||
return s->sendData(tele.toBytestream());
|
||||
}
|
||||
|
||||
void SocketHandler::handleDirectFire(int id, const Telegrams::PanDirectFire *tele)
|
||||
{
|
||||
if (!tele)
|
||||
return;
|
||||
|
||||
if (tele->m_ammunitionId == 0)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Got direct fire without valid ammunition - ignoring: " << tele->print();
|
||||
return;
|
||||
}
|
||||
OpticalShot osNew;
|
||||
osNew.id = id;
|
||||
osNew.ammunitionId = tele->m_ammunitionId;
|
||||
osNew.originatorId = tele->m_originatorId;
|
||||
osNew.deposition1 = tele->m_deposition1;
|
||||
osNew.deposition2 = tele->m_deposition2;
|
||||
osNew.timeStampMSec = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
m_lastShots += osNew;
|
||||
QTimer::singleShot(500, this, &SocketHandler::handleDirectFireSummray);
|
||||
|
||||
}
|
||||
|
||||
void SocketHandler::handleDirectFireSummray()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "handleDirectFireSummray m_lastShots.size=" << m_lastShots.size();
|
||||
OpticalShot osNew;
|
||||
if ( m_lastShots.size() == 0)
|
||||
return;
|
||||
int distance = 3000; // Unrealistisch hohe Distanz
|
||||
DEBUG_LOG(m_logger) << "distance=" << distance;
|
||||
for (const OpticalShot &os : qAsConst(m_lastShots))
|
||||
{
|
||||
int act_distance = os.deposition1 * os.deposition1 + os.deposition2 * os.deposition2;
|
||||
DEBUG_LOG(m_logger) << "act_distance=" << act_distance << " BSM-ID=" << os.id
|
||||
<< " ammunitionId=" << os.ammunitionId;
|
||||
if ( act_distance < distance)
|
||||
{
|
||||
distance = act_distance;
|
||||
DEBUG_LOG(m_logger) << "distance=" << distance << " BSM-ID=" << os.id;
|
||||
osNew = os;
|
||||
}
|
||||
}
|
||||
|
||||
emit opticalShot(QDateTime::currentMSecsSinceEpoch(),
|
||||
osNew.id,
|
||||
osNew.originatorId,
|
||||
osNew.ammunitionId,
|
||||
osNew.deposition1,
|
||||
osNew.deposition2);
|
||||
m_lastShots.clear();
|
||||
}
|
||||
|
||||
void SocketHandler::handleObserverController(int id, const Telegrams::PanObserverController *tele)
|
||||
{
|
||||
DamageState damageState = DamageState::Unknown;
|
||||
if (tele->m_codeNo == 2) // Zerstoerung
|
||||
damageState = DamageState::Destroyed;
|
||||
else if (tele->m_codeNo == 4 || tele->m_codeNo == 18 || tele->m_codeNo == 28) // Aktivierung, Reaktivierung
|
||||
damageState = DamageState::NoDamage;
|
||||
if (damageState == DamageState::Unknown)
|
||||
return;
|
||||
if (m_timerOC.isValid())
|
||||
{
|
||||
if (m_timerOC.elapsed() < 500) // < 500ms -> ignore event
|
||||
return;
|
||||
}
|
||||
m_timerOC.start();
|
||||
|
||||
emit opticalShotOC(QDateTime::currentMSecsSinceEpoch(),
|
||||
id,
|
||||
tele->m_originatorId,
|
||||
tele->m_ammunitionId,
|
||||
damageState);
|
||||
}
|
||||
|
||||
bool SocketHandler::findNextSyncStartByte(const QByteArray &buffer, int &iCurReadPos)
|
||||
{
|
||||
// Suchen nach s_stx
|
||||
while (iCurReadPos < buffer.size())
|
||||
{
|
||||
const char data = buffer.at(iCurReadPos);
|
||||
if (data == Telegrams::Telegram::s_stx)
|
||||
return true;
|
||||
++iCurReadPos;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SocketHandler::findNextSyncEndByte(const QByteArray &buffer, int &iCurReadPos)
|
||||
{
|
||||
// Suchen nach s_endMark
|
||||
while (iCurReadPos < buffer.size())
|
||||
{
|
||||
const char data = buffer.at(iCurReadPos);
|
||||
if (data == Telegrams::Telegram::s_etx)
|
||||
return true;
|
||||
++iCurReadPos;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool isSameAmmuniton(int a1, int a2)
|
||||
{
|
||||
if (a1 == a2 - 1)
|
||||
return true;
|
||||
if (a1 == a2)
|
||||
return true;
|
||||
if (a1 == a2 + 1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool isSameOriginator(int o1, int o2)
|
||||
{
|
||||
if (o1 == o2)
|
||||
return true;
|
||||
// o1 == 0 || o2 == 0 is filtered out before
|
||||
if (o1 == 0)
|
||||
return true;
|
||||
if (o2 == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SocketHandler::isSameOpticalShot(const OpticalShot &o1, const OpticalShot &o2)
|
||||
{
|
||||
// mehr als 100ms auseinander -> nicht der gleiche Treffer
|
||||
if (o1.timeStampMSec < o2.timeStampMSec - s_opticalTimeSlot)
|
||||
return false;
|
||||
return (isSameAmmuniton(o1.ammunitionId, o2.ammunitionId) &&
|
||||
isSameOriginator(o1.originatorId, o2.originatorId));
|
||||
}
|
||||
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Handle incoming/outgoing data from/to all BSMs of one building
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2017-01-18
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
#include <QTimer>
|
||||
#include <QElapsedTimer>
|
||||
#include <logger.h>
|
||||
#include "bsm_socket.h"
|
||||
#include "bsm_telegrams_base.h"
|
||||
#include "bsm_types.h"
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
class PanDirectFire;
|
||||
class PanObserverController;
|
||||
}
|
||||
|
||||
|
||||
class SocketHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SocketHandler(QObject *parent = nullptr);
|
||||
|
||||
bool init(const BuildingBsmConfig &bsmConfig);
|
||||
bool triggerFlashlight(int bsmId, const QString &hostname, int numberOfFlashes, int pauseBetweenFlashesSec);
|
||||
bool triggerFlashlightPulse(int bsmId, const QString &hostname = QString(),
|
||||
int numberOfFlashes = 1,
|
||||
int pauseDuration = 1,
|
||||
int choppedConfiguration = 10,
|
||||
int flashDuration = 30);
|
||||
|
||||
bool triggerFlashlights(int numberOfFlashes,
|
||||
int pauseDuration,
|
||||
int choppedConfiguration,
|
||||
int flashDuration);
|
||||
|
||||
bool getBsmConfiguration(int bsmId);
|
||||
bool getBsmBitTimeout(int bsmId);
|
||||
bool getBsmTechnicalStatus(int bsmId);
|
||||
|
||||
QVector<BsmState> bsmStates() const;
|
||||
Q_SIGNALS:
|
||||
void opticalShot(qint64 timeMSec,
|
||||
int sensorId,
|
||||
int originatorId,
|
||||
int ammunitionId,
|
||||
int deposition1,
|
||||
int deposition2);
|
||||
void opticalShotOC(qint64 timeMSec,
|
||||
int sensorId,
|
||||
int originatorId,
|
||||
int ammunitionId,
|
||||
DamageState damageState);
|
||||
void bsmStateChanged(const QVector<BsmState> &bsmStates);
|
||||
private Q_SLOTS:
|
||||
void onBsmStateTimerTimeOut();
|
||||
void onDataAvailable(int id, const QByteArray &data);
|
||||
void onSocketConnected(int id);
|
||||
void onSocketDisconnected(int id);
|
||||
void onCleanupQueue();
|
||||
void handleDirectFireSummray();
|
||||
|
||||
private:
|
||||
Socket *getSocketForBsm(int bsmId);
|
||||
Socket *getSocketForBsm(const QString &hostname);
|
||||
QByteArray parseBuffer(int id, const QByteArray &buffer);
|
||||
void parseBsmTelegram(int id, const QByteArray &baTele);
|
||||
bool requestVersion(int id);
|
||||
void handleDirectFire(int id, const Telegrams::PanDirectFire *tele);
|
||||
void handleObserverController(int id, const Telegrams::PanObserverController *tele);
|
||||
|
||||
static bool findNextSyncStartByte(const QByteArray &buffer, int &iCurReadPos);
|
||||
static bool findNextSyncEndByte(const QByteArray &buffer, int &iCurReadPos);
|
||||
static QByteArray substituteData(const QByteArray &data);
|
||||
static QByteArray desubstituteData(const QByteArray &data);
|
||||
static bool isSameOpticalShot(const OpticalShot &o1, const OpticalShot &o2);
|
||||
private:
|
||||
QMap<int, Socket *> m_sockets;
|
||||
QMap<int, QByteArray> m_socketData;
|
||||
QVector<OpticalShot> m_lastShots;
|
||||
QElapsedTimer m_timerOC;
|
||||
QTimer m_cleanupQueueTimer;
|
||||
QTimer m_bsmStateTimer;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms Alive
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bsm_telegrams_base.h"
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
class BUILDINGCONTROLBSM_EXPORT PanAlive : public Telegram
|
||||
{
|
||||
public:
|
||||
PanAlive()
|
||||
: Telegram(PanTelegramId::ALIVE)
|
||||
{}
|
||||
|
||||
static Telegram *fromBytestream(const QByteArray &data)
|
||||
{
|
||||
Q_UNUSED(data)
|
||||
return new PanAlive;
|
||||
}
|
||||
protected:
|
||||
QByteArray payload() const override
|
||||
{
|
||||
return QByteArray();
|
||||
}
|
||||
};
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
@@ -0,0 +1,279 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Oberklasser der BSM-Telegramme
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#include "bsm_telegrams_base.h"
|
||||
#include "bsm_telegrams_alive.h"
|
||||
#include "bsm_telegrams_bit_timeout_report.h"
|
||||
#include "bsm_telegrams_direct_fire.h"
|
||||
#include "bsm_telegrams_sw_version_report.h"
|
||||
#include "bsm_telegrams_sw_version_request.h"
|
||||
#include "bsm_telegrams_configuration_report.h"
|
||||
#include "bsm_telegrams_observer_controller.h"
|
||||
#include "bsm_telegrams_technical_status.h"
|
||||
|
||||
#include <logger.h>
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
|
||||
static inline QByteArray escapeData(const QByteArray &bufferData)
|
||||
{
|
||||
QByteArray ret;
|
||||
ret.reserve(bufferData.size() * 1.2);
|
||||
for (const unsigned char c : bufferData)
|
||||
{
|
||||
if (c >= 0x20 && c < 0x7f)
|
||||
ret += c;
|
||||
else
|
||||
ret += "\\x" + QByteArray::number(static_cast<unsigned char>(c), 16);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QByteArray toString(PanTelegramId teleId)
|
||||
{
|
||||
switch (teleId)
|
||||
{
|
||||
case PanTelegramId::ALIVE:
|
||||
return "ALIVE";
|
||||
case PanTelegramId::REQ_BIT_TIMEOUT:
|
||||
return "REQ_BIT_TIMEOUT";
|
||||
case PanTelegramId::BIT_TIMEOUT_REPORT:
|
||||
return "BIT_TIMEOUT_REPORT";
|
||||
case PanTelegramId::REQ_SW_VERSION:
|
||||
return "REQ_SW_VERSION";
|
||||
case PanTelegramId::SW_VERSION_REPORT:
|
||||
return "SW_VERSION_REPORT";
|
||||
case PanTelegramId::CONFIGURATION_SETUP:
|
||||
return "CONFIGURATION_SETUP";
|
||||
case PanTelegramId::REQ_CONFIGURATION:
|
||||
return "REQ_CONFIGURATION";
|
||||
case PanTelegramId::CONFIGURATION_REPORT:
|
||||
return "CONFIGURATION_REPORT";
|
||||
case PanTelegramId::ER_DIRECT_FIRE:
|
||||
return "ER_DIRECT_FIRE";
|
||||
case PanTelegramId::ER_OBSERVER_CONTR:
|
||||
return "ER_OBSERVER_CONTR";
|
||||
case PanTelegramId::REQ_TECHNICAL_STATUS:
|
||||
return "REQ_TECHNICAL_STATUS";
|
||||
case PanTelegramId::TECHNICAL_STATUS:
|
||||
return "TECHNICAL_STATUS";
|
||||
case PanTelegramId::SIGNAL_FLASHLIGHT:
|
||||
return "SIGNAL_FLASHLIGHT";
|
||||
case PanTelegramId::CHOPPED_SIGNAL_FLASH:
|
||||
return "CHOPPED_SIGNAL_FLASH";
|
||||
}
|
||||
return QByteArray("Unknown: ") + QByteArray::number(static_cast<int>(teleId));
|
||||
}
|
||||
|
||||
QByteArray Telegram::toBytestream() const
|
||||
{
|
||||
const int teleId = static_cast<int>(telId());
|
||||
const int payloadLen = payload().size();
|
||||
|
||||
QByteArray ret;
|
||||
ret.reserve(5 + payloadLen);
|
||||
|
||||
// N. Thoden, 02.11.2021
|
||||
// without resize following message appears:
|
||||
// "Using QByteRef with an index pointing outside the valid range of a QByteArray. The corresponding behavior is deprecated, and will be changed in a future version of Qt."
|
||||
// Qt doc at operator[]: "If an assignment is made beyond the end of the byte array, the array is extended with resize() before the assignment takes place."
|
||||
// so resize explicit:
|
||||
ret.resize(2);
|
||||
ret[0] = teleId & 0xFF; //Message.ID (LSB)
|
||||
ret[1] = ((teleId & 0x100) >> 1) | (((payloadLen + 3) & 0x1F) << 2); //Bit 1 MsgID-MSB; Bit 2-6 Length (Payload == Datafields+Checksum)
|
||||
// END
|
||||
|
||||
ret += payload();
|
||||
ret += calcChecksum(ret);
|
||||
|
||||
ret = substituteData(ret);
|
||||
ret.prepend(s_stx);
|
||||
ret.append(s_etx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Telegram *Telegram::telegramFromBytestream(const QByteArray &data_)
|
||||
{
|
||||
NGL::INGLLogger &logger = BuildingControlUnit::getLogger("BSM.Telegrams");
|
||||
QByteArray data = desubstituteData(data_);
|
||||
if (data.size() < 2)
|
||||
return nullptr;
|
||||
TRACE_LOG(logger) << "Incoming data: 0x" << data.toHex();
|
||||
|
||||
const unsigned char cs = data.at(data.size() - 1);
|
||||
// jetzt checksum wegnehmen
|
||||
data.chop(1);
|
||||
// und checksumme über Rest berechnen
|
||||
const unsigned char csCalc = calcChecksum(data);
|
||||
if (cs != csCalc)
|
||||
{
|
||||
WARNING_LOG(logger) << "Checksum does not match. Is: 0x" << QByteArray::number(cs, 16)
|
||||
<< ", should be: 0x" << QByteArray::number(csCalc, 16);
|
||||
}
|
||||
|
||||
int msg_id; // die ersten 9 Bits
|
||||
int msg_id_lsb = static_cast<int>(data.at(0)) & 0xFF;
|
||||
int msg_id_msb = static_cast<int>(data.at(1)) & 0x80;
|
||||
msg_id_msb <<= 1;
|
||||
msg_id = msg_id_lsb + msg_id_msb;
|
||||
const PanTelegramId teleId = static_cast<PanTelegramId>(msg_id);
|
||||
const QByteArray payload = data.mid(2);
|
||||
TRACE_LOG(logger) << "incoming data: " << data.toHex() << ", - payload: " << payload.toHex();
|
||||
|
||||
Telegram *tele = nullptr;
|
||||
switch (teleId)
|
||||
{
|
||||
case PanTelegramId::ALIVE:
|
||||
tele = PanAlive::fromBytestream(payload);
|
||||
break;
|
||||
case PanTelegramId::REQ_BIT_TIMEOUT:
|
||||
break;
|
||||
case PanTelegramId::BIT_TIMEOUT_REPORT:
|
||||
tele = PanBitTimeoutReport::fromBytestream(payload);
|
||||
break;
|
||||
case PanTelegramId::SW_VERSION_REPORT:
|
||||
tele = PanSwVersionReport::fromBytestream(payload);
|
||||
break;
|
||||
case PanTelegramId::REQ_SW_VERSION:
|
||||
break;
|
||||
case PanTelegramId::CONFIGURATION_SETUP:
|
||||
break;
|
||||
case PanTelegramId::REQ_CONFIGURATION:
|
||||
break;
|
||||
case PanTelegramId::CONFIGURATION_REPORT:
|
||||
tele = PanConfigurationReport::fromBytestream(payload);
|
||||
break;
|
||||
case PanTelegramId::ER_DIRECT_FIRE:
|
||||
tele = PanDirectFire::fromBytestream(payload);
|
||||
break;
|
||||
case PanTelegramId::ER_OBSERVER_CONTR:
|
||||
tele = PanObserverController::fromBytestream(payload);
|
||||
break;
|
||||
case PanTelegramId::REQ_TECHNICAL_STATUS:
|
||||
break;
|
||||
case PanTelegramId::TECHNICAL_STATUS:
|
||||
tele = PanTechnicalStatus::fromBytestream(payload);
|
||||
break;
|
||||
case PanTelegramId::SIGNAL_FLASHLIGHT:
|
||||
break;
|
||||
case PanTelegramId::CHOPPED_SIGNAL_FLASH:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!tele)
|
||||
{
|
||||
WARNING_LOG(logger) << "Error parsing bsm tele with id " << toString(teleId)
|
||||
<< ", data: " << escapeData(data);
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// if (tele->telId() != PanTelegramId::ALIVE)
|
||||
// DEBUG_LOG(logger) << "tele: " << tele->print();
|
||||
// }
|
||||
return tele;
|
||||
}
|
||||
|
||||
unsigned short Telegram::decode_ushort_little(const QByteArray &data, const int start, bool &bOk)
|
||||
{
|
||||
bOk = false;
|
||||
// Always 2 Bytes
|
||||
unsigned short byte1 = 0;
|
||||
unsigned short byte2 = 0;
|
||||
if (start + 2 <= data.size())
|
||||
{
|
||||
byte1 = ((data[start + 1]) & 0xFF) << 8;
|
||||
byte2 = (data[start]) & 0xFF;
|
||||
bOk = true;
|
||||
}
|
||||
|
||||
return (byte1 + byte2);
|
||||
}
|
||||
|
||||
unsigned char Telegram::calcChecksum(const QByteArray &data)
|
||||
{
|
||||
unsigned char cs = 0;
|
||||
for (const unsigned char c : data)
|
||||
cs += c;
|
||||
return cs ^ 0xff;
|
||||
}
|
||||
|
||||
|
||||
QByteArray Telegram::substituteData(const QByteArray &data)
|
||||
{
|
||||
QByteArray ret;
|
||||
ret.reserve(data.size());
|
||||
|
||||
for (const unsigned char c : data)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case s_stx:
|
||||
ret += s_subMark;
|
||||
ret += s_subStx;
|
||||
break;
|
||||
case s_etx:
|
||||
ret += s_subMark;
|
||||
ret += s_subEtx;
|
||||
break;
|
||||
case s_subMark:
|
||||
ret += s_subMark;
|
||||
ret += static_cast<char>(s_subSub);
|
||||
break;
|
||||
default:
|
||||
ret += c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QByteArray Telegram::desubstituteData(const QByteArray &data)
|
||||
{
|
||||
QByteArray ret;
|
||||
ret.reserve(data.size());
|
||||
for (int i = 0; i < data.size(); ++i)
|
||||
{
|
||||
const unsigned char c = data.at(i);
|
||||
if (c == s_subMark)
|
||||
{
|
||||
++i;
|
||||
if (i < data.size())
|
||||
{
|
||||
const unsigned char s = data.at(i);
|
||||
switch (s)
|
||||
{
|
||||
case s_subStx:
|
||||
ret += s_stx;
|
||||
break;
|
||||
case s_subEtx:
|
||||
ret += s_etx;
|
||||
break;
|
||||
case s_subSub:
|
||||
ret += s_subMark;
|
||||
break;
|
||||
default:
|
||||
ret += s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
ret += c;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} //namespace BuildingControlUnit
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Oberklasser der BSM-Telegramme
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QByteArray>
|
||||
#include "buildingcontrolbsm_export.h"
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
enum class PanTelegramId
|
||||
{
|
||||
ALIVE = 0x08,
|
||||
REQ_BIT_TIMEOUT = 0x09,
|
||||
BIT_TIMEOUT_REPORT = 0x0a,
|
||||
REQ_SW_VERSION = 0x0e,
|
||||
SW_VERSION_REPORT = 0x0f,
|
||||
CONFIGURATION_SETUP = 0x20,
|
||||
REQ_CONFIGURATION = 0x21,
|
||||
CONFIGURATION_REPORT = 0x22,
|
||||
ER_DIRECT_FIRE = 0x23,
|
||||
ER_OBSERVER_CONTR = 0x24,
|
||||
REQ_TECHNICAL_STATUS = 0x27,
|
||||
TECHNICAL_STATUS = 0x28,
|
||||
SIGNAL_FLASHLIGHT = 0x30, // not described in icd
|
||||
CHOPPED_SIGNAL_FLASH = 0x39,
|
||||
};
|
||||
QByteArray toString(PanTelegramId teleId);
|
||||
|
||||
class BUILDINGCONTROLBSM_EXPORT Telegram
|
||||
{
|
||||
protected:
|
||||
explicit Telegram(PanTelegramId telId)
|
||||
: m_telId(telId)
|
||||
{}
|
||||
public:
|
||||
virtual ~Telegram() = default;
|
||||
|
||||
virtual QByteArray print() const
|
||||
{
|
||||
return toString(m_telId);
|
||||
}
|
||||
QByteArray toBytestream() const;
|
||||
|
||||
PanTelegramId telId() const
|
||||
{
|
||||
return m_telId;
|
||||
}
|
||||
|
||||
static Telegram *telegramFromBytestream(const QByteArray &data_);
|
||||
static const unsigned char s_stx = 0x02;
|
||||
static const unsigned char s_etx = 0x03;
|
||||
static const unsigned char s_subMark = 0x80;
|
||||
static const unsigned char s_subStx = 0x82;
|
||||
static const unsigned char s_subEtx = 0x83;
|
||||
static const unsigned char s_subSub = 0x00;
|
||||
protected:
|
||||
virtual QByteArray payload() const = 0;
|
||||
static unsigned short decode_ushort_little(const QByteArray &data, const int start, bool &bOk);
|
||||
private:
|
||||
static unsigned char calcChecksum(const QByteArray &data);
|
||||
static QByteArray substituteData(const QByteArray &data);
|
||||
static QByteArray desubstituteData(const QByteArray &data);
|
||||
PanTelegramId m_telId;
|
||||
};
|
||||
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms BitTimeoutReport
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
|
||||
#include "bsm_telegrams_bit_timeout_report.h"
|
||||
#include <QStringBuilder>
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
|
||||
QByteArray PanBitTimeoutReport::print() const
|
||||
{
|
||||
QByteArray ret = Telegram::print() ;
|
||||
ret += "\n BitTimeout = " + QByteArray::number(m_bitTimeout);
|
||||
return ret;
|
||||
}
|
||||
|
||||
QByteArray PanBitTimeoutReport::payload() const
|
||||
{
|
||||
Q_ASSERT(false);
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
Telegram *PanBitTimeoutReport::fromBytestream(const QByteArray &data)
|
||||
{
|
||||
if (data.length() < 2)
|
||||
return nullptr;
|
||||
|
||||
bool bOk = true;
|
||||
PanBitTimeoutReport rep;
|
||||
rep.m_bitTimeout = decode_ushort_little(data, 0, bOk);
|
||||
return bOk ? new PanBitTimeoutReport(rep) : nullptr;
|
||||
}
|
||||
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms BitTimeoutReport
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bsm_telegrams_base.h"
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
class BUILDINGCONTROLBSM_EXPORT PanBitTimeoutReport : public Telegram
|
||||
{
|
||||
public:
|
||||
PanBitTimeoutReport()
|
||||
: Telegram(PanTelegramId::BIT_TIMEOUT_REPORT)
|
||||
{}
|
||||
|
||||
QByteArray print() const override;
|
||||
static Telegram *fromBytestream(const QByteArray &data);
|
||||
|
||||
unsigned short m_bitTimeout = 0;
|
||||
protected:
|
||||
QByteArray payload() const override;
|
||||
};
|
||||
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms PanSwVersionRequest
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bsm_telegrams_base.h"
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
class BUILDINGCONTROLBSM_EXPORT PanBitTimeoutRequest : public Telegram
|
||||
{
|
||||
public:
|
||||
PanBitTimeoutRequest()
|
||||
: Telegram(PanTelegramId::REQ_BIT_TIMEOUT)
|
||||
{}
|
||||
|
||||
static Telegram *fromBytestream(const QByteArray &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
Q_ASSERT(false);
|
||||
return new PanBitTimeoutRequest;
|
||||
}
|
||||
protected:
|
||||
QByteArray payload() const override
|
||||
{
|
||||
return QByteArray();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms PanChoppedSignalFlashlight
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#include "bsm_telegrams_chopped_signal_flash.h"
|
||||
#include <QStringBuilder>
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
|
||||
QByteArray PanChoppedSignalFlashlight::print() const
|
||||
{
|
||||
QByteArray ret = Telegram::print() ;
|
||||
ret += "\n Number of Flashes = " + QByteArray::number(m_noOfFlashes);
|
||||
ret += "\n Pause duration = " + QByteArray::number(m_pauseDuration);
|
||||
ret += "\n Choped Flash configuration = " + QByteArray::number(m_choppedFlashConfig);
|
||||
ret += "\n Number of Flash Pulses = " + QByteArray::number(m_noOfFlashPulses);
|
||||
ret += "\n Flash duration = " + QByteArray::number(m_flashDuration);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QByteArray PanChoppedSignalFlashlight::payload() const
|
||||
{
|
||||
QByteArray result;
|
||||
result.resize(5);
|
||||
result[0] = m_noOfFlashes;
|
||||
result[1] = m_pauseDuration;
|
||||
result[2] = m_choppedFlashConfig;
|
||||
result[3] = m_noOfFlashPulses;
|
||||
result[4] = m_flashDuration;
|
||||
return result;
|
||||
}
|
||||
|
||||
Telegram *PanChoppedSignalFlashlight::fromBytestream(const QByteArray &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
Q_ASSERT(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms PanChoppedSignalFlashlight
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bsm_telegrams_base.h"
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
class BUILDINGCONTROLBSM_EXPORT PanChoppedSignalFlashlight : public Telegram
|
||||
{
|
||||
public:
|
||||
PanChoppedSignalFlashlight()
|
||||
: Telegram(PanTelegramId::CHOPPED_SIGNAL_FLASH)
|
||||
{}
|
||||
|
||||
QByteArray print() const override;
|
||||
static Telegram *fromBytestream(const QByteArray &data);
|
||||
|
||||
char m_noOfFlashes = 0;
|
||||
char m_pauseDuration = 0;
|
||||
char m_choppedFlashConfig = 0;
|
||||
char m_noOfFlashPulses = 0;
|
||||
char m_flashDuration = 0;
|
||||
protected:
|
||||
QByteArray payload() const override;
|
||||
};
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms PanConfigurationReport
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#include "bsm_telegrams_configuration_report.h"
|
||||
#include <QStringBuilder>
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
|
||||
QByteArray PanConfigurationReport::print() const
|
||||
{
|
||||
QByteArray ret = Telegram::print() ;
|
||||
ret += "\n Reserved1 = " + QByteArray::number(m_reserved1);
|
||||
ret += "\n ModesOfOperations = " + QByteArray::number(m_modesOfOperations);
|
||||
ret += "\n AlivePresence = " + QByteArray::number(m_aliveMessage);
|
||||
ret += "\n Reserved2 = " + QByteArray::number(m_reserved2);
|
||||
ret += "\n Position = " + QByteArray::number(m_position);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QByteArray PanConfigurationReport::payload() const
|
||||
{
|
||||
Q_ASSERT(false);
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
Telegram *PanConfigurationReport::fromBytestream(const QByteArray &data)
|
||||
{
|
||||
if (data.length() < 5)
|
||||
return nullptr;
|
||||
|
||||
PanConfigurationReport rep;
|
||||
rep.m_reserved1 = static_cast<unsigned short>(data[0]);
|
||||
rep.m_modesOfOperations = static_cast<unsigned short>(data[1]);
|
||||
rep.m_aliveMessage = static_cast<unsigned short>(data[2]);
|
||||
rep.m_reserved2 = static_cast<unsigned short>(data[3]);
|
||||
rep.m_position = static_cast<unsigned short>(data[4]);
|
||||
// the last 2 bytes are rde specific and not decoded here
|
||||
|
||||
return new PanConfigurationReport(rep);
|
||||
}
|
||||
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms PanConfigurationReport
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bsm_telegrams_base.h"
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
class BUILDINGCONTROLBSM_EXPORT PanConfigurationReport : public Telegram
|
||||
{
|
||||
public:
|
||||
PanConfigurationReport()
|
||||
: Telegram(PanTelegramId::CONFIGURATION_REPORT)
|
||||
{}
|
||||
|
||||
QByteArray print() const override;
|
||||
static Telegram *fromBytestream(const QByteArray &data);
|
||||
|
||||
unsigned short m_reserved1 = 0;
|
||||
unsigned short m_modesOfOperations = 0;
|
||||
unsigned short m_aliveMessage = 0;
|
||||
unsigned short m_reserved2 = 0;
|
||||
unsigned short m_position = 0;
|
||||
protected:
|
||||
QByteArray payload() const override;
|
||||
};
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms PanSwVersionRequest
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bsm_telegrams_base.h"
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
class BUILDINGCONTROLBSM_EXPORT PanConfigurationRequest : public Telegram
|
||||
{
|
||||
public:
|
||||
PanConfigurationRequest()
|
||||
: Telegram(PanTelegramId::REQ_CONFIGURATION)
|
||||
{}
|
||||
|
||||
static Telegram *fromBytestream(const QByteArray &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
Q_ASSERT(false);
|
||||
return new PanConfigurationRequest;
|
||||
}
|
||||
protected:
|
||||
QByteArray payload() const override
|
||||
{
|
||||
return QByteArray();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms PanConfigurationSetup
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#include "bsm_telegrams_configuration_setup.h"
|
||||
#include <QStringBuilder>
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
|
||||
QByteArray PanConfigurationSetup::print() const
|
||||
{
|
||||
QByteArray ret = Telegram::print() ;
|
||||
ret += "\n Modes of Operations = " + QByteArray::number(m_modesOfOperations);
|
||||
ret += "\n Alive message [s] = " + QByteArray::number(m_aliveMessage);
|
||||
ret += "\n IpsInterval [s] = " + QByteArray::number(m_ipsInterval);
|
||||
ret += "\n reserved = " + QByteArray::number(m_reserved);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QByteArray PanConfigurationSetup::payload() const
|
||||
{
|
||||
QByteArray result;
|
||||
result.resize(4);
|
||||
result[0] = m_modesOfOperations;
|
||||
result[1] = m_ipsInterval;
|
||||
result[2] = static_cast<unsigned char>(m_aliveMessage / 10); // 10s
|
||||
result[3] = m_reserved;
|
||||
return result;
|
||||
}
|
||||
|
||||
Telegram *PanConfigurationSetup::fromBytestream(const QByteArray &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
Q_ASSERT(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms PanConfigurationSetup
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bsm_telegrams_base.h"
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
class BUILDINGCONTROLBSM_EXPORT PanConfigurationSetup : public Telegram
|
||||
{
|
||||
public:
|
||||
PanConfigurationSetup()
|
||||
: Telegram(PanTelegramId::CONFIGURATION_SETUP)
|
||||
{}
|
||||
|
||||
QByteArray print() const override;
|
||||
static Telegram *fromBytestream(const QByteArray &data);
|
||||
|
||||
int m_aliveMessage = 0; // in seconds
|
||||
|
||||
char m_ipsInterval = 0;
|
||||
// enable OSAG 2.0
|
||||
char m_modesOfOperations = 0b00000001;
|
||||
char m_reserved = 0;
|
||||
protected:
|
||||
QByteArray payload() const override;
|
||||
};
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms PanErDirectFire
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#include "bsm_telegrams_direct_fire.h"
|
||||
#include "logger.h"
|
||||
#include <QStringBuilder>
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
|
||||
QByteArray PanDirectFire::print() const
|
||||
{
|
||||
QByteArray ret = Telegram::print() ;
|
||||
ret += "\n TimeofEvent = " + QByteArray::number(m_timeofEvent);
|
||||
ret += "\n AmmunitionId = " + QByteArray::number(m_ammunitionId);
|
||||
ret += "\n Deposition1 = " + QByteArray::number(m_deposition1);
|
||||
ret += "\n Deposition2 = " + QByteArray::number(m_deposition2);
|
||||
ret += "\n NumberOpticalPulses = " + QByteArray::number(m_numberOpticalPulses);
|
||||
ret += "\n IDNumberOriginator = " + QByteArray::number(m_originatorId);
|
||||
ret += "\n DetectorNo = " + QByteArray::number(m_detectorNo);
|
||||
ret += "\n AmmunitionChildCode = " + QByteArray::number(m_ammunitionChildCode);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QByteArray PanDirectFire::payload() const
|
||||
{
|
||||
Q_ASSERT(false);
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
Telegram *PanDirectFire::fromBytestream(const QByteArray &data)
|
||||
{
|
||||
NGL::INGLLogger &logger = getLogger("PanDirectFire");
|
||||
DEBUG_LOG(logger) << "data.length=" << data.length();
|
||||
if (data.length() < 9)
|
||||
return nullptr;
|
||||
|
||||
bool bOk = true;
|
||||
PanDirectFire rep;
|
||||
rep.m_timeofEvent = decode_ushort_little(data, 0, bOk);
|
||||
rep.m_ammunitionId = decode_ushort_little(data, 2, bOk);
|
||||
if (data.length() == 9)
|
||||
{
|
||||
rep.m_deposition1 = static_cast<short>(data[3]);
|
||||
rep.m_deposition2 = static_cast<short>(data[4]);
|
||||
rep.m_numberOpticalPulses = static_cast<unsigned short>(data[5]);
|
||||
rep.m_originatorId = decode_ushort_little(data, 6, bOk);
|
||||
rep.m_detectorNo = static_cast<unsigned short>(data[8] & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
rep.m_deposition1 = static_cast<short>(data[4]);
|
||||
rep.m_deposition2 = static_cast<short>(data[5]);
|
||||
rep.m_numberOpticalPulses = static_cast<unsigned short>(data[6]);
|
||||
rep.m_originatorId = decode_ushort_little(data, 7, bOk);
|
||||
rep.m_detectorNo = static_cast<unsigned short>(data[9] & 0xFF);
|
||||
}
|
||||
// optional
|
||||
if (data.length() >= 12)
|
||||
rep.m_ammunitionChildCode = decode_ushort_little(data, 10, bOk);
|
||||
|
||||
return bOk ? new PanDirectFire(rep) : nullptr;
|
||||
}
|
||||
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms PanErDirectFire
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bsm_telegrams_base.h"
|
||||
#include <QObject>
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
class BUILDINGCONTROLBSM_EXPORT PanDirectFire : public Telegram
|
||||
{
|
||||
public:
|
||||
PanDirectFire()
|
||||
: Telegram(PanTelegramId::ER_DIRECT_FIRE)
|
||||
{}
|
||||
|
||||
QByteArray print() const override;
|
||||
static Telegram *fromBytestream(const QByteArray &data);
|
||||
|
||||
short m_timeofEvent = 0;
|
||||
unsigned short m_ammunitionId = 0;
|
||||
short m_deposition1 = 0;
|
||||
short m_deposition2 = 0;
|
||||
unsigned short m_numberOpticalPulses = 0;
|
||||
unsigned short m_originatorId = 0;
|
||||
unsigned short m_detectorNo = 0;
|
||||
unsigned short m_ammunitionChildCode = 0;
|
||||
protected:
|
||||
QByteArray payload() const override;
|
||||
};
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms PanObserverController
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#include "bsm_telegrams_observer_controller.h"
|
||||
#include <QStringBuilder>
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
|
||||
QByteArray PanObserverController::print() const
|
||||
{
|
||||
QByteArray ret = Telegram::print() ;
|
||||
|
||||
ret += "\n TimeofEvent = " + QByteArray::number(m_timeofEvent);
|
||||
ret += "\n AmmunitionId = " + QByteArray::number(m_ammunitionId);
|
||||
switch (m_ammunitionId)
|
||||
{
|
||||
case 208:
|
||||
ret += " (Observer/Controller)";
|
||||
break;
|
||||
case 209:
|
||||
ret += " (Medical Gun)";
|
||||
break;
|
||||
case 210:
|
||||
ret += " (Logistic Gun)";
|
||||
break;
|
||||
case 211:
|
||||
ret += " (Configuration Tool)";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ret += "\n Code Number = " + QByteArray::number(m_codeNo);
|
||||
ret += "\n Detector Number = " + QByteArray::number(m_detectorNo);
|
||||
switch (m_codeNo)
|
||||
{
|
||||
case 1:
|
||||
ret += " (Test)";
|
||||
break;
|
||||
case 2:
|
||||
ret += " (Zerstoerung, Ausfall)";
|
||||
break;
|
||||
case 4:
|
||||
ret += " (Aktivierung)";
|
||||
break;
|
||||
case 18:
|
||||
ret += " (Reaktivierung)";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ret += "\n ID Originator = " + QByteArray::number(m_originatorId);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QByteArray PanObserverController::payload() const
|
||||
{
|
||||
Q_ASSERT(false);
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
Telegram *PanObserverController::fromBytestream(const QByteArray &data)
|
||||
{
|
||||
if (data.length() < 6)
|
||||
return nullptr;
|
||||
|
||||
bool bOk = true;
|
||||
PanObserverController rep;
|
||||
rep.m_timeofEvent = decode_ushort_little(data, 0, bOk);
|
||||
rep.m_ammunitionId = static_cast<unsigned short>(data[2] & 0xFF);
|
||||
rep.m_codeNo = static_cast<unsigned short>(data[3] & 0xFF);
|
||||
rep.m_detectorNo = static_cast<unsigned short>(data[4] & 0xFF);
|
||||
rep.m_originatorId = decode_ushort_little(data, 5, bOk);
|
||||
|
||||
return bOk ? new PanObserverController(rep) : nullptr;
|
||||
}
|
||||
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms PanObserverController
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bsm_telegrams_base.h"
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
class BUILDINGCONTROLBSM_EXPORT PanObserverController : public Telegram
|
||||
{
|
||||
public:
|
||||
PanObserverController()
|
||||
: Telegram(PanTelegramId::ER_OBSERVER_CONTR)
|
||||
{}
|
||||
|
||||
QByteArray print() const override;
|
||||
static Telegram *fromBytestream(const QByteArray &data);
|
||||
|
||||
unsigned short m_timeofEvent = 0;
|
||||
unsigned short m_ammunitionId = 0;
|
||||
unsigned short m_codeNo = 0;
|
||||
unsigned short m_detectorNo = 0;
|
||||
unsigned short m_originatorId = 0;
|
||||
protected:
|
||||
QByteArray payload() const override;
|
||||
};
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms SwVersionReport
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#include "bsm_telegrams_sw_version_report.h"
|
||||
#include <QStringBuilder>
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
|
||||
QByteArray PanSwVersionReport::print() const
|
||||
{
|
||||
QByteArray ret = Telegram::print() ;
|
||||
ret += "\n mainVersion = " + QByteArray::number(m_mainVersion);
|
||||
ret += "\n subVersion = " + QByteArray::number(m_subVersion);
|
||||
ret += "\n revision = " + QByteArray::number(m_revision);
|
||||
ret += "\n manufacturer = " + m_manufacturer;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QByteArray PanSwVersionReport::payload() const
|
||||
{
|
||||
Q_ASSERT(false);
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
Telegram *PanSwVersionReport::fromBytestream(const QByteArray &data)
|
||||
{
|
||||
if (data.length() < 4)
|
||||
return nullptr;
|
||||
|
||||
PanSwVersionReport rep;
|
||||
unsigned short version = (unsigned short)data.at(0);
|
||||
version <<= 8;
|
||||
version |= (unsigned short)(data.at(1));
|
||||
|
||||
// highest 4 bits
|
||||
rep.m_mainVersion = (version & 0xF000) >> 12;
|
||||
// next 7 bits
|
||||
rep.m_subVersion = (version & 0x0FE0) >> 5;
|
||||
// last 5 bits
|
||||
rep.m_revision = (version & 0x001F); // not used as letter
|
||||
|
||||
rep.m_manufacturer = data.mid(2, 8);
|
||||
|
||||
return new PanSwVersionReport(rep);
|
||||
}
|
||||
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms SwVersionReport
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bsm_telegrams_base.h"
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
class BUILDINGCONTROLBSM_EXPORT PanSwVersionReport : public Telegram
|
||||
{
|
||||
public:
|
||||
PanSwVersionReport()
|
||||
: Telegram(PanTelegramId::SW_VERSION_REPORT)
|
||||
{}
|
||||
|
||||
QByteArray print() const override;
|
||||
static Telegram *fromBytestream(const QByteArray &data);
|
||||
|
||||
QByteArray m_manufacturer;
|
||||
int m_mainVersion = 0;
|
||||
int m_subVersion = 0;
|
||||
int m_revision = 0;
|
||||
protected:
|
||||
QByteArray payload() const override;
|
||||
};
|
||||
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms PanSwVersionRequest
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bsm_telegrams_base.h"
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
class BUILDINGCONTROLBSM_EXPORT PanSwVersionRequest : public Telegram
|
||||
{
|
||||
public:
|
||||
PanSwVersionRequest()
|
||||
: Telegram(PanTelegramId::REQ_SW_VERSION)
|
||||
{}
|
||||
|
||||
static Telegram *fromBytestream(const QByteArray &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
Q_ASSERT(false);
|
||||
return new PanSwVersionRequest;
|
||||
}
|
||||
protected:
|
||||
QByteArray payload() const override
|
||||
{
|
||||
return QByteArray();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms PanTechnicalStatus
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#include "bsm_telegrams_technical_status.h"
|
||||
#include <QStringBuilder>
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
|
||||
QByteArray PanTechnicalStatus::print() const
|
||||
{
|
||||
QByteArray ret = Telegram::print() ;
|
||||
|
||||
unsigned short first = m_failures;
|
||||
unsigned short failRFComm = (first & 0x80) >> 7;
|
||||
unsigned short failRAM = (first & 0x40) >> 6;
|
||||
unsigned short failFlashRom = (first & 0x20) >> 5;
|
||||
unsigned short batteryLow = (first & 0x10) >> 4;
|
||||
unsigned short batteryEol = (first & 0x8) >> 3;
|
||||
unsigned short optical = (first & 0x4) >> 2;
|
||||
unsigned short flashlight = (first & 0x2) >> 1;
|
||||
|
||||
|
||||
ret += "\n TimeofEvent = " + QByteArray::number(m_timeofEvent);
|
||||
ret += "\n Failures = " + QByteArray::number(m_failures);
|
||||
ret += "\n FailRFComm = " + QByteArray::number(failRFComm);
|
||||
ret += "\n FailRAM = " + QByteArray::number(failRAM);
|
||||
ret += "\n FailROM = " + QByteArray::number(failFlashRom);
|
||||
ret += "\n MCBattery = " + QByteArray::number(batteryLow);
|
||||
ret += "\n OSBattery = " + QByteArray::number(batteryEol);
|
||||
ret += "\n Optical = " + QByteArray::number(optical);
|
||||
ret += "\n Flashlight = " + QByteArray::number(flashlight);
|
||||
ret += "\n RFCommCRCErrorCount = " + QByteArray::number(m_rfCommCRCErrorCount);
|
||||
ret += "\n LostBeaconsCount = " + QByteArray::number(m_lostBeaconsCount);
|
||||
ret += "\n DetectorNo = " + QByteArray::number(m_detectorNo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
QByteArray PanTechnicalStatus::payload() const
|
||||
{
|
||||
Q_ASSERT(false);
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
Telegram *PanTechnicalStatus::fromBytestream(const QByteArray &data)
|
||||
{
|
||||
if (data.length() < 6)
|
||||
return nullptr;
|
||||
|
||||
bool bOk = true;
|
||||
PanTechnicalStatus rep;
|
||||
rep.m_timeofEvent = decode_ushort_little(data, 0, bOk);
|
||||
rep.m_failures = static_cast<unsigned short>(data[2] & 0xFF);
|
||||
rep.m_rfCommCRCErrorCount = static_cast<unsigned short>(data[3] & 0xFF);
|
||||
rep.m_lostBeaconsCount = static_cast<unsigned short>(data[4] & 0xFF);
|
||||
rep.m_detectorNo = static_cast<unsigned short>(data[5] & 0xFF);
|
||||
|
||||
return bOk ? new PanTechnicalStatus(rep) : nullptr;
|
||||
}
|
||||
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms PanTechnicalStatus
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bsm_telegrams_base.h"
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
class BUILDINGCONTROLBSM_EXPORT PanTechnicalStatus : public Telegram
|
||||
{
|
||||
public:
|
||||
PanTechnicalStatus()
|
||||
: Telegram(PanTelegramId::TECHNICAL_STATUS)
|
||||
{}
|
||||
|
||||
QByteArray print() const override;
|
||||
static Telegram *fromBytestream(const QByteArray &data);
|
||||
|
||||
unsigned short m_timeofEvent = 0;
|
||||
unsigned short m_failures = 0;
|
||||
unsigned short m_rfCommCRCErrorCount = 0;
|
||||
unsigned short m_lostBeaconsCount = 0;
|
||||
unsigned short m_detectorNo = 0;
|
||||
|
||||
protected:
|
||||
QByteArray payload() const override;
|
||||
};
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Definition des PAN-Telegramms PanSwVersionRequest
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bsm_telegrams_base.h"
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
namespace Telegrams
|
||||
{
|
||||
class BUILDINGCONTROLBSM_EXPORT PanTechnicalStatusRequest : public Telegram
|
||||
{
|
||||
public:
|
||||
PanTechnicalStatusRequest()
|
||||
: Telegram(PanTelegramId::REQ_TECHNICAL_STATUS)
|
||||
{}
|
||||
|
||||
static Telegram *fromBytestream(const QByteArray &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
Q_ASSERT(false);
|
||||
return new PanTechnicalStatusRequest;
|
||||
}
|
||||
protected:
|
||||
QByteArray payload() const override
|
||||
{
|
||||
return QByteArray();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Telegrams
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Kleines Testprogramm für BSMs
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Gerlinde Rudolphus, SLSA, 2013-03-05
|
||||
*/
|
||||
|
||||
#include <nglapplication/nglcoreapplication.h>
|
||||
#include <QVector>
|
||||
#include "bsm_api.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
NGLCoreApplication app(argc, argv);
|
||||
app.createLogger("BCU", -1);
|
||||
|
||||
BuildingControlUnit::BuildingBsmConfig config;
|
||||
BuildingControlUnit::Bsm c;
|
||||
c.id = 42;
|
||||
//c.hostname = QStringLiteral("192.168.133.177");
|
||||
c.hostname = QStringLiteral("localhost");
|
||||
c.port = 10001;
|
||||
config.bsmMap.insert(c.id, c);
|
||||
BuildingControlUnit::BSM::Api *a = new BuildingControlUnit::BSM::Api;
|
||||
|
||||
int ret = -1;
|
||||
if (a->init(config))
|
||||
ret = app.exec();
|
||||
delete a;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Api for BSM access
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2017-01-26
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <bcu_types.h>
|
||||
|
||||
namespace BuildingControlUnit
|
||||
{
|
||||
namespace BSM
|
||||
{
|
||||
enum FlashState
|
||||
{
|
||||
Off,
|
||||
On
|
||||
};
|
||||
|
||||
struct OpticalShot
|
||||
{
|
||||
int id = 0;
|
||||
int ammunitionId = 0;
|
||||
int originatorId = 0;
|
||||
int deposition1 = 0;
|
||||
int deposition2 = 0;
|
||||
int64_t timeStampMSec = 0;
|
||||
};
|
||||
|
||||
struct BsmState : public BuildingControlUnit::Bsm
|
||||
{
|
||||
QString versionInfo;
|
||||
bool bConnected = false;
|
||||
|
||||
explicit BsmState(const BuildingControlUnit::Bsm &c = BuildingControlUnit::Bsm())
|
||||
: BuildingControlUnit::Bsm(c)
|
||||
{}
|
||||
};
|
||||
} // namespace BSM
|
||||
} // namespace BuildingControlUnit
|
||||
Reference in new issue
Block a user