From 472f0fdc4f4f6b3a18269b93df9feda2142cf28a Mon Sep 17 00:00:00 2001 From: Jens Geudens Date: Thu, 19 Mar 2026 20:26:05 +0100 Subject: [PATCH 1/2] Remove most of modbus protocol --- src/communication/modbusconnection.cpp | 410 --------------- src/communication/modbusconnection.h | 97 ---- src/communication/modbusdataunit.cpp | 44 -- src/communication/modbusdataunit.h | 29 - src/communication/modbusmaster.cpp | 256 --------- src/communication/modbusmaster.h | 60 --- src/communication/modbuspoll.cpp | 193 +------ src/communication/modbuspoll.h | 30 +- src/communication/modbusresultmap.h | 10 - src/communication/readregisters.cpp | 190 ------- src/communication/readregisters.h | 57 -- src/communication/registervaluehandler.cpp | 124 ----- src/communication/registervaluehandler.h | 38 -- src/util/modbusdatatype.cpp | 1 - tests/CMakeLists.txt | 1 - tests/communication/CMakeLists.txt | 28 - tests/communication/communicationhelpers.h | 1 - tests/communication/tst_communication.cpp | 258 --------- tests/communication/tst_communication.h | 40 -- .../communication/tst_communicationstats.cpp | 113 ---- tests/communication/tst_communicationstats.h | 31 -- tests/communication/tst_modbusconnection.cpp | 198 ------- tests/communication/tst_modbusconnection.h | 33 -- tests/communication/tst_modbusdatatype.cpp | 190 ------- tests/communication/tst_modbusdatatype.h | 34 -- tests/communication/tst_modbusdataunit.cpp | 93 ---- tests/communication/tst_modbusdataunit.h | 23 - tests/communication/tst_modbusmaster.cpp | 398 -------------- tests/communication/tst_modbusmaster.h | 34 -- tests/communication/tst_modbusmasterfake.cpp | 111 ---- tests/communication/tst_modbusmasterfake.h | 20 - tests/communication/tst_modbuspoll.cpp | 497 ------------------ tests/communication/tst_modbuspoll.h | 39 -- tests/communication/tst_modbusregister.cpp | 209 -------- tests/communication/tst_modbusregister.h | 31 -- tests/communication/tst_readregisters.cpp | 326 ------------ tests/communication/tst_readregisters.h | 43 -- .../tst_registervaluehandler.cpp | 400 -------------- .../communication/tst_registervaluehandler.h | 54 -- tests/testslave/modbusconnectionfake.cpp | 120 ----- tests/testslave/modbusconnectionfake.h | 32 -- tests/testslave/testdevice.cpp | 61 --- tests/testslave/testdevice.h | 31 -- tests/testslave/testslavedata.cpp | 118 ----- tests/testslave/testslavedata.h | 44 -- tests/testslave/testslavemodbus.cpp | 117 ----- tests/testslave/testslavemodbus.h | 44 -- tests/testslave/testslavemodbusmulti.cpp | 149 ------ tests/testslave/testslavemodbusmulti.h | 40 -- tests/util/CMakeLists.txt | 1 - tests/util/tst_modbusaddress.cpp | 172 ------ tests/util/tst_modbusaddress.h | 31 -- 52 files changed, 18 insertions(+), 5686 deletions(-) delete mode 100644 src/communication/modbusconnection.cpp delete mode 100644 src/communication/modbusconnection.h delete mode 100644 src/communication/modbusdataunit.cpp delete mode 100644 src/communication/modbusdataunit.h delete mode 100644 src/communication/modbusmaster.cpp delete mode 100644 src/communication/modbusmaster.h delete mode 100644 src/communication/modbusresultmap.h delete mode 100644 src/communication/readregisters.cpp delete mode 100644 src/communication/readregisters.h delete mode 100644 src/communication/registervaluehandler.cpp delete mode 100644 src/communication/registervaluehandler.h delete mode 100644 tests/communication/CMakeLists.txt delete mode 100644 tests/communication/tst_communication.cpp delete mode 100644 tests/communication/tst_communication.h delete mode 100644 tests/communication/tst_communicationstats.cpp delete mode 100644 tests/communication/tst_communicationstats.h delete mode 100644 tests/communication/tst_modbusconnection.cpp delete mode 100644 tests/communication/tst_modbusconnection.h delete mode 100644 tests/communication/tst_modbusdatatype.cpp delete mode 100644 tests/communication/tst_modbusdatatype.h delete mode 100644 tests/communication/tst_modbusdataunit.cpp delete mode 100644 tests/communication/tst_modbusdataunit.h delete mode 100644 tests/communication/tst_modbusmaster.cpp delete mode 100644 tests/communication/tst_modbusmaster.h delete mode 100644 tests/communication/tst_modbusmasterfake.cpp delete mode 100644 tests/communication/tst_modbusmasterfake.h delete mode 100644 tests/communication/tst_modbuspoll.cpp delete mode 100644 tests/communication/tst_modbuspoll.h delete mode 100644 tests/communication/tst_modbusregister.cpp delete mode 100644 tests/communication/tst_modbusregister.h delete mode 100644 tests/communication/tst_readregisters.cpp delete mode 100644 tests/communication/tst_readregisters.h delete mode 100644 tests/communication/tst_registervaluehandler.cpp delete mode 100644 tests/communication/tst_registervaluehandler.h delete mode 100644 tests/testslave/modbusconnectionfake.cpp delete mode 100644 tests/testslave/modbusconnectionfake.h delete mode 100644 tests/testslave/testdevice.cpp delete mode 100644 tests/testslave/testdevice.h delete mode 100644 tests/testslave/testslavedata.cpp delete mode 100644 tests/testslave/testslavedata.h delete mode 100644 tests/testslave/testslavemodbus.cpp delete mode 100644 tests/testslave/testslavemodbus.h delete mode 100644 tests/testslave/testslavemodbusmulti.cpp delete mode 100644 tests/testslave/testslavemodbusmulti.h delete mode 100644 tests/util/tst_modbusaddress.cpp delete mode 100644 tests/util/tst_modbusaddress.h diff --git a/src/communication/modbusconnection.cpp b/src/communication/modbusconnection.cpp deleted file mode 100644 index b4b72949..00000000 --- a/src/communication/modbusconnection.cpp +++ /dev/null @@ -1,410 +0,0 @@ - -#include "modbusconnection.h" - -#include "communication/modbusdataunit.h" -#include "util/scopelogging.h" - -#include -#include -#include -#include - -using RegisterType = QModbusDataUnit::RegisterType; -using ObjectType = ModbusAddress::ObjectType; - -/*! - * Constructor for ModbusConnection module - */ -ModbusConnection::ModbusConnection(QObject* parent) : QObject(parent) -{ - _bWaitingForConnection = false; -} - -void ModbusConnection::configureTcpConnection(tcpSettings_t const& tcpSettings) -{ - _tcpSettings = tcpSettings; - _connectionType = ConnectionTypes::TYPE_TCP; -} - -void ModbusConnection::configureSerialConnection(serialSettings_t const& serialSettings) -{ - _serialSettings = serialSettings; - _connectionType = ConnectionTypes::TYPE_SERIAL; -} - -/*! - * Start opening of connection - * Emits signals (\ref connectionSuccess, \ref errorOccurred) when connection is ready or failed - * - * \param[in] timeout Timeout of connection (in seconds) - */ -void ModbusConnection::open(quint32 timeout) -{ - if (prepareConnectionOpen()) - { - if (_connectionType == ConnectionTypes::TYPE_SERIAL) - { - auto connectionData = - QPointer(new ConnectionData(std::make_unique())); - - connectionData->pModbusClient->setConnectionParameter(QModbusDevice::SerialPortNameParameter, - QVariant(_serialSettings.portName)); - connectionData->pModbusClient->setConnectionParameter(QModbusDevice::SerialParityParameter, - QVariant::fromValue(_serialSettings.parity)); - connectionData->pModbusClient->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, - QVariant::fromValue(_serialSettings.baudrate)); - connectionData->pModbusClient->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, - QVariant::fromValue(_serialSettings.databits)); - connectionData->pModbusClient->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, - QVariant::fromValue(_serialSettings.stopbits)); - - openConnection(connectionData, timeout); - } - else if (_connectionType == ConnectionTypes::TYPE_TCP) - { - auto connectionData = QPointer(new ConnectionData(std::make_unique())); - - connectionData->pModbusClient->setConnectionParameter(QModbusDevice::NetworkAddressParameter, - QVariant(_tcpSettings.ip)); - connectionData->pModbusClient->setConnectionParameter(QModbusDevice::NetworkPortParameter, - QVariant(_tcpSettings.port)); - - openConnection(connectionData, timeout); - } - else - { - qCDebug(scopeCommConnection) << "Unknown connection type"; - emit connectionError(QModbusDevice::ConnectionError, QString("Unknown connection type")); - } - } -} - -/*! - * Close connection - */ -void ModbusConnection::close(void) -{ - if (!_connectionList.isEmpty()) - { - _connectionList.last()->connectionTimeoutTimer.stop(); - _connectionList.last()->pModbusClient->disconnectDevice(); - } -} - -/*! - * Send read request over connection - * - * \param regAddress register address - * \param size number of registers - * \param serverAddress slave address - */ -void ModbusConnection::sendReadRequest(ModbusDataUnit const& regAddress, quint16 size) -{ - if (isConnected()) - { - auto type = registerType(regAddress.objectType()); - QModbusDataUnit dataUnit(type, static_cast(regAddress.protocolAddress()), size); - _connectionList.last()->pReply = - _connectionList.last()->pModbusClient->sendReadRequest(dataUnit, regAddress.slaveId()); - - connect(_connectionList.last()->pReply, &QModbusReply::finished, this, - &ModbusConnection::handleRequestFinished); - } - else - { - emit connectionError(QModbusDevice::ReadError, QString("Not connected")); - } -} - -/*! - * Return whether connection is ok - * - * \return Connection state - */ -bool ModbusConnection::isConnected(void) -{ - return !_connectionList.isEmpty() - && _connectionList.last()->pModbusClient->state() == QModbusDevice::ConnectedState; -} - -/*! - * Handle change of internal connection object - * - * \param state New state of connection - */ -void ModbusConnection::handleConnectionStateChanged(QModbusDevice::State state) -{ - QModbusClient* pClient = qobject_cast(QObject::sender()); - const qint32 senderIdx = findConnectionData(nullptr, pClient); - - if (state == QModbusDevice::ConnectingState || state == QModbusDevice::ClosingState) - { - // Nothing to do, wait for next state - } - else if (state == QModbusDevice::ConnectedState) - { - - if (senderIdx != -1) - { - // Stop timeout counter - _connectionList[senderIdx]->connectionTimeoutTimer.stop(); - } - - if (senderIdx == _connectionList.size() - 1) - { - _bWaitingForConnection = false; - - // Most recent connection is opened - emit connectionSuccess(); - } - else if (senderIdx != -1) - { - // Stale connection is open, close it - _connectionList[senderIdx]->pModbusClient->disconnectDevice(); - } - else - { - // Nothing to do - } - } - else if (state == QModbusDevice::UnconnectedState) - { - // Unconnected state can occur before timeout when connection is refused - if (_bWaitingForConnection) - { - if (senderIdx == _connectionList.size() - 1) - { - handleConnectionError(_connectionList.last(), QString("Connection timeout")); - } - } - else if (senderIdx != -1) - { - // Prepare to remove old connection - _connectionList[senderIdx]->pModbusClient->disconnect(); - _connectionList[senderIdx]->connectionTimeoutTimer.disconnect(); - - connect(_connectionList[senderIdx], &ConnectionData::destroyed, this, - &ModbusConnection::connectionDestroyed); - - // Use deleteLater because otherwise we receive SIGSEGV error - _connectionList[senderIdx]->deleteLater(); - } - } -} - -/*! - * Handle error on connecting - * \param error The error - */ -void ModbusConnection::handleConnectionErrorOccurred(QModbusDevice::Error error) -{ - QModbusClient* pClient = qobject_cast(QObject::sender()); - const qint32 senderIdx = findConnectionData(nullptr, pClient); - - // Only handle error is latest connection, the rest is automatically closed on state change - if (senderIdx >= 0 && senderIdx == _connectionList.size() - 1) - { - handleConnectionError(_connectionList.last(), QString("Error: %1").arg(error)); - } -} - -/*! - * Handle time out of connection start - */ -void ModbusConnection::connectionTimeOut() -{ - QTimer* pTimeoutTimer = qobject_cast(QObject::sender()); - const qint32 senderIdx = findConnectionData(pTimeoutTimer, nullptr); - - /* Stop timer */ - pTimeoutTimer->stop(); - - // Only handle error is latest connection, the rest is automatically closed on state change - if (senderIdx >= 0 && senderIdx == _connectionList.size() - 1) - { - handleConnectionError(_connectionList.last(), QString("Connection timeout")); - } -} - -/*! - * Handle deletion of connection object - */ -void ModbusConnection::connectionDestroyed() -{ - // Remove all nullptr from list - _connectionList.removeAll(nullptr); -} - -/*! - * Handle request finished - */ -void ModbusConnection::handleRequestFinished() -{ - QModbusReply* pReply = qobject_cast(QObject::sender()); - auto err = pReply->error(); - - // Start deletion of reply object before handling data (and closing connection) - pReply->deleteLater(); - - /* Check if reply is for valid connection (the last) */ - if (pReply == _connectionList.last()->pReply) - { - if (err == QModbusDevice::NoError) - { - QModbusDataUnit dataUnit = pReply->result(); - auto addr = - ModbusDataUnit(static_cast(dataUnit.startAddress()), objectType(dataUnit.registerType()), - static_cast(pReply->serverAddress())); - emit readRequestSuccess(addr, dataUnit.values().toList()); - } - else if (err == QModbusDevice::ProtocolError) - { - auto exceptionCode = pReply->rawResult().exceptionCode(); - - emit readRequestProtocolError(exceptionCode); - } - else - { - emit readRequestError(pReply->errorString(), pReply->error()); - } - } - else - { - // ignore data from reply - } -} - -/*! - * \brief Prepare for opening a connection - * \retval true when connection needs to be opened - * \retval false when connection already opened - */ -bool ModbusConnection::prepareConnectionOpen() -{ - bool bRet; - - if (isConnected()) - { - bRet = false; - - // Already connected and ready - emit connectionSuccess(); - } - else - { - bRet = true; - } - - return bRet; -} - -RegisterType ModbusConnection::registerType(ObjectType type) -{ - switch (type) - { - case ObjectType::COIL: - return RegisterType::Coils; - case ObjectType::DISCRETE_INPUT: - return RegisterType::DiscreteInputs; - case ObjectType::INPUT_REGISTER: - return RegisterType::InputRegisters; - case ObjectType::HOLDING_REGISTER: - case ObjectType::UNKNOWN: - default: - return RegisterType::HoldingRegisters; - } -} - -ObjectType ModbusConnection::objectType(RegisterType type) -{ - switch (type) - { - case RegisterType::Coils: - return ObjectType::COIL; - case RegisterType::DiscreteInputs: - return ObjectType::DISCRETE_INPUT; - case RegisterType::InputRegisters: - return ObjectType::INPUT_REGISTER; - case RegisterType::HoldingRegisters: - return ObjectType::HOLDING_REGISTER; - default: - return ObjectType::UNKNOWN; - } -} - -/*! - * General internal error handler - * Should only be called for last connection in the list, the rest is stale - * \param errMsg Error message - */ -void ModbusConnection::handleConnectionError(QPointer connectionData, QString errMsg) -{ - qCWarning(scopeCommConnection) << "Connection error:" << errMsg; - - if (!connectionData->bConnectionErrorHandled) - { - connectionData->bConnectionErrorHandled = true; - - close(); - - emit connectionError(QModbusDevice::ConnectionError, errMsg); - } -} - -/*! - * Find specific ConnectionData instance in list based on QTimer or QModbusClient pointer - * \param pTimer Pointer to QTimer object to find (nullptr when ignored) - * \param pClient Pointer to QModbusClient object to find (nullptr when ignored) - * \retval -1 Not found - * \retval != -1 Index in list - */ -qint32 ModbusConnection::findConnectionData(QTimer* pTimer, QModbusClient* pClient) -{ - for (qint32 idx = 0; idx < _connectionList.size(); idx++) - { - if (((pTimer != nullptr) && (pTimer == &_connectionList[idx]->connectionTimeoutTimer)) - || ((pClient != nullptr) && (pClient == _connectionList[idx]->pModbusClient.get()))) - { - return idx; - } - } - - return -1; -} - -QString ModbusConnection::connectionSummary() const -{ - if (_connectionType == ConnectionTypes::TYPE_TCP) - { - return QString("TCP %1:%2").arg(_tcpSettings.ip).arg(_tcpSettings.port); - } - else - { - return QString("Serial %1 at %2").arg(_serialSettings.portName).arg(_serialSettings.baudrate); - } -} - -void ModbusConnection::openConnection(QPointer connectionData, quint32 timeout) -{ - connectionData->pModbusClient->setNumberOfRetries(0); - connectionData->pModbusClient->setTimeout(static_cast(timeout)); - - connect(&connectionData->connectionTimeoutTimer, &QTimer::timeout, this, &ModbusConnection::connectionTimeOut); - connect(connectionData->pModbusClient.get(), &QModbusClient::stateChanged, this, - &ModbusConnection::handleConnectionStateChanged); - connect(connectionData->pModbusClient.get(), &QModbusClient::errorOccurred, this, - &ModbusConnection::handleConnectionErrorOccurred); - - _connectionList.append(connectionData); - - qCDebug(scopeCommConnection) << "Connection start:" << connectionSummary(); - - _connectionList.last()->connectionTimeoutTimer.start(static_cast(timeout)); - _bWaitingForConnection = true; - - if (!_connectionList.last()->pModbusClient->connectDevice()) - { - auto pClient = _connectionList.last()->pModbusClient.get(); - handleConnectionError(_connectionList.last(), QString("Connect failed: %1").arg(pClient->error())); - } -} diff --git a/src/communication/modbusconnection.h b/src/communication/modbusconnection.h deleted file mode 100644 index 69d0caa9..00000000 --- a/src/communication/modbusconnection.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef MODBUSCONNECTION_H -#define MODBUSCONNECTION_H - -#include "communication/modbusdataunit.h" -#include "models/connectiontypes.h" -#include -#include -#include -#include -#include -#include - -class ConnectionData : public QObject -{ - Q_OBJECT -public: - explicit ConnectionData(std::unique_ptr pModbus) - : connectionTimeoutTimer(this), bConnectionErrorHandled(false), pReply(nullptr) - { - pModbusClient = std::move(pModbus); - } - - QTimer connectionTimeoutTimer; - std::unique_ptr pModbusClient; - bool bConnectionErrorHandled; - - QModbusReply * pReply; -}; - - -class ModbusConnection : public QObject -{ - Q_OBJECT -public: - explicit ModbusConnection(QObject *parent = nullptr); - - typedef struct - { - QString ip; - qint32 port; - } tcpSettings_t; - - typedef struct - { - QString portName; - QSerialPort::Parity parity; - QSerialPort::BaudRate baudrate; - QSerialPort::DataBits databits; - QSerialPort::StopBits stopbits; - } serialSettings_t; - - virtual void configureTcpConnection(tcpSettings_t const& tcpSettings); - virtual void configureSerialConnection(serialSettings_t const& serialSettings); - - virtual void open(quint32 timeout); - virtual void close(void); - - virtual void sendReadRequest(ModbusDataUnit const& regAddress, quint16 size); - - virtual bool isConnected(void); - -signals: - void connectionSuccess(void); - void connectionError(QModbusDevice::Error error, QString msg); - - void readRequestSuccess(ModbusDataUnit startRegister, QList registerDataList); - void readRequestProtocolError(QModbusPdu::ExceptionCode exceptionCode); - void readRequestError(QString errorString, QModbusDevice::Error error); - -private slots: - void handleConnectionStateChanged(QModbusDevice::State connectionState); - void handleConnectionErrorOccurred(QModbusDevice::Error error); - - void connectionTimeOut(); - void connectionDestroyed(); - - void handleRequestFinished(); - -private: - bool prepareConnectionOpen(); - void openConnection(QPointer connectionData, quint32 timeout); - QModbusDataUnit::RegisterType registerType(ModbusAddress::ObjectType type); - ModbusAddress::ObjectType objectType(QModbusDataUnit::RegisterType type); - void handleConnectionError(QPointer connectionData, QString errMsg); - qint32 findConnectionData(QTimer * pTimer, QModbusClient * pClient); - QString connectionSummary() const; - - ConnectionTypes::type_t _connectionType; - tcpSettings_t _tcpSettings; - serialSettings_t _serialSettings; - - QList> _connectionList; - bool _bWaitingForConnection; - -}; - -#endif // MODBUSCONNECTION_H diff --git a/src/communication/modbusdataunit.cpp b/src/communication/modbusdataunit.cpp deleted file mode 100644 index 6007bbd9..00000000 --- a/src/communication/modbusdataunit.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "modbusdataunit.h" - -#include - -ModbusDataUnit::ModbusDataUnit(quint16 protocolAddress, ObjectType type, slaveId_t slaveId) - : ModbusAddress(protocolAddress, type), _slaveId(slaveId) -{ -} - -ModbusDataUnit::ModbusDataUnit(ModbusAddress const& addr, slaveId_t slaveId) : ModbusAddress(addr), _slaveId(slaveId) -{ -} - -ModbusDataUnit::slaveId_t ModbusDataUnit::slaveId() const -{ - return _slaveId; -} - -void ModbusDataUnit::setSlaveId(slaveId_t id) -{ - _slaveId = id; -} - -ModbusDataUnit ModbusDataUnit::next(int i) const -{ - return ModbusDataUnit(_protocolAddress + i, _type, _slaveId); -} - -QString ModbusDataUnit::toString() const -{ - return QString("%1, slave id %2").arg(ModbusAddress::toString()).arg(_slaveId); -} - -bool operator==(const ModbusDataUnit& unit1, const ModbusDataUnit& unit2) -{ - return std::tie(unit1._slaveId, unit1._type, unit1._protocolAddress) - == std::tie(unit2._slaveId, unit2._type, unit2._protocolAddress); -} - -bool operator<(const ModbusDataUnit& unit1, const ModbusDataUnit& unit2) -{ - return std::tie(unit1._slaveId, unit1._type, unit1._protocolAddress) - < std::tie(unit2._slaveId, unit2._type, unit2._protocolAddress); -} diff --git a/src/communication/modbusdataunit.h b/src/communication/modbusdataunit.h deleted file mode 100644 index da327cb4..00000000 --- a/src/communication/modbusdataunit.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef MODBUSDATAUNIT_H -#define MODBUSDATAUNIT_H - -#include "util/modbusaddress.h" - -class ModbusDataUnit : public ModbusAddress -{ -public: - using slaveId_t = quint8; - - explicit ModbusDataUnit(quint16 protocolAddress = 0, ObjectType type = ObjectType::UNKNOWN, slaveId_t slaveId = 1); - ModbusDataUnit(ModbusAddress const& addr, slaveId_t slaveId); - virtual ~ModbusDataUnit() = default; - - slaveId_t slaveId() const; - void setSlaveId(slaveId_t id); - - ModbusDataUnit next(int i = 1) const; - - QString toString() const override; - - friend bool operator==(const ModbusDataUnit& unit1, const ModbusDataUnit& unit2); - friend bool operator<(const ModbusDataUnit& unit1, const ModbusDataUnit& unit2); - -private: - slaveId_t _slaveId; -}; - -#endif // MODBUSDATAUNIT_H diff --git a/src/communication/modbusmaster.cpp b/src/communication/modbusmaster.cpp deleted file mode 100644 index 05b544bd..00000000 --- a/src/communication/modbusmaster.cpp +++ /dev/null @@ -1,256 +0,0 @@ -#include "modbusmaster.h" - -#include "communication/modbusconnection.h" -#include "communication/modbusresultmap.h" -#include "communication/readregisters.h" -#include "models/settingsmodel.h" -#include "util/scopelogging.h" - -Q_DECLARE_METATYPE(Result); - -using State = ResultState::State; - -ModbusMaster::ModbusMaster(ModbusConnection* pModbusConnection, - SettingsModel* pSettingsModel, - ConnectionTypes::connectionId_t connectionId) - : QObject(nullptr), _connectionId(connectionId), _pSettingsModel(pSettingsModel) -{ - qMetaTypeId >(); - - _pModbusConnection = std::unique_ptr(pModbusConnection); - - // Use queued connection to make sure reply is deleted before closing connection - connect(this, &ModbusMaster::triggerNextRequest, this, &ModbusMaster::handleTriggerNextRequest, Qt::QueuedConnection); - - connect(_pModbusConnection.get(), &ModbusConnection::connectionSuccess, this, - &ModbusMaster::handleConnectionOpened); - connect(_pModbusConnection.get(), &ModbusConnection::connectionError, this, &ModbusMaster::handlerConnectionError); - connect(_pModbusConnection.get(), &ModbusConnection::readRequestSuccess, this, &ModbusMaster::handleRequestSuccess); - connect(_pModbusConnection.get(), &ModbusConnection::readRequestProtocolError, this, - &ModbusMaster::handleRequestProtocolError); - connect(_pModbusConnection.get(), &ModbusConnection::readRequestError, this, &ModbusMaster::handleRequestError); -} - -ModbusMaster::~ModbusMaster() -{ - _pModbusConnection->disconnect(); - _pModbusConnection->close(); -} - -void ModbusMaster::readRegisterList(QList registerList, quint8 consecutiveMax) -{ - auto connData = _pSettingsModel->connectionSettings(_connectionId); - if (_pSettingsModel->connectionState(_connectionId) == false) - { - ModbusResultMap errMap; - - for (int i = 0; i < registerList.size(); i++) - { - const auto result = Result(0, State::INVALID); - errMap.insert(registerList.at(i), result); - } - - logError(QStringLiteral("Read failed because connection is disabled")); - logResults(errMap); - } - else if (registerList.size() > 0) - { - if (scopeCommConnection().isDebugEnabled()) - { - logDebug("Register list read: " + dumpToString(registerList)); - } - - _readRegisters.resetRead(registerList, consecutiveMax); - - /* Open connection */ - if (connData->connectionType() == ConnectionTypes::TYPE_SERIAL) - { - ModbusConnection::serialSettings_t serialSettings = { - .portName = connData->portName(), - .parity = connData->parity(), - .baudrate = connData->baudrate(), - .databits = connData->databits(), - .stopbits = connData->stopbits(), - }; - _pModbusConnection->configureSerialConnection(serialSettings); - } - else - { - ModbusConnection::tcpSettings_t tcpSettings = { - .ip = connData->ipAddress(), - .port = connData->port(), - }; - _pModbusConnection->configureTcpConnection(tcpSettings); - } - - _pModbusConnection->open(connData->timeout()); - } - else - { - ModbusResultMap emptyResults; - emit modbusPollDone(emptyResults, _connectionId); - } -} - -void ModbusMaster::cleanUp() -{ - /* Close connection when not closing automatically */ - if (_pSettingsModel->connectionSettings(_connectionId)->persistentConnection()) - { - _pModbusConnection->close(); - } -} - -void ModbusMaster::handleConnectionOpened() -{ - emit triggerNextRequest(); -} - -void ModbusMaster::handlerConnectionError(QModbusDevice::Error error, QString msg) -{ - Q_UNUSED(error); - - logError(QString("Connection error: ") + msg); - - _readRegisters.addAllErrors(); - - finishRead(true); -} - -void ModbusMaster::handleRequestSuccess(ModbusDataUnit const& startRegister, QList registerDataList) -{ - // Success - _readRegisters.addSuccess(startRegister, registerDataList); - - // Start next read - emit triggerNextRequest(); -} - -void ModbusMaster::handleRequestProtocolError(QModbusPdu::ExceptionCode exceptionCode) -{ - logError(QString("Modbus Exception: %1").arg(exceptionCode)); - - if ( - (exceptionCode == QModbusPdu::IllegalDataAddress) - || (exceptionCode == QModbusPdu::IllegalDataValue) - ) - { - if (_readRegisters.next().count() > 1) - { - // Split read into separate reads on specific exception code and count is more than 1 - _readRegisters.splitNextToSingleReads(); - } - else - { - // Add error to results - _readRegisters.addError(); - } - } - else if (exceptionCode == QModbusPdu::IllegalFunction) - { - // No need to continue this read - _readRegisters.addAllErrors(); - } - else - { - _readRegisters.addError(); - } - - // Start next read - emit triggerNextRequest(); -} - -void ModbusMaster::handleRequestError(QString errorString, QModbusDevice::Error error) -{ - logError(QString("Request Failed: %1 (%2)").arg(errorString).arg(error)); - - // When we don't receive an exception, abort read and close connection - _readRegisters.addAllErrors(); - - // Start next read - emit triggerNextRequest(); -} - -void ModbusMaster::handleTriggerNextRequest(void) -{ - if (_readRegisters.hasNext()) - { - ModbusReadItem readItem = _readRegisters.next(); - - if (scopeCommConnection().isDebugEnabled()) - { - logDebug("Partial list read: " + - QString("Start address (%1) and count (%2)").arg(readItem.address().toString()).arg(readItem.count())); - } - - _pModbusConnection->sendReadRequest(readItem.address(), readItem.count()); - } - else - { - finishRead(false); - } -} - -void ModbusMaster::finishRead(bool bError) -{ - ModbusResultMap results = _readRegisters.resultMap(); - - logResults(results); - - bool bcloseConnection; - - if (bError) - { - /* Always close connection on error */ - bcloseConnection = true; - } - else - { - bcloseConnection = !_pSettingsModel->connectionSettings(_connectionId)->persistentConnection(); - } - - if (bcloseConnection) - { - _pModbusConnection->close(); - } -} - -QString ModbusMaster::dumpToString(ModbusResultMap map) const -{ - QString str; - QDebug dStream(&str); - - dStream << map; - - return str; -} - -QString ModbusMaster::dumpToString(QList list) const -{ - QString str; - QDebug dStream(&str); - - dStream << &list; - - return str; -} - -void ModbusMaster::logResults(ModbusResultMap const &results) -{ - if (scopeCommConnection().isDebugEnabled()) - { - logDebug("Result map: " + dumpToString(results)); - } - - emit modbusPollDone(results, _connectionId); -} - -void ModbusMaster::logDebug(const QString& msg) -{ - qCDebug(scopeCommConnection) << QString("[Conn %1] %2").arg(_connectionId + 1).arg(msg); -} - -void ModbusMaster::logError(const QString& msg) -{ - qCWarning(scopeCommConnection) << QString("[Conn %1] %2").arg(_connectionId + 1).arg(msg); -} diff --git a/src/communication/modbusmaster.h b/src/communication/modbusmaster.h deleted file mode 100644 index 93b4abf1..00000000 --- a/src/communication/modbusmaster.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef MODBUSMASTER_H -#define MODBUSMASTER_H - -#include -#include -#include - -#include "communication/modbusconnection.h" -#include "communication/modbusresultmap.h" -#include "communication/readregisters.h" -#include "models/connectiontypes.h" - -/* Forward declaration */ -class SettingsModel; - -class ModbusMaster : public QObject -{ - Q_OBJECT -public: - explicit ModbusMaster(ModbusConnection* pModbusConnection, - SettingsModel* pSettingsModel, - ConnectionTypes::connectionId_t connectionId); - virtual ~ModbusMaster(); - - void readRegisterList(QList registerList, quint8 consecutiveMax); - - void cleanUp(); - -signals: - void modbusPollDone(ModbusResultMap modbusResults, ConnectionTypes::connectionId_t connectionId); - void triggerNextRequest(); - -private slots: - void handleConnectionOpened(); - void handlerConnectionError(QModbusDevice::Error error, QString msg); - - void handleRequestSuccess(ModbusDataUnit const& startRegister, QList registerDataList); - void handleRequestProtocolError(QModbusPdu::ExceptionCode exceptionCode); - void handleRequestError(QString errorString, QModbusDevice::Error error); - - void handleTriggerNextRequest(void); - -private: - void finishRead(bool bError); - QString dumpToString(ModbusResultMap map) const; - QString dumpToString(QList list) const; - - void logResults(const ModbusResultMap &results); - - void logDebug(const QString& msg); - void logError(const QString& msg); - - ConnectionTypes::connectionId_t _connectionId{}; - - std::unique_ptr _pModbusConnection; - SettingsModel* _pSettingsModel{}; - ReadRegisters _readRegisters{}; -}; - -#endif // MODBUSMASTER_H diff --git a/src/communication/modbuspoll.cpp b/src/communication/modbuspoll.cpp index c7c34298..20215ca7 100755 --- a/src/communication/modbuspoll.cpp +++ b/src/communication/modbuspoll.cpp @@ -3,54 +3,25 @@ #include -#include "communication/modbusmaster.h" -#include "communication/registervaluehandler.h" #include "models/settingsmodel.h" #include "util/formatdatetime.h" #include "util/scopelogging.h" -using connectionId_t = ConnectionTypes::connectionId_t; - ModbusPoll::ModbusPoll(SettingsModel* pSettingsModel, QObject* parent) : QObject(parent), _bPollActive(false) { - _pPollTimer = new QTimer(); _pSettingsModel = pSettingsModel; - - _pRegisterValueHandler = new RegisterValueHandler(_pSettingsModel); - connect(_pRegisterValueHandler, &RegisterValueHandler::registerDataReady, this, &ModbusPoll::registerDataReady); - - /* Setup modbus master */ - for (quint8 i = 0u; i < ConnectionTypes::ID_CNT; i++) - { - auto conn = new ModbusConnection(); // ModbusMaster takes ownership - auto master = new ModbusMaster(conn, pSettingsModel, i); - auto modbusData = new ModbusMasterData(master); - _modbusMasters.append(modbusData); - - connect(_modbusMasters.last()->pModbusMaster, &ModbusMaster::modbusPollDone, this, &ModbusPoll::handlePollDone); - } - - _activeMastersCount = 0; _lastPollStart = QDateTime::currentMSecsSinceEpoch(); } ModbusPoll::~ModbusPoll() { - for (qsizetype i = 0; i < _modbusMasters.size(); i++) - { - _modbusMasters[i]->pModbusMaster->disconnect(); - - delete _modbusMasters[i]->pModbusMaster; - delete _modbusMasters[i]; - } - delete _pPollTimer; } void ModbusPoll::startCommunication(QList& registerList) { - _pRegisterValueHandler->setRegisters(registerList); + _registerList = registerList; // Trigger read immediately _pPollTimer->singleShot(1, this, &ModbusPoll::triggerRegisterRead); @@ -59,48 +30,6 @@ void ModbusPoll::startCommunication(QList& registerList) qCInfo(scopeComm) << QString("Start logging: %1").arg(FormatDateTime::currentDateTime()); - for (quint8 i = 0u; i < ConnectionTypes::ID_CNT; i++) - { - QList addrList; - _pRegisterValueHandler->registerAddresListForConnection(addrList, i); - - if (!addrList.isEmpty()) - { - auto connData = _pSettingsModel->connectionSettings(i); - QString str; - if (connData->connectionType() == ConnectionTypes::TYPE_TCP) - { - str = QString("[Conn %1] %2:%3").arg(i + 1).arg(connData->ipAddress()).arg(connData->port()); - } - else - { - QString strParity; - QString strDataBits; - QString strStopBits; - connData->serialConnectionStrings(strParity, strDataBits, strStopBits); - - str = QString("[Conn %1] %2, %3, %4, %5, %6") - .arg(i + 1) - .arg(connData->portName()) - .arg(connData->baudrate()) - .arg(strParity, strDataBits, strStopBits); - } - qCInfo(scopeCommConnection) << qPrintable(str); - - const auto devicesForConn = _pSettingsModel->deviceListForConnection(i); - for (deviceId_t devId : devicesForConn) - { - Device* dev = _pSettingsModel->deviceSettings(devId); - QString devStr = QString("[Device] %1: slave ID %2, max consecutive %3, 32-bit little endian %4") - .arg(dev->name()) - .arg(dev->slaveId()) - .arg(dev->consecutiveMax()) - .arg(dev->int32LittleEndian() ? "true" : "false"); - qCInfo(scopeCommConnection) << qPrintable(devStr); - } - } - } - resetCommunicationStats(); } @@ -109,69 +38,12 @@ void ModbusPoll::resetCommunicationStats() _lastPollStart = QDateTime::currentMSecsSinceEpoch(); } -void ModbusPoll::handlePollDone(ModbusResultMap partialResultMap, connectionId_t connectionId) -{ - bool lastResult = false; - - quint8 activeCnt = 0; - for (quint8 i = 0; i < ConnectionTypes::ID_CNT; i++) - { - if (_modbusMasters[i]->bActive) - { - activeCnt++; - } - } - - /* Last active modbus master has returned its result */ - if (activeCnt == 1 || activeCnt == 0) - { - /* Last result */ - lastResult = true; - } - - // Always add data to result map - _pRegisterValueHandler->processPartialResult(partialResultMap, connectionId); - - // Set master as inactive - if (connectionId < ConnectionTypes::ID_CNT) - { - _modbusMasters[connectionId]->bActive = false; - } - - if (lastResult) - { - _pRegisterValueHandler->finishRead(); - - // Restart timer when previous request has been handled - uint waitInterval; - const quint32 passedInterval = static_cast(QDateTime::currentMSecsSinceEpoch() - _lastPollStart); - - if (passedInterval > _pSettingsModel->pollTime()) - { - // Poll again immediately - waitInterval = 1; - } - else - { - // Set waitInterval to remaining time - waitInterval = _pSettingsModel->pollTime() - passedInterval; - } - - _pPollTimer->singleShot(static_cast(waitInterval), this, &ModbusPoll::triggerRegisterRead); - } -} - void ModbusPoll::stopCommunication() { _bPollActive = false; _pPollTimer->stop(); qCInfo(scopeComm) << QString("Stop logging: %1").arg(FormatDateTime::currentDateTime()); - - for (quint8 i = 0; i < ConnectionTypes::ID_CNT; i++) - { - _modbusMasters[i]->pModbusMaster->cleanUp(); - } } bool ModbusPoll::isActive() @@ -185,61 +57,28 @@ void ModbusPoll::triggerRegisterRead() { _lastPollStart = QDateTime::currentMSecsSinceEpoch(); - _pRegisterValueHandler->startRead(); - - /* Strange construction is required to avoid race condition: - * - * First set _activeMastersCount to correct value - * And only then activate masters (readRegisterList) - * - * readRegisterList can return immediately and this will give race condition otherwise - */ - - _activeMastersCount = 0; - - QList > regAddrList; - - for (connectionId_t i = 0u; i < ConnectionTypes::ID_CNT; i++) + ResultDoubleList results; + for (qsizetype i = 0; i < _registerList.size(); i++) { - regAddrList.append(QList()); - - _pRegisterValueHandler->registerAddresListForConnection(regAddrList.last(), i); - - if (regAddrList.last().count() > 0) - { - _activeMastersCount++; - } + results.append(ResultDouble()); } + emit registerDataReady(results); - for (connectionId_t i = 0u; i < ConnectionTypes::ID_CNT; i++) - { - if (regAddrList.at(i).count() > 0) - { - quint8 consecutiveMax = lowestConsecutiveMaxForConnection(i); - _modbusMasters[i]->bActive = true; - _modbusMasters[i]->pModbusMaster->readRegisterList(regAddrList.at(i), consecutiveMax); - } - } + // Reschedule timer + uint waitInterval; + const quint32 passedInterval = static_cast(QDateTime::currentMSecsSinceEpoch() - _lastPollStart); - if (_activeMastersCount == 0) + if (passedInterval > _pSettingsModel->pollTime()) { - ModbusResultMap emptyResultMap; - handlePollDone(emptyResultMap, ConnectionTypes::ID_1); + // Poll again immediately + waitInterval = 1; } - } -} - -quint8 ModbusPoll::lowestConsecutiveMaxForConnection(connectionId_t connId) const -{ - quint8 consecutiveMax = 128; - QList devList = _pSettingsModel->deviceListForConnection(connId); - for (deviceId_t devId : std::as_const(devList)) - { - quint8 devConsecutiveMax = _pSettingsModel->deviceSettings(devId)->consecutiveMax(); - if (devConsecutiveMax < consecutiveMax) + else { - consecutiveMax = devConsecutiveMax; + // Set waitInterval to remaining time + waitInterval = _pSettingsModel->pollTime() - passedInterval; } + + _pPollTimer->singleShot(static_cast(waitInterval), this, &ModbusPoll::triggerRegisterRead); } - return consecutiveMax; } diff --git a/src/communication/modbuspoll.h b/src/communication/modbuspoll.h index aada25ab..af405242 100755 --- a/src/communication/modbuspoll.h +++ b/src/communication/modbuspoll.h @@ -2,31 +2,11 @@ #define COMMUNICATION_MANAGER_H #include "communication/modbusregister.h" -#include "communication/modbusresultmap.h" -#include "models/connectiontypes.h" -#include +#include "util/result.h" #include //Forward declaration class SettingsModel; -class RegisterValueHandler; -class ModbusMaster; - -class ModbusMasterData : public QObject -{ - Q_OBJECT -public: - - explicit ModbusMasterData(ModbusMaster * pArgModbusMaster, QObject *parent = nullptr): - QObject(parent) - { - pModbusMaster = pArgModbusMaster; - bActive = false; - } - - ModbusMaster * pModbusMaster; - bool bActive; -}; class ModbusPoll : public QObject { @@ -45,21 +25,15 @@ class ModbusPoll : public QObject void registerDataReady(ResultDoubleList registers); private slots: - void handlePollDone(ModbusResultMap partialResultMap, ConnectionTypes::connectionId_t connectionId); void triggerRegisterRead(); private: - quint8 lowestConsecutiveMaxForConnection(ConnectionTypes::connectionId_t connId) const; - - QList _modbusMasters; - quint32 _activeMastersCount; + QList _registerList; bool _bPollActive; QTimer * _pPollTimer; qint64 _lastPollStart; - RegisterValueHandler* _pRegisterValueHandler; - SettingsModel * _pSettingsModel; }; diff --git a/src/communication/modbusresultmap.h b/src/communication/modbusresultmap.h deleted file mode 100644 index 18d787ec..00000000 --- a/src/communication/modbusresultmap.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef MODBUSRESULTMAP_H -#define MODBUSRESULTMAP_H - -#include "communication/modbusdataunit.h" -#include "util/result.h" -#include - -using ModbusResultMap = QMap>; - -#endif // MODBUSRESULTMAP_H diff --git a/src/communication/readregisters.cpp b/src/communication/readregisters.cpp deleted file mode 100644 index 3d02ea4d..00000000 --- a/src/communication/readregisters.cpp +++ /dev/null @@ -1,190 +0,0 @@ -#include "readregisters.h" - -using State = ResultState::State; - -ReadRegisters::ReadRegisters() -{ - -} - -/*! - * Load ReadRegisterCollection with register read list - * \param registerList Register read list - * \param consecutiveMax Number of consecutive registers that is allowed to read at once - */ -void ReadRegisters::resetRead(QList registerList, quint16 consecutiveMax) -{ - _resultMap.clear(); - - if (registerList.size() == 0) - { - _readItemList.clear(); - } - - while(registerList.size() > 0) - { - if ( - (registerList.size() == 1) - || (consecutiveMax == 1) - ) - { - // Only single reads allowed - _readItemList.append(ModbusReadItem(registerList.first(), 1)); - - registerList.removeFirst(); - } - else - { - int currentIdx = 0; - - bool bSubsequent = false; - do - { - - // if next is current + 1, dan subsequent = true - if (registerList.at(currentIdx).next() == registerList.at(currentIdx + 1)) - { - bSubsequent = true; - currentIdx++; - } - else - { - bSubsequent = false; - } - - // Break loop when end of list - if (currentIdx >= (registerList.size() - 1)) - { - break; - } - - // Limit number of register in 1 read - if ((currentIdx + 1) >= consecutiveMax) - { - break; - } - - } while(bSubsequent == true); - - - // Convert idx to count - quint8 count = static_cast(currentIdx) + 1; - - _readItemList.append(ModbusReadItem(registerList.first(), count)); - - for (int idx = 0; idx < count; idx++) - { - registerList.removeFirst(); - } - } - } -} - -/*! - * Return whether there is still a ModbusReadItem left - * \retval true Still ModbusReadItemLeft - * \retval false None left - */ -bool ReadRegisters::hasNext() -{ - return !_readItemList.isEmpty(); -} - -/*! - * Get next ModbusReadItem - * \return next ModbusReadItem (item with count 0 when no item available) - */ -ModbusReadItem ReadRegisters::next() -{ - if (hasNext()) - { - return _readItemList.first(); - } - else - { - return ModbusReadItem(ModbusDataUnit(0), 0); - } -} - -/*! - * Add success result for current ReadRegister cluster - * \param startRegister Start register address - * \param registerDataList List with result data - */ -void ReadRegisters::addSuccess(ModbusDataUnit const& startRegister, QList registerDataList) -{ - if ( - hasNext() - && (next().address() == startRegister) - && (registerDataList.size() >= next().count()) - ) - { - for (qint32 i = 0; i < next().count(); i++) - { - const auto registerAddr = startRegister.next(i); - const auto result = Result(registerDataList[i], State::SUCCESS); - - _resultMap.insert(registerAddr, result); - } - - _readItemList.removeFirst(); - } -} - -/*! - * Add error result for current ReadRegister cluster - */ -void ReadRegisters::addError() -{ - if (hasNext()) - { - auto nextRequestData = next(); - for (int i = 0; i < nextRequestData.count(); i++) - { - const auto registerAddr = nextRequestData.address().next(i); - const auto result = Result(0, State::INVALID); - - _resultMap.insert(registerAddr, result); - } - - _readItemList.removeFirst(); - } -} - -/*! - * Mark all remaining register as errors - */ -void ReadRegisters::addAllErrors() -{ - while(hasNext()) - { - addError(); - } -} - -/*! - * Split "next" ModbusReadItem into single reads. - */ -void ReadRegisters::splitNextToSingleReads() -{ - if (hasNext()) - { - ModbusReadItem firstItem = _readItemList.first(); - - _readItemList.removeFirst(); - - for(int idx = firstItem.count(); idx > 0; idx--) - { - _readItemList.prepend(ModbusReadItem(firstItem.address().next(idx - 1), 1)); - } - } -} - -/*! - * Return result map - * \return Result map - */ -ModbusResultMap ReadRegisters::resultMap() -{ - return _resultMap; -} diff --git a/src/communication/readregisters.h b/src/communication/readregisters.h deleted file mode 100644 index f29eb439..00000000 --- a/src/communication/readregisters.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef READREGISTERCOLLECTION_H -#define READREGISTERCOLLECTION_H - -#include - -#include "communication/modbusresultmap.h" - -class ModbusReadItem -{ -public: - ModbusReadItem(ModbusDataUnit const& address, quint8 count) : _address(address), _count(count) - { - } - - ModbusDataUnit address() const - { - return _address; - } - quint8 count() const - { - return _count; - } - -private: - ModbusDataUnit _address; - quint8 _count{}; - -}; - - -class ReadRegisters -{ -public: - ReadRegisters(); - - void resetRead(QList registerList, quint16 consecutiveMax); - - bool hasNext(); - ModbusReadItem next(); - - void addSuccess(ModbusDataUnit const& startRegister, QList registerDataList); - void addError(); - void addAllErrors(); - void splitNextToSingleReads(); - - ModbusResultMap resultMap(); - -private: - - - QList _readItemList; - - ModbusResultMap _resultMap; - -}; - -#endif // READREGISTERCOLLECTION_H diff --git a/src/communication/registervaluehandler.cpp b/src/communication/registervaluehandler.cpp deleted file mode 100644 index a364bbb3..00000000 --- a/src/communication/registervaluehandler.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include "registervaluehandler.h" - -#include "communication/modbusdataunit.h" -#include "models/settingsmodel.h" -#include "util/modbusdatatype.h" - -using State = ResultState::State; -using connectionId_t = ConnectionTypes::connectionId_t; - -RegisterValueHandler::RegisterValueHandler(SettingsModel* pSettingsModel) : _pSettingsModel(pSettingsModel) -{ -} - -void RegisterValueHandler::startRead() -{ - _resultList.clear(); - - for (qsizetype listIdx = 0; listIdx < _registerList.size(); listIdx++) - { - _resultList.append(ResultDouble(0, State::INVALID)); - } -} - -void RegisterValueHandler::finishRead() -{ - emit registerDataReady(_resultList); -} - -void RegisterValueHandler::processPartialResult(ModbusResultMap partialResultMap, connectionId_t connectionId) -{ - auto deviceList = _pSettingsModel->deviceListForConnection(connectionId); - - for (qint32 listIdx = 0; listIdx < _registerList.size(); listIdx++) - { - const ModbusRegister mbReg = _registerList[listIdx]; - - if (deviceList.contains(mbReg.deviceId())) - { - auto slaveId = _pSettingsModel->deviceSettings(mbReg.deviceId())->slaveId(); - ModbusDataUnit dataUnit(mbReg.address(), slaveId); - if (partialResultMap.contains(dataUnit)) - { - Result upperRegister; - Result lowerRegister; - - lowerRegister = partialResultMap.value(dataUnit); - - if (ModbusDataType::is32Bit(mbReg.type())) - { - const auto addr = dataUnit.next(); - if (partialResultMap.contains(addr)) - { - upperRegister = partialResultMap.value(addr); - } - } - else - { - /* Dummy valid value */ - upperRegister = Result(0, State::SUCCESS); - } - - bool bSuccess = lowerRegister.isValid() && upperRegister.isValid(); - ResultDouble result; - if (bSuccess) - { - double processedResult = - mbReg.processValue(lowerRegister.value(), upperRegister.value(), - _pSettingsModel->deviceSettings(mbReg.deviceId())->int32LittleEndian()); - result.setValue(processedResult); - } - else - { - result.setError(); - } - - _resultList[listIdx] = result; - } - } - } -} - -// Get sorted list of active (unique) register addresses for a specific connection id -void RegisterValueHandler::registerAddresListForConnection(QList& registerList, - connectionId_t connectionId) -{ - QList connRegisterList; - - // Get list of devices for specific connection - auto deviceList = _pSettingsModel->deviceListForConnection(connectionId); - - for (auto const& mbReg : std::as_const(_registerList)) - { - if (deviceList.contains(mbReg.deviceId())) - { - auto slaveId = _pSettingsModel->deviceSettings(mbReg.deviceId())->slaveId(); - auto address = ModbusDataUnit(mbReg.address(), slaveId); - - if (!connRegisterList.contains(address)) - { - connRegisterList.append(address); - } - - /* When reading 32 bit value, also read next address */ - if (ModbusDataType::is32Bit(mbReg.type())) - { - const auto reg = address.next(); - if (!connRegisterList.contains(reg)) - { - connRegisterList.append(reg); - } - } - } - } - - // sort qList - std::sort(connRegisterList.begin(), connRegisterList.end(), std::less()); - - registerList = connRegisterList; -} - -void RegisterValueHandler::setRegisters(QList& registerList) -{ - _registerList = registerList; -} diff --git a/src/communication/registervaluehandler.h b/src/communication/registervaluehandler.h deleted file mode 100644 index ddb7222e..00000000 --- a/src/communication/registervaluehandler.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef REGISTERVALUEHANDLER_H -#define REGISTERVALUEHANDLER_H - -#include - -#include "communication/modbusregister.h" -#include "communication/modbusresultmap.h" -#include "models/connectiontypes.h" - -class SettingsModel; - -class RegisterValueHandler : public QObject -{ - Q_OBJECT -public: - - explicit RegisterValueHandler(SettingsModel *pSettingsModel); - - void setRegisters(QList ®isterList); - - void startRead(); - void processPartialResult(ModbusResultMap partialResultMap, ConnectionTypes::connectionId_t connectionId); - void finishRead(); - - void registerAddresListForConnection(QList& registerList, - ConnectionTypes::connectionId_t connectionId); - -signals: - void registerDataReady(ResultDoubleList registers); - -private: - SettingsModel* _pSettingsModel; - - QList _registerList; - ResultDoubleList _resultList; -}; - -#endif // REGISTERVALUEHANDLER_H diff --git a/src/util/modbusdatatype.cpp b/src/util/modbusdatatype.cpp index b57f63a3..27098d25 100644 --- a/src/util/modbusdatatype.cpp +++ b/src/util/modbusdatatype.cpp @@ -1,4 +1,3 @@ - #include "modbusdatatype.h" const ModbusDataType::TypeSettings ModbusDataType::cDataTypes[] = diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 107a64c7..97e3fe9b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -49,7 +49,6 @@ endfunction() set(CMAKE_AUTOUIC_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../src/dialogs ${CMAKE_CURRENT_SOURCE_DIR}/../src/customwidgets) -add_subdirectory(communication) add_subdirectory(customwidgets) add_subdirectory(datahandling) add_subdirectory(dialogs) diff --git a/tests/communication/CMakeLists.txt b/tests/communication/CMakeLists.txt deleted file mode 100644 index 0e1004ef..00000000 --- a/tests/communication/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ - -SET(TEST_SRCS - ${CMAKE_CURRENT_SOURCE_DIR}/../testslave/testslavedata.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/../testslave/testslavemodbus.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/../testslave/testslavemodbusmulti.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/../testslave/testdevice.cpp -) - -SET(FAKE_SRCS - ${CMAKE_CURRENT_SOURCE_DIR}/../testslave/modbusconnectionfake.cpp -) - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/../testslave -) - -add_xtest(tst_communicationstats) -add_xtest(tst_communication ${TEST_SRCS}) -add_xtest(tst_modbusconnection ${TEST_SRCS}) -add_xtest(tst_modbusdatatype) -add_xtest(tst_modbusdataunit) -add_xtest(tst_modbusmaster ${TEST_SRCS}) -add_xtest(tst_modbusmasterfake ${TEST_SRCS} ${FAKE_SRCS}) -add_xtest(tst_modbuspoll ${TEST_SRCS}) -add_xtest(tst_modbusregister) -add_xtest(tst_readregisters) -add_xtest(tst_registervaluehandler) - diff --git a/tests/communication/communicationhelpers.h b/tests/communication/communicationhelpers.h index c88f4d70..ee0b307e 100644 --- a/tests/communication/communicationhelpers.h +++ b/tests/communication/communicationhelpers.h @@ -37,4 +37,3 @@ class CommunicationHelpers : public QObject #endif // COMMUNICATIONHELPERS_H - diff --git a/tests/communication/tst_communication.cpp b/tests/communication/tst_communication.cpp deleted file mode 100644 index 6368ce2e..00000000 --- a/tests/communication/tst_communication.cpp +++ /dev/null @@ -1,258 +0,0 @@ - -#include "tst_communication.h" - -#include "communication/modbuspoll.h" -#include "communicationhelpers.h" -#include "datahandling/graphdatahandler.h" -#include "models/graphdatamodel.h" -#include "models/settingsmodel.h" - -#include "testslavemodbus.h" - -#include -#include - -using State = ResultState::State; - -void TestCommunication::init() -{ - _pSettingsModel = new SettingsModel; - _pGraphDataModel = new GraphDataModel(_pSettingsModel); - - auto connData = _pSettingsModel->connectionSettings(ConnectionTypes::ID_1); - connData->setIpAddress("127.0.0.1"); - connData->setPort(5020); - connData->setTimeout(500); - - _pSettingsModel->setConnectionState(ConnectionTypes::ID_2, true); - connData = _pSettingsModel->connectionSettings(ConnectionTypes::ID_2); - connData->setIpAddress("127.0.0.1"); - connData->setPort(5021); - connData->setTimeout(500); - - _pSettingsModel->setConnectionState(ConnectionTypes::ID_3, true); - connData = _pSettingsModel->connectionSettings(ConnectionTypes::ID_3); - connData->setIpAddress("127.0.0.1"); - connData->setPort(5022); - connData->setTimeout(500); - - deviceId_t devId = Device::cFirstDeviceId; - _pSettingsModel->addDevice(devId); - _pSettingsModel->deviceSettings(devId)->setConnectionId(ConnectionTypes::ID_1); - _pSettingsModel->deviceSettings(devId)->setSlaveId(ConnectionTypes::ID_1 + 1); // TODO: dev: dirty hack - - devId++; - _pSettingsModel->addDevice(devId); - _pSettingsModel->deviceSettings(devId)->setConnectionId(ConnectionTypes::ID_2); - _pSettingsModel->deviceSettings(devId)->setSlaveId(ConnectionTypes::ID_1 + 2); - - devId++; - _pSettingsModel->addDevice(devId); - _pSettingsModel->deviceSettings(devId)->setConnectionId(ConnectionTypes::ID_3); - _pSettingsModel->deviceSettings(devId)->setSlaveId(ConnectionTypes::ID_1 + 3); - - _pSettingsModel->setPollTime(100); - - const auto deviceList = _pSettingsModel->deviceList(); - for (deviceId_t devId : std::as_const(deviceList)) - { - auto device = _pSettingsModel->deviceSettings(devId); - - connData = _pSettingsModel->connectionSettings(device->connectionId()); - - _testSlaveMap[devId] = new TestSlaveModbus(); - auto& testSlave = _testSlaveMap[devId]; - - QVERIFY(testSlave->connect(connData->ipAddress(), connData->port(), device->slaveId())); - } -} - -void TestCommunication::cleanup() -{ - for (auto& testSlave : _testSlaveMap) - { - testSlave->disconnect(); - delete testSlave; - } - - delete _pGraphDataModel; - delete _pSettingsModel; -} - -void TestCommunication::singleSlaveSuccess() -{ - auto exprList = QStringList() << "${40002}" - << "${40001}"; - CommunicationHelpers::addExpressionsToModel(_pGraphDataModel, exprList); - - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - device->configureHoldingRegister(0, true, 1); - device->configureHoldingRegister(1, true, 2); - - auto resultList = ResultDoubleList() << ResultDouble(2, State::SUCCESS) << ResultDouble(1, State::SUCCESS); - - QList rawRegData; - doHandleRegisterData(rawRegData); - - CommunicationHelpers::verifyReceivedDataSignal(rawRegData, resultList); -} - -void TestCommunication::typeFloat32() -{ - auto exprList = QStringList() << "${40001: f32b}"; - CommunicationHelpers::addExpressionsToModel(_pGraphDataModel, exprList); - - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - device->configureHoldingRegister(0, true, 0xffff); - device->configureHoldingRegister(1, true, 0x3f7f); - - auto resultList = ResultDoubleList() << ResultDouble(static_cast(0.999999940395355225f), State::SUCCESS); - - QList rawRegData; - doHandleRegisterData(rawRegData); - - CommunicationHelpers::verifyReceivedDataSignal(rawRegData, resultList); -} - -void TestCommunication::constantExpression() -{ - auto exprList = QStringList() << "3"; - CommunicationHelpers::addExpressionsToModel(_pGraphDataModel, exprList); - - auto resultList = ResultDoubleList() << ResultDouble(3, State::SUCCESS); - - QList rawRegData; - doHandleRegisterData(rawRegData); - - CommunicationHelpers::verifyReceivedDataSignal(rawRegData, resultList); -} - -void TestCommunication::mixed_1() -{ - auto exprList = QStringList() << "${40002@2} + ${40003}" - << "2" - << "${40004:32b}"; - - CommunicationHelpers::addExpressionsToModel(_pGraphDataModel, exprList); - - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - auto device_2 = _testSlaveMap[Device::cFirstDeviceId + 1]->testDevice(); - device_2->configureHoldingRegister(1, true, 1); - device->configureHoldingRegister(2, true, 5); - device->configureHoldingRegister(3, true, 2); - device->configureHoldingRegister(4, true, 1); - - auto resultList = ResultDoubleList() << ResultDouble(6, State::SUCCESS) << ResultDouble(2, State::SUCCESS) - << ResultDouble(65538, State::SUCCESS); - - QList rawRegData; - doHandleRegisterData(rawRegData); - - CommunicationHelpers::verifyReceivedDataSignal(rawRegData, resultList); -} - -void TestCommunication::mixed_fail() -{ - auto exprList = QStringList() << "${40001} + ${40002}" - << "${40003}" - << "${40004}"; - - CommunicationHelpers::addExpressionsToModel(_pGraphDataModel, exprList); - - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - device->configureHoldingRegister(0, false, 0); - device->configureHoldingRegister(1, true, 1); - device->configureHoldingRegister(2, false, 2); - device->configureHoldingRegister(3, true, 3); - - auto resultList = ResultDoubleList() << ResultDouble(0, State::INVALID) << ResultDouble(0, State::INVALID) - << ResultDouble(3, State::SUCCESS); - - QList rawRegData; - doHandleRegisterData(rawRegData); - - CommunicationHelpers::verifyReceivedDataSignal(rawRegData, resultList); -} - -void TestCommunication::readLargeRegisterAddress() -{ - auto testSlaveData = new TestSlaveData(71001 - 40001, 50); - - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - device->setSlaveData(QModbusDataUnit::HoldingRegisters, testSlaveData); - - testSlaveData->setRegisterState(71001 - 40001, true); - testSlaveData->setRegisterValue(71001 - 40001, 1); - - auto exprList = QStringList() << "${71001}"; - CommunicationHelpers::addExpressionsToModel(_pGraphDataModel, exprList); - - auto resultList = ResultDoubleList() << ResultDouble(1, State::SUCCESS); - - QList rawRegData; - doHandleRegisterData(rawRegData); - - CommunicationHelpers::verifyReceivedDataSignal(rawRegData, resultList); -} - -void TestCommunication::unknownConnection() -{ - auto exprList = QStringList() << "${40001@255}" - << "${40001}"; - - CommunicationHelpers::addExpressionsToModel(_pGraphDataModel, exprList); - - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - device->configureHoldingRegister(0, true, 2); - - auto resultList = ResultDoubleList() << ResultDouble(0, State::INVALID) - << ResultDouble(2, State::SUCCESS); - - QList rawRegData; - doHandleRegisterData(rawRegData); - - CommunicationHelpers::verifyReceivedDataSignal(rawRegData, resultList); -} - -void TestCommunication::disabledConnection() -{ - auto exprList = QStringList() << "${40001@1}" - << "${40001@2}"; - - _pSettingsModel->setConnectionState(ConnectionTypes::ID_2, false); - - CommunicationHelpers::addExpressionsToModel(_pGraphDataModel, exprList); - - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - device->configureHoldingRegister(0, true, 5); - - auto resultList = ResultDoubleList() << ResultDouble(5, State::SUCCESS) - << ResultDouble(0, State::INVALID); - - QList rawRegData; - doHandleRegisterData(rawRegData); - - CommunicationHelpers::verifyReceivedDataSignal(rawRegData, resultList); -} - -void TestCommunication::doHandleRegisterData(QList& actRawData) -{ - GraphDataHandler dataHandler; - ModbusPoll modbusPoll(_pSettingsModel); - connect(&modbusPoll, &ModbusPoll::registerDataReady, &dataHandler, &GraphDataHandler::handleRegisterData); - - QList registerList; - dataHandler.setupExpressions(_pGraphDataModel, registerList); - - QSignalSpy spyDataReady(&dataHandler, &GraphDataHandler::graphDataReady); - - modbusPoll.startCommunication(registerList); - - auto timeout = _pSettingsModel->connectionSettings(ConnectionTypes::ID_1)->timeout(); - QVERIFY(spyDataReady.wait(static_cast(timeout) + 100)); - QCOMPARE(spyDataReady.count(), 1); - - actRawData = spyDataReady.takeFirst(); -} - -QTEST_GUILESS_MAIN(TestCommunication) diff --git a/tests/communication/tst_communication.h b/tests/communication/tst_communication.h deleted file mode 100644 index 0450bb95..00000000 --- a/tests/communication/tst_communication.h +++ /dev/null @@ -1,40 +0,0 @@ - -#include "models/device.h" -#include "testdevice.h" - -#include - -/* Forward declaration */ -class SettingsModel; -class GraphDataModel; -class ModbusPoll; -class TestSlaveModbus; - -class TestCommunication: public QObject -{ - Q_OBJECT -private slots: - void init(); - void cleanup(); - - void singleSlaveSuccess(); - - void typeFloat32(); - - void constantExpression(); - - void mixed_1(); - void mixed_fail(); - - void readLargeRegisterAddress(); - - void unknownConnection(); - void disabledConnection(); - -private: - void doHandleRegisterData(QList& actRawData); - - SettingsModel * _pSettingsModel; - GraphDataModel* _pGraphDataModel; - QMap _testSlaveMap; -}; diff --git a/tests/communication/tst_communicationstats.cpp b/tests/communication/tst_communicationstats.cpp deleted file mode 100644 index a8017caa..00000000 --- a/tests/communication/tst_communicationstats.cpp +++ /dev/null @@ -1,113 +0,0 @@ - -#include "tst_communicationstats.h" - -#include "communication/communicationstats.h" -#include "models/graphdatamodel.h" - -#include - -void TestCommunicationStats::init() -{ - _pGraphDataModel = new GraphDataModel(); - _pGraphDataModel->add(); - - _pCommunicationStats = new CommunicationStats(_pGraphDataModel); -} - -void TestCommunicationStats::cleanup() -{ - delete _pCommunicationStats; - delete _pGraphDataModel; -} - -void TestCommunicationStats::noGraph() -{ - _pGraphDataModel->clear(); - - _pCommunicationStats->updateTimingInfo(); - - QCOMPARE(_pGraphDataModel->medianPollTime(), 0); -} - -void TestCommunicationStats::notEnoughDataCount() -{ - QVector times = QVector() << 1; - setPollData(times); - _pCommunicationStats->updateTimingInfo(); - - QCOMPARE(_pGraphDataModel->medianPollTime(), 0); -} - -void TestCommunicationStats::justEnoughDataCount() -{ - QVector times = QVector() << 1 << 2; - setPollData(times); - - _pCommunicationStats->updateTimingInfo(); - - QCOMPARE(_pGraphDataModel->medianPollTime(), 1); -} - -void TestCommunicationStats::dataCountIsEven() -{ - QVector times = QVector() << 1 << 1 << 2 << 3 << 5 << 8; - setPollData(times); - - _pCommunicationStats->updateTimingInfo(); - - QCOMPARE(_pGraphDataModel->medianPollTime(), 1); -} - -void TestCommunicationStats::dataCountIsNotEven() -{ - QVector times = QVector() << 1 << 1 << 2 << 3 << 5 << 7 << 12; - setPollData(times); - - _pCommunicationStats->updateTimingInfo(); - - QCOMPARE(_pGraphDataModel->medianPollTime(), 2); -} - -void TestCommunicationStats::pollTimeDiffIsGettingSmaller() -{ - /* 100 ms sample time with variation of reverse fibonacci (12 to 1) */ - QVector times = QVector() << 0 << 112 << 219 << 324 << 427 << 529 << 630; - setPollData(times); - - _pCommunicationStats->updateTimingInfo(); - - QCOMPARE(_pGraphDataModel->medianPollTime(), 105); -} - -void TestCommunicationStats::onlyLastXSamples() -{ - auto _pCommunicationStatsLimited = new CommunicationStats(_pGraphDataModel, 3); - - QVector times = QVector() << 1 << 1 << 2 << 3 << 5 << 7 << 12; - setPollData(times); - - _pCommunicationStats->updateTimingInfo(); - QCOMPARE(_pGraphDataModel->medianPollTime(), 2); - - _pCommunicationStatsLimited->updateTimingInfo(); - QCOMPARE(_pGraphDataModel->medianPollTime(), 5); - - delete _pCommunicationStatsLimited; -} - -void TestCommunicationStats::setPollData(QVector times) -{ - QSharedPointer dataMap = _pGraphDataModel->dataMap(0); - - QVector data; - - foreach (double time, times) - { - data.append(QCPGraphData(time, 0)); - } - - dataMap->add(data); -} - - -QTEST_GUILESS_MAIN(TestCommunicationStats) diff --git a/tests/communication/tst_communicationstats.h b/tests/communication/tst_communicationstats.h deleted file mode 100644 index ada787e3..00000000 --- a/tests/communication/tst_communicationstats.h +++ /dev/null @@ -1,31 +0,0 @@ - -#include - -/* Forward declaration */ -class GraphDataModel; -class CommunicationStats; - -class TestCommunicationStats: public QObject -{ - Q_OBJECT - -private slots: - void init(); - void cleanup(); - - void noGraph(); - void notEnoughDataCount(); - void justEnoughDataCount(); - void dataCountIsEven(); - void dataCountIsNotEven(); - void pollTimeDiffIsGettingSmaller(); - void onlyLastXSamples(); - -private: - void setPollData(QVector times); - - GraphDataModel* _pGraphDataModel; - - CommunicationStats* _pCommunicationStats; - -}; diff --git a/tests/communication/tst_modbusconnection.cpp b/tests/communication/tst_modbusconnection.cpp deleted file mode 100644 index e9d547a3..00000000 --- a/tests/communication/tst_modbusconnection.cpp +++ /dev/null @@ -1,198 +0,0 @@ - -#include "tst_modbusconnection.h" - -#include -#include - -Q_DECLARE_METATYPE(ModbusDataUnit); - -void TestModbusConnection::init() -{ - qRegisterMetaType("QModbusDevice::Error"); - - _slaveId = 1; - _port = 5020; - _ip = "127.0.0.1"; - - /* Server not started */ -} - -void TestModbusConnection::cleanup() -{ - _testSlaveModbus.disconnectDevice(); -} - -void TestModbusConnection::connectionSuccess() -{ - /* Start server */ - QVERIFY(_testSlaveModbus.connect(_ip, _port, _slaveId)); - - ModbusConnection* pConnection = new ModbusConnection(this); - - QSignalSpy spySuccess(pConnection, &ModbusConnection::connectionSuccess); - QSignalSpy spyError(pConnection, &ModbusConnection::connectionError); - - pConnection->configureTcpConnection(constructTcpSettings(_ip, _port)); - pConnection->open(1000); - - QVERIFY(spySuccess.wait(100)); - - QCOMPARE(spySuccess.count(), 1); - QCOMPARE(spyError.count(), 0); - - QVERIFY(pConnection->isConnected()); - - pConnection->close(); - - QVERIFY(!pConnection->isConnected()); -} - -void TestModbusConnection::connectionFail() -{ - ModbusConnection* pConnection = new ModbusConnection(this); - - QSignalSpy spySuccess(pConnection, &ModbusConnection::connectionSuccess); - QSignalSpy spyError(pConnection, &ModbusConnection::connectionError); - - pConnection->configureTcpConnection(constructTcpSettings(_ip, _port)); - pConnection->open(1000); - - QVERIFY(spyError.wait(1500)); - - QCOMPARE(spySuccess.count(), 0); - QCOMPARE(spyError.count(), 1); - - QVERIFY(!pConnection->isConnected()); -} - -void TestModbusConnection::connectionSuccesAfterFail() -{ - ModbusConnection* pConnection = new ModbusConnection(this); - - QSignalSpy spySuccess(pConnection, &ModbusConnection::connectionSuccess); - QSignalSpy spyError(pConnection, &ModbusConnection::connectionError); - - pConnection->configureTcpConnection(constructTcpSettings(_ip, _port)); - pConnection->open(1000); - - QVERIFY(spyError.wait(1500)); - - QCOMPARE(spySuccess.count(), 0); - QCOMPARE(spyError.count(), 1); - - QVERIFY(!pConnection->isConnected()); - - // Start server - QVERIFY(_testSlaveModbus.connect(_ip, _port, _slaveId)); - - pConnection->configureTcpConnection(constructTcpSettings(_ip, _port)); - pConnection->open(1000); - - QVERIFY(spySuccess.wait(500)); - - QCOMPARE(spySuccess.count(), 1); - QVERIFY(pConnection->isConnected()); - - pConnection->close(); -} - -void TestModbusConnection::readRequestSuccess() -{ - /* Start server */ - QVERIFY(_testSlaveModbus.connect(_ip, _port, _slaveId)); - - _testSlaveModbus.testDevice()->configureHoldingRegister(0, true, 0); - _testSlaveModbus.testDevice()->configureHoldingRegister(1, true, 1); - - /* Open connection */ - ModbusConnection* pConnection = new ModbusConnection(this); - QSignalSpy spySuccess(pConnection, &ModbusConnection::connectionSuccess); - pConnection->configureTcpConnection(constructTcpSettings(_ip, _port)); - pConnection->open(1000); - - QVERIFY(spySuccess.wait(100)); - - QVERIFY(pConnection->isConnected()); - - QSignalSpy spyResultSuccess(pConnection, &ModbusConnection::readRequestSuccess); - QSignalSpy spyResultProtocolError(pConnection, &ModbusConnection::readRequestProtocolError); - QSignalSpy spyResultError(pConnection, &ModbusConnection::readRequestError); - - pConnection->sendReadRequest(ModbusDataUnit(40001), 2); - - QVERIFY(spyResultSuccess.wait(100)); - QCOMPARE(spyResultSuccess.count(), 1); - QCOMPARE(spyResultProtocolError.count(), 0); - QCOMPARE(spyResultError.count(), 0); - - QList arguments = spyResultSuccess.takeFirst(); - QCOMPARE(arguments.count(), 2); - - /* Check start address */ - QVERIFY((arguments[0].canConvert())); - auto resultAddr = arguments[0].value(); - QCOMPARE(resultAddr.fullAddress(), "40001"); - - /* Check result */ - QVERIFY((arguments[1].canConvert >())); - QList resultList = arguments[1].value >(); - QCOMPARE(resultList.count(), 2); - QCOMPARE(resultList[0], static_cast(0)); - QCOMPARE(resultList[1], static_cast(1)); -} - -void TestModbusConnection::readRequestProtocolError() -{ - /* Start server */ - QVERIFY(_testSlaveModbus.connect(_ip, _port, _slaveId)); - - _testSlaveModbus.testDevice()->configureHoldingRegister(0, false, 0); - _testSlaveModbus.testDevice()->configureHoldingRegister(1, true, 1); - - /* Open connection */ - ModbusConnection* pConnection = new ModbusConnection(this); - QSignalSpy spySuccess(pConnection, &ModbusConnection::connectionSuccess); - pConnection->configureTcpConnection(constructTcpSettings(_ip, _port)); - pConnection->open(1000); - - QVERIFY(spySuccess.wait(100)); - - QVERIFY(pConnection->isConnected()); - - QSignalSpy spyResultSuccess(pConnection, &ModbusConnection::readRequestSuccess); - QSignalSpy spyResultProtocolError(pConnection, &ModbusConnection::readRequestProtocolError); - QSignalSpy spyResultError(pConnection, &ModbusConnection::readRequestError); - - pConnection->sendReadRequest(ModbusDataUnit(40001), 2); - - QVERIFY(spyResultProtocolError.wait(100)); - QCOMPARE(spyResultSuccess.count(), 0); - QCOMPARE(spyResultProtocolError.count(), 1); - QCOMPARE(spyResultError.count(), 0); - - QList arguments = spyResultProtocolError.takeFirst(); - QCOMPARE(arguments.count(), 1); - - /* Check modbus exception */ - QCOMPARE(static_cast(arguments.first().toInt()), QModbusPdu::IllegalDataAddress); -} - -void TestModbusConnection::readRequestError() -{ - /* TODO: - * Add test for this case. - * Is this case possible? - */ -} - -ModbusConnection::tcpSettings_t TestModbusConnection::constructTcpSettings(QString ip, qint32 port) -{ - ModbusConnection::tcpSettings_t tcpSettings = { - .ip = ip, - .port = port, - }; - - return tcpSettings; -} - -QTEST_GUILESS_MAIN(TestModbusConnection) diff --git a/tests/communication/tst_modbusconnection.h b/tests/communication/tst_modbusconnection.h deleted file mode 100644 index 5b4f5d16..00000000 --- a/tests/communication/tst_modbusconnection.h +++ /dev/null @@ -1,33 +0,0 @@ - -#include "communication/modbusconnection.h" -#include "models/device.h" -#include "testslavemodbus.h" - -#include - -class TestSlaveModbus; - -class TestModbusConnection: public QObject -{ - Q_OBJECT -private slots: - void init(); - void cleanup(); - - void connectionSuccess(); - void connectionFail(); - void connectionSuccesAfterFail(); - - void readRequestSuccess(); - void readRequestProtocolError(); - void readRequestError(); - -private: - ModbusConnection::tcpSettings_t constructTcpSettings(QString ip, qint32 port); - - TestSlaveModbus _testSlaveModbus; - - quint8 _slaveId; - QString _ip; - qint32 _port; -}; diff --git a/tests/communication/tst_modbusdatatype.cpp b/tests/communication/tst_modbusdatatype.cpp deleted file mode 100644 index 6d1bd3f9..00000000 --- a/tests/communication/tst_modbusdatatype.cpp +++ /dev/null @@ -1,190 +0,0 @@ - -#include "tst_modbusdatatype.h" - -#include "util/modbusdatatype.h" - -#include - -using Type = ModbusDataType::Type; - -#define ADD_TYPE_TEST(strType, type) QTest::newRow(strType) << strType << type -#define ADD_STRING_TEST(type, strType) QTest::newRow(strType) << type << strType; - -void TestModbusDataType::init() -{ - -} - -void TestModbusDataType::cleanup() -{ - -} - -void TestModbusDataType::is32bit() -{ - QCOMPARE(ModbusDataType::is32Bit(Type::UNSIGNED_16), false); - QCOMPARE(ModbusDataType::is32Bit(Type::SIGNED_16), false); - QCOMPARE(ModbusDataType::is32Bit(Type::UNSIGNED_32), true); - QCOMPARE(ModbusDataType::is32Bit(Type::SIGNED_32), true); - QCOMPARE(ModbusDataType::is32Bit(Type::FLOAT_32), true); -} - -void TestModbusDataType::isUnsigned() -{ - QCOMPARE(ModbusDataType::isUnsigned(Type::UNSIGNED_16), true); - QCOMPARE(ModbusDataType::isUnsigned(Type::SIGNED_16), false); - QCOMPARE(ModbusDataType::isUnsigned(Type::UNSIGNED_32), true); - QCOMPARE(ModbusDataType::isUnsigned(Type::SIGNED_32), false); - QCOMPARE(ModbusDataType::isUnsigned(Type::FLOAT_32), false); -} - -void TestModbusDataType::isFloat() -{ - QCOMPARE(ModbusDataType::isFloat(Type::UNSIGNED_16), false); - QCOMPARE(ModbusDataType::isFloat(Type::SIGNED_16), false); - QCOMPARE(ModbusDataType::isFloat(Type::UNSIGNED_32), false); - QCOMPARE(ModbusDataType::isFloat(Type::SIGNED_32), false); - QCOMPARE(ModbusDataType::isFloat(Type::FLOAT_32), true); -} - -void TestModbusDataType::convertString_data() -{ - QTest::addColumn("strType"); - QTest::addColumn("type"); - - ADD_TYPE_TEST("16b", Type::UNSIGNED_16); - ADD_TYPE_TEST("s16b", Type::SIGNED_16); - ADD_TYPE_TEST("32b", Type::UNSIGNED_32); - ADD_TYPE_TEST("s32b", Type::SIGNED_32); - ADD_TYPE_TEST("f32b", Type::FLOAT_32); -} - -void TestModbusDataType::convertString() -{ - QFETCH(QString, strType); - QFETCH(ModbusDataType::Type, type); - - bool bOk; - ModbusDataType::Type actType = ModbusDataType::convertString(strType, bOk); - - QCOMPARE(type, actType); - QVERIFY(bOk); -} - -void TestModbusDataType::convertMbcString_data() -{ - QTest::addColumn("strType"); - QTest::addColumn("type"); - - ADD_TYPE_TEST("uint16", Type::UNSIGNED_16); - ADD_TYPE_TEST("bin16", Type::UNSIGNED_16); - ADD_TYPE_TEST("hex16", Type::UNSIGNED_16); - ADD_TYPE_TEST("ascii16", Type::UNSIGNED_16); - ADD_TYPE_TEST("int16", Type::SIGNED_16); - ADD_TYPE_TEST("uint32", Type::UNSIGNED_32); - ADD_TYPE_TEST("bin32", Type::UNSIGNED_32); - ADD_TYPE_TEST("hex32", Type::UNSIGNED_32); - ADD_TYPE_TEST("ascii32", Type::UNSIGNED_32); - ADD_TYPE_TEST("int32", Type::SIGNED_32); - ADD_TYPE_TEST("float32", Type::FLOAT_32); -} - -void TestModbusDataType::convertMbcString() -{ - QFETCH(QString, strType); - QFETCH(ModbusDataType::Type, type); - - bool bOk; - ModbusDataType::Type actType = ModbusDataType::convertMbcString(strType, bOk); - - QCOMPARE(type, actType); - QVERIFY(bOk); -} - -void TestModbusDataType::convertStringUnknown() -{ - bool bOk; - ModbusDataType::Type actType = ModbusDataType::convertString("noType", bOk); - - QVERIFY(!bOk); - QCOMPARE(actType, Type::UNSIGNED_16); -} - -void TestModbusDataType::typeString_data() -{ - QTest::addColumn("type"); - QTest::addColumn("strType"); - - ADD_STRING_TEST(Type::UNSIGNED_16, "16b"); - ADD_STRING_TEST(Type::SIGNED_16, "s16b"); - ADD_STRING_TEST(Type::UNSIGNED_32, "32b"); - ADD_STRING_TEST(Type::SIGNED_32, "s32b"); - ADD_STRING_TEST(Type::FLOAT_32, "f32b"); - ADD_STRING_TEST(static_cast(255), "16b"); -} - -void TestModbusDataType::typeString() -{ - QFETCH(ModbusDataType::Type, type); - QFETCH(QString, strType); - - QString actTypeString = ModbusDataType::typeString(type); - - QCOMPARE(strType, actTypeString); -} - -void TestModbusDataType::description_data() -{ - QTest::addColumn("type"); - QTest::addColumn("strType"); - - ADD_STRING_TEST(Type::UNSIGNED_16, "unsigned 16-bit"); - ADD_STRING_TEST(Type::SIGNED_16, "signed 16-bit"); - ADD_STRING_TEST(Type::UNSIGNED_32, "unsigned 32-bit"); - ADD_STRING_TEST(Type::SIGNED_32, "signed 32-bit"); - ADD_STRING_TEST(Type::FLOAT_32, "32-bit float"); - ADD_STRING_TEST(static_cast(255), "unsigned 16-bit"); -} - -void TestModbusDataType::description() -{ - QFETCH(ModbusDataType::Type, type); - QFETCH(QString, strType); - - QString actDescriptionString = ModbusDataType::description(type); - - QCOMPARE(strType, actDescriptionString); -} - -void TestModbusDataType::convertSettings_data() -{ - QTest::addColumn("is32bit"); - QTest::addColumn("bUnsigned"); - QTest::addColumn("bFloat"); - QTest::addColumn("type"); - - /* 32bit unsigned float */ - QTest::newRow("0") << false << true << true << ModbusDataType::Type::FLOAT_32; - QTest::newRow("1") << false << true << false << ModbusDataType::Type::UNSIGNED_16; - QTest::newRow("2") << false << false << true << ModbusDataType::Type::FLOAT_32; - QTest::newRow("3") << false << false << false << ModbusDataType::Type::SIGNED_16; - - QTest::newRow("4") << true << true << true << ModbusDataType::Type::FLOAT_32; - QTest::newRow("5") << true << true << false << ModbusDataType::Type::UNSIGNED_32; - QTest::newRow("6") << true << false << true << ModbusDataType::Type::FLOAT_32; - QTest::newRow("7") << true << false << false << ModbusDataType::Type::SIGNED_32; -} - -void TestModbusDataType::convertSettings() -{ - QFETCH(ModbusDataType::Type, type); - QFETCH(bool, is32bit); - QFETCH(bool, bUnsigned); - QFETCH(bool, bFloat); - - ModbusDataType::Type actType = ModbusDataType::convertSettings(is32bit, bUnsigned, bFloat); - - QCOMPARE(actType, type); -} - -QTEST_GUILESS_MAIN(TestModbusDataType) diff --git a/tests/communication/tst_modbusdatatype.h b/tests/communication/tst_modbusdatatype.h deleted file mode 100644 index 48dcdec6..00000000 --- a/tests/communication/tst_modbusdatatype.h +++ /dev/null @@ -1,34 +0,0 @@ - -#include - -class TestModbusDataType: public QObject -{ - Q_OBJECT -private slots: - void init(); - void cleanup(); - - void is32bit(); - void isUnsigned(); - void isFloat(); - - void convertString_data(); - void convertString(); - - void convertMbcString_data(); - void convertMbcString(); - - void convertStringUnknown(); - - void typeString_data(); - void typeString(); - - void description_data(); - void description(); - - void convertSettings_data(); - void convertSettings(); - -private: - -}; diff --git a/tests/communication/tst_modbusdataunit.cpp b/tests/communication/tst_modbusdataunit.cpp deleted file mode 100644 index 3a6f89bc..00000000 --- a/tests/communication/tst_modbusdataunit.cpp +++ /dev/null @@ -1,93 +0,0 @@ - -#include "tst_modbusdataunit.h" - -#include "communication/modbusdataunit.h" - -#include - -void TestModbusDataUnit::init() -{ -} - -void TestModbusDataUnit::cleanup() -{ -} - -void TestModbusDataUnit::constructor_params() -{ - ModbusDataUnit unit(123, ModbusAddress::ObjectType::COIL, 42); - QCOMPARE(unit.protocolAddress(), static_cast(123)); - QCOMPARE(unit.objectType(), ModbusAddress::ObjectType::COIL); - QCOMPARE(unit.slaveId(), static_cast(42)); -} - -void TestModbusDataUnit::constructor_from_address() -{ - ModbusAddress addr(40001); - ModbusDataUnit unit(addr, 7); - QCOMPARE(unit.protocolAddress(), addr.protocolAddress()); - QCOMPARE(unit.objectType(), addr.objectType()); - QCOMPARE(unit.slaveId(), static_cast(7)); -} - -void TestModbusDataUnit::slave_getter_setter() -{ - ModbusDataUnit unit(10, ModbusAddress::ObjectType::COIL, 5); - QCOMPARE(unit.slaveId(), static_cast(5)); - - unit.setSlaveId(99); - QCOMPARE(unit.slaveId(), static_cast(99)); -} - -void TestModbusDataUnit::operator_equality() -{ - ModbusDataUnit unit1(10, ModbusAddress::ObjectType::COIL, 5); - ModbusDataUnit unit2(10, ModbusAddress::ObjectType::COIL, 5); - ModbusDataUnit unit3(10, ModbusAddress::ObjectType::COIL, 6); - ModbusDataUnit unit4(11, ModbusAddress::ObjectType::COIL, 5); - ModbusDataUnit unit5(10, ModbusAddress::ObjectType::INPUT_REGISTER, 5); - - QVERIFY(unit1 == unit2); - QVERIFY(!(unit1 == unit3)); - QVERIFY(!(unit1 == unit4)); - QVERIFY(!(unit1 == unit5)); -} - -void TestModbusDataUnit::operator_less_than() -{ - ModbusDataUnit unit1(10, ModbusAddress::ObjectType::COIL, 5); - ModbusDataUnit unit2(11, ModbusAddress::ObjectType::COIL, 5); - ModbusDataUnit unit3(10, ModbusAddress::ObjectType::DISCRETE_INPUT, 5); - ModbusDataUnit unit4(10, ModbusAddress::ObjectType::COIL, 6); // same addr+type, different slaveId - - QVERIFY(unit1 < unit2); // protocolAddress comparison - QVERIFY(unit1 < unit3); // type comparison - QVERIFY(!(unit2 < unit1)); - QVERIFY(!(unit3 < unit1)); - // slaveId comparison (regression for multi-slave bug) - QVERIFY(unit1 < unit4); // slaveId 5 < slaveId 6, same address+type - QVERIFY(!(unit4 < unit1)); -} - -void TestModbusDataUnit::qmap_different_slave_ids_are_distinct_keys() -{ - ModbusDataUnit unit1(40001, ModbusAddress::ObjectType::HOLDING_REGISTER, 1); - ModbusDataUnit unit2(40001, ModbusAddress::ObjectType::HOLDING_REGISTER, 2); - - QMap map; - map.insert(unit1, 100); - map.insert(unit2, 200); - - QCOMPARE(map.size(), 2); - QCOMPARE(map.value(unit1), 100); - QCOMPARE(map.value(unit2), 200); -} - -void TestModbusDataUnit::toString() -{ - ModbusDataUnit unit(123, ModbusAddress::ObjectType::INPUT_REGISTER, 42); - QString expected = "input register, 123, slave id 42"; - QCOMPARE(unit.toString(), expected); -} - -QTEST_GUILESS_MAIN(TestModbusDataUnit) diff --git a/tests/communication/tst_modbusdataunit.h b/tests/communication/tst_modbusdataunit.h deleted file mode 100644 index 97ed65e4..00000000 --- a/tests/communication/tst_modbusdataunit.h +++ /dev/null @@ -1,23 +0,0 @@ - -#include - -class TestModbusDataUnit : public QObject -{ - Q_OBJECT - -private slots: - void init(); - void cleanup(); - - void constructor_params(); - void constructor_from_address(); - void slave_getter_setter(); - - void operator_equality(); - void operator_less_than(); - void qmap_different_slave_ids_are_distinct_keys(); - - void toString(); - -private: -}; diff --git a/tests/communication/tst_modbusmaster.cpp b/tests/communication/tst_modbusmaster.cpp deleted file mode 100644 index bd05d873..00000000 --- a/tests/communication/tst_modbusmaster.cpp +++ /dev/null @@ -1,398 +0,0 @@ -#include "tst_modbusmaster.h" - -#include "communication/modbusmaster.h" -#include "testslavemodbus.h" - -#include -#include - -Q_DECLARE_METATYPE(Result); - -void TestModbusMaster::init() -{ - qRegisterMetaType>("Result"); - - _pSettingsModel = new SettingsModel; - - auto connData = _pSettingsModel->connectionSettings(ConnectionTypes::ID_1); - connData->setIpAddress("127.0.0.1"); - connData->setPort(5020); - connData->setTimeout(500); - - _pSettingsModel->setPollTime(100); - - deviceId_t devId = Device::cFirstDeviceId; - _pSettingsModel->addDevice(devId); - _pSettingsModel->deviceSettings(devId)->setConnectionId(ConnectionTypes::ID_1); - _pSettingsModel->deviceSettings(devId)->setSlaveId(devId); - - const auto deviceList = _pSettingsModel->deviceList(); - for (deviceId_t devId : std::as_const(deviceList)) - { - auto device = _pSettingsModel->deviceSettings(devId); - - connData = _pSettingsModel->connectionSettings(device->connectionId()); - - _testSlaveMap[devId] = new TestSlaveModbus(); - auto& testSlave = _testSlaveMap[devId]; - - QVERIFY(testSlave->connect(connData->ipAddress(), connData->port(), device->slaveId())); - } -} - -void TestModbusMaster::cleanup() -{ - for (auto& testSlave : _testSlaveMap) - { - testSlave->disconnect(); - delete testSlave; - } - - delete _pSettingsModel; -} - -void TestModbusMaster::singleRequestSuccess() -{ - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - device->configureHoldingRegister(0, true, 0); - - auto conn = new ModbusConnection(); // ModbusMaster takes ownership - ModbusMaster modbusMaster(conn, _pSettingsModel, ConnectionTypes::ID_1); - - auto registerList = QList() << ModbusDataUnit(40001); - QSignalSpy spyModbusPollDone(&modbusMaster, &ModbusMaster::modbusPollDone); - - for (uint i = 0; i < _cReadCount; i++) - { - modbusMaster.readRegisterList(registerList, 128); - - QVERIFY(spyModbusPollDone.wait(100)); - QCOMPARE(spyModbusPollDone.count(), 1); - - QList arguments = spyModbusPollDone.takeFirst(); - QVERIFY(arguments.count() > 0); - - QVariant varResultList = arguments.first(); - QVERIFY(varResultList.canConvert()); - ModbusResultMap result = varResultList.value(); - QCOMPARE(result.size(), 1); - - QVERIFY(result[ModbusDataUnit(40001)].isValid()); - QCOMPARE(result[ModbusDataUnit(40001)].value(), static_cast(0)); - } -} - -void TestModbusMaster::singleRequestEmpty() -{ - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - device->configureHoldingRegister(0, true, 0); - - auto conn = new ModbusConnection(); // ModbusMaster takes ownership - ModbusMaster modbusMaster(conn, _pSettingsModel, ConnectionTypes::ID_1); - - QList registerList; - QSignalSpy spyModbusPollDone(&modbusMaster, &ModbusMaster::modbusPollDone); - - modbusMaster.readRegisterList(registerList, 128); - - QCOMPARE(spyModbusPollDone.count(), 1); - - QList arguments = spyModbusPollDone.takeFirst(); - QVERIFY(arguments.count() > 0); - - QVariant varResultList = arguments.first(); - QVERIFY(varResultList.canConvert()); - ModbusResultMap result = varResultList.value(); - QCOMPARE(result.size(), 0); -} - -void TestModbusMaster::singleRequestGatewayNotAvailable() -{ - _testSlaveMap[Device::cFirstDeviceId]->setException(QModbusPdu::GatewayTargetDeviceFailedToRespond, true); - - auto conn = new ModbusConnection(); // ModbusMaster takes ownership - ModbusMaster modbusMaster(conn, _pSettingsModel, ConnectionTypes::ID_1); - QSignalSpy spyModbusPollDone(&modbusMaster, &ModbusMaster::modbusPollDone); - auto registerList = QList() << ModbusDataUnit(40001); - - for (uint i = 0; i < _cReadCount; i++) - { - modbusMaster.readRegisterList(registerList, 128); - - QVERIFY(spyModbusPollDone.wait(100)); - QCOMPARE(spyModbusPollDone.count(), 1); - - QList arguments = spyModbusPollDone.takeFirst(); - QVERIFY(arguments.count() > 0); - - QVariant varResultList = arguments.first(); - QVERIFY(varResultList.canConvert()); - ModbusResultMap result = varResultList.value(); - QCOMPARE(result.size(), 1); - - QVERIFY(result[ModbusDataUnit(40001)].isValid() == false); - } -} - -void TestModbusMaster::singleRequestNoResponse() -{ - _testSlaveMap[Device::cFirstDeviceId]->disconnect(); - - auto conn = new ModbusConnection(); // ModbusMaster takes ownership - ModbusMaster modbusMaster(conn, _pSettingsModel, ConnectionTypes::ID_1); - - auto registerList = QList() << ModbusDataUnit(40001); - QSignalSpy spyModbusPollDone(&modbusMaster, &ModbusMaster::modbusPollDone); - - for (uint i = 0; i < _cReadCount; i++) - { - modbusMaster.readRegisterList(registerList, 128); - - auto connData = _pSettingsModel->connectionSettings(ConnectionTypes::ID_1); - spyModbusPollDone.wait(static_cast(connData->timeout()) + 100); - QCOMPARE(spyModbusPollDone.count(), 1); - - QList arguments = spyModbusPollDone.takeFirst(); - QVERIFY(arguments.count() > 0); - - QVariant varResultList = arguments.first(); - QVERIFY(varResultList.canConvert()); - ModbusResultMap result = varResultList.value(); - QCOMPARE(result.size(), 1); - - QVERIFY(result[ModbusDataUnit(40001)].isValid() == false); - } -} - -void TestModbusMaster::singleRequestInvalidAddressOnce() -{ - auto conn = new ModbusConnection(); // ModbusMaster takes ownership - ModbusMaster modbusMaster(conn, _pSettingsModel, ConnectionTypes::ID_1); - QSignalSpy spyModbusPollDone(&modbusMaster, &ModbusMaster::modbusPollDone); - - auto registerList = QList() - << ModbusDataUnit(40001) << ModbusDataUnit(40002) << ModbusDataUnit(40003); - - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - device->configureHoldingRegister(0, false, 0); - device->configureHoldingRegister(1, true, 1); - device->configureHoldingRegister(2, true, 2); - - for (uint i = 0; i < _cReadCount; i++) - { - modbusMaster.readRegisterList(registerList, 128); - - QVERIFY(spyModbusPollDone.wait(100)); - QCOMPARE(spyModbusPollDone.count(), 1); - - QList arguments = spyModbusPollDone.takeFirst(); - QVERIFY(arguments.count() > 0); - - QVariant varResultList = arguments.first(); - QVERIFY(varResultList.canConvert()); - ModbusResultMap result = varResultList.value(); - QCOMPARE(result.size(), 3); - - QVERIFY(result[ModbusDataUnit(40001)].isValid() == false); - - QVERIFY(result[ModbusDataUnit(40002)].isValid()); - QCOMPARE(result[ModbusDataUnit(40002)].value(), static_cast(1)); - - QVERIFY(result[ModbusDataUnit(40003)].isValid()); - QCOMPARE(result[ModbusDataUnit(40003)].value(), static_cast(2)); - } -} - -void TestModbusMaster::singleRequestInvalidAddressPersistent() -{ - _testSlaveMap[Device::cFirstDeviceId]->setException(QModbusPdu::IllegalDataAddress, true); - - auto conn = new ModbusConnection(); // ModbusMaster takes ownership - ModbusMaster modbusMaster(conn, _pSettingsModel, ConnectionTypes::ID_1); - QSignalSpy spyModbusPollDone(&modbusMaster, &ModbusMaster::modbusPollDone); - - auto registerList = QList() << ModbusDataUnit(40001); - - for (uint i = 0; i < _cReadCount; i++) - { - modbusMaster.readRegisterList(registerList, 128); - - QVERIFY(spyModbusPollDone.wait(100)); - QCOMPARE(spyModbusPollDone.count(), 1); - - QList arguments = spyModbusPollDone.takeFirst(); - QVERIFY(arguments.count() > 0); - - QVariant varResultList = arguments.first(); - QVERIFY(varResultList.canConvert()); - ModbusResultMap result = varResultList.value(); - QCOMPARE(result.size(), 1); - - QVERIFY(result[ModbusDataUnit(40001)].isValid() == false); - } -} - -void TestModbusMaster::multiRequestSuccess() -{ - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - device->configureHoldingRegister(0, true, 0); - device->configureHoldingRegister(1, true, 1); - device->configureHoldingRegister(3, true, 3); - - auto conn = new ModbusConnection(); // ModbusMaster takes ownership - ModbusMaster modbusMaster(conn, _pSettingsModel, ConnectionTypes::ID_1); - - auto registerList = QList() - << ModbusDataUnit(40001) << ModbusDataUnit(40002) << ModbusDataUnit(40004); - QSignalSpy spyModbusPollDone(&modbusMaster, &ModbusMaster::modbusPollDone); - - for (uint i = 0; i < _cReadCount; i++) - { - modbusMaster.readRegisterList(registerList, 128); - - auto timeout = _pSettingsModel->connectionSettings(ConnectionTypes::ID_1)->timeout(); - QVERIFY(spyModbusPollDone.wait(static_cast(timeout))); - QCOMPARE(spyModbusPollDone.count(), 1); - - QList arguments = spyModbusPollDone.takeFirst(); - QVERIFY(arguments.count() > 0); - - QVariant varResultList = arguments.first(); - QVERIFY(varResultList.canConvert()); - ModbusResultMap result = varResultList.value(); - QCOMPARE(result.size(), 3); - - QVERIFY(result[ModbusDataUnit(40001)].isValid()); - QCOMPARE(result[ModbusDataUnit(40001)].value(), static_cast(0)); - - QVERIFY(result[ModbusDataUnit(40002)].isValid()); - QCOMPARE(result[ModbusDataUnit(40002)].value(), static_cast(1)); - - QVERIFY(result[ModbusDataUnit(40004)].isValid()); - QCOMPARE(result[ModbusDataUnit(40004)].value(), static_cast(3)); - } -} - -void TestModbusMaster::multiRequestGatewayNotAvailable() -{ - _testSlaveMap[Device::cFirstDeviceId]->setException(QModbusPdu::IllegalDataAddress, true); - - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - device->configureHoldingRegister(0, true, 0); - device->configureHoldingRegister(1, true, 1); - device->configureHoldingRegister(3, true, 3); - - auto conn = new ModbusConnection(); // ModbusMaster takes ownership - ModbusMaster modbusMaster(conn, _pSettingsModel, ConnectionTypes::ID_1); - - auto registerList = QList() - << ModbusDataUnit(40001) << ModbusDataUnit(40002) << ModbusDataUnit(40004); - QSignalSpy spyModbusPollDone(&modbusMaster, &ModbusMaster::modbusPollDone); - - for (uint i = 0; i < _cReadCount; i++) - { - modbusMaster.readRegisterList(registerList, 128); - - QVERIFY(spyModbusPollDone.wait(100)); - QCOMPARE(spyModbusPollDone.count(), 1); - - QList arguments = spyModbusPollDone.takeFirst(); - QVERIFY(arguments.count() > 0); - - QVariant varResultList = arguments.first(); - QVERIFY(varResultList.canConvert()); - ModbusResultMap result = varResultList.value(); - QCOMPARE(result.size(), 3); - - QVERIFY(result[ModbusDataUnit(40001)].isValid() == false); - QVERIFY(result[ModbusDataUnit(40002)].isValid() == false); - QVERIFY(result[ModbusDataUnit(40004)].isValid() == false); - } -} - -void TestModbusMaster::multiRequestNoResponse() -{ - _testSlaveMap[Device::cFirstDeviceId]->disconnect(); - - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - device->configureHoldingRegister(0, true, 0); - device->configureHoldingRegister(1, true, 1); - device->configureHoldingRegister(3, true, 3); - - auto conn = new ModbusConnection(); // ModbusMaster takes ownership - ModbusMaster modbusMaster(conn, _pSettingsModel, ConnectionTypes::ID_1); - - auto registerList = QList() - << ModbusDataUnit(40001) << ModbusDataUnit(40002) << ModbusDataUnit(40004); - QSignalSpy spyModbusPollDone(&modbusMaster, &ModbusMaster::modbusPollDone); - - for (uint i = 0; i < _cReadCount; i++) - { - modbusMaster.readRegisterList(registerList, 128); - - auto timeout = _pSettingsModel->connectionSettings(ConnectionTypes::ID_1)->timeout(); - spyModbusPollDone.wait(static_cast(timeout) + 100); - QCOMPARE(spyModbusPollDone.count(), 1); - - QList arguments = spyModbusPollDone.takeFirst(); - QVERIFY(arguments.count() > 0); - - QVariant varResultList = arguments.first(); - QVERIFY(varResultList.canConvert()); - ModbusResultMap result = varResultList.value(); - QCOMPARE(result.size(), 3); - - QVERIFY(result[ModbusDataUnit(40001)].isValid() == false); - QVERIFY(result[ModbusDataUnit(40002)].isValid() == false); - QVERIFY(result[ModbusDataUnit(40004)].isValid() == false); - } -} - -void TestModbusMaster::multiRequestInvalidAddress() -{ - _testSlaveMap[Device::cFirstDeviceId]->setException(QModbusPdu::IllegalDataAddress, true); - - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - device->configureHoldingRegister(0, true, 0); - device->configureHoldingRegister(1, true, 1); - device->configureHoldingRegister(3, true, 3); - - auto conn = new ModbusConnection(); // ModbusMaster takes ownership - ModbusMaster modbusMaster(conn, _pSettingsModel, ConnectionTypes::ID_1); - - auto registerList = QList() - << ModbusDataUnit(40001) << ModbusDataUnit(40002) << ModbusDataUnit(40004); - QSignalSpy spyModbusPollDone(&modbusMaster, &ModbusMaster::modbusPollDone); - - for (uint i = 0; i < _cReadCount; i++) - { - modbusMaster.readRegisterList(registerList, 128); - - auto timeout = _pSettingsModel->connectionSettings(ConnectionTypes::ID_1)->timeout(); - QVERIFY(spyModbusPollDone.wait(static_cast(timeout) + 100)); - QCOMPARE(spyModbusPollDone.count(), 1); - - QList arguments = spyModbusPollDone.takeFirst(); - QVERIFY(arguments.count() > 0); - - QVariant varResultList = arguments.first(); - QVERIFY(varResultList.canConvert()); - ModbusResultMap result = varResultList.value(); - QCOMPARE(result.size(), 3); - - QVERIFY(result[ModbusDataUnit(40001)].isValid() == false); - QVERIFY(result[ModbusDataUnit(40002)].isValid() == false); - QVERIFY(result[ModbusDataUnit(40004)].isValid() == false); - } -} - -/* TODO: - * Add extra test with actual timeout of no response - * When test slave is disconnected, the port is closed and the error will come directly - * and not after a response - * - * But this test is still valuable. - * This test when ModbusControl server is not enabled - */ - -QTEST_GUILESS_MAIN(TestModbusMaster) diff --git a/tests/communication/tst_modbusmaster.h b/tests/communication/tst_modbusmaster.h deleted file mode 100644 index e5231407..00000000 --- a/tests/communication/tst_modbusmaster.h +++ /dev/null @@ -1,34 +0,0 @@ - -#include "models/settingsmodel.h" -#include "testdevice.h" - -#include - -class TestSlaveModbus; - -class TestModbusMaster: public QObject -{ - Q_OBJECT -private slots: - void init(); - void cleanup(); - - void singleRequestSuccess(); - void singleRequestEmpty(); - void singleRequestGatewayNotAvailable(); - void singleRequestNoResponse(); - void singleRequestInvalidAddressOnce(); - void singleRequestInvalidAddressPersistent(); - - void multiRequestSuccess(); - void multiRequestGatewayNotAvailable(); - void multiRequestNoResponse(); - void multiRequestInvalidAddress(); - -private: - QMap _testSlaveMap; - - SettingsModel* _pSettingsModel; - - const uint _cReadCount = 3; -}; diff --git a/tests/communication/tst_modbusmasterfake.cpp b/tests/communication/tst_modbusmasterfake.cpp deleted file mode 100644 index eb9d2ca4..00000000 --- a/tests/communication/tst_modbusmasterfake.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include "tst_modbusmasterfake.h" - -#include "communication/modbusmaster.h" -#include "modbusconnectionfake.h" - -#include -#include - -void TestModbusMasterFake::init() -{ - _pSettingsModel = new SettingsModel; - - auto connData = _pSettingsModel->connectionSettings(ConnectionTypes::ID_1); - connData->setIpAddress("127.0.0.1"); - connData->setPort(5020); - connData->setTimeout(500); - - _pSettingsModel->setPollTime(100); - - deviceId_t devId = Device::cFirstDeviceId; - _pSettingsModel->addDevice(devId); - _pSettingsModel->deviceSettings(devId)->setConnectionId(ConnectionTypes::ID_1); - _pSettingsModel->deviceSettings(devId)->setSlaveId(devId); - - devId = Device::cFirstDeviceId + 1; - _pSettingsModel->addDevice(devId); - _pSettingsModel->deviceSettings(devId)->setConnectionId(ConnectionTypes::ID_1); - _pSettingsModel->deviceSettings(devId)->setSlaveId(devId); - - const auto deviceList = _pSettingsModel->deviceList(); - for (deviceId_t devId : std::as_const(deviceList)) - { - _testDeviceMap[devId] = new TestDevice(); - } -} - -void TestModbusMasterFake::cleanup() -{ - for (auto& testDevice : _testDeviceMap) - { - testDevice->disconnect(); - delete testDevice; - } - - delete _pSettingsModel; -} - -void TestModbusMasterFake::singleRequestSuccess() -{ - _testDeviceMap[Device::cFirstDeviceId]->configureHoldingRegister(0, true, 0); - - ModbusConnectionFake* conn = new ModbusConnectionFake(); // ModbusMaster takes ownership - conn->addSlaveDevice(Device::cFirstDeviceId, _testDeviceMap[Device::cFirstDeviceId]); - ModbusMaster modbusMaster(conn, _pSettingsModel, ConnectionTypes::ID_1); - - auto registerList = QList() << ModbusDataUnit(40001); - QSignalSpy spyModbusPollDone(&modbusMaster, &ModbusMaster::modbusPollDone); - - modbusMaster.readRegisterList(registerList, 128); - - QVERIFY(spyModbusPollDone.wait(100)); - QCOMPARE(spyModbusPollDone.count(), 1); - - QList arguments = spyModbusPollDone.takeFirst(); - QVERIFY(arguments.count() > 0); - - QVariant varResultList = arguments.first(); - QVERIFY(varResultList.canConvert()); - ModbusResultMap result = varResultList.value(); - QCOMPARE(result.size(), 1); - - QVERIFY(result[ModbusDataUnit(40001)].isValid()); - QCOMPARE(result[ModbusDataUnit(40001)].value(), static_cast(0)); -} - -void TestModbusMasterFake::requestToDevicesOnSameConnection() -{ - _testDeviceMap[Device::cFirstDeviceId]->configureHoldingRegister(0, true, 0); - _testDeviceMap[Device::cFirstDeviceId + 1]->configureHoldingRegister(1, true, 5); - - ModbusConnectionFake* conn = new ModbusConnectionFake(); // ModbusMaster takes ownership - conn->addSlaveDevice(Device::cFirstDeviceId, _testDeviceMap[Device::cFirstDeviceId]); - conn->addSlaveDevice(Device::cFirstDeviceId + 1, _testDeviceMap[Device::cFirstDeviceId + 1]); - ModbusMaster modbusMaster(conn, _pSettingsModel, ConnectionTypes::ID_1); - - ModbusDataUnit dataUnit1(0, ModbusAddress::ObjectType::HOLDING_REGISTER, Device::cFirstDeviceId); - ModbusDataUnit dataUnit2(1, ModbusAddress::ObjectType::HOLDING_REGISTER, Device::cFirstDeviceId + 1); - auto registerList = QList() << dataUnit1 << dataUnit2; - QSignalSpy spyModbusPollDone(&modbusMaster, &ModbusMaster::modbusPollDone); - - modbusMaster.readRegisterList(registerList, 128); - - QVERIFY(spyModbusPollDone.wait(100)); - QCOMPARE(spyModbusPollDone.count(), 1); - - QList arguments = spyModbusPollDone.takeFirst(); - QVERIFY(arguments.count() > 0); - - QVariant varResultList = arguments.first(); - QVERIFY(varResultList.canConvert()); - ModbusResultMap result = varResultList.value(); - QCOMPARE(result.size(), 2); - - QVERIFY(result[dataUnit1].isValid()); - QCOMPARE(result[dataUnit1].value(), static_cast(0)); - - QVERIFY(result[dataUnit2].isValid()); - QCOMPARE(result[dataUnit2].value(), static_cast(5)); -} - -QTEST_GUILESS_MAIN(TestModbusMasterFake) diff --git a/tests/communication/tst_modbusmasterfake.h b/tests/communication/tst_modbusmasterfake.h deleted file mode 100644 index ba526b32..00000000 --- a/tests/communication/tst_modbusmasterfake.h +++ /dev/null @@ -1,20 +0,0 @@ - -#include - -#include "models/settingsmodel.h" -#include "testdevice.h" - -class TestModbusMasterFake : public QObject -{ - Q_OBJECT -private slots: - void init(); - void cleanup(); - - void singleRequestSuccess(); - void requestToDevicesOnSameConnection(); - -private: - QMap _testDeviceMap; - SettingsModel* _pSettingsModel; -}; diff --git a/tests/communication/tst_modbuspoll.cpp b/tests/communication/tst_modbuspoll.cpp deleted file mode 100644 index 6aa9854f..00000000 --- a/tests/communication/tst_modbuspoll.cpp +++ /dev/null @@ -1,497 +0,0 @@ - -#include "tst_modbuspoll.h" - -#include "communication/modbuspoll.h" -#include "communicationhelpers.h" -#include "testslavemodbus.h" -#include "testslavemodbusmulti.h" -#include "util/modbusdatatype.h" - -#include -#include - -Q_DECLARE_METATYPE(ResultDouble); - -using Type = ModbusDataType::Type; -using State = ResultState::State; - -void TestModbusPoll::init() -{ - qRegisterMetaType("ResultDouble"); - qRegisterMetaType("ResultDoubleList"); - - _pSettingsModel = new SettingsModel; - - auto connData = _pSettingsModel->connectionSettings(ConnectionTypes::ID_1); - connData->setIpAddress("127.0.0.1"); - connData->setPort(5020); - connData->setTimeout(500); - - _pSettingsModel->setConnectionState(ConnectionTypes::ID_2, true); - connData = _pSettingsModel->connectionSettings(ConnectionTypes::ID_2); - connData->setIpAddress("127.0.0.1"); - connData->setPort(5021); - connData->setTimeout(500); - - _pSettingsModel->setConnectionState(ConnectionTypes::ID_3, true); - connData = _pSettingsModel->connectionSettings(ConnectionTypes::ID_3); - connData->setIpAddress("127.0.0.1"); - connData->setPort(5022); - connData->setTimeout(500); - - deviceId_t devId = Device::cFirstDeviceId; - _pSettingsModel->addDevice(devId); - _pSettingsModel->deviceSettings(devId)->setConnectionId(ConnectionTypes::ID_1); - _pSettingsModel->deviceSettings(devId)->setSlaveId(devId); - - devId++; - _pSettingsModel->addDevice(devId); - _pSettingsModel->deviceSettings(devId)->setConnectionId(ConnectionTypes::ID_2); - _pSettingsModel->deviceSettings(devId)->setSlaveId(devId); - - devId++; - _pSettingsModel->addDevice(devId); - _pSettingsModel->deviceSettings(devId)->setConnectionId(ConnectionTypes::ID_3); - _pSettingsModel->deviceSettings(devId)->setSlaveId(devId); - - _pSettingsModel->setPollTime(100); - - const auto deviceList = _pSettingsModel->deviceList(); - for (deviceId_t devId : std::as_const(deviceList)) - { - auto device = _pSettingsModel->deviceSettings(devId); - - connData = _pSettingsModel->connectionSettings(device->connectionId()); - - _testSlaveMap[devId] = new TestSlaveModbus(); - auto& testSlave = _testSlaveMap[devId]; - - QVERIFY(testSlave->connect(connData->ipAddress(), connData->port(), device->slaveId())); - } -} - -void TestModbusPoll::cleanup() -{ - for (auto& testSlave : _testSlaveMap) - { - testSlave->disconnect(); - delete testSlave; - } - - delete _pSettingsModel; -} - -void TestModbusPoll::singleSlaveSuccess() -{ - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - device->configureHoldingRegister(0, true, 5); - device->configureHoldingRegister(1, true, 65000); - - ModbusPoll modbusPoll(_pSettingsModel); - QSignalSpy spyDataReady(&modbusPoll, &ModbusPoll::registerDataReady); - - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(40002), Device::cFirstDeviceId, Type::UNSIGNED_16); - - /*-- Start communication --*/ - modbusPoll.startCommunication(modbusRegisters); - - QVERIFY(spyDataReady.wait(50)); - QCOMPARE(spyDataReady.count(), 1); - - QList arguments = spyDataReady.takeFirst(); - auto expResults = ResultDoubleList() << ResultDouble(5, State::SUCCESS) << ResultDouble(65000, State::SUCCESS); - - /* Verify arguments of signal */ - CommunicationHelpers::verifyReceivedDataSignal(arguments, expResults); -} - -void TestModbusPoll::singleSlaveFail() -{ - for (auto& testSlaveModbus : _testSlaveMap) - { - testSlaveModbus->disconnect(); - } - - ModbusPoll modbusPoll(_pSettingsModel); - QSignalSpy spyDataReady(&modbusPoll, &ModbusPoll::registerDataReady); - - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(40002), Device::cFirstDeviceId, Type::UNSIGNED_16); - - /*-- Start communication --*/ - modbusPoll.startCommunication(modbusRegisters); - - auto timeout = _pSettingsModel->connectionSettings(ConnectionTypes::ID_1)->timeout(); - QVERIFY(spyDataReady.wait(static_cast(timeout) + 100)); - QCOMPARE(spyDataReady.count(), 1); - - QList arguments = spyDataReady.takeFirst(); - - auto expResults = ResultDoubleList() << ResultDouble(0, State::INVALID) << ResultDouble(0, State::INVALID); - - /* Verify arguments of signal */ - CommunicationHelpers::verifyReceivedDataSignal(arguments, expResults); -} - -void TestModbusPoll::singleOnlyConstantDataPoll() -{ - ModbusPoll modbusPoll(_pSettingsModel); - QSignalSpy spyDataReady(&modbusPoll, &ModbusPoll::registerDataReady); - - auto modbusRegisters = QList(); /* No registers to poll */ - - /*-- Start communication --*/ - modbusPoll.startCommunication(modbusRegisters); - - QVERIFY(spyDataReady.wait(50)); - QCOMPARE(spyDataReady.count(), 1); - - QList arguments = spyDataReady.takeFirst(); - auto expResults = ResultDoubleList(); - - /* Verify arguments of signal */ - CommunicationHelpers::verifyReceivedDataSignal(arguments, expResults); -} - -void TestModbusPoll::singleSlaveCoil() -{ - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - device->configureCoil(0, true, false); - device->configureCoil(2, true, true); - - ModbusPoll modbusPoll(_pSettingsModel); - QSignalSpy spyDataReady(&modbusPoll, &ModbusPoll::registerDataReady); - - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(0), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(2), Device::cFirstDeviceId, Type::UNSIGNED_16); - - /*-- Start communication --*/ - modbusPoll.startCommunication(modbusRegisters); - - QVERIFY(spyDataReady.wait(50)); - QCOMPARE(spyDataReady.count(), 1); - - QList arguments = spyDataReady.takeFirst(); - auto expResults = ResultDoubleList() << ResultDouble(0, State::SUCCESS) << ResultDouble(1, State::SUCCESS); - - /* Verify arguments of signal */ - CommunicationHelpers::verifyReceivedDataSignal(arguments, expResults); -} - -void TestModbusPoll::singleSlaveMixedObjects() -{ - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - device->configureCoil(0, true, false); - device->configureDiscreteInput(0, true, true); - device->configureInputRegister(0, true, 100); - device->configureHoldingRegister(0, true, 101); - - ModbusPoll modbusPoll(_pSettingsModel); - QSignalSpy spyDataReady(&modbusPoll, &ModbusPoll::registerDataReady); - - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(0), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(10001), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(30001), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_16); - - /*-- Start communication --*/ - modbusPoll.startCommunication(modbusRegisters); - - QVERIFY(spyDataReady.wait(50)); - QCOMPARE(spyDataReady.count(), 1); - - QList arguments = spyDataReady.takeFirst(); - auto expResults = ResultDoubleList() << ResultDouble(0, State::SUCCESS) << ResultDouble(1, State::SUCCESS) - << ResultDouble(100, State::SUCCESS) << ResultDouble(101, State::SUCCESS); - - /* Verify arguments of signal */ - CommunicationHelpers::verifyReceivedDataSignal(arguments, expResults); -} - -void TestModbusPoll::verifyRestartAfterStop() -{ - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - device->configureHoldingRegister(0, true, 5); - device->configureHoldingRegister(1, true, 65000); - - ModbusPoll modbusPoll(_pSettingsModel); - QSignalSpy spyDataReady(&modbusPoll, &ModbusPoll::registerDataReady); - - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(40002), Device::cFirstDeviceId, Type::UNSIGNED_16); - - /*-- Start communication --*/ - modbusPoll.startCommunication(modbusRegisters); - - QVERIFY(modbusPoll.isActive()); - - QVERIFY(spyDataReady.wait(50)); - QCOMPARE(spyDataReady.count(), 1); - - QList arguments = spyDataReady.takeFirst(); - auto expResults = ResultDoubleList() << ResultDouble(5, State::SUCCESS) << ResultDouble(65000, State::SUCCESS); - - /* Verify arguments of signal */ - CommunicationHelpers::verifyReceivedDataSignal(arguments, expResults); - - /*-- Stop communication --*/ - modbusPoll.stopCommunication(); - - QVERIFY(!modbusPoll.isActive()); - - /*-- Restart communication --*/ - modbusPoll.startCommunication(modbusRegisters); - - QVERIFY(spyDataReady.wait(50)); - QCOMPARE(spyDataReady.count(), 1); - - arguments = spyDataReady.takeFirst(); - - /* Verify arguments of signal */ - CommunicationHelpers::verifyReceivedDataSignal(arguments, expResults); -} - -void TestModbusPoll::multiSlaveSuccess() -{ - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - auto device_1 = _testSlaveMap[Device::cFirstDeviceId + 1]->testDevice(); - device->configureHoldingRegister(0, true, 5020); - device_1->configureHoldingRegister(0, true, 5021); - - ModbusPoll modbusPoll(_pSettingsModel); - QSignalSpy spyDataReady(&modbusPoll, &ModbusPoll::registerDataReady); - - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId + 1, Type::UNSIGNED_16); - - /*-- Start communication --*/ - modbusPoll.startCommunication(modbusRegisters); - - QVERIFY(spyDataReady.wait(50)); - QCOMPARE(spyDataReady.count(), 1); - - QList arguments = spyDataReady.takeFirst(); - auto expResults = ResultDoubleList() << ResultDouble(5020, State::SUCCESS) << ResultDouble(5021, State::SUCCESS); - - /* Verify arguments of signal */ - CommunicationHelpers::verifyReceivedDataSignal(arguments, expResults); -} - -void TestModbusPoll::multiSlaveSuccess_2() -{ - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - auto device_1 = _testSlaveMap[Device::cFirstDeviceId + 1]->testDevice(); - device->configureHoldingRegister(0, true, 5020); - device_1->configureHoldingRegister(1, true, 5021); - - ModbusPoll modbusPoll(_pSettingsModel); - QSignalSpy spyDataReady(&modbusPoll, &ModbusPoll::registerDataReady); - - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(40002), Device::cFirstDeviceId + 1, Type::UNSIGNED_16); - - /*-- Start communication --*/ - modbusPoll.startCommunication(modbusRegisters); - - QVERIFY(spyDataReady.wait(50)); - QCOMPARE(spyDataReady.count(), 1); - - QList arguments = spyDataReady.takeFirst(); - auto expResults = ResultDoubleList() << ResultDouble(5020, State::SUCCESS) << ResultDouble(5021, State::SUCCESS); - - /* Verify arguments of signal */ - CommunicationHelpers::verifyReceivedDataSignal(arguments, expResults); -} - -void TestModbusPoll::multiSlaveSuccess_3() -{ - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - auto device_1 = _testSlaveMap[Device::cFirstDeviceId + 1]->testDevice(); - device->configureHoldingRegister(0, true, 5020); - device->configureHoldingRegister(1, true, 5021); - device_1->configureHoldingRegister(1, true, 5022); - - ModbusPoll modbusPoll(_pSettingsModel); - QSignalSpy spyDataReady(&modbusPoll, &ModbusPoll::registerDataReady); - - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(40002), Device::cFirstDeviceId + 1, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(40002), Device::cFirstDeviceId, Type::UNSIGNED_16); - - /*-- Start communication --*/ - modbusPoll.startCommunication(modbusRegisters); - - QVERIFY(spyDataReady.wait(50)); - QCOMPARE(spyDataReady.count(), 1); - - QList arguments = spyDataReady.takeFirst(); - auto expResults = ResultDoubleList() << ResultDouble(5020, State::SUCCESS) << ResultDouble(5022, State::SUCCESS) - << ResultDouble(5021, State::SUCCESS); - - /* Verify arguments of signal */ - CommunicationHelpers::verifyReceivedDataSignal(arguments, expResults); -} - -void TestModbusPoll::multiSlaveSameConnectionSameAddress() -{ - /* Reproduce the reported bug: two slaves with different IDs share the same - * connection (same port) and both read the same register address. - * Before the operator< fix, both curves showed the value from the last-polled - * slave because the result map treated (addr=40001, slaveId=1) and - * (addr=40001, slaveId=4) as the same key. */ - - const quint8 newSlaveId = 4; - const deviceId_t newDevId = Device::cFirstDeviceId + 3; - - /* Replace the single-slave server at port 5020 with a multi-slave server - * that responds to slave ID 1 (device 1) and slave ID 4 (new device) */ - _testSlaveMap[Device::cFirstDeviceId]->disconnect(); - - TestSlaveMultiModbus multiSlave; - QVERIFY(multiSlave.listenOnPort(5020)); - - multiSlave.testDevice(Device::cFirstDeviceId)->configureHoldingRegister(0, true, 1111); - multiSlave.testDevice(newSlaveId)->configureHoldingRegister(0, true, 4444); - - /* Add a 4th device that shares connection ID_1 (port 5020) with device 1 */ - _pSettingsModel->addDevice(newDevId); - _pSettingsModel->deviceSettings(newDevId)->setConnectionId(ConnectionTypes::ID_1); - _pSettingsModel->deviceSettings(newDevId)->setSlaveId(newSlaveId); - - ModbusPoll modbusPoll(_pSettingsModel); - QSignalSpy spyDataReady(&modbusPoll, &ModbusPoll::registerDataReady); - - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(40001), newDevId, Type::UNSIGNED_16); - - modbusPoll.startCommunication(modbusRegisters); - - QVERIFY(spyDataReady.wait(500)); - QCOMPARE(spyDataReady.count(), 1); - - QList arguments = spyDataReady.takeFirst(); - auto expResults = ResultDoubleList() << ResultDouble(1111, State::SUCCESS) - << ResultDouble(4444, State::SUCCESS); - - CommunicationHelpers::verifyReceivedDataSignal(arguments, expResults); - - multiSlave.stopListening(); -} - -void TestModbusPoll::multiSlaveSingleFail() -{ - _testSlaveMap[Device::cFirstDeviceId]->disconnect(); - auto device_1 = _testSlaveMap[Device::cFirstDeviceId + 1]->testDevice(); - device_1->configureHoldingRegister(0, true, 5021); - - ModbusPoll modbusPoll(_pSettingsModel); - QSignalSpy spyDataReady(&modbusPoll, &ModbusPoll::registerDataReady); - - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId + 1, Type::UNSIGNED_16); - - /*-- Start communication --*/ - modbusPoll.startCommunication(modbusRegisters); - - auto timeout = _pSettingsModel->connectionSettings(ConnectionTypes::ID_1)->timeout(); - QVERIFY(spyDataReady.wait(static_cast(timeout) + 100)); - QCOMPARE(spyDataReady.count(), 1); - - QList arguments = spyDataReady.takeFirst(); - auto expResults = ResultDoubleList() << ResultDouble(0, State::INVALID) << ResultDouble(5021, State::SUCCESS); - - /* Verify arguments of signal */ - CommunicationHelpers::verifyReceivedDataSignal(arguments, expResults); -} - -void TestModbusPoll::multiSlaveAllFail() -{ - for (auto& testslaveModbus : _testSlaveMap) - { - testslaveModbus->disconnect(); - } - - ModbusPoll modbusPoll(_pSettingsModel); - QSignalSpy spyDataReady(&modbusPoll, &ModbusPoll::registerDataReady); - - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId + 1, Type::UNSIGNED_16); - - /*-- Start communication --*/ - modbusPoll.startCommunication(modbusRegisters); - - auto timeout = _pSettingsModel->connectionSettings(ConnectionTypes::ID_1)->timeout(); - QVERIFY(spyDataReady.wait(static_cast(timeout) + 100)); - QCOMPARE(spyDataReady.count(), 1); - - QList arguments = spyDataReady.takeFirst(); - auto expResults = ResultDoubleList() << ResultDouble(0, State::INVALID) << ResultDouble(0, State::INVALID); - - /* Verify arguments of signal */ - CommunicationHelpers::verifyReceivedDataSignal(arguments, expResults); -} - -void TestModbusPoll::multiSlaveDisabledConnection() -{ - auto device = _testSlaveMap[Device::cFirstDeviceId]->testDevice(); - auto device_1 = _testSlaveMap[Device::cFirstDeviceId + 1]->testDevice(); - device->configureHoldingRegister(0, true, 5020); - device_1->configureHoldingRegister(0, true, 5021); - - /* Disable connection */ - _pSettingsModel->setConnectionState(ConnectionTypes::ID_2, false); - - ModbusPoll modbusPoll(_pSettingsModel); - QSignalSpy spyDataReady(&modbusPoll, &ModbusPoll::registerDataReady); - - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId + 1, Type::UNSIGNED_16); - - /*-- Start communication --*/ - modbusPoll.startCommunication(modbusRegisters); - - QVERIFY(spyDataReady.wait(50)); - QCOMPARE(spyDataReady.count(), 1); - - QList arguments = spyDataReady.takeFirst(); - - /* Disabled connections return error and zero */ - auto expResults = ResultDoubleList() << ResultDouble(5020, State::SUCCESS) << ResultDouble(0, State::INVALID); - - /* Verify arguments of signal */ - CommunicationHelpers::verifyReceivedDataSignal(arguments, expResults); -} - -void TestModbusPoll::notExistingDevice() -{ - /* Test fail with non existing device id */ - ModbusPoll modbusPoll(_pSettingsModel); - QSignalSpy spyDataReady(&modbusPoll, &ModbusPoll::registerDataReady); - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), 99, Type::UNSIGNED_16); /* Non existing device id */ - - /*-- Start communication --*/ - modbusPoll.startCommunication(modbusRegisters); - QVERIFY(spyDataReady.wait(50)); - QCOMPARE(spyDataReady.count(), 1); - QList arguments = spyDataReady.takeFirst(); - - /* Verify arguments of signal */ - auto expResults = ResultDoubleList() << ResultDouble(0, State::INVALID); - CommunicationHelpers::verifyReceivedDataSignal(arguments, expResults); -} - -QTEST_GUILESS_MAIN(TestModbusPoll) diff --git a/tests/communication/tst_modbuspoll.h b/tests/communication/tst_modbuspoll.h deleted file mode 100644 index ed51e4b0..00000000 --- a/tests/communication/tst_modbuspoll.h +++ /dev/null @@ -1,39 +0,0 @@ - -#include "models/settingsmodel.h" - -#include "testslavemodbus.h" - -#include - -class TestModbusPoll : public QObject -{ - Q_OBJECT - -private slots: - void init(); - void cleanup(); - - void singleSlaveSuccess(); - void singleSlaveFail(); - void singleOnlyConstantDataPoll(); - - void singleSlaveCoil(); - void singleSlaveMixedObjects(); - - void verifyRestartAfterStop(); - - void multiSlaveSuccess(); - void multiSlaveSuccess_2(); - void multiSlaveSuccess_3(); - void multiSlaveSameConnectionSameAddress(); - void multiSlaveSingleFail(); - void multiSlaveAllFail(); - - void multiSlaveDisabledConnection(); - void notExistingDevice(); - -private: - SettingsModel* _pSettingsModel; - - QMap _testSlaveMap; -}; diff --git a/tests/communication/tst_modbusregister.cpp b/tests/communication/tst_modbusregister.cpp deleted file mode 100644 index 1734dfbb..00000000 --- a/tests/communication/tst_modbusregister.cpp +++ /dev/null @@ -1,209 +0,0 @@ - -#include - -#include "tst_modbusregister.h" - -#include "communication/modbusregister.h" - -using Type = ModbusDataType::Type; - -#define ADD_TEST_16(name, registerValue, value) QTest::newRow(name) << static_cast(registerValue) \ - << static_cast(value) - -#define ADD_TEST_32(name, upperRegister, lowerRegister, value) QTest::newRow(name) << static_cast(upperRegister) \ - << static_cast(lowerRegister) \ - << static_cast(value) - -void TestModbusRegister::init() -{ - -} - -void TestModbusRegister::cleanup() -{ - -} - -void TestModbusRegister::constructor() -{ - ModbusRegister reg(ModbusAddress(40001), 2, Type::SIGNED_16); - - QCOMPARE(reg.address(), ModbusAddress(40001)); - QCOMPARE(reg.deviceId(), 2); - QCOMPARE(reg.type(), Type::SIGNED_16); -} - -void TestModbusRegister::comparison() -{ - ModbusRegister reg_1(ModbusAddress(40001), 1, Type::SIGNED_16); - ModbusRegister reg_2(ModbusAddress(40001), 1, Type::SIGNED_16); - - QVERIFY(reg_1 == reg_2); - - reg_1.setAddress(ModbusAddress(40002)); - - QVERIFY(!(reg_1 == reg_2)); -} - -void TestModbusRegister::copy() -{ - ModbusRegister reg_1(ModbusAddress(40001), 2, Type::SIGNED_32); - ModbusRegister reg_2; - - QVERIFY(!(reg_1 == reg_2)); - - reg_2 = reg_1; - - QCOMPARE(reg_1.address(), ModbusAddress(40001)); - QCOMPARE(reg_1.deviceId(), 2); - QCOMPARE(reg_1.type(), Type::SIGNED_32); - - QVERIFY(reg_1 == reg_2); -} - -void TestModbusRegister::description() -{ - ModbusRegister reg_1(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_16); - ModbusRegister reg_2(ModbusAddress(40002), Device::cFirstDeviceId + 1, Type::SIGNED_32); - ModbusRegister reg_3(ModbusAddress(40003), Device::cFirstDeviceId + 1, Type::FLOAT_32); - - QCOMPARE(reg_1.description(), "holding register, 0, unsigned 16-bit, device id 1"); - QCOMPARE(reg_2.description(), "holding register, 1, signed 32-bit, device id 2"); - QCOMPARE(reg_3.description(), "holding register, 2, 32-bit float, device id 2"); -} - -void TestModbusRegister::processValue_16b_data() -{ - QTest::addColumn("registerValue"); - QTest::addColumn("expValue"); - - ADD_TEST_16("16b_1", 0, 0); - ADD_TEST_16("16b_2", 0xFFFF, UINT16_MAX); -} - -void TestModbusRegister::processValue_16b() -{ - QFETCH(uint16_t, registerValue); - QFETCH(double, expValue); - - ModbusRegister reg(ModbusAddress(40001), 1, Type::UNSIGNED_16); - - double actValue = reg.processValue(registerValue, 0, false); - QCOMPARE(actValue, expValue); -} - -void TestModbusRegister::processValue_s16b_data() -{ - QTest::addColumn("registerValue"); - QTest::addColumn("expValue"); - - ADD_TEST_16("s16b_1", 0, 0); - ADD_TEST_16("s16b_2", 0xFFFF, -1); -} - -void TestModbusRegister::processValue_s16b() -{ - QFETCH(uint16_t, registerValue); - QFETCH(double, expValue); - - ModbusRegister reg(ModbusAddress(40001), 1, Type::SIGNED_16); - - double actValue = reg.processValue(registerValue, 0, false); - QCOMPARE(actValue, expValue); -} - -void TestModbusRegister::processValue_32b_data() -{ - QTest::addColumn("upperRegister"); - QTest::addColumn("lowerRegister"); - QTest::addColumn("expValue"); - - ADD_TEST_32("32b_1", 0, 0, 0); - ADD_TEST_32("32b_2", 0, 1, 1); - ADD_TEST_32("32b_3", 1, 0, 65536); - ADD_TEST_32("32b_4", 0xFFFF, 0xFFFF, UINT32_MAX); -} - -void TestModbusRegister::processValue_32b() -{ - QFETCH(uint16_t, upperRegister); - QFETCH(uint16_t, lowerRegister); - - QFETCH(double, expValue); - - ModbusRegister reg(ModbusAddress(40001), 1, Type::UNSIGNED_32); - - double actValue = reg.processValue(upperRegister, lowerRegister, false); - QCOMPARE(actValue, expValue); - - double actValue2 = reg.processValue(lowerRegister, upperRegister, true); - QCOMPARE(actValue2, expValue); -} - -void TestModbusRegister::processValue_s32b_data() -{ - QTest::addColumn("upperRegister"); - QTest::addColumn("lowerRegister"); - QTest::addColumn("expValue"); - - ADD_TEST_32("s32b_1", 0, 0, 0); - ADD_TEST_32("s32b_2", 0, 1, 1); - ADD_TEST_32("s32b_3", 1, 0, 65536); - ADD_TEST_32("s32b_4", 0xFFFF, 0xFFFF, -1); -} - -void TestModbusRegister::processValue_s32b() -{ - QFETCH(uint16_t, upperRegister); - QFETCH(uint16_t, lowerRegister); - QFETCH(double, expValue); - - ModbusRegister reg(ModbusAddress(40001), 1, Type::SIGNED_32); - - double actValue = reg.processValue(upperRegister, lowerRegister, false); - QCOMPARE(actValue, expValue); - - double actValue2 = reg.processValue(lowerRegister, upperRegister, true); - QCOMPARE(actValue2, expValue); -} - -void TestModbusRegister::processValue_f32b_data() -{ - QTest::addColumn("upperRegister"); - QTest::addColumn("lowerRegister"); - QTest::addColumn("expValue"); - - ADD_TEST_32("f32b_1", 0x0000, 0x0001, 1.4012984643e-45f); // smallest positive subnormal number - ADD_TEST_32("f32b_2", 0x007f, 0xffff, 1.1754942107e-38f); // largest subnormal number - ADD_TEST_32("f32b_3", 0x0080, 0x0000, 1.1754943508e-38f); // smallest positive normal number - ADD_TEST_32("f32b_4", 0x7f7f, 0xffff, 3.40282346639e38f); // largest normal number - ADD_TEST_32("f32b_5", 0x3f7f, 0xffff, 0.999999940395355225f); // largest number less than one - ADD_TEST_32("f32b_6", 0x3f80, 0x0000, 1); - ADD_TEST_32("f32b_7", 0x3f80, 0x0001, 1.000000119209289505f); // smallest number larger than one - ADD_TEST_32("f32b_8", 0xc000, 0x0000, -2); - ADD_TEST_32("f32b_9", 0x0000, 0x0000, 0); - ADD_TEST_32("f32b_10", 0x8000, 0x0000, 0); // -0 - ADD_TEST_32("f32b_11", 0x7f80, 0x0000, 0); // infinity - ADD_TEST_32("f32b_12", 0xff80, 0x0000, 0); // −infinity - ADD_TEST_32("f32b_13", 0x4049, 0x0fdb, 3.14159274101257324f); // pi - ADD_TEST_32("f32b_14", 0x3eaa, 0xaaab, 0.333333343267440796f); // 1/3 - ADD_TEST_32("f32b_15", 0xffc0, 0x0001, 0); // qNaN (on x86 and ARM processors) - ADD_TEST_32("f32b_16", 0xff80, 0x0001, 0); // sNaN (on x86 and ARM processors) -} - -void TestModbusRegister::processValue_f32b() -{ - QFETCH(uint16_t, upperRegister); - QFETCH(uint16_t, lowerRegister); - QFETCH(double, expValue); - - ModbusRegister reg(ModbusAddress(40001), 1, ModbusDataType::Type::FLOAT_32); - - double actValue = reg.processValue(upperRegister, lowerRegister, false); - QCOMPARE(actValue, expValue); - - double actValue2 = reg.processValue(lowerRegister, upperRegister, true); - QCOMPARE(actValue2, expValue); -} - -QTEST_GUILESS_MAIN(TestModbusRegister) diff --git a/tests/communication/tst_modbusregister.h b/tests/communication/tst_modbusregister.h deleted file mode 100644 index 90e65111..00000000 --- a/tests/communication/tst_modbusregister.h +++ /dev/null @@ -1,31 +0,0 @@ - -#include - -class TestModbusRegister: public QObject -{ - Q_OBJECT -private slots: - void init(); - void cleanup(); - - void constructor(); - void comparison(); - void copy(); - void description(); - - void processValue_16b_data(); - void processValue_16b(); - void processValue_s16b_data(); - void processValue_s16b(); - - void processValue_32b_data(); - void processValue_32b(); - void processValue_s32b_data(); - void processValue_s32b(); - - void processValue_f32b_data(); - void processValue_f32b(); - -private: - -}; diff --git a/tests/communication/tst_readregisters.cpp b/tests/communication/tst_readregisters.cpp deleted file mode 100644 index 616d55ed..00000000 --- a/tests/communication/tst_readregisters.cpp +++ /dev/null @@ -1,326 +0,0 @@ - -#include - -#include "tst_readregisters.h" - -#include "communication/readregisters.h" - -using ObjectType = ModbusDataUnit::ObjectType; - -void TestReadRegisters::init() -{ - -} - -void TestReadRegisters::cleanup() -{ - -} - -void TestReadRegisters::verifyAndAddErrorResult(ReadRegisters& readRegister, ModbusDataUnit addr, quint16 cnt) -{ - QVERIFY(readRegister.hasNext()); - - auto object = readRegister.next(); - QCOMPARE(object.address(), addr); - QCOMPARE(object.count(), cnt); - - readRegister.addError(); -} - -void TestReadRegisters::resetRead_1() -{ - ReadRegisters readRegister; - auto registerList = QList() << ModbusDataUnit(0); - - readRegister.resetRead(registerList, 255); - - verifyAndAddErrorResult(readRegister, ModbusDataUnit(0), 1); - - QVERIFY(!readRegister.hasNext()); -} - -void TestReadRegisters::resetRead_2() -{ - ReadRegisters readRegister; - auto registerList = QList() - << ModbusDataUnit(0) << ModbusDataUnit(1) << ModbusDataUnit(2) << ModbusDataUnit(3); - - readRegister.resetRead(registerList, 255); - - verifyAndAddErrorResult(readRegister, ModbusDataUnit(0), 4); - - QVERIFY(!readRegister.hasNext()); -} - -void TestReadRegisters::resetReadSplit_1() -{ - ReadRegisters readRegister; - auto registerList = QList() << ModbusDataUnit(0) << ModbusDataUnit(1) << ModbusDataUnit(3) - << ModbusDataUnit(5) << ModbusDataUnit(6) << ModbusDataUnit(8); - - readRegister.resetRead(registerList, 255); - - verifyAndAddErrorResult(readRegister, ModbusDataUnit(0), 2); - verifyAndAddErrorResult(readRegister, ModbusDataUnit(3), 1); - verifyAndAddErrorResult(readRegister, ModbusDataUnit(5), 2); - verifyAndAddErrorResult(readRegister, ModbusDataUnit(8), 1); - - QVERIFY(!readRegister.hasNext()); -} - -void TestReadRegisters::resetReadSplit_2() -{ - ReadRegisters readRegister; - auto registerList = QList() << ModbusDataUnit(0) << ModbusDataUnit(3); - - readRegister.resetRead(registerList, 255); - - verifyAndAddErrorResult(readRegister, ModbusDataUnit(0), 1); - verifyAndAddErrorResult(readRegister, ModbusDataUnit(3), 1); - - QVERIFY(!readRegister.hasNext()); -} - -void TestReadRegisters::resetReadDifferentObjectTypes_1() -{ - ReadRegisters readRegister; - auto registerList = QList() - << ModbusDataUnit(0, ObjectType::COIL) << ModbusDataUnit(1, ObjectType::COIL) - << ModbusDataUnit(0, ObjectType::HOLDING_REGISTER) - << ModbusDataUnit(2, ObjectType::HOLDING_REGISTER); - - readRegister.resetRead(registerList, 255); - - verifyAndAddErrorResult(readRegister, ModbusDataUnit(0, ObjectType::COIL), 2); - verifyAndAddErrorResult(readRegister, ModbusDataUnit(0, ObjectType::HOLDING_REGISTER), 1); - verifyAndAddErrorResult(readRegister, ModbusDataUnit(2, ObjectType::HOLDING_REGISTER), 1); - - QVERIFY(!readRegister.hasNext()); -} - -void TestReadRegisters::resetReadDifferentObjectTypes_2() -{ - ReadRegisters readRegister; - auto registerList = QList() - << ModbusDataUnit(10000) << ModbusDataUnit(10001) << ModbusDataUnit(10002) - << ModbusDataUnit(40000) << ModbusDataUnit(40001) << ModbusDataUnit(40002); - - readRegister.resetRead(registerList, 255); - - verifyAndAddErrorResult(readRegister, ModbusDataUnit(10000), 1); - verifyAndAddErrorResult(readRegister, ModbusDataUnit(10001), 2); - verifyAndAddErrorResult(readRegister, ModbusDataUnit(40000), 1); - verifyAndAddErrorResult(readRegister, ModbusDataUnit(40001), 2); - - QVERIFY(!readRegister.hasNext()); -} - -void TestReadRegisters::consecutive_1() -{ - ReadRegisters readRegister; - auto registerList = QList() << ModbusDataUnit(0) << ModbusDataUnit(1) << ModbusDataUnit(2) - << ModbusDataUnit(3) << ModbusDataUnit(4) << ModbusDataUnit(5); - - readRegister.resetRead(registerList, 3); - - verifyAndAddErrorResult(readRegister, ModbusDataUnit(0), 3); - verifyAndAddErrorResult(readRegister, ModbusDataUnit(3), 3); - - QVERIFY(!readRegister.hasNext()); -} - -void TestReadRegisters::consecutive_2() -{ - ReadRegisters readRegister; - auto registerList = QList() << ModbusDataUnit(0) << ModbusDataUnit(1); - - readRegister.resetRead(registerList, 5); - - verifyAndAddErrorResult(readRegister, ModbusDataUnit(0), 2); - - QVERIFY(!readRegister.hasNext()); -} - -void TestReadRegisters::consecutive_3() -{ - ReadRegisters readRegister; - auto registerList = QList() << ModbusDataUnit(0) << ModbusDataUnit(1) << ModbusDataUnit(2); - - readRegister.resetRead(registerList, 2); - - verifyAndAddErrorResult(readRegister, ModbusDataUnit(0), 2); - verifyAndAddErrorResult(readRegister, ModbusDataUnit(2), 1); - - QVERIFY(!readRegister.hasNext()); -} - -void TestReadRegisters::splitNextToSingleReads_1() -{ - ReadRegisters readRegister; - auto registerList = QList() << ModbusDataUnit(0); - - readRegister.resetRead(registerList, 2); - - QVERIFY(readRegister.hasNext()); - QCOMPARE(readRegister.next().address(), ModbusDataUnit(0)); - QCOMPARE(readRegister.next().count(), 1); - - readRegister.splitNextToSingleReads(); - - verifyAndAddErrorResult(readRegister, ModbusDataUnit(0), 1); - - QVERIFY(!readRegister.hasNext()); -} - -void TestReadRegisters::splitNextToSingleReads_2() -{ - ReadRegisters readRegister; - auto registerList = QList() << ModbusDataUnit(0) << ModbusDataUnit(1) << ModbusDataUnit(2); - - readRegister.resetRead(registerList, 100); - - QVERIFY(readRegister.hasNext()); - QCOMPARE(readRegister.next().address(), ModbusDataUnit(0)); - QCOMPARE(readRegister.next().count(), 3); - - readRegister.splitNextToSingleReads(); - - verifyAndAddErrorResult(readRegister, ModbusDataUnit(0), 1); - verifyAndAddErrorResult(readRegister, ModbusDataUnit(1), 1); - verifyAndAddErrorResult(readRegister, ModbusDataUnit(2), 1); - - QVERIFY(!readRegister.hasNext()); -} - -void TestReadRegisters::splitNextToSingleReads_3() -{ - ReadRegisters readRegister; - auto registerList = QList() << ModbusDataUnit(0) << ModbusDataUnit(1) << ModbusDataUnit(2) - << ModbusDataUnit(5) << ModbusDataUnit(6); - - readRegister.resetRead(registerList, 100); - - QVERIFY(readRegister.hasNext()); - QCOMPARE(readRegister.next().address(), ModbusDataUnit(0)); - QCOMPARE(readRegister.next().count(), 3); - - readRegister.splitNextToSingleReads(); - - verifyAndAddErrorResult(readRegister, ModbusDataUnit(0), 1); - verifyAndAddErrorResult(readRegister, ModbusDataUnit(1), 1); - verifyAndAddErrorResult(readRegister, ModbusDataUnit(2), 1); - - verifyAndAddErrorResult(readRegister, ModbusDataUnit(5), 2); - - QVERIFY(!readRegister.hasNext()); -} - -void TestReadRegisters::addAllErrors() -{ - ReadRegisters readRegister; - auto registerList = QList() << ModbusDataUnit(0) << ModbusDataUnit(1) << ModbusDataUnit(2) - << ModbusDataUnit(5) << ModbusDataUnit(6) << ModbusDataUnit(7); - - readRegister.resetRead(registerList, 100); - - readRegister.addAllErrors(); - - QVERIFY(!readRegister.hasNext()); - - auto resultMap = readRegister.resultMap(); - - QCOMPARE(resultMap.size(), registerList.size()); - - for(quint16 idx = 0; idx < static_cast(registerList.size()); idx++) - { - QCOMPARE(resultMap.value(registerList[idx]).value(), 0); - QVERIFY(!resultMap.value(registerList[idx]).isValid()); - } -} - -void TestReadRegisters::addSuccess() -{ - ReadRegisters readRegister; - auto registerList = QList() << ModbusDataUnit(0) << ModbusDataUnit(1) << ModbusDataUnit(2) - << ModbusDataUnit(5) << ModbusDataUnit(6) << ModbusDataUnit(8); - - readRegister.resetRead(registerList, 100); - - QVERIFY(readRegister.hasNext()); - QCOMPARE(readRegister.next().address(), ModbusDataUnit(0)); - QCOMPARE(readRegister.next().count(), 3); - - readRegister.addSuccess(ModbusDataUnit(0), QList() << 1000 << 1001 << 1002); - - QVERIFY(readRegister.hasNext()); - QCOMPARE(readRegister.next().address(), ModbusDataUnit(5)); - QCOMPARE(readRegister.next().count(), 2); - - readRegister.addSuccess(ModbusDataUnit(5), QList() << 1005 << 1006); - - QVERIFY(readRegister.hasNext()); - QCOMPARE(readRegister.next().address(), ModbusDataUnit(8)); - QCOMPARE(readRegister.next().count(), 1); - - readRegister.addSuccess(ModbusDataUnit(8), QList() << 1008); - - QVERIFY(!readRegister.hasNext()); - - auto resultMap = readRegister.resultMap(); - - QCOMPARE(resultMap.size(), registerList.size()); - - for(quint16 idx = 0; idx < static_cast(registerList.size()); idx++) - { - QCOMPARE(resultMap.value(registerList[idx]).value(), registerList[idx].protocolAddress() + 1000); - QVERIFY(resultMap.value(registerList[idx]).isValid()); - } -} - -void TestReadRegisters::addSuccessAndErrors() -{ - ReadRegisters readRegister; - auto registerList = QList() - << ModbusDataUnit(0) << ModbusDataUnit(1) << ModbusDataUnit(5) << ModbusDataUnit(8); - - readRegister.resetRead(registerList, 100); - - QVERIFY(readRegister.hasNext()); - QCOMPARE(readRegister.next().address(), ModbusDataUnit(0)); - QCOMPARE(readRegister.next().count(), 2); - - readRegister.addSuccess(ModbusDataUnit(0), QList() << 1000 << 1001); - - QVERIFY(readRegister.hasNext()); - QCOMPARE(readRegister.next().address(), ModbusDataUnit(5)); - QCOMPARE(readRegister.next().count(), 1); - - readRegister.addError(); - - QVERIFY(readRegister.hasNext()); - QCOMPARE(readRegister.next().address(), ModbusDataUnit(8)); - QCOMPARE(readRegister.next().count(), 1); - - readRegister.addSuccess(ModbusDataUnit(8), QList() << 1008); - - QVERIFY(!readRegister.hasNext()); - - auto resultMap = readRegister.resultMap(); - - QCOMPARE(resultMap.size(), registerList.size()); - - QCOMPARE(resultMap.value(ModbusDataUnit(0)).value(), 1000); - QVERIFY(resultMap.value(ModbusDataUnit(0)).isValid()); - - QCOMPARE(resultMap.value(ModbusDataUnit(1)).value(), 1001); - QVERIFY(resultMap.value(ModbusDataUnit(1)).isValid()); - - QCOMPARE(resultMap.value(ModbusDataUnit(5)).value(), 0); - QVERIFY(!resultMap.value(ModbusDataUnit(5)).isValid()); - - QCOMPARE(resultMap.value(ModbusDataUnit(8)).value(), 1008); - QVERIFY(resultMap.value(ModbusDataUnit(8)).isValid()); -} - -QTEST_GUILESS_MAIN(TestReadRegisters) diff --git a/tests/communication/tst_readregisters.h b/tests/communication/tst_readregisters.h deleted file mode 100644 index 2bdaf003..00000000 --- a/tests/communication/tst_readregisters.h +++ /dev/null @@ -1,43 +0,0 @@ - -#ifndef TEST_READREGISTERS_H__ -#define TEST_READREGISTERS_H__ - -#include "communication/modbusdataunit.h" - -#include - -/* Forward declaration */ -class ReadRegisters; - -class TestReadRegisters: public QObject -{ - Q_OBJECT -private slots: - void init(); - void cleanup(); - - void resetRead_1(); - void resetRead_2(); - void resetReadSplit_1(); - void resetReadSplit_2(); - - void resetReadDifferentObjectTypes_1(); - void resetReadDifferentObjectTypes_2(); - - void consecutive_1(); - void consecutive_2(); - void consecutive_3(); - - void splitNextToSingleReads_1(); - void splitNextToSingleReads_2(); - void splitNextToSingleReads_3(); - - void addAllErrors(); - void addSuccess(); - void addSuccessAndErrors(); - -private: - void verifyAndAddErrorResult(ReadRegisters& readRegister, ModbusDataUnit addr, quint16 cnt); -}; - -#endif /* TEST_READREGISTERS_H__ */ diff --git a/tests/communication/tst_registervaluehandler.cpp b/tests/communication/tst_registervaluehandler.cpp deleted file mode 100644 index 5074b834..00000000 --- a/tests/communication/tst_registervaluehandler.cpp +++ /dev/null @@ -1,400 +0,0 @@ - -#include "tst_registervaluehandler.h" - -#include "communication/registervaluehandler.h" -#include "models/settingsmodel.h" - -#include -#include - -Q_DECLARE_METATYPE(ResultDouble); - -using Type = ModbusDataType::Type; -using State = ResultState::State; - -void TestRegisterValueHandler::init() -{ - qRegisterMetaType("ResultDouble"); - qRegisterMetaType("ResultDoubleList"); - - _pSettingsModel = new SettingsModel(); - - _pSettingsModel->deviceSettings(Device::cFirstDeviceId)->setInt32LittleEndian(true); - - deviceId_t devId = Device::cFirstDeviceId + 1; - _pSettingsModel->addDevice(devId); - _pSettingsModel->deviceSettings(devId)->setConnectionId(ConnectionTypes::ID_2); - _pSettingsModel->deviceSettings(devId)->setInt32LittleEndian(true); - _pSettingsModel->deviceSettings(devId)->setSlaveId(2); -} - -void TestRegisterValueHandler::cleanup() -{ - delete _pSettingsModel; -} - -void TestRegisterValueHandler::addressList_16() -{ - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_16); - auto expRegisterList = QList() << ModbusDataUnit(40001); - - RegisterValueHandler regHandler(_pSettingsModel); - regHandler.setRegisters(modbusRegisters); - - QList actualRegisterList; - regHandler.registerAddresListForConnection(actualRegisterList, ConnectionTypes::ID_1); - - QVERIFY(actualRegisterList == expRegisterList); -} - -void TestRegisterValueHandler::addressList_16_multiple() -{ - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(40002), Device::cFirstDeviceId, Type::UNSIGNED_16); - auto expRegisterList = QList() << ModbusDataUnit(40001) << ModbusDataUnit(40002); - - RegisterValueHandler regHandler(_pSettingsModel); - regHandler.setRegisters(modbusRegisters); - - QList actualRegisterList; - regHandler.registerAddresListForConnection(actualRegisterList, ConnectionTypes::ID_1); - - QVERIFY(actualRegisterList == expRegisterList); -} - -void TestRegisterValueHandler::addressList_32() -{ - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_32); - auto expRegisterList = QList() << ModbusDataUnit(40001) << ModbusDataUnit(40002); - - RegisterValueHandler regHandler(_pSettingsModel); - regHandler.setRegisters(modbusRegisters); - - QList actualRegisterList; - regHandler.registerAddresListForConnection(actualRegisterList, ConnectionTypes::ID_1); - - QVERIFY(actualRegisterList == expRegisterList); -} - -void TestRegisterValueHandler::addressList_32_multiple() -{ - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_32) - << ModbusRegister(ModbusAddress(40005), Device::cFirstDeviceId, Type::UNSIGNED_32); - auto expRegisterList = QList() << ModbusDataUnit(40001) << ModbusDataUnit(40002) - << ModbusDataUnit(40005) << ModbusDataUnit(40006); - - RegisterValueHandler regHandler(_pSettingsModel); - regHandler.setRegisters(modbusRegisters); - - QList actualRegisterList; - regHandler.registerAddresListForConnection(actualRegisterList, ConnectionTypes::ID_1); - - QVERIFY(actualRegisterList == expRegisterList); -} - -void TestRegisterValueHandler::addressList_float32() -{ - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::FLOAT_32); - auto expRegisterList = QList() << ModbusDataUnit(40001) << ModbusDataUnit(40002); - - RegisterValueHandler regHandler(_pSettingsModel); - regHandler.setRegisters(modbusRegisters); - - QList actualRegisterList; - regHandler.registerAddresListForConnection(actualRegisterList, ConnectionTypes::ID_1); - - QVERIFY(actualRegisterList == expRegisterList); -} - -void TestRegisterValueHandler::addressList_float32_multiple() -{ - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::FLOAT_32) - << ModbusRegister(ModbusAddress(40005), Device::cFirstDeviceId, Type::FLOAT_32); - auto expRegisterList = QList() << ModbusDataUnit(40001) << ModbusDataUnit(40002) - << ModbusDataUnit(40005) << ModbusDataUnit(40006); - - RegisterValueHandler regHandler(_pSettingsModel); - regHandler.setRegisters(modbusRegisters); - - QList actualRegisterList; - regHandler.registerAddresListForConnection(actualRegisterList, ConnectionTypes::ID_1); - - QVERIFY(actualRegisterList == expRegisterList); -} - -void TestRegisterValueHandler::addressListCombinations() -{ - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(40005), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(40005), Device::cFirstDeviceId, Type::UNSIGNED_32) - << ModbusRegister(ModbusAddress(40008), Device::cFirstDeviceId, Type::UNSIGNED_32); - auto expRegisterList = QList() - << ModbusDataUnit(40001) << ModbusDataUnit(40005) << ModbusDataUnit(40006) - << ModbusDataUnit(40008) << ModbusDataUnit(40009); - - RegisterValueHandler regHandler(_pSettingsModel); - regHandler.setRegisters(modbusRegisters); - - QList actualRegisterList; - regHandler.registerAddresListForConnection(actualRegisterList, ConnectionTypes::ID_1); - - QVERIFY(actualRegisterList == expRegisterList); -} - -void TestRegisterValueHandler::addressListMultipleConnections() -{ - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_32) - << ModbusRegister(ModbusAddress(40005), Device::cFirstDeviceId + 1, Type::UNSIGNED_32) - << ModbusRegister(ModbusAddress(40010), Device::cFirstDeviceId, Type::UNSIGNED_32); - auto expRegisterList0 = QList() << ModbusDataUnit(40001) << ModbusDataUnit(40002) - << ModbusDataUnit(40010) << ModbusDataUnit(40011); - auto expRegisterList1 = QList() - << ModbusDataUnit(40005 - 40001, ModbusDataUnit::ObjectType::HOLDING_REGISTER, 2) - << ModbusDataUnit(40006 - 40001, ModbusDataUnit::ObjectType::HOLDING_REGISTER, 2); - - RegisterValueHandler regHandler(_pSettingsModel); - regHandler.setRegisters(modbusRegisters); - - QList actualRegisterList0; - QList actualRegisterList1; - regHandler.registerAddresListForConnection(actualRegisterList0, ConnectionTypes::ID_1); - regHandler.registerAddresListForConnection(actualRegisterList1, ConnectionTypes::ID_2); - - QVERIFY(actualRegisterList0 == expRegisterList0); - QVERIFY(actualRegisterList1 == expRegisterList1); -} - -void TestRegisterValueHandler::addressListMixedObjects() -{ - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(0), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(30002), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(40002), Device::cFirstDeviceId, Type::UNSIGNED_16); - auto expRegisterList = QList() - << ModbusDataUnit(0) << ModbusDataUnit(30002) << ModbusDataUnit(40002); - - RegisterValueHandler regHandler(_pSettingsModel); - regHandler.setRegisters(modbusRegisters); - - QList actualRegisterList; - regHandler.registerAddresListForConnection(actualRegisterList, ConnectionTypes::ID_1); - - QVERIFY(actualRegisterList == expRegisterList); -} - -void TestRegisterValueHandler::addressListSameRegisterDifferentType() -{ - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(0), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(0), Device::cFirstDeviceId, Type::SIGNED_16); - auto expRegisterList = QList() << ModbusDataUnit(0); - - RegisterValueHandler regHandler(_pSettingsModel); - regHandler.setRegisters(modbusRegisters); - - QList actualRegisterList; - regHandler.registerAddresListForConnection(actualRegisterList, ConnectionTypes::ID_1); - - QVERIFY(actualRegisterList == expRegisterList); -} - -void TestRegisterValueHandler::read_16() -{ - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(40002), Device::cFirstDeviceId, Type::SIGNED_16); - ModbusResultMap partialResultMap; - addToResultMap(partialResultMap, 40001, false, 256, State::SUCCESS); - addToResultMap(partialResultMap, 40002, false, -100, State::SUCCESS); - - auto expResults = ResultDoubleList() << ResultDouble(256, State::SUCCESS) - << ResultDouble(-100, State::SUCCESS); - - verifyRegisterResult(modbusRegisters, partialResultMap, expResults); -} - -void TestRegisterValueHandler::read_32() -{ - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_32) - << ModbusRegister(ModbusAddress(40005), Device::cFirstDeviceId, Type::SIGNED_32); - ModbusResultMap partialResultMap; - addToResultMap(partialResultMap, 40001, true, 1000000, State::SUCCESS); - addToResultMap(partialResultMap, 40005, true, -100000, State::SUCCESS); - - auto expResults = ResultDoubleList() << ResultDouble(1000000, State::SUCCESS) - << ResultDouble(-100000, State::SUCCESS); - - verifyRegisterResult(modbusRegisters, partialResultMap, expResults); -} - -void TestRegisterValueHandler::readBigEndian_32() -{ - _pSettingsModel->deviceSettings(Device::cFirstDeviceId)->setInt32LittleEndian(false); - - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_32); - ModbusResultMap partialResultMap; - quint32 value = 1000000; - - partialResultMap.insert(ModbusDataUnit(40001), Result(static_cast(value) >> 16, State::SUCCESS)); - partialResultMap.insert(ModbusDataUnit(40001 + 1), Result(static_cast(value), State::SUCCESS)); - - auto expResults = ResultDoubleList() << ResultDouble(1000000, State::SUCCESS); - - verifyRegisterResult(modbusRegisters, partialResultMap, expResults); -} - -void TestRegisterValueHandler::readBigEndian_s32() -{ - _pSettingsModel->deviceSettings(Device::cFirstDeviceId)->setInt32LittleEndian(false); - - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::SIGNED_32); - ModbusResultMap partialResultMap; - quint32 value = -1000000; - - partialResultMap.insert(ModbusDataUnit(40001), Result(static_cast(value) >> 16, State::SUCCESS)); - partialResultMap.insert(ModbusDataUnit(40001 + 1), Result(static_cast(value), State::SUCCESS)); - - auto expResults = ResultDoubleList() << ResultDouble(-1000000, State::SUCCESS); - - verifyRegisterResult(modbusRegisters, partialResultMap, expResults); -} - -void TestRegisterValueHandler::readSameRegisterDifferentType() -{ - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_32) - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::SIGNED_32); - - ModbusResultMap partialResultMap; - addToResultMap(partialResultMap, 40001, true, 255, State::SUCCESS); - - auto expResults = ResultDoubleList() << ResultDouble(255, State::SUCCESS) - << ResultDouble(255, State::SUCCESS); - - verifyRegisterResult(modbusRegisters, partialResultMap, expResults); -} - -void TestRegisterValueHandler::readConnections() -{ - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId + 1, Type::SIGNED_16); - ModbusResultMap partialResultMap1; - addToResultMap(partialResultMap1, 40001, false, 256, State::SUCCESS, 1); - - ModbusResultMap partialResultMap2; - addToResultMap(partialResultMap2, 40001, false, 100, State::SUCCESS, 2); - - auto expResults = ResultDoubleList() << ResultDouble(256, State::SUCCESS) - << ResultDouble(100, State::SUCCESS); - - - RegisterValueHandler regHandler(_pSettingsModel); - regHandler.setRegisters(modbusRegisters); - - QSignalSpy spyDataReady(®Handler, &RegisterValueHandler::registerDataReady); - - regHandler.startRead(); - regHandler.processPartialResult(partialResultMap1, ConnectionTypes::ID_1); - regHandler.processPartialResult(partialResultMap2, ConnectionTypes::ID_2); - regHandler.finishRead(); - - QCOMPARE(spyDataReady.count(), 1); - - QList arguments = spyDataReady.takeFirst(); - QVERIFY(arguments.count() > 0); - - QVariant varResultList = arguments.first(); - QVERIFY(varResultList.canConvert()); - ResultDoubleList result = varResultList.value(); - - QCOMPARE(result, expResults); -} - -void TestRegisterValueHandler::readFail() -{ - auto modbusRegisters = QList() - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId, Type::UNSIGNED_16) - << ModbusRegister(ModbusAddress(40001), Device::cFirstDeviceId + 1, Type::SIGNED_16); - - ModbusResultMap partialResultMap2; - addToResultMap(partialResultMap2, 40001, false, 100, State::SUCCESS, 2); - - auto expResults = ResultDoubleList() << ResultDouble(0, State::INVALID) - << ResultDouble(100, State::SUCCESS); - - - RegisterValueHandler regHandler(_pSettingsModel); - regHandler.setRegisters(modbusRegisters); - - QSignalSpy spyDataReady(®Handler, &RegisterValueHandler::registerDataReady); - - regHandler.startRead(); - regHandler.processPartialResult(partialResultMap2, ConnectionTypes::ID_2); - regHandler.finishRead(); - - QCOMPARE(spyDataReady.count(), 1); - - QList arguments = spyDataReady.takeFirst(); - QVERIFY(arguments.count() > 0); - - QVariant varResultList = arguments.first(); - QVERIFY(varResultList.canConvert()); - ResultDoubleList result = varResultList.value(); - - QCOMPARE(result, expResults); -} - -void TestRegisterValueHandler::verifyRegisterResult(QList& regList, - ModbusResultMap ®Data, - ResultDoubleList expResults) -{ - RegisterValueHandler regHandler(_pSettingsModel); - regHandler.setRegisters(regList); - - QSignalSpy spyDataReady(®Handler, &RegisterValueHandler::registerDataReady); - - regHandler.startRead(); - regHandler.processPartialResult(regData, ConnectionTypes::ID_1); - regHandler.finishRead(); - - QCOMPARE(spyDataReady.count(), 1); - - QList arguments = spyDataReady.takeFirst(); - QVERIFY(arguments.count() > 0); - - QVariant varResultList = arguments.first(); - QVERIFY(varResultList.canConvert()); - ResultDoubleList result = varResultList.value(); - - QCOMPARE(result, expResults); -} - -void TestRegisterValueHandler::addToResultMap(ModbusResultMap &resultMap, - quint32 addr, - bool b32bit, - qint64 value, - State resultState, - ModbusDataUnit::slaveId_t slaveId - ) -{ - resultMap.insert(ModbusDataUnit(addr, ModbusAddress::ObjectType::UNKNOWN, slaveId), Result(static_cast(value), resultState)); - - if (b32bit) - { - resultMap.insert(ModbusDataUnit(addr + 1, ModbusAddress::ObjectType::UNKNOWN, slaveId), Result(static_cast(value) >> 16, resultState)); - } -} - -QTEST_GUILESS_MAIN(TestRegisterValueHandler) diff --git a/tests/communication/tst_registervaluehandler.h b/tests/communication/tst_registervaluehandler.h deleted file mode 100644 index cc6c3b98..00000000 --- a/tests/communication/tst_registervaluehandler.h +++ /dev/null @@ -1,54 +0,0 @@ - -#include "communication/modbusregister.h" -#include "communication/modbusresultmap.h" - -#include - -/* Forward declaration */ -class SettingsModel; - -class TestRegisterValueHandler: public QObject -{ - Q_OBJECT -private slots: - void init(); - void cleanup(); - - void addressList_16(); - void addressList_16_multiple(); - void addressList_32(); - void addressList_32_multiple(); - void addressList_float32(); - void addressList_float32_multiple(); - void addressListCombinations(); - void addressListMultipleConnections(); - void addressListMixedObjects(); - void addressListSameRegisterDifferentType(); - - void read_16(); - void read_32(); - - void readBigEndian_32(); - void readBigEndian_s32(); - - void readSameRegisterDifferentType(); - void readConnections(); - void readFail(); - -private: - - void verifyRegisterResult(QList& regList, - ModbusResultMap ®Data, - ResultDoubleList expResults); - - void addToResultMap(ModbusResultMap &resultMap, - quint32 addr, - bool b32bit, - qint64 value, - ResultState::State resultState, - ModbusDataUnit::slaveId_t slaveId = 1 - ); - - SettingsModel* _pSettingsModel; - -}; diff --git a/tests/testslave/modbusconnectionfake.cpp b/tests/testslave/modbusconnectionfake.cpp deleted file mode 100644 index 7bf40e4c..00000000 --- a/tests/testslave/modbusconnectionfake.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "modbusconnectionfake.h" - -#include "communication/modbusdataunit.h" - -#include - -using RegisterType = QModbusDataUnit::RegisterType; -using ObjectType = ModbusAddress::ObjectType; - -/*! - * Constructor for ModbusConnectionFake module - */ -ModbusConnectionFake::ModbusConnectionFake() -{ -} - -void ModbusConnectionFake::addSlaveDevice(ModbusAddress::slaveId_t slaveId, TestDevice* pDevice) -{ - _deviceMap.insert(slaveId, pDevice); -} - -void ModbusConnectionFake::configureTcpConnection(tcpSettings_t const& tcpSettings) -{ - Q_UNUSED(tcpSettings); -} - -void ModbusConnectionFake::configureSerialConnection(serialSettings_t const& serialSettings) -{ - Q_UNUSED(serialSettings); -} - -/*! - * Start opening of connection - * Emits signals (\ref connectionSuccess, \ref errorOccurred) when connection is ready or failed - * - * \param[in] timeout Timeout of connection (in seconds) - */ -void ModbusConnectionFake::open(quint32 timeout) -{ - Q_UNUSED(timeout); - - emit connectionSuccess(); -} - -/*! - * Close connection - */ -void ModbusConnectionFake::close(void) -{ -} - -/*! - * Send read request over connection - * - * \param regAddress register address - * \param size number of registers - * \param serverAddress slave address - */ -void ModbusConnectionFake::sendReadRequest(const ModbusDataUnit& regAddress, quint16 size) -{ - using RegisterType = QModbusDataUnit::RegisterType; - - // Map ModbusAddress::ObjectType to QModbusDataUnit::RegisterType - RegisterType type = QModbusDataUnit::HoldingRegisters; - switch (regAddress.objectType()) - { - case ModbusAddress::ObjectType::COIL: - type = QModbusDataUnit::Coils; - break; - case ModbusAddress::ObjectType::DISCRETE_INPUT: - type = QModbusDataUnit::DiscreteInputs; - break; - case ModbusAddress::ObjectType::INPUT_REGISTER: - type = QModbusDataUnit::InputRegisters; - break; - case ModbusAddress::ObjectType::HOLDING_REGISTER: - type = QModbusDataUnit::HoldingRegisters; - break; - default: - emit readRequestProtocolError(QModbusPdu::IllegalDataAddress); - return; - } - - // find device for requested slave id - const ModbusAddress::slaveId_t sid = regAddress.slaveId(); - TestDevice* pDevice = _deviceMap.value(sid, nullptr); - if (!pDevice) - { - emit readRequestError(QStringLiteral("No test device for slave id %1").arg(static_cast(sid)), - QModbusDevice::ConfigurationError); - return; - } - - TestSlaveData* pData = pDevice->slaveData(type); - if (!pData) - { - emit readRequestProtocolError(QModbusPdu::IllegalDataAddress); - return; - } - - const quint32 startAddress = regAddress.protocolAddress(); - QList registerData; - registerData.reserve(size); - for (quint16 i = 0; i < size; ++i) - { - registerData.append(pData->registerValue(startAddress + i)); - } - - emit readRequestSuccess(regAddress, registerData); -} - -/*! - * Return whether connection is ok - * - * \return Connection state - */ -bool ModbusConnectionFake::isConnected(void) -{ - return true; -} diff --git a/tests/testslave/modbusconnectionfake.h b/tests/testslave/modbusconnectionfake.h deleted file mode 100644 index 8c390cd9..00000000 --- a/tests/testslave/modbusconnectionfake.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef MODBUSCONNECTIONFAKE_H -#define MODBUSCONNECTIONFAKE_H - -#include "communication/modbusconnection.h" -#include "communication/modbusdataunit.h" -#include "testdevice.h" - -using SlaveDeviceMap = QMap; - -class ModbusConnectionFake : public ModbusConnection -{ - Q_OBJECT -public: - explicit ModbusConnectionFake(); - - void addSlaveDevice(ModbusAddress::slaveId_t slaveId, TestDevice* pDevice); - - void configureTcpConnection(tcpSettings_t const& tcpSettings) override; - void configureSerialConnection(serialSettings_t const& serialSettings) override; - - void open(quint32 timeout) override; - void close(void) override; - - void sendReadRequest(ModbusDataUnit const& regAddress, quint16 size) override; - - bool isConnected(void) override; - -private: - SlaveDeviceMap _deviceMap; -}; - -#endif // MODBUSCONNECTIONFAKE_H diff --git a/tests/testslave/testdevice.cpp b/tests/testslave/testdevice.cpp deleted file mode 100644 index 2253c9b6..00000000 --- a/tests/testslave/testdevice.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "testdevice.h" - -TestDevice::TestDevice(QObject* parent) : QObject(parent) -{ - _slaveDataMap[QModbusDataUnit::Coils] = new TestSlaveData(); - _slaveDataMap[QModbusDataUnit::DiscreteInputs] = new TestSlaveData(); - _slaveDataMap[QModbusDataUnit::InputRegisters] = new TestSlaveData(); - _slaveDataMap[QModbusDataUnit::HoldingRegisters] = new TestSlaveData(); -} - -TestDevice::~TestDevice() -{ - if (!_slaveDataMap.isEmpty()) - { - qDeleteAll(_slaveDataMap); - _slaveDataMap.clear(); - } -} - -TestSlaveData* TestDevice::slaveData(QModbusDataUnit::RegisterType type) const -{ - return _slaveDataMap.value(type, nullptr); -} - -void TestDevice::setSlaveData(QModbusDataUnit::RegisterType type, TestSlaveData* slaveData) -{ - if (_slaveDataMap.contains(type)) - { - delete _slaveDataMap[type]; - } - _slaveDataMap[type] = slaveData; -} - -void TestDevice::configureHoldingRegister(uint address, bool state, quint16 value) -{ - configureRegister(QModbusDataUnit::HoldingRegisters, address, state, value); -} - -void TestDevice::configureInputRegister(uint address, bool state, quint16 value) -{ - configureRegister(QModbusDataUnit::InputRegisters, address, state, value); -} - -void TestDevice::configureCoil(uint address, bool state, bool value) -{ - configureRegister(QModbusDataUnit::Coils, address, state, value ? 1 : 0); -} - -void TestDevice::configureDiscreteInput(uint address, bool state, bool value) -{ - configureRegister(QModbusDataUnit::DiscreteInputs, address, state, value ? 1 : 0); -} - -void TestDevice::configureRegister(QModbusDataUnit::RegisterType type, uint address, bool state, quint16 value) -{ - if (_slaveDataMap.contains(type)) - { - _slaveDataMap[type]->setRegisterState(address, state); - _slaveDataMap[type]->setRegisterValue(address, value); - } -} diff --git a/tests/testslave/testdevice.h b/tests/testslave/testdevice.h deleted file mode 100644 index 51054be2..00000000 --- a/tests/testslave/testdevice.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef TEST_DEVICE_H -#define TEST_DEVICE_H - -#include "testslavedata.h" -#include -#include - -class TestDevice : public QObject -{ - Q_OBJECT -public: - explicit TestDevice(QObject* parent = nullptr); - ~TestDevice(); - - TestSlaveData* slaveData(QModbusDataUnit::RegisterType type) const; - void setSlaveData(QModbusDataUnit::RegisterType type, TestSlaveData* slaveData); - - void configureHoldingRegister(uint address, bool state, quint16 value); - void configureInputRegister(uint address, bool state, quint16 value); - void configureCoil(uint address, bool state, bool value); - void configureDiscreteInput(uint address, bool state, bool value); - -private: - void configureRegister(QModbusDataUnit::RegisterType type, uint address, bool state, quint16 value); - - typedef QMap ModbusDataMap; - - ModbusDataMap _slaveDataMap; -}; - -#endif // TEST_DEVICE_H diff --git a/tests/testslave/testslavedata.cpp b/tests/testslave/testslavedata.cpp deleted file mode 100644 index 62216f5f..00000000 --- a/tests/testslave/testslavedata.cpp +++ /dev/null @@ -1,118 +0,0 @@ -#include "testslavedata.h" - -TestSlaveData::TestSlaveData(quint32 offset, quint32 registerCount) - : QObject(nullptr), - _offset(offset) -{ - _registerList.clear(); - for(quint32 idx = 0u; idx < registerCount; idx++) - { - _registerList.append({false, 0}); - } -} - -TestSlaveData::~TestSlaveData() -{ - -} - -bool TestSlaveData::isValidAddress(quint32 startAddress, quint32 valueCount) -{ - bool isValid = false; - if (startAddress >= _offset) - { - quint32 regIdx = startAddress - _offset; - if (regIdx + valueCount <= static_cast(_registerList.size())) - { - isValid = true; - } - } - - return isValid; -} - -void TestSlaveData::setRegisterState(uint registerAddress, bool bState) -{ - setRegisterState(QList() << registerAddress, bState); -} - -void TestSlaveData::setRegisterState(QList registerAddressList, bool bState) -{ - bool bChanged = false; - - Q_FOREACH(uint registerAddress, registerAddressList) - { - Q_ASSERT(registerAddress >= _offset); - - uint regIndex = registerAddress - _offset; - if (static_cast(regIndex) < _registerList.size()) - { - if (_registerList[regIndex].bState != bState) - { - _registerList[regIndex].bState = bState; - - bChanged = true; - } - } - } - - if (bChanged) - { - emit dataChanged(); - } -} - -void TestSlaveData::setRegisterValue(uint registerAddress, quint16 value) -{ - Q_ASSERT(registerAddress >= _offset); - uint regIndex = registerAddress - _offset; - - if (static_cast(regIndex) < _registerList.size()) - { - if (_registerList[regIndex].value != value) - { - _registerList[regIndex].value = value; - - emit dataChanged(); - } - } -} - -bool TestSlaveData::registerState(uint registerAddress) -{ - Q_ASSERT(registerAddress >= _offset); - uint regIndex = registerAddress - _offset; - - if (static_cast(regIndex) < _registerList.size()) - { - return _registerList[regIndex].bState; - } - - return false; -} - -quint16 TestSlaveData::registerValue(uint registerAddress) -{ - Q_ASSERT(registerAddress >= _offset); - uint regIndex = registerAddress - _offset; - - if (static_cast(regIndex) < _registerList.size()) - { - return _registerList[regIndex].value; - } - - return 0; -} - -void TestSlaveData::incrementAllEnabledRegisters() -{ - for(int idx = 0u; idx < _registerList.size(); idx++) - { - if (_registerList[idx].bState) - { - _registerList[idx].value++; - } - } - - emit dataChanged(); -} diff --git a/tests/testslave/testslavedata.h b/tests/testslave/testslavedata.h deleted file mode 100644 index e29b29ac..00000000 --- a/tests/testslave/testslavedata.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef TESTSLAVEDATA_H -#define TESTSLAVEDATA_H - -#include -#include -#include - -class TestSlaveData : public QObject -{ - Q_OBJECT -public: - explicit TestSlaveData(quint32 offset = 0, quint32 registerCount = 50); - ~TestSlaveData(); - - bool isValidAddress(quint32 startAddress, quint32 valueCount); - - void setRegisterState(uint registerAddress, bool bState); - void setRegisterState(QList registerAddressList, bool bState); - - void setRegisterValue(uint registerAddress, quint16 value); - - bool registerState(uint registerAddress); - quint16 registerValue(uint registerAddress); - - void incrementAllEnabledRegisters(); - -signals: - void dataChanged(); - -private: - - typedef struct - { - bool bState; - quint16 value; - } registerData_t; - - QList _registerList; - - quint32 _offset; - -}; - -#endif // TESTSLAVEDATA_H diff --git a/tests/testslave/testslavemodbus.cpp b/tests/testslave/testslavemodbus.cpp deleted file mode 100644 index 213ffffa..00000000 --- a/tests/testslave/testslavemodbus.cpp +++ /dev/null @@ -1,117 +0,0 @@ -#include "testslavemodbus.h" - -TestSlaveModbus::TestSlaveModbus(QObject* parent) : QModbusTcpServer(parent) -{ - _exceptionCode = static_cast(0); - _bExceptionPersistent = false; -} - -TestSlaveModbus::~TestSlaveModbus() -{ - -} - -bool TestSlaveModbus::connect(QString ip, quint16 port, int slaveId) -{ - setConnectionParameter(QModbusDevice::NetworkPortParameter, port); - setConnectionParameter(QModbusDevice::NetworkAddressParameter, ip); - setServerAddress(slaveId); - - return connectDevice(); -} - -void TestSlaveModbus::disconnect() -{ - disconnectDevice(); -} - -void TestSlaveModbus::setException(QModbusPdu::ExceptionCode exception, bool bPersistent) -{ - _exceptionCode = exception; - _bExceptionPersistent = bPersistent; -} - -bool TestSlaveModbus::readData(QModbusDataUnit *newData) const -{ - if (!verifyValidObject(newData)) - { - return false; - } - - for(uint idx = 0; idx < static_cast(newData->valueCount()); idx++) - { - const uint regAddress = static_cast(newData->startAddress()) + idx; - - TestSlaveData* slaveData = _testDevice.slaveData(newData->registerType()); - if (!slaveData->registerState(regAddress)) - { - return false; - } - - newData->setValue(idx, slaveData->registerValue(regAddress)); - } - - return true; -} - -bool TestSlaveModbus::setMap(const QModbusDataUnitMap &map) -{ - Q_UNUSED(map); - return false; /* Not implemented */ -} - -bool TestSlaveModbus::writeData(const QModbusDataUnit &newData) -{ - if (!verifyValidObject(&newData)) - { - return false; - } - - for(uint idx = 0; idx < static_cast(newData.valueCount()); idx++) - { - const uint regAddress = static_cast(newData.startAddress()) + idx; - TestSlaveData* slaveData = _testDevice.slaveData(newData.registerType()); - slaveData->setRegisterState(regAddress, true); - slaveData->setRegisterValue(regAddress, newData.value(regAddress)); - } - - emit dataWritten(newData.registerType(), newData.startAddress(), newData.valueCount()); - - return true; -} - -QModbusResponse TestSlaveModbus::processRequest(const QModbusPdu &request) -{ - QModbusResponse response; - if (_exceptionCode == 0) - { - response = QModbusTcpServer::processRequest(request); - } - else - { - response = QModbusExceptionResponse(request.functionCode(), _exceptionCode); - } - - emit requestProcessed(); - - /* Reset exception when not persistent */ - if (!_bExceptionPersistent) - { - _exceptionCode = static_cast(0); - } - - return response; -} - -bool TestSlaveModbus::verifyValidObject(QModbusDataUnit const * dataUnit) const -{ - TestSlaveData* slaveData = _testDevice.slaveData(dataUnit->registerType()); - if (dataUnit->isValid() && slaveData->isValidAddress(dataUnit->startAddress(), dataUnit->valueCount())) - { - return true; - } - else - { - return false; - } -} diff --git a/tests/testslave/testslavemodbus.h b/tests/testslave/testslavemodbus.h deleted file mode 100644 index 834437d0..00000000 --- a/tests/testslave/testslavemodbus.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef TESTSLAVEMODBUS_H -#define TESTSLAVEMODBUS_H - -#include - -#include "testdevice.h" - -class TestSlaveModbus : public QModbusTcpServer -{ - Q_OBJECT -public: - explicit TestSlaveModbus(QObject* parent = nullptr); - ~TestSlaveModbus(); - - bool connect(QString ip, quint16 port, int slaveId); - void disconnect(); - - void setException(QModbusPdu::ExceptionCode exception, bool bPersistent); - - TestDevice* testDevice() - { - return &_testDevice; - } - -signals: - void requestProcessed(); - -protected: - bool readData(QModbusDataUnit* newData) const; - bool setMap(const QModbusDataUnitMap& map); - bool writeData(const QModbusDataUnit& newData); - - QModbusResponse processRequest(const QModbusPdu& request); - -private: - bool verifyValidObject(const QModbusDataUnit* dataUnit) const; - - TestDevice _testDevice; - - QModbusPdu::ExceptionCode _exceptionCode; - bool _bExceptionPersistent; -}; - -#endif // TESTSLAVEMODBUS_H diff --git a/tests/testslave/testslavemodbusmulti.cpp b/tests/testslave/testslavemodbusmulti.cpp deleted file mode 100644 index 68b7d460..00000000 --- a/tests/testslave/testslavemodbusmulti.cpp +++ /dev/null @@ -1,149 +0,0 @@ -#include "testslavemodbusmulti.h" - -#include -#include - -/* Modbus TCP frame layout: - * Bytes 0-1 : Transaction Identifier - * Bytes 2-3 : Protocol Identifier (0x0000) - * Bytes 4-5 : Length (number of bytes that follow, including Unit ID) - * Byte 6 : Unit Identifier (slave ID) - * Byte 7+ : PDU (function code + data) - */ -static const int MBAP_SIZE = 6; - -TestSlaveMultiModbus::TestSlaveMultiModbus(QObject* parent) : QTcpServer(parent) -{ -} - -TestSlaveMultiModbus::~TestSlaveMultiModbus() -{ - qDeleteAll(_devices); -} - -bool TestSlaveMultiModbus::listenOnPort(quint16 port) -{ - return listen(QHostAddress::LocalHost, port); -} - -void TestSlaveMultiModbus::stopListening() -{ - for (auto* socket : std::as_const(_sockets)) - { - socket->disconnectFromHost(); - } - _sockets.clear(); - close(); -} - -TestDevice* TestSlaveMultiModbus::testDevice(quint8 slaveId) -{ - if (!_devices.contains(slaveId)) - { - _devices.insert(slaveId, new TestDevice(this)); - } - return _devices.value(slaveId); -} - -void TestSlaveMultiModbus::incomingConnection(qintptr socketDescriptor) -{ - auto* socket = new QTcpSocket(this); - socket->setSocketDescriptor(socketDescriptor); - connect(socket, &QTcpSocket::readyRead, this, &TestSlaveMultiModbus::handleReadyRead); - connect(socket, &QTcpSocket::disconnected, this, [this, socket]() { - _sockets.removeOne(socket); - socket->deleteLater(); - }); - _sockets.append(socket); -} - -void TestSlaveMultiModbus::handleReadyRead() -{ - auto* socket = qobject_cast(sender()); - if (!socket) - { - return; - } - - while (socket->bytesAvailable() >= MBAP_SIZE) - { - const QByteArray header = socket->peek(MBAP_SIZE); - const quint16 length = (static_cast(header[4]) << 8) | static_cast(header[5]); - - if (socket->bytesAvailable() < MBAP_SIZE + length) - { - break; - } - - const QByteArray frame = socket->read(MBAP_SIZE + length); // NOLINT(clang-analyzer-security.insecureAPI*) - processFrame(socket, frame); - } -} - -void TestSlaveMultiModbus::processFrame(QTcpSocket* socket, const QByteArray& frame) -{ - /* Minimum: MBAP (6) + unit ID (1) + function code (1) + 2-byte address + 2-byte quantity */ - if (frame.size() < MBAP_SIZE + 6) - { - return; - } - - const quint8 unitId = static_cast(frame[6]); - const quint8 fc = static_cast(frame[7]); - const quint16 startAddr = (static_cast(frame[8]) << 8) | static_cast(frame[9]); - const quint16 quantity = (static_cast(frame[10]) << 8) | static_cast(frame[11]); - - /* Only Read Holding Registers (FC 0x03) is implemented */ - if (fc != 0x03) - { - /* Modbus exception response: error FC + exception code 0x01 (Illegal Function) */ - const quint16 excLength = 3u; /* unit ID (1) + error FC (1) + exception code (1) */ - QByteArray excResponse(MBAP_SIZE + excLength, 0x00); - excResponse[0] = frame[0]; excResponse[1] = frame[1]; /* Transaction ID */ - excResponse[4] = static_cast((excLength >> 8) & 0xFF); - excResponse[5] = static_cast(excLength & 0xFF); - excResponse[6] = static_cast(unitId); - excResponse[7] = static_cast(fc | 0x80); - excResponse[8] = 0x01; /* Illegal Function */ - socket->write(excResponse); - return; - } - - static const quint16 maxQuantity = 125u; /* Modbus FC 0x03 max registers per request */ - if (quantity > maxQuantity) - { - return; - } - - /* Response length field: unit ID (1) + FC (1) + byte count (1) + data (2*qty) */ - const quint32 respLength = 3u + quantity * 2u; - - QByteArray response; - response.resize(MBAP_SIZE + respLength); - - response[0] = frame[0]; response[1] = frame[1]; /* Transaction ID */ - response[2] = 0x00; response[3] = 0x00; /* Protocol ID */ - response[4] = static_cast((respLength >> 8) & 0xFF); - response[5] = static_cast(respLength & 0xFF); - response[6] = static_cast(unitId); - response[7] = static_cast(fc); - response[8] = static_cast((quantity * 2u) & 0xFF); /* Byte count */ - - TestDevice* device = _devices.value(unitId, nullptr); - for (quint16 i = 0; i < quantity; i++) - { - quint16 value = 0; - if (device) - { - auto* slaveData = device->slaveData(QModbusDataUnit::HoldingRegisters); - if (slaveData && slaveData->registerState(startAddr + i)) - { - value = slaveData->registerValue(startAddr + i); - } - } - response[9 + i * 2] = static_cast((value >> 8) & 0xFF); - response[9 + i * 2 + 1] = static_cast(value & 0xFF); - } - - socket->write(response); -} diff --git a/tests/testslave/testslavemodbusmulti.h b/tests/testslave/testslavemodbusmulti.h deleted file mode 100644 index 5abf99b3..00000000 --- a/tests/testslave/testslavemodbusmulti.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef TESTSLAVEMODBUSMULTI_H -#define TESTSLAVEMODBUSMULTI_H - -#include "testdevice.h" - -#include -#include - -/*! - * Minimal Modbus TCP server that serves multiple slave IDs on a single port. - * QModbusTcpServer only handles one slave ID, making it impossible to bind two - * instances to the same port. This class implements enough of the Modbus TCP - * protocol (Read Holding Registers, FC 0x03) to support multi-slave tests. - */ -class TestSlaveMultiModbus : public QTcpServer -{ - Q_OBJECT -public: - explicit TestSlaveMultiModbus(QObject* parent = nullptr); - ~TestSlaveMultiModbus(); - - bool listenOnPort(quint16 port); - void stopListening(); - - TestDevice* testDevice(quint8 slaveId); - -protected: - void incomingConnection(qintptr socketDescriptor) override; - -private slots: - void handleReadyRead(); - -private: - void processFrame(QTcpSocket* socket, const QByteArray& frame); - - QMap _devices; - QList _sockets; -}; - -#endif // TESTSLAVEMODBUSMULTI_H diff --git a/tests/util/CMakeLists.txt b/tests/util/CMakeLists.txt index 0d719c5c..9eb8e914 100644 --- a/tests/util/CMakeLists.txt +++ b/tests/util/CMakeLists.txt @@ -1,5 +1,4 @@ add_xtest(tst_expressionchecker) add_xtest(tst_formatrelativetime) -add_xtest(tst_modbusaddress) add_xtest_mock(tst_updatenotify) add_xtest(tst_util) diff --git a/tests/util/tst_modbusaddress.cpp b/tests/util/tst_modbusaddress.cpp deleted file mode 100644 index 6d537bf4..00000000 --- a/tests/util/tst_modbusaddress.cpp +++ /dev/null @@ -1,172 +0,0 @@ - -#include "tst_modbusaddress.h" - -#include "util/modbusaddress.h" - -#include - -using ObjectType = ModbusAddress::ObjectType; - -void TestModbusAddress::init() -{ - -} - -void TestModbusAddress::cleanup() -{ - -} - -void TestModbusAddress::constructor_default() -{ - ModbusAddress addr; - - QCOMPARE(addr.fullAddress(), "40001"); - QCOMPARE(addr.objectType(), ObjectType::HOLDING_REGISTER); -} - -void TestModbusAddress::constructor_address() -{ - ModbusAddress addr(40001); - - QCOMPARE(addr.fullAddress(), "40001"); - QCOMPARE(addr.objectType(), ObjectType::HOLDING_REGISTER); -} - -void TestModbusAddress::constructor_string_address() -{ - ModbusAddress addr_1("h20000"); - QCOMPARE(addr_1.protocolAddress(), 20000); - QCOMPARE(addr_1.objectType(), ObjectType::HOLDING_REGISTER); - - ModbusAddress addr_2("d20000"); - QCOMPARE(addr_2.protocolAddress(), 20000); - QCOMPARE(addr_2.objectType(), ObjectType::DISCRETE_INPUT); - - ModbusAddress addr_3("c20000"); - QCOMPARE(addr_3.protocolAddress(), 20000); - QCOMPARE(addr_3.objectType(), ObjectType::COIL); - - ModbusAddress addr_4("i20000"); - QCOMPARE(addr_4.protocolAddress(), 20000); - QCOMPARE(addr_4.objectType(), ObjectType::INPUT_REGISTER); - - ModbusAddress addr_5("40001"); - QCOMPARE(addr_5.protocolAddress(), 0); - QCOMPARE(addr_5.objectType(), ObjectType::HOLDING_REGISTER); -} - -void TestModbusAddress::constructor_type() -{ - ModbusAddress addr(1); - - QCOMPARE(addr.protocolAddress(), 1); - QCOMPARE(addr.objectType(), ObjectType::COIL); -} - -void TestModbusAddress::constructor_assignment() -{ - ModbusAddress addrOriginal(40001); - ModbusAddress addr; - - addr = addrOriginal; - - QCOMPARE(addr.fullAddress(), "40001"); - QCOMPARE(addr.objectType(), ObjectType::HOLDING_REGISTER); -} - -void TestModbusAddress::constructor_copy() -{ - ModbusAddress addrOriginal(40001); - ModbusAddress addr(addrOriginal); - - QCOMPARE(addr.fullAddress(), "40001"); - QCOMPARE(addr.objectType(), ObjectType::HOLDING_REGISTER); -} - -void TestModbusAddress::constructor_invalid_string() -{ - ModbusAddress addr_1("x12345"); - QCOMPARE(addr_1.objectType(), ObjectType::UNKNOWN); - QCOMPARE(addr_1.protocolAddress(), 0); - - ModbusAddress addr_2("hnotanumber"); - QCOMPARE(addr_2.objectType(), ObjectType::UNKNOWN); - QCOMPARE(addr_2.protocolAddress(), 0); - - ModbusAddress addr_3(""); - QCOMPARE(addr_3.objectType(), ObjectType::UNKNOWN); - QCOMPARE(addr_3.protocolAddress(), 0); -} - -void TestModbusAddress::addressFunctions_data() -{ - QTest::addColumn("modbusAddr"); - QTest::addColumn("fullAddress"); - QTest::addColumn("protocolAddress"); - - /* Full addr Protocol address */ - QTest::newRow("Test 01") << ModbusAddress(0, ObjectType::COIL) << "0" << static_cast(0); - QTest::newRow("Test 02") << ModbusAddress(0, ObjectType::DISCRETE_INPUT) << "10001" << static_cast(0); - QTest::newRow("Test 03") << ModbusAddress(0, ObjectType::INPUT_REGISTER) << "30001" << static_cast(0); - QTest::newRow("Test 04") << ModbusAddress(0, ObjectType::HOLDING_REGISTER) << "40001" << static_cast(0); - - /* Last possible values with 5 digits notation */ - QTest::newRow("Test 05") << ModbusAddress(9999, ObjectType::COIL) << "9999" << static_cast(9999); - QTest::newRow("Test 06") << ModbusAddress(9999, ObjectType::DISCRETE_INPUT) << "20000" << static_cast(9999); - QTest::newRow("Test 07") << ModbusAddress(9999, ObjectType::INPUT_REGISTER) << "40000" << static_cast(9999); - QTest::newRow("Test 08") << ModbusAddress(9999, ObjectType::HOLDING_REGISTER) << "50000" << static_cast(9999); - - /* Last possible address with 5 digits notation */ - QTest::newRow("Test 09") << ModbusAddress(10000, ObjectType::COIL) << "c10000" << static_cast(10000); - QTest::newRow("Test 10") << ModbusAddress(10000, ObjectType::DISCRETE_INPUT) << "d10000" << static_cast(10000); - QTest::newRow("Test 11") << ModbusAddress(10000, ObjectType::INPUT_REGISTER) << "i10000" << static_cast(10000); - QTest::newRow("Test 12") << ModbusAddress(10000, ObjectType::HOLDING_REGISTER) << "h10000" << static_cast(10000); - - /* Largest possible address */ - QTest::newRow("Test 13") << ModbusAddress(65535, ObjectType::COIL) << "c65535" << static_cast(65535); - QTest::newRow("Test 14") << ModbusAddress(65535, ObjectType::DISCRETE_INPUT) << "d65535" << static_cast(65535); - QTest::newRow("Test 15") << ModbusAddress(65535, ObjectType::INPUT_REGISTER) << "i65535" << static_cast(65535); - QTest::newRow("Test 16") << ModbusAddress(65535, ObjectType::HOLDING_REGISTER) << "h65535" << static_cast(65535); - -} - -void TestModbusAddress::addressFunctions() -{ - QFETCH(ModbusAddress, modbusAddr); - QFETCH(QString, fullAddress); - QFETCH(quint16, protocolAddress); - - QCOMPARE(modbusAddr.fullAddress(), fullAddress); - QCOMPARE(modbusAddr.protocolAddress(), protocolAddress); -} - -void TestModbusAddress::equality_operator() -{ - ModbusAddress addr_1(40001); - ModbusAddress addr_2("40001"); - QVERIFY(addr_1 == addr_2); - - ModbusAddress addr_3(1, ObjectType::COIL); - ModbusAddress addr_4("c1"); - QVERIFY(addr_3 == addr_4); - - ModbusAddress addr_5(2, ObjectType::COIL); - QVERIFY(!(addr_3 == addr_5)); -} - -void TestModbusAddress::to_string() -{ - ModbusAddress addr(40011); - - QCOMPARE(addr.toString(), "holding register, 10"); -} - -void TestModbusAddress::to_string_coil() -{ - ModbusAddress addr(1); - - QCOMPARE(addr.toString(), "coil, 1"); -} - -QTEST_GUILESS_MAIN(TestModbusAddress) diff --git a/tests/util/tst_modbusaddress.h b/tests/util/tst_modbusaddress.h deleted file mode 100644 index 69f9af90..00000000 --- a/tests/util/tst_modbusaddress.h +++ /dev/null @@ -1,31 +0,0 @@ - -#include - -class TestModbusAddress: public QObject -{ - Q_OBJECT - -private slots: - void init(); - void cleanup(); - - void constructor_default(); - void constructor_address(); - void constructor_string_address(); - void constructor_type(); - void constructor_assignment(); - void constructor_copy(); - void constructor_invalid_string(); - - void addressFunctions_data(); - void addressFunctions(); - - void equality_operator(); - - void to_string(); - void to_string_coil(); - -private: - - -}; From ecc0e527b5625ff0684a61b4895b8c8bcaaa371b Mon Sep 17 00:00:00 2001 From: Jens Geudens Date: Fri, 20 Mar 2026 14:26:19 +0100 Subject: [PATCH 2/2] Remove mbc import --- data/example.mbc | 47 -- src/dialogs/importmbcdialog.cpp | 338 ------------- src/dialogs/importmbcdialog.h | 64 --- src/dialogs/importmbcdialog.ui | 191 ------- src/dialogs/mainwindow.cpp | 32 +- src/dialogs/mainwindow.h | 3 +- src/dialogs/mainwindow.ui | 6 - src/dialogs/mbcheader.h | 69 --- src/importexport/mbcfileimporter.cpp | 279 ----------- src/importexport/mbcfileimporter.h | 50 -- src/importexport/mbcregisterdata.cpp | 148 ------ src/importexport/mbcregisterdata.h | 49 -- src/models/guimodel.cpp | 11 - src/models/guimodel.h | 3 - src/models/mbcregisterfilter.cpp | 76 --- src/models/mbcregisterfilter.h | 29 -- src/models/mbcregistermodel.cpp | 316 ------------ src/models/mbcregistermodel.h | 65 --- src/models/mbcupdatemodel.cpp | 202 -------- src/models/mbcupdatemodel.h | 60 --- tests/importexport/CMakeLists.txt | 2 - tests/importexport/mbctestdata.cpp | 106 ---- tests/importexport/mbctestdata.h | 29 -- tests/importexport/tst_mbcfileimporter.cpp | 79 --- tests/importexport/tst_mbcfileimporter.h | 21 - tests/importexport/tst_mbcregisterfilter.cpp | 82 --- tests/importexport/tst_mbcregisterfilter.h | 27 - tests/models/CMakeLists.txt | 2 - tests/models/tst_mbcregistermodel.cpp | 502 ------------------- tests/models/tst_mbcregistermodel.h | 40 -- tests/models/tst_mbcupdatemodel.cpp | 148 ------ tests/models/tst_mbcupdatemodel.h | 29 -- 32 files changed, 4 insertions(+), 3101 deletions(-) delete mode 100644 data/example.mbc delete mode 100644 src/dialogs/importmbcdialog.cpp delete mode 100644 src/dialogs/importmbcdialog.h delete mode 100644 src/dialogs/importmbcdialog.ui delete mode 100644 src/dialogs/mbcheader.h delete mode 100644 src/importexport/mbcfileimporter.cpp delete mode 100644 src/importexport/mbcfileimporter.h delete mode 100644 src/importexport/mbcregisterdata.cpp delete mode 100644 src/importexport/mbcregisterdata.h delete mode 100644 src/models/mbcregisterfilter.cpp delete mode 100644 src/models/mbcregisterfilter.h delete mode 100644 src/models/mbcregistermodel.cpp delete mode 100644 src/models/mbcregistermodel.h delete mode 100644 src/models/mbcupdatemodel.cpp delete mode 100644 src/models/mbcupdatemodel.h delete mode 100644 tests/importexport/mbctestdata.cpp delete mode 100644 tests/importexport/mbctestdata.h delete mode 100644 tests/importexport/tst_mbcfileimporter.cpp delete mode 100644 tests/importexport/tst_mbcfileimporter.h delete mode 100644 tests/importexport/tst_mbcregisterfilter.cpp delete mode 100644 tests/importexport/tst_mbcregisterfilter.h delete mode 100644 tests/models/tst_mbcregistermodel.cpp delete mode 100644 tests/models/tst_mbcregistermodel.h delete mode 100644 tests/models/tst_mbcupdatemodel.cpp delete mode 100644 tests/models/tst_mbcupdatemodel.h diff --git a/data/example.mbc b/data/example.mbc deleted file mode 100644 index 59ce9878..00000000 --- a/data/example.mbc +++ /dev/null @@ -1,47 +0,0 @@ - - - 820 - 600 - - - - COM3 - 9600 - none - 1 - 500 - 1000 - 129 - 40001 - 16 - little - true - true - - - - true - 502 - - - - General Info and Commands - 40001Data 1uint16r - 40002Data 2uint16r - 40003Data 3uint16r - - - - System State - 40004System Pressureuint162r225,225,255 - *Inlet Pressureuint162r225,225,255 - *Setpointuint161rw255,225,225 - 40007Bandwidthuint162rw255,225,225 - - 40008Data largeuint32r - 40009Float32float32r - 40010Signed dataint16r - 40011Large signed dataint32r - - - diff --git a/src/dialogs/importmbcdialog.cpp b/src/dialogs/importmbcdialog.cpp deleted file mode 100644 index e779148b..00000000 --- a/src/dialogs/importmbcdialog.cpp +++ /dev/null @@ -1,338 +0,0 @@ -#include "importmbcdialog.h" - -#include "customwidgets/actionbuttondelegate.h" -#include "dialogs/mbcheader.h" -#include "dialogs/ui_importmbcdialog.h" -#include "importexport/mbcfileimporter.h" -#include "models/graphdatamodel.h" -#include "models/guimodel.h" -#include "models/mbcregisterfilter.h" -#include "models/mbcregistermodel.h" -#include "models/mbcupdatemodel.h" -#include "util/fileselectionhelper.h" -#include "util/util.h" - -#include - -ImportMbcDialog::ImportMbcDialog(GuiModel* pGuiModel, GraphDataModel* pGraphDatamodel, QWidget* parent) - : QDialog(parent), _pUi(new Ui::ImportMbcDialog), _pGuiModel(pGuiModel), _pGraphDataModel(pGraphDatamodel) -{ - _pUi->setupUi(this); - - _pMbcUpdateModel = new MbcUpdateModel(_pGraphDataModel); - - _pTabProxyFilter = new MbcRegisterFilter(); - _pTabProxyFilter->setSourceModel(&_mbcRegisterModel); - - /* Disable question mark button */ - setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); - - this->setAcceptDrops(true); - _pUi->lineTextFilter->setAcceptDrops(false); - - // Setup registerView - _pUi->tblMbcRegisters->setModel(_pTabProxyFilter); - _pUi->tblMbcRegisters->setSortingEnabled(false); - - auto mbcHeader = new MbcHeader(Qt::Horizontal, _pUi->tblMbcRegisters); - _pUi->tblMbcRegisters->setHorizontalHeader(mbcHeader); - - /* Don't stretch columns */ - _pUi->tblMbcRegisters->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); - - /* Except following columns */ - _pUi->tblMbcRegisters->horizontalHeader()->setSectionResizeMode(MbcRegisterModel::cColumnText, - QHeaderView::Stretch); - _pUi->tblMbcRegisters->horizontalHeader()->setSectionResizeMode(MbcRegisterModel::cColumnTab, QHeaderView::Stretch); - - // Select using click, shift and control - _pUi->tblMbcRegisters->setSelectionBehavior(QAbstractItemView::SelectItems); - _pUi->tblMbcRegisters->setSelectionMode(QAbstractItemView::NoSelection); - - _pUi->tblMbcRegisters->setFocusPolicy(Qt::NoFocus); - - _pUi->tblMbcRegisters->setStyle(&_centeredBoxStyle); - - // setup register - _pUi->tblMbcUpdate->setModel(_pMbcUpdateModel); - _pUi->tblMbcUpdate->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); - - // Select using click, shift and control - _pUi->tblMbcUpdate->setSelectionBehavior(QAbstractItemView::SelectItems); - _pUi->tblMbcUpdate->setSelectionMode(QAbstractItemView::NoSelection); - - _pUi->tblMbcUpdate->setFocusPolicy(Qt::NoFocus); - - _pUpdateDelegate = std::make_unique(_pUi->tblMbcUpdate); - _pUpdateDelegate->setCharacter(QChar(0x2190)); - connect(_pUpdateDelegate.get(), &ActionButtonDelegate::clicked, this, &ImportMbcDialog::handleAcceptUpdate); - - _pUi->tblMbcUpdate->setItemDelegateForColumn(MbcUpdateModel::cColumnUpdateExpression, _pUpdateDelegate.get()); - _pUi->tblMbcUpdate->setItemDelegateForColumn(MbcUpdateModel::cColumnUpdateText, _pUpdateDelegate.get()); - - connect(_pUi->btnSelectMbcFile, &QToolButton::clicked, this, &ImportMbcDialog::selectMbcFile); - connect(_pUi->btnImportRegisters, &QPushButton::clicked, this, &ImportMbcDialog::importSelectedRegisters); - connect(&_mbcRegisterModel, &QAbstractItemModel::dataChanged, this, &ImportMbcDialog::registerDataChanged); - connect(_pTabProxyFilter, &MbcRegisterFilter::dataChanged, this, &ImportMbcDialog::visibleItemsDataChanged); - connect(mbcHeader, &MbcHeader::selectAllClicked, this, &ImportMbcDialog::handleSelectAllClicked); - - connect(_pUi->cmbTabFilter, &QComboBox::currentTextChanged, _pTabProxyFilter, &MbcRegisterFilter::setTab); - connect(_pUi->lineTextFilter, &QLineEdit::textChanged, this, &ImportMbcDialog::updateTextFilter); -} - -ImportMbcDialog::~ImportMbcDialog() -{ - delete _pUi; -} - -int ImportMbcDialog::exec() -{ - QString filePath = _pGuiModel->lastMbcImportedFile(); - if (!filePath.isEmpty()) - { - /* Auto load with supplied path */ - updateMbcRegisters(filePath); - - _pUi->lineMbcfile->setText(filePath); - } - else - { - /* Skip auto load: no file path */ - _pUi->lineMbcfile->setText(""); - } - - return QDialog::exec(); -} - -void ImportMbcDialog::updateTextFilter() -{ - auto checkHeight = _pUi->tblMbcRegisters->rowHeight(0) / 2; - QModelIndex topRow = _pUi->tblMbcRegisters->indexAt(QPoint(checkHeight, checkHeight)); - - auto currentTopModelIndex = _pTabProxyFilter->mapToSource(topRow); - _pTabProxyFilter->setTextFilter(_pUi->lineTextFilter->text()); - - auto newTopModelIndex = _pTabProxyFilter->mapFromSource(currentTopModelIndex); - - _pUi->tblMbcRegisters->scrollTo(newTopModelIndex, QAbstractItemView::PositionAtTop); -} - -void ImportMbcDialog::selectMbcFile() -{ - QFileDialog dialog(this); - FileSelectionHelper::configureFileDialog(&dialog, FileSelectionHelper::DIALOG_TYPE_OPEN, - FileSelectionHelper::FILE_TYPE_MBC); - - QString selectedFile = FileSelectionHelper::showDialog(&dialog); - if (!selectedFile.isEmpty()) - { - _pUi->lineMbcfile->setText(selectedFile); - _pGuiModel->setLastMbcImportedFile(selectedFile); - - updateMbcRegisters(selectedFile); - } -} - -void ImportMbcDialog::importSelectedRegisters() -{ - QList regList = _mbcRegisterModel.selectedRegisterList(); - - if (!regList.isEmpty()) - { - _pGraphDataModel->add(regList); - } - - setSelectedSelectionstate(Qt::Unchecked); -} - -void ImportMbcDialog::visibleItemsDataChanged() -{ - const int regCount = _pTabProxyFilter->rowCount(); - - bool checked = true; - bool unchecked = true; - - for (int idx = 0; idx < regCount; idx++) - { - QModelIndex idxOfItem = _pTabProxyFilter->index(idx, MbcRegisterModel::cColumnSelected); - if (_pTabProxyFilter->data(idxOfItem, Qt::CheckStateRole) == Qt::Checked) - { - unchecked = false; - } - - if (_pTabProxyFilter->data(idxOfItem, Qt::CheckStateRole) == Qt::Unchecked) - { - checked = false; - } - } - - Qt::CheckState selectAllState; - if (checked) - { - selectAllState = Qt::Checked; - } - else if (unchecked) - { - selectAllState = Qt::Unchecked; - } - else - { - selectAllState = Qt::PartiallyChecked; - } - - _mbcRegisterModel.setHeaderData(MbcRegisterModel::cColumnSelected, Qt::Horizontal, selectAllState, - Qt::CheckStateRole); -} - -void ImportMbcDialog::registerDataChanged() -{ - const quint32 count = _mbcRegisterModel.selectedRegisterCount(); - if (count == 1) - { - _pUi->lblSelectedCount->setText(QString("You have selected %1 register.").arg(count)); - } - else - { - _pUi->lblSelectedCount->setText(QString("You have selected %1 registers.").arg(count)); - } -} - -void ImportMbcDialog::handleSelectAllClicked(Qt::CheckState state) -{ - if (state == Qt::Unchecked) - { - setSelectedSelectionstate(Qt::Unchecked); - } - else if (state == Qt::Checked) - { - setSelectedSelectionstate(Qt::Checked); - } - else - { - // No need to handle PartialChecked - } -} - -void ImportMbcDialog::dragEnterEvent(QDragEnterEvent* e) -{ - if (e->mimeData()->hasUrls()) - { - e->acceptProposedAction(); - } -} - -void ImportMbcDialog::dropEvent(QDropEvent* e) -{ - const QString filename(e->mimeData()->urls().constLast().toLocalFile()); - - _pUi->lineMbcfile->setText(filename); - _pGuiModel->setLastMbcImportedFile(filename); - - updateMbcRegisters(filename); -} - -void ImportMbcDialog::closeEvent(QCloseEvent* event) -{ - if (confirmClose()) - { - event->accept(); // allow window to close - } - else - { - event->ignore(); // block window close - } -} - -void ImportMbcDialog::reject() -{ - if (confirmClose()) - { - QDialog::reject(); // close via reject - } - // else: do nothing, dialog stays open -} - -void ImportMbcDialog::setSelectedSelectionstate(Qt::CheckState state) -{ - QList indexList; - for (int idx = 0; idx < _pTabProxyFilter->rowCount(); idx++) - { - QModelIndex idxOfItem = _pTabProxyFilter->index(idx, MbcRegisterModel::cColumnSelected); - indexList.append(_pTabProxyFilter->mapToSource(idxOfItem)); - } - - _mbcRegisterModel.setSelectionstate(indexList, state); -} - -void ImportMbcDialog::updateMbcRegisters(QString filePath) -{ - QFile file(filePath); - if (file.open(QIODevice::ReadOnly | QIODevice::Text)) - { - QTextStream in(&file); - QString mbcFileContent = in.readAll(); - MbcFileImporter fileImporter(&mbcFileContent); - QList registerList = fileImporter.registerList(); - QStringList tabList = fileImporter.tabList(); - - /* Clear data from table widget */ - _mbcRegisterModel.reset(); - registerDataChanged(); - - if (registerList.size() > 0) - { - _mbcRegisterModel.fill(registerList, tabList); - _pMbcUpdateModel->setMbcRegisters(registerList); - - /* Update combo box */ - _pUi->cmbTabFilter->clear(); - _pUi->cmbTabFilter->addItem(MbcRegisterFilter::cTabNoFilter); - _pUi->cmbTabFilter->addItems(tabList); - } - } - else - { - Util::showError(tr("The file (\"%1\") can't be read.").arg(filePath)); - } -} - -void ImportMbcDialog::handleAcceptUpdate(const QModelIndex& index) -{ - if (!index.isValid()) - { - return; - } - - if (index.column() == MbcUpdateModel::cColumnUpdateExpression) - { - _pGraphDataModel->setExpression(index.row(), _pMbcUpdateModel->data(index).toString()); - } - else if (index.column() == MbcUpdateModel::cColumnUpdateText) - { - _pGraphDataModel->setLabel(index.row(), _pMbcUpdateModel->data(index).toString()); - } - else - { - // nothing to do - } -} - -bool ImportMbcDialog::confirmClose() -{ - bool bClose = true; - if (_mbcRegisterModel.selectedRegisterCount() > 0) - { - auto reply = QMessageBox::question( - this, tr("Unimported registers"), - tr("Some registers are selected, but aren't imported yet.\n\nDo you really want to close this dialog?"), - QMessageBox::Yes | QMessageBox::No, QMessageBox::No); - bClose = reply == QMessageBox::Yes; - - if (!bClose) - { - /* User has selected to NOT close the dialog, so switch to first tab */ - _pUi->tabWidget->setCurrentIndex(0); - } - } - return bClose; -} diff --git a/src/dialogs/importmbcdialog.h b/src/dialogs/importmbcdialog.h deleted file mode 100644 index 1794f6e9..00000000 --- a/src/dialogs/importmbcdialog.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef IMPORTMBCDIALOG_H -#define IMPORTMBCDIALOG_H - -#include - -#include "customwidgets/centeredbox.h" -#include "models/mbcregistermodel.h" - -/* Forward declaration */ -class ActionButtonDelegate; -class GuiModel; -class GraphDataModel; -class MbcRegisterFilter; -class MbcUpdateModel; - -namespace Ui { -class ImportMbcDialog; -} - -class ImportMbcDialog : public QDialog -{ - Q_OBJECT - -public: - explicit ImportMbcDialog(GuiModel* pGuiModel, GraphDataModel* _pGraphDatamodel, QWidget* parent = nullptr); - ~ImportMbcDialog(); - -public slots: - int exec(void) override; - -private slots: - void updateTextFilter(); - void selectMbcFile(); - void importSelectedRegisters(); - void visibleItemsDataChanged(); - void registerDataChanged(); - void handleSelectAllClicked(Qt::CheckState state); - -protected: - void closeEvent(QCloseEvent* event) override; - void dragEnterEvent(QDragEnterEvent* e) override; - void dropEvent(QDropEvent* e) override; - void reject() override; - -private: - void setSelectedSelectionstate(Qt::CheckState state); - void updateMbcRegisters(QString filePath); - void handleAcceptUpdate(const QModelIndex& index); - bool confirmClose(); - - Ui::ImportMbcDialog *_pUi; - - CenteredBoxProxyStyle _centeredBoxStyle; - std::unique_ptr _pUpdateDelegate; - - GuiModel * _pGuiModel; - GraphDataModel* _pGraphDataModel; - MbcRegisterModel _mbcRegisterModel; - MbcUpdateModel* _pMbcUpdateModel; - - MbcRegisterFilter * _pTabProxyFilter; -}; - -#endif // IMPORTMBCDIALOG_H diff --git a/src/dialogs/importmbcdialog.ui b/src/dialogs/importmbcdialog.ui deleted file mode 100644 index 02bd838b..00000000 --- a/src/dialogs/importmbcdialog.ui +++ /dev/null @@ -1,191 +0,0 @@ - - - ImportMbcDialog - - - - 0 - 0 - 832 - 405 - - - - Import registers from mbc file - - - - - - 0 - - - - Import - - - - 10 - - - - - - - Tab filter: - - - - - - - - - - Text/Address filter - - - - - - - - - - - - - - - - true - - - - - - - - - - - - - Qt::Orientation::Horizontal - - - - 40 - 20 - - - - - - - - Import selected registers - - - - - - - - - - Update - - - - - - - - - - - - - - - false - - - true - - - - - - - true - - - ... - - - - - - - - - MBC file: - - - - - - - Qt::Orientation::Horizontal - - - QDialogButtonBox::StandardButton::Close - - - - - - - lineMbcfile - btnSelectMbcFile - cmbTabFilter - lineTextFilter - - - - - buttonBox - accepted() - ImportMbcDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - ImportMbcDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/src/dialogs/mainwindow.cpp b/src/dialogs/mainwindow.cpp index 5e1e31ee..1e70b4ec 100755 --- a/src/dialogs/mainwindow.cpp +++ b/src/dialogs/mainwindow.cpp @@ -9,7 +9,6 @@ #include "datahandling/graphdatahandler.h" #include "dialogs/aboutdialog.h" #include "dialogs/diagnosticdialog.h" -#include "dialogs/importmbcdialog.h" #include "dialogs/registerdialog.h" #include "dialogs/settingsdialog.h" #include "dialogs/ui_mainwindow.h" @@ -87,7 +86,6 @@ MainWindow::MainWindow(QStringList cmdArguments, GuiModel* pGuiModel, connect(_pUi->actionOpenProjectFile, &QAction::triggered, _pProjectFileHandler, &ProjectFileHandler::selectProjectOpenFile); connect(_pUi->actionReloadProjectFile, &QAction::triggered, _pProjectFileHandler, &ProjectFileHandler::reloadProjectFile); connect(_pUi->actionOpenDataFile, &QAction::triggered, _pDataFileHandler, &DataFileHandler::selectDataImportFile); - connect(_pUi->actionImportFromMbcFile, &QAction::triggered, this, &MainWindow::showMbcImportDialog); connect(_pUi->actionExportImage, &QAction::triggered, this, &MainWindow::selectImageExportFile); connect(_pUi->actionSaveProjectFileAs, &QAction::triggered, _pProjectFileHandler, &ProjectFileHandler::selectProjectSaveFile); connect(_pUi->actionSaveProjectFile, &QAction::triggered, _pProjectFileHandler, &ProjectFileHandler::saveProjectFile); @@ -358,7 +356,7 @@ void MainWindow::showSettingsDialog() void MainWindow::handleShowRegisterDialog(bool checked) { Q_UNUSED(checked); - showRegisterDialog(QString("")); + showRegisterDialog(); } void MainWindow::setAxisToAuto() @@ -368,7 +366,7 @@ void MainWindow::setAxisToAuto() _pGuiModel->sety2AxisScale(AxisMode::SCALE_AUTO); } -void MainWindow::showRegisterDialog(QString mbcFile) +void MainWindow::showRegisterDialog() { if (_pGuiModel->guiState() == GuiState::DATA_LOADED) { @@ -386,16 +384,7 @@ void MainWindow::showRegisterDialog(QString mbcFile) } RegisterDialog registerDialog(_pGraphDataModel, _pSettingsModel, this); - - if (mbcFile.isEmpty()) - { - registerDialog.exec(); - } - else - { - _pGuiModel->setLastMbcImportedFile(mbcFile); - showMbcImportDialog(); - } + registerDialog.exec(); } void MainWindow::addNoteToGraph() @@ -519,13 +508,6 @@ void MainWindow::showNotesDialog() _pNotesDock->show(); } -void MainWindow::showMbcImportDialog() -{ - ImportMbcDialog importMbcDialog(_pGuiModel, _pGraphDataModel, this); - - importMbcDialog.exec(); -} - void MainWindow::toggleMarkersState() { if (_pGuiModel->markerState()) @@ -662,7 +644,6 @@ void MainWindow::updateGuiState() _pUi->actionRegisterSettings->setEnabled(true); _pUi->actionStart->setEnabled(true); _pUi->actionOpenDataFile->setEnabled(true); - _pUi->actionImportFromMbcFile->setEnabled(true); _pUi->actionOpenProjectFile->setEnabled(true); _pUi->actionSaveDataFile->setEnabled(false); _pUi->actionExportImage->setEnabled(false); @@ -682,7 +663,6 @@ void MainWindow::updateGuiState() _pUi->actionRegisterSettings->setEnabled(false); _pUi->actionStart->setEnabled(false); _pUi->actionOpenDataFile->setEnabled(false); - _pUi->actionImportFromMbcFile->setEnabled(false); _pUi->actionOpenProjectFile->setEnabled(false); _pUi->actionSaveDataFile->setEnabled(false); _pUi->actionSaveProjectFileAs->setEnabled(false); @@ -699,7 +679,6 @@ void MainWindow::updateGuiState() _pUi->actionRegisterSettings->setEnabled(true); _pUi->actionStart->setEnabled(true); _pUi->actionOpenDataFile->setEnabled(true); - _pUi->actionImportFromMbcFile->setEnabled(true); _pUi->actionOpenProjectFile->setEnabled(true); _pUi->actionSaveDataFile->setEnabled(true); _pUi->actionSaveProjectFileAs->setEnabled(true); @@ -727,7 +706,6 @@ void MainWindow::updateGuiState() _pUi->actionRegisterSettings->setEnabled(true); _pUi->actionStart->setEnabled(true); _pUi->actionOpenDataFile->setEnabled(true); - _pUi->actionImportFromMbcFile->setEnabled(true); _pUi->actionOpenProjectFile->setEnabled(true); _pUi->actionSaveDataFile->setEnabled(false); @@ -877,10 +855,6 @@ void MainWindow::handleFileOpen(QString filename) { _pProjectFileHandler->openProjectFile(filename); } - else if (fileInfo.completeSuffix().toLower() == QString("mbc")) - { - showRegisterDialog(filename); - } else { /* Assume data file import */ diff --git a/src/dialogs/mainwindow.h b/src/dialogs/mainwindow.h index 64d0e026..b1c45d99 100755 --- a/src/dialogs/mainwindow.h +++ b/src/dialogs/mainwindow.h @@ -69,7 +69,6 @@ private slots: void stopScope(); void showDiagnostic(); void showNotesDialog(); - void showMbcImportDialog(); void toggleMarkersState(); void handleOpenRecentProject(QString projectFile); @@ -100,7 +99,7 @@ private slots: private: void setAxisToAuto(); - void showRegisterDialog(QString mbcFile); + void showRegisterDialog(); void handleCommandLineArguments(QStringList cmdArguments); void handleFileOpen(QString filename); diff --git a/src/dialogs/mainwindow.ui b/src/dialogs/mainwindow.ui index 1442a6d8..5f8457c4 100755 --- a/src/dialogs/mainwindow.ui +++ b/src/dialogs/mainwindow.ui @@ -61,7 +61,6 @@ - @@ -497,11 +496,6 @@ Save &Project - - - &Import MBC File... - - diff --git a/src/dialogs/mbcheader.h b/src/dialogs/mbcheader.h deleted file mode 100644 index 0d18428d..00000000 --- a/src/dialogs/mbcheader.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef MBCHEADER_H -#define MBCHEADER_H - -#include -#include -#include - -class MbcHeader : public QHeaderView -{ - Q_OBJECT - -public: - MbcHeader(Qt::Orientation orientation, QWidget* parent = nullptr) : QHeaderView(orientation, parent) - { - } - -signals: - void selectAllClicked(Qt::CheckState); - -protected: - void paintSection(QPainter* painter, const QRect& rect, int logicalIndex) const override - { - painter->save(); - QHeaderView::paintSection(painter, rect, logicalIndex); - painter->restore(); - - if (model() && logicalIndex == 0) - { - QStyleOptionButton option; - option.initFrom(this); - - QRect checkbox_rect = style()->subElementRect(QStyle::SubElement::SE_CheckBoxIndicator, &option, this); - checkbox_rect.moveCenter(rect.center()); - - bool checked = model()->headerData(logicalIndex, orientation(), Qt::CheckStateRole).toBool(); - - option.rect = checkbox_rect; - option.state = checked ? QStyle::State_On : QStyle::State_Off; - - style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter); - } - } - - void mouseReleaseEvent(QMouseEvent* event) override - { - QHeaderView::mouseReleaseEvent(event); - if (model()) - { - int section = logicalIndexAt(event->pos()); - if (section == 0) - { - const uint state = model()->headerData(section, orientation(), Qt::CheckStateRole).toUInt(); - auto selectAllState = static_cast(state); - if ((selectAllState == Qt::Checked) || (selectAllState == Qt::PartiallyChecked)) - { - selectAllState = Qt::Unchecked; - } - else - { - selectAllState = Qt::Checked; - } - - emit selectAllClicked(selectAllState); - } - } - } -}; - -#endif // MBCHEADER_H diff --git a/src/importexport/mbcfileimporter.cpp b/src/importexport/mbcfileimporter.cpp deleted file mode 100644 index e92e62cf..00000000 --- a/src/importexport/mbcfileimporter.cpp +++ /dev/null @@ -1,279 +0,0 @@ -#include "mbcfileimporter.h" - -#include "importexport/mbcregisterdata.h" -#include "util/util.h" - -MbcFileImporter::MbcFileImporter(QString * pMbcFileContent) : QObject(nullptr) -{ - parseRegisters(pMbcFileContent); -} - -QList MbcFileImporter::registerList() -{ - return _registerList; -} - -QStringList MbcFileImporter::tabList() -{ - return _tabList; -} - -void MbcFileImporter::parseRegisters(QString* pMbcFileContent) -{ - bool bRet = true; - - /* Clear register and tab list */ - _registerList.clear(); - _tabList.clear(); - - QDomDocument domDocument; - QDomDocument::ParseResult result = - domDocument.setContent(*pMbcFileContent, QDomDocument::ParseOption::UseNamespaceProcessing); - if (result) - { - QDomElement root = domDocument.documentElement(); - if (root.tagName().toLower().trimmed() == MbcFileDefinitions::cModbusControlTag) - { - QDomElement tag = root.firstChildElement(); - while (!tag.isNull()) - { - if (tag.tagName().toLower().trimmed() == MbcFileDefinitions::cTabTag) - { - bRet = parseTabTag(tag); - if (!bRet) - { - break; - } - } - else - { - /* Ignore other tags */ - } - - tag = tag.nextSiblingElement(); - } - } - else - { - Util::showError(tr("The file is not a valid ModbusControl project file.")); - bRet = false; - } - } - else - { - Util::showError(tr("Parse error at line %1, column %2:\n%3") - .arg(result.errorLine) - .arg(result.errorColumn) - .arg(result.errorMessage)); - bRet = false; - } - - if (bRet == false) - { - _registerList.clear(); - _tabList.clear(); - } -} - -bool MbcFileImporter::parseTabTag(const QDomElement &element) -{ - bool bRet = true; - bool bFoundName = false; - QDomElement child = element.firstChildElement(); - - _nextRegisterAddr = -1; - - while (!child.isNull()) - { - if (child.tagName().toLower().trimmed() == MbcFileDefinitions::cTabNameTag) - { - _tabList.append(child.text()); - bFoundName = true; - } - else if (child.tagName().toLower().trimmed() == MbcFileDefinitions::cVarTag) - { - if (bFoundName) - { - bRet = parseVarTag(child, _tabList.size() - 1); - if (!bRet) - { - break; - } - } - else - { - Util::showError(tr("No name tag in tab tag")); - bRet = false; - break; - } - } - else - { - // unknown tag: ignore - } - child = child.nextSiblingElement(); - } - - return bRet; -} - -bool MbcFileImporter::parseVarTag(const QDomElement &element, qint32 tabIdx) -{ - bool bRet = true; - - QString name; - QString addr; - QString strType; - QString rw; - QString decimals; - MbcRegisterData modbusRegister; - - modbusRegister.setTabIdx(tabIdx); - - QDomElement child = element.firstChildElement(); - - while (!child.isNull()) - { - if (child.tagName().toLower().trimmed() == MbcFileDefinitions::cRegisterTag) - { - addr = child.text().toLower().trimmed(); - } - else if (child.tagName().toLower().trimmed() == MbcFileDefinitions::cTextTag) - { - name = child.text(); - } - else if (child.tagName().toLower().trimmed() == MbcFileDefinitions::cTypeTag) - { - strType = child.text().toLower().trimmed(); - } - else if (child.tagName().toLower().trimmed() == MbcFileDefinitions::cReadWrite) - { - rw = child.text().toLower().trimmed(); - } - else if (child.tagName().toLower().trimmed() == MbcFileDefinitions::cDecimals) - { - decimals = child.text(); - } - else - { - // unknown tag: ignore - } - child = child.nextSiblingElement(); - } - - /* Check for empty tag or unsupported 32 bit register */ - if ( - !name.isEmpty() - || !addr.isEmpty() - || !strType.isEmpty() - || !rw.isEmpty() - || !decimals.isEmpty() - ) - { - /* Obligated */ - if (name.isEmpty()) - { - bRet = false; - } - else - { - modbusRegister.setName(name); - } - - /* Obligated */ - if (bRet) - { - if (addr.isEmpty()) - { - bRet = false; - } - else if (addr == "*") - { - if (_nextRegisterAddr > 0) - { - modbusRegister.setRegisterAddress(_nextRegisterAddr); - } - else - { - bRet = false; - } - } - else - { - modbusRegister.setRegisterAddress(static_cast(addr.toUInt(&bRet))); - } - } - - /* Obligated */ - if (rw.isEmpty()) - { - bRet = false; - } - else - { - if (rw.contains("r")) - { - modbusRegister.setReadable(true); - } - else - { - modbusRegister.setReadable(false); - } - } - - /* Optional */ - if (bRet) - { - bool bOk; - ModbusDataType::Type type = ModbusDataType::convertMbcString(strType, bOk); - - if (bOk) - { - modbusRegister.setType(type); - } - else - { - bRet = false; - } - } - - /* optional */ - if (bRet) - { - if (!decimals.isEmpty()) - { - modbusRegister.setDecimals(static_cast(decimals.toUInt(&bRet))); - } - } - - if (bRet) - { - /* Save register in list */ - _registerList.append(modbusRegister); - - if (ModbusDataType::is32Bit(modbusRegister.type())) - { - /* Increment address with 2 */ - _nextRegisterAddr = static_cast(modbusRegister.registerAddress()) + 2; - } - else - { - /* Increment address with 1 */ - _nextRegisterAddr = static_cast(modbusRegister.registerAddress()) + 1; - } - } - else - { - Util::showError(tr("A tag is not present or value is not valid.\n\nName: %1\nRegister address: %2\nType: %3\nDecimals: %4") - .arg(name, addr, strType, decimals) - ); - } - - } - else - { - /* Empty var tag or 32 bit register: ignore */ - } - - return bRet; -} diff --git a/src/importexport/mbcfileimporter.h b/src/importexport/mbcfileimporter.h deleted file mode 100644 index 7d71439d..00000000 --- a/src/importexport/mbcfileimporter.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef MBCFILEIMPORTER_H -#define MBCFILEIMPORTER_H - -#include "importexport/mbcregisterdata.h" - -#include -#include - -namespace MbcFileDefinitions -{ - - /* Tag strings */ - const char cModbusControlTag[] = "modbuscontrol"; - const char cTabTag[] = "tab"; - - const char cTabNameTag[] = "name"; - const char cVarTag[] = "var"; - - const char cRegisterTag[] = "reg"; - const char cTextTag[] = "text"; - const char cTypeTag[] = "type"; - const char cReadWrite[] = "rw"; - const char cDecimals[] = "decimals"; -} - -class MbcFileImporter : public QObject -{ - Q_OBJECT -public: - explicit MbcFileImporter(QString *mbcFileContent); - - QList registerList(); - QStringList tabList(); - -signals: - -public slots: - -private: - void parseRegisters(QString* mbcFileContent); - bool parseTabTag(const QDomElement &element); - bool parseVarTag(const QDomElement &element, qint32 tabIdx); - - qint32 _nextRegisterAddr; - - QList _registerList; - QStringList _tabList; -}; - -#endif // MBCFILEIMPORTER_H diff --git a/src/importexport/mbcregisterdata.cpp b/src/importexport/mbcregisterdata.cpp deleted file mode 100644 index 13a5f95e..00000000 --- a/src/importexport/mbcregisterdata.cpp +++ /dev/null @@ -1,148 +0,0 @@ -#include "mbcregisterdata.h" - -#include "util/expressiongenerator.h" - -#include - -MbcRegisterData::MbcRegisterData() : - _registerAddress(0), - _tabIdx(0), - _type(ModbusDataType::Type::UNSIGNED_16), - _bReadable(true), - _decimals(0) -{ -} - -MbcRegisterData::~MbcRegisterData() -{ - -} - -MbcRegisterData::MbcRegisterData(quint32 registerAddress, ModbusDataType::Type type, QString name, qint32 tabIdx, bool bReadable, quint8 decimals) : - _registerAddress(registerAddress), - _name(name), - _tabIdx(tabIdx), - _type(type), - _bReadable(bReadable), - _decimals(decimals) -{ -} - -bool MbcRegisterData::compare(MbcRegisterData* pMbcRegdata) -{ - bool bRet = true; - - if (_registerAddress != pMbcRegdata->registerAddress()) - { - bRet = false; - } - - if (_type != pMbcRegdata->type()) - { - bRet = false; - } - - if (_tabIdx != pMbcRegdata->tabIdx()) - { - bRet = false; - } - - if (_name != pMbcRegdata->name()) - { - bRet = false; - } - - if (_bReadable != pMbcRegdata->isReadable()) - { - bRet = false; - } - - if (_decimals != pMbcRegdata->decimals()) - { - bRet = false; - } - - return bRet; -} - -quint32 MbcRegisterData::registerAddress() const -{ - return _registerAddress; -} - -void MbcRegisterData::setRegisterAddress(const quint32 ®isterAddress) -{ - _registerAddress = registerAddress; -} - -void MbcRegisterData::setType(ModbusDataType::Type type) -{ - _type = type; -} - -ModbusDataType::Type MbcRegisterData::type() const -{ - return _type; -} - -QString MbcRegisterData::name() const -{ - return _name; -} - -void MbcRegisterData::setName(const QString &name) -{ - _name = name; -} - -qint32 MbcRegisterData::tabIdx() const -{ - return _tabIdx; -} - -void MbcRegisterData::setTabIdx(const qint32 &tabIdx) -{ - _tabIdx = tabIdx; -} - -bool MbcRegisterData::isReadable() const -{ - return _bReadable; -} - -void MbcRegisterData::setReadable(bool isReadable) -{ - _bReadable = isReadable; -} - -quint8 MbcRegisterData::decimals() const -{ - return _decimals; -} - -void MbcRegisterData::setDecimals(const quint8 &decimals) -{ - _decimals = decimals; -} - -QString MbcRegisterData::toExpression() const -{ - QString expression; - QString registerStr = - ExpressionGenerator::constructRegisterString(QString("%1").arg(_registerAddress), _type, Device::cFirstDeviceId); - if (_decimals != 0) - { - expression = QString("%1/%2").arg(registerStr) - .arg(static_cast(qPow(10, _decimals))); - } - else - { - expression = registerStr; - } - - return expression; -} - - - - diff --git a/src/importexport/mbcregisterdata.h b/src/importexport/mbcregisterdata.h deleted file mode 100644 index 2cba2234..00000000 --- a/src/importexport/mbcregisterdata.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef MBCREGISTERDATA_H -#define MBCREGISTERDATA_H - -#include "util/modbusdatatype.h" - -#include -#include - -class MbcRegisterData -{ -public: - explicit MbcRegisterData(); - MbcRegisterData(quint32 registerAddress, ModbusDataType::Type type, QString name, qint32 tabIdx, bool bReadable, quint8 decimals); - ~MbcRegisterData(); - - bool compare(MbcRegisterData* pMbcRegdata); - - quint32 registerAddress() const; - void setRegisterAddress(const quint32 ®isterAddress); - - void setType(ModbusDataType::Type type); - - ModbusDataType::Type type() const; - - QString name() const; - void setName(const QString &name); - - qint32 tabIdx() const; - void setTabIdx(const qint32 &tabIdx); - - bool isReadable() const; - void setReadable(bool isReadable); - - quint8 decimals() const; - void setDecimals(const quint8 &decimals); - - QString toExpression() const; - -private: - - quint32 _registerAddress; - QString _name; - qint32 _tabIdx; - ModbusDataType::Type _type; - bool _bReadable; - quint8 _decimals; -}; - -#endif // MBCREGISTERDATA_H diff --git a/src/models/guimodel.cpp b/src/models/guimodel.cpp index 10b39850..6666995d 100644 --- a/src/models/guimodel.cpp +++ b/src/models/guimodel.cpp @@ -45,7 +45,6 @@ GuiModel::GuiModel(QObject *parent) : QObject(parent) { _lastDir = docPath[0]; } - _lastMbcImportedFile = QString(); _guiSettings.xScaleMode = AxisMode::SCALE_AUTO; _guiSettings.yScaleMode = AxisMode::SCALE_AUTO; @@ -166,16 +165,6 @@ QString GuiModel::lastDir() return _lastDir; } -void GuiModel::setLastMbcImportedFile(QString file) -{ - _lastMbcImportedFile = file; -} - -QString GuiModel::lastMbcImportedFile() -{ - return _lastMbcImportedFile; -} - void GuiModel::setxAxisScale(AxisMode::AxisScaleOptions scaleMode) { if (_guiSettings.xScaleMode != scaleMode) diff --git a/src/models/guimodel.h b/src/models/guimodel.h index 964e7ba8..ab332074 100644 --- a/src/models/guimodel.h +++ b/src/models/guimodel.h @@ -57,7 +57,6 @@ class GuiModel : public QObject QString windowTitle(); QString projectFilePath(); QString lastDir(); - QString lastMbcImportedFile(); AxisMode::AxisScaleOptions xAxisScalingMode(); quint32 xAxisSlidingSec(); AxisMode::AxisScaleOptions yAxisScalingMode(); @@ -76,7 +75,6 @@ class GuiModel : public QObject void setProjectFilePath(QString path); void setLastDir(QString dir); - void setLastMbcImportedFile(QString file); void setMarkerExpressionMask(quint32 mask); public slots: @@ -148,7 +146,6 @@ private slots: QString _projectFilePath; QString _lastDir; // Last directory opened for import/export/load project - QString _lastMbcImportedFile; bool _bHighlightSamples; bool _bCursorValues; diff --git a/src/models/mbcregisterfilter.cpp b/src/models/mbcregisterfilter.cpp deleted file mode 100644 index 957ece74..00000000 --- a/src/models/mbcregisterfilter.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include "mbcregisterfilter.h" - -#include "models/mbcregistermodel.h" - -const QString MbcRegisterFilter::cTabNoFilter = QString("No Filter"); - -MbcRegisterFilter::MbcRegisterFilter(QObject* parent) : QSortFilterProxyModel(parent) -{ - _tab = cTabNoFilter; - _textFilter.clear(); -} - -bool MbcRegisterFilter::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const -{ - if (source_row < sourceModel()->rowCount()) - { - return performTabFilter(source_row, source_parent) && performTextFilter(source_row, source_parent); - } - else - { - return false; - } -} - -void MbcRegisterFilter::setTab(QString tab) -{ - if (tab != _tab) - { - _tab = tab; - } - - invalidateFilter(); -} - -void MbcRegisterFilter::setTextFilter(QString filterText) -{ - if (filterText.trimmed() != _textFilter) - { - _textFilter = filterText.trimmed(); - } - - invalidateFilter(); -} - -bool MbcRegisterFilter::performTabFilter(int source_row, const QModelIndex& source_parent) const -{ - QModelIndex tabIdx = sourceModel()->index(source_row, MbcRegisterModel::cColumnTab, source_parent); - QString tabName = tabIdx.data().toString(); - - bool bAllowed = true; - - /* Filter on tab */ - bAllowed = (_tab == cTabNoFilter || tabName == _tab); - - return bAllowed; -} - -bool MbcRegisterFilter::performTextFilter(int source_row, const QModelIndex& source_parent) const -{ - bool bAllowed = true; - - QModelIndex descriptionIdx = sourceModel()->index(source_row, MbcRegisterModel::cColumnText, source_parent); - QString description = descriptionIdx.data().toString(); - - QModelIndex addressIdx = sourceModel()->index(source_row, MbcRegisterModel::cColumnAddress, source_parent); - QString strAddress = addressIdx.data().toString(); - - /* Filter on text */ - if ((!_textFilter.isEmpty()) && (!description.contains(_textFilter, Qt::CaseInsensitive)) && - (!strAddress.contains(_textFilter, Qt::CaseInsensitive))) - { - bAllowed = false; - } - - return bAllowed; -} diff --git a/src/models/mbcregisterfilter.h b/src/models/mbcregisterfilter.h deleted file mode 100644 index 45a6846b..00000000 --- a/src/models/mbcregisterfilter.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef MBCREGISTERFILTER_H -#define MBCREGISTERFILTER_H - -#include - -class MbcRegisterFilter : public QSortFilterProxyModel -{ - -public: - MbcRegisterFilter(QObject* parent = nullptr); - bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; - - static const QString cTabNoFilter; - -public slots: - void setTab(QString tab); - void setTextFilter(QString filterText); - -private: - - bool performTabFilter(int source_row, const QModelIndex &source_parent) const; - bool performTextFilter(int source_row, const QModelIndex &source_parent) const; - - QString _tab; - QString _textFilter; - -}; - -#endif // MBCREGISTERFILTER_H diff --git a/src/models/mbcregistermodel.cpp b/src/models/mbcregistermodel.cpp deleted file mode 100644 index dcfa2e57..00000000 --- a/src/models/mbcregistermodel.cpp +++ /dev/null @@ -1,316 +0,0 @@ -#include "mbcregistermodel.h" - -#include "customwidgets/centeredbox.h" - -MbcRegisterModel::MbcRegisterModel(QObject *parent) - : QAbstractTableModel(parent) -{ - _mbcRegisterList.clear(); - _tabList.clear(); - _selection = Qt::Unchecked; -} - -QVariant MbcRegisterModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (orientation == Qt::Horizontal) - { - if (role == Qt::DisplayRole) - { - switch (section) - { - case cColumnAddress: - return QString("Address"); - case cColumnText: - return QString("Text"); - case cColumnType: - return QString("Type"); - case cColumnTab: - return QString("Tab"); - case cColumnDecimals: - return QString("Decimals"); - - default: - return QVariant(); - } - } - else if (role == Qt::CheckStateRole) - { - if (section == cColumnSelected) - { - return _selection; - } - } - else - { - return QVariant(); - } - } - else - { - // Can't happen because it is hidden - } - - return QVariant(); -} - -bool MbcRegisterModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant& value, int role) -{ - bool bRet = false; - - if ((section == cColumnSelected) && (role == Qt::CheckStateRole)) - { - auto selectAllState = static_cast(value.toUInt()); - if (_selection <= Qt::Checked) - { - _selection = selectAllState; - bRet = true; - } - } - - if (bRet) - { - // Notify view(s) of change - emit headerDataChanged(orientation, cColumnSelected, cColumnSelected); - } - - return bRet; -} - -int MbcRegisterModel::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return _mbcRegisterList.size(); -} - -int MbcRegisterModel::columnCount(const QModelIndex &parent) const -{ - if (parent.isValid()) - return 0; - - return cColumnCnt; -} - -QVariant MbcRegisterModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - auto const mbcRegister = _mbcRegisterList[index.row()]; - - if (role == Qt::ToolTipRole) - { - if (!mbcRegister.registerData.isReadable()) - { - return "Not readable"; - } - else - { - return ""; - } - } - else if (role == Qt::CheckStateRole) - { - if (index.column() == cColumnSelected) - { - if (mbcRegister.bSelected) - { - return Qt::Checked; - } - else - { - return Qt::Unchecked; - } - } - } - else if (role == CheckAlignmentRole) - { - if (index.column() == cColumnSelected) - { - return Qt::AlignCenter; - } - } - else if (role == Qt::DisplayRole) - { - switch (index.column()) - { - - case cColumnAddress: - return mbcRegister.registerData.registerAddress(); - break; - - case cColumnDecimals: - return mbcRegister.registerData.decimals(); - break; - - case cColumnTab: - { - const qint32 tabIdx = mbcRegister.registerData.tabIdx(); - - if (tabIdx < _tabList.size()) - { - return _tabList[tabIdx]; - } - } - break; - - case cColumnText: - return mbcRegister.registerData.name(); - break; - - case cColumnType: - return ModbusDataType::typeString(mbcRegister.registerData.type()); - break; - - default: - return QVariant(); - } - } - - return QVariant(); -} - -bool MbcRegisterModel::setData(const QModelIndex & index, const QVariant & value, int role) -{ - if (!index.isValid()) - return false; - - bool bRet = false; - - if ((index.column() == cColumnSelected) && (role == Qt::CheckStateRole) && _mbcRegisterList[index.row()].bEnabled) - { - _mbcRegisterList[index.row()].bSelected = value == Qt::Checked; - - bRet = true; - } - - if (bRet) - { - emit dataChanged(this->index(0, 0), this->index(rowCount() - 1, 0)); - } - - return bRet; -} - -void MbcRegisterModel::setSelectionstate(QList& indexList, Qt::CheckState state) -{ - if (indexList.isEmpty()) - { - return; - } - - for (QModelIndex index : indexList) - { - if (index.isValid()) - { - if (_mbcRegisterList[index.row()].bEnabled) - { - _mbcRegisterList[index.row()].bSelected = state == Qt::Checked; - } - else - { - _mbcRegisterList[index.row()].bSelected = Qt::Unchecked; - } - } - } - - emit dataChanged(this->index(0, 0), this->index(rowCount() - 1, 0)); -} - -void MbcRegisterModel::reset() -{ - beginResetModel(); - - _mbcRegisterList.clear(); - _tabList.clear(); - - endResetModel(); -} - -void MbcRegisterModel::fill(QList mbcRegisterList, QStringList tabList) -{ - if (rowCount() != 0) - { - reset(); - } - - /* Call function to prepare view */ - beginInsertRows(QModelIndex(), rowCount(), rowCount() + mbcRegisterList.size() - 1); - - _tabList = tabList; - - for(qint32 idx = 0; idx < mbcRegisterList.size(); idx++) - { - // Get result before adding to list - _mbcRegisterList.append({ mbcRegisterList[idx], false, false }); - - if (_mbcRegisterList.last().registerData.isReadable()) - { - _mbcRegisterList.last().bEnabled = true; - } - } - - /* Call function to trigger view update */ - endInsertRows(); -} - -Qt::ItemFlags MbcRegisterModel::flags(const QModelIndex & index) const -{ - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - - Qt::ItemFlags flags = Qt::NoItemFlags; - - if (index.column() == cColumnSelected) - { - // checkable - flags = Qt::ItemIsUserCheckable; - } - - if (_mbcRegisterList[index.row()].bEnabled) - { - flags |= Qt::ItemIsSelectable | Qt::ItemIsEnabled; - } - - return flags; -} - -QList MbcRegisterModel::selectedRegisterList() -{ - QList _selectedRegisterList; - - // Get selected register from table widget */ - for (const MbcRegister& row : std::as_const(_mbcRegisterList)) - { - if (row.bSelected) - { - GraphData graphData; - graphData.setActive(true); - graphData.setLabel(row.registerData.name()); - graphData.setExpression(row.registerData.toExpression()); - - _selectedRegisterList.append(graphData); - } - } - - return _selectedRegisterList; -} - -quint32 MbcRegisterModel::selectedRegisterCount() -{ - quint32 cnt = 0; - - // Get selected register from table widget */ - for (const MbcRegister& row : std::as_const(_mbcRegisterList)) - { - if (row.bSelected) - { - cnt++; - } - } - - return cnt; -} diff --git a/src/models/mbcregistermodel.h b/src/models/mbcregistermodel.h deleted file mode 100644 index c1546636..00000000 --- a/src/models/mbcregistermodel.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef MBCREGISTERMODEL_H -#define MBCREGISTERMODEL_H - -#include "importexport/mbcregisterdata.h" -#include "models/graphdata.h" - -#include - -class MbcRegisterModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - explicit MbcRegisterModel(QObject *parent = nullptr); - - // Header: - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - bool setHeaderData(int section, - Qt::Orientation orientation, - const QVariant& value, - int role = Qt::EditRole) override; - - // Basic functionality: - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - Qt::ItemFlags flags(const QModelIndex & index) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - bool setData(const QModelIndex & index, const QVariant & value, int role) override; - - void setSelectionstate(QList& indexList, Qt::CheckState state); - - void reset(); - - // Add data: - void fill(QList mbcRegisterList, QStringList tabList); - - QList selectedRegisterList(); - quint32 selectedRegisterCount(); - - static const quint32 cColumnSelected = 0; - static const quint32 cColumnAddress = 1; - static const quint32 cColumnText = 2; - static const quint32 cColumnType = 3; - static const quint32 cColumnTab = 4; - static const quint32 cColumnDecimals = 5; - static const quint32 cColumnCnt = 6; - -private: - typedef struct - { - MbcRegisterData registerData; - bool bSelected; - bool bEnabled; - } MbcRegister; - - QList _mbcRegisterList; - - QStringList _tabList; - - Qt::CheckState _selection; -}; - -#endif // MBCREGISTERMODEL_H diff --git a/src/models/mbcupdatemodel.cpp b/src/models/mbcupdatemodel.cpp deleted file mode 100644 index 88e0a3a4..00000000 --- a/src/models/mbcupdatemodel.cpp +++ /dev/null @@ -1,202 +0,0 @@ -#include "mbcupdatemodel.h" - -#include "graphdatamodel.h" - -MbcUpdateModel::MbcUpdateModel(GraphDataModel* pGraphDataModel, QObject* parent) - : QAbstractTableModel(parent), _pGraphDataModel(pGraphDataModel) -{ - _mbcRegisterList.clear(); - _updateInfo = QList(_pGraphDataModel->size()); - - connect(_pGraphDataModel, &GraphDataModel::expressionChanged, this, &MbcUpdateModel::checkUpdate); - connect(_pGraphDataModel, &GraphDataModel::labelChanged, this, &MbcUpdateModel::checkUpdate); - connect(_pGraphDataModel, &GraphDataModel::added, this, &MbcUpdateModel::checkUpdate); - connect(_pGraphDataModel, &GraphDataModel::removed, this, &MbcUpdateModel::checkUpdate); -} - -QVariant MbcUpdateModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if ((orientation == Qt::Horizontal) && (role == Qt::DisplayRole)) - { - switch (section) - { - case cColumnExpression: - return QString("Current expression"); - case cColumnText: - return QString("Current Text"); - case cColumnUpdateExpression: - return QString("New Expression"); - case cColumnUpdateText: - return QString("New Text"); - default: - return QVariant(); - } - } - else - { - // Can't happen because it is hidden - } - - return QVariant(); -} - -int MbcUpdateModel::rowCount(const QModelIndex& parent) const -{ - if (parent.isValid()) - return 0; - - return _pGraphDataModel->size(); -} - -int MbcUpdateModel::columnCount(const QModelIndex& parent) const -{ - if (parent.isValid()) - return 0; - - return cColumnCnt; -} - -Qt::ItemFlags MbcUpdateModel::flags(const QModelIndex& index) const -{ - using UpdateField = MbcUpdateModel::UpdateInfo::UpdateField; - - if (!index.isValid()) - { - return Qt::NoItemFlags; - } - - Qt::ItemFlags flags = Qt::NoItemFlags; - if (_updateInfo[index.row()].update != UpdateField::None) - { - flags |= Qt::ItemIsEnabled; - } - - return flags; -} - -QVariant MbcUpdateModel::data(const QModelIndex& index, int role) const -{ - using UpdateField = MbcUpdateModel::UpdateInfo::UpdateField; - - if (!index.isValid()) - return QVariant(); - - if (role == Qt::ToolTipRole) - { - switch (_updateInfo[index.row()].update) - { - - case UpdateField::Expression: - return "Update of expression detected"; - break; - - case UpdateField::Text: - return "Update of text detected"; - break; - - default: - return QVariant(); - } - } - else if (role == Qt::DisplayRole) - { - switch (index.column()) - { - - case cColumnExpression: - return _pGraphDataModel->simplifiedExpression(index.row()); - break; - - case cColumnText: - return _pGraphDataModel->label(index.row()); - break; - - case cColumnUpdateExpression: - if (_updateInfo[index.row()].update == UpdateField::Expression) - { - return _updateInfo[index.row()].expression; - } - break; - - case cColumnUpdateText: - if (_updateInfo[index.row()].update == UpdateField::Text) - { - return _updateInfo[index.row()].text; - } - break; - - default: - return QVariant(); - } - } - else if (role == Qt::UserRole) - { - const bool textColumnWithUpdate = - (index.column() == cColumnUpdateText) && (_updateInfo[index.row()].update == UpdateField::Text); - const bool expressionColumnWithUpdate = - (index.column() == cColumnUpdateExpression) && (_updateInfo[index.row()].update == UpdateField::Expression); - - if (!textColumnWithUpdate && !expressionColumnWithUpdate) - { - return "hidden"; - } - } - - return QVariant(); -} - -void MbcUpdateModel::setMbcRegisters(QList mbcRegisterList) -{ - _mbcRegisterList = mbcRegisterList; - - checkUpdate(); -} - -void MbcUpdateModel::checkUpdate() -{ - using UpdateField = MbcUpdateModel::UpdateInfo::UpdateField; - - beginResetModel(); - - const quint32 graphSize = _pGraphDataModel->size(); - _updateInfo = QList(graphSize); - - QHash exprToIndex; - QHash labelToIndex; - - // Preprocess graph data model into lookup tables - for (quint32 idx = 0; idx < graphSize; ++idx) - { - exprToIndex.insert(_pGraphDataModel->expression(idx), idx); - labelToIndex.insert(_pGraphDataModel->label(idx), idx); - } - - for (const auto& mbcRegister : std::as_const(_mbcRegisterList)) - { - const QString checkExpr = mbcRegister.toExpression(); - const QString checkName = mbcRegister.name(); - - if (exprToIndex.contains(checkExpr)) - { - int idx = exprToIndex[checkExpr]; - if (_updateInfo[idx].update == UpdateField::None && _pGraphDataModel->label(idx) != checkName) - { - _updateInfo[idx].update = UpdateField::Text; - _updateInfo[idx].expression.clear(); - _updateInfo[idx].text = checkName; - } - } - else if (labelToIndex.contains(checkName)) - { - int idx = labelToIndex[checkName]; - if (_updateInfo[idx].update == UpdateField::None && _pGraphDataModel->expression(idx) != checkExpr) - { - _updateInfo[idx].update = UpdateField::Expression; - _updateInfo[idx].expression = checkExpr; - _updateInfo[idx].text.clear(); - } - } - } - - endResetModel(); -} diff --git a/src/models/mbcupdatemodel.h b/src/models/mbcupdatemodel.h deleted file mode 100644 index aed3c139..00000000 --- a/src/models/mbcupdatemodel.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef MBCUPDATEMODEL_H -#define MBCUPDATEMODEL_H - -#include "importexport/mbcregisterdata.h" - -#include - -// Forward declaration -class GraphDataModel; - -class MbcUpdateModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - explicit MbcUpdateModel(GraphDataModel* pGraphDataModel, QObject* parent = nullptr); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - int rowCount(const QModelIndex& parent = QModelIndex()) const override; - int columnCount(const QModelIndex& parent = QModelIndex()) const override; - - Qt::ItemFlags flags(const QModelIndex& index) const override; - - QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - - void setMbcRegisters(QList mbcRegisterList); - - static const quint32 cColumnExpression = 0; - static const quint32 cColumnText = 1; - static const quint32 cColumnUpdateExpression = 2; - static const quint32 cColumnUpdateText = 3; - static const quint32 cColumnCnt = 4; - -private slots: - void checkUpdate(); - -private: - class UpdateInfo - { - - public: - enum class UpdateField - { - None, - Text, - Expression - }; - UpdateField update = UpdateField::None; - QString text; - QString expression; - }; - - GraphDataModel* _pGraphDataModel; - - QList _mbcRegisterList; - QList _updateInfo; -}; - -#endif // MBCUPDATEMODEL_H diff --git a/tests/importexport/CMakeLists.txt b/tests/importexport/CMakeLists.txt index ae53deb8..c6c4f648 100644 --- a/tests/importexport/CMakeLists.txt +++ b/tests/importexport/CMakeLists.txt @@ -1,7 +1,5 @@ add_xtest(tst_datafileparser ${CMAKE_CURRENT_SOURCE_DIR}/csvdata.cpp) -add_xtest(tst_mbcfileimporter ${CMAKE_CURRENT_SOURCE_DIR}/mbctestdata.cpp) -add_xtest(tst_mbcregisterfilter) add_xtest_mock(tst_presethandler) add_xtest(tst_presetparser ${CMAKE_CURRENT_SOURCE_DIR}/presetfiletestdata.cpp) add_xtest(tst_projectfileparser ${CMAKE_CURRENT_SOURCE_DIR}/projectfiletestdata.cpp) diff --git a/tests/importexport/mbctestdata.cpp b/tests/importexport/mbctestdata.cpp deleted file mode 100644 index badc51c7..00000000 --- a/tests/importexport/mbctestdata.cpp +++ /dev/null @@ -1,106 +0,0 @@ - -#include "mbctestdata.h" - -QString MbcTestData::cSingleTab = QString( - "" "\n"\ - "" "\n"\ - "" "\n"\ - " Tab1" "\n"\ - " 40001Reg1uint16r" "\n"\ - " 40002Reg2uint16r" "\n"\ - "" "\n"\ - "" "\n"\ -); - -QStringList MbcTestData::cSingleTab_TabList = - QStringList() << "Tab1"; - -QList MbcTestData::cSingleTab_RegList = - QList () << MbcRegisterData(40001, ModbusDataType::Type::UNSIGNED_16, "Reg1", 0, true, 0) - << MbcRegisterData(40002, ModbusDataType::Type::UNSIGNED_16, "Reg2", 0, true, 0); - - -QString MbcTestData::cMultiTab = QString( - "" "\n"\ - "" "\n"\ - "" "\n"\ - " Tab1" "\n"\ - " 40001Reg1uint16r" "\n"\ - "" "\n"\ - "" "\n"\ - " Tab2" "\n"\ - " 40002Reg2uint16r" "\n"\ - "" "\n"\ - "" "\n"\ - " Tab3" "\n"\ - " 40003Reg3uint16r" "\n"\ - "" "\n"\ - "" "\n"\ -); - -QStringList MbcTestData::cMultiTab_TabList = - QStringList() << "Tab1" - << "Tab2" - << "Tab3"; - -QList MbcTestData::cMultiTab_RegList = - QList () << MbcRegisterData(40001, ModbusDataType::Type::UNSIGNED_16, "Reg1", 0, true, 0) - << MbcRegisterData(40002, ModbusDataType::Type::UNSIGNED_16, "Reg2", 1, true, 0) - << MbcRegisterData(40003, ModbusDataType::Type::UNSIGNED_16, "Reg3", 2, true, 0); - -QString MbcTestData::cRegisterOptions = QString( - "" "\n"\ - "" "\n"\ - "" "\n"\ - " Tab1" "\n"\ - " 40001Reg1uint16r" "\n"\ - " 40002Reg2int16r" "\n"\ - " 40003Reg3uint16w" "\n"\ - " 40004Reg4uint32r" "\n"\ - " 40006Reg5uint16r" "\n"\ - " 40007Reg6uint160r" "\n"\ - " 40008Reg7uint165r" "\n"\ - " 40009Reg8float32r" "\n"\ - "" "\n"\ - "" "\n"\ -); - -QStringList MbcTestData::cRegisterOptions_TabList = QStringList() << "Tab1"; - -QList MbcTestData::cRegisterOptions_RegList = - QList () << MbcRegisterData(40001, ModbusDataType::Type::UNSIGNED_16, "Reg1", 0, true, 0) - << MbcRegisterData(40002, ModbusDataType::Type::SIGNED_16, "Reg2", 0, true, 0) - << MbcRegisterData(40003, ModbusDataType::Type::UNSIGNED_16, "Reg3", 0, false, 0) - << MbcRegisterData(40004, ModbusDataType::Type::UNSIGNED_32, "Reg4", 0, true, 0) - << MbcRegisterData(40006, ModbusDataType::Type::UNSIGNED_16, "Reg5", 0, true, 0) - << MbcRegisterData(40007, ModbusDataType::Type::UNSIGNED_16, "Reg6", 0, true, 0) - << MbcRegisterData(40008, ModbusDataType::Type::UNSIGNED_16, "Reg7", 0, true, 5) - << MbcRegisterData(40009, ModbusDataType::Type::FLOAT_32, "Reg8", 0, true, 0) - ; - - -QString MbcTestData::cAutoincrement = QString( - "" "\n"\ - "" "\n"\ - "" "\n"\ - " Tab1" "\n"\ - " 40001Reg1uint16r" "\n"\ - " *Reg2uint16r" "\n"\ - " *Reg3uint16r" "\n"\ - " 40010Reg10uint16r" "\n"\ - " *Reg11uint16r" "\n"\ - - "" "\n"\ - "" "\n"\ -); - -QStringList MbcTestData::cAutoincrement_TabList = - QStringList() << "Tab1"; - -QList MbcTestData::cAutoincrement_RegList = - QList () << MbcRegisterData(40001, ModbusDataType::Type::UNSIGNED_16, "Reg1", 0, true, 0) - << MbcRegisterData(40002, ModbusDataType::Type::UNSIGNED_16, "Reg2", 0, true, 0) - << MbcRegisterData(40003, ModbusDataType::Type::UNSIGNED_16, "Reg3", 0, true, 0) - << MbcRegisterData(40010, ModbusDataType::Type::UNSIGNED_16, "Reg10", 0, true, 0) - << MbcRegisterData(40011, ModbusDataType::Type::UNSIGNED_16, "Reg11", 0, true, 0) - ; diff --git a/tests/importexport/mbctestdata.h b/tests/importexport/mbctestdata.h deleted file mode 100644 index e07384e9..00000000 --- a/tests/importexport/mbctestdata.h +++ /dev/null @@ -1,29 +0,0 @@ - -#include "importexport/mbcregisterdata.h" - -#include - -class MbcTestData: public QObject -{ - Q_OBJECT - -public: - static QString cSingleTab; - static QStringList cSingleTab_TabList; - static QList cSingleTab_RegList; - - static QString cMultiTab; - static QStringList cMultiTab_TabList; - static QList cMultiTab_RegList; - - static QString cRegisterOptions; - static QStringList cRegisterOptions_TabList; - static QList cRegisterOptions_RegList; - - static QString cAutoincrement; - static QStringList cAutoincrement_TabList; - static QList cAutoincrement_RegList; - -private: - -}; diff --git a/tests/importexport/tst_mbcfileimporter.cpp b/tests/importexport/tst_mbcfileimporter.cpp deleted file mode 100644 index fab0d2c1..00000000 --- a/tests/importexport/tst_mbcfileimporter.cpp +++ /dev/null @@ -1,79 +0,0 @@ - -#include "tst_mbcfileimporter.h" - -#include "importexport/mbcfileimporter.h" -#include "mbctestdata.h" - -#include - -void TestMbcFileImporter::init() -{ - -} - -void TestMbcFileImporter::cleanup() -{ - -} - -void TestMbcFileImporter::importSingleTab() -{ - MbcFileImporter mbcFileImporter(&MbcTestData::cSingleTab); - - QList regList = mbcFileImporter.registerList(); - QStringList tabList = mbcFileImporter.tabList(); - - verifyRegList(MbcTestData::cSingleTab_RegList, regList); - - QCOMPARE(tabList, MbcTestData::cSingleTab_TabList); -} - -void TestMbcFileImporter::importMultiTab() -{ - MbcFileImporter mbcFileImporter(&MbcTestData::cMultiTab); - - QList regList = mbcFileImporter.registerList(); - QStringList tabList = mbcFileImporter.tabList(); - - verifyRegList(MbcTestData::cMultiTab_RegList, regList); - - QCOMPARE(tabList, MbcTestData::cMultiTab_TabList); -} - -void TestMbcFileImporter::importRegisterOptions() -{ - MbcFileImporter mbcFileImporter(&MbcTestData::cRegisterOptions); - - QList regList = mbcFileImporter.registerList(); - QStringList tabList = mbcFileImporter.tabList(); - - verifyRegList(MbcTestData::cRegisterOptions_RegList, regList); - - QCOMPARE(tabList, MbcTestData::cRegisterOptions_TabList); -} - -void TestMbcFileImporter::importAutoIncrement() -{ - - MbcFileImporter mbcFileImporter(&MbcTestData::cAutoincrement); - - QList regList = mbcFileImporter.registerList(); - QStringList tabList = mbcFileImporter.tabList(); - - verifyRegList(MbcTestData::cAutoincrement_RegList, regList); - - QCOMPARE(tabList, MbcTestData::cAutoincrement_TabList); - -} - -void TestMbcFileImporter::verifyRegList(QList list1, QList list2) -{ - QVERIFY(list1.size() == list2.size()); - - for (int32_t i = 0; i < list1.size(); i++) - { - QVERIFY(list1[i].compare(&list2[i])); - } -} - -QTEST_GUILESS_MAIN(TestMbcFileImporter) diff --git a/tests/importexport/tst_mbcfileimporter.h b/tests/importexport/tst_mbcfileimporter.h deleted file mode 100644 index 7fdf79d6..00000000 --- a/tests/importexport/tst_mbcfileimporter.h +++ /dev/null @@ -1,21 +0,0 @@ - -#include "importexport/mbcregisterdata.h" - -#include - -class TestMbcFileImporter: public QObject -{ - Q_OBJECT - -private slots: - void init(); - void cleanup(); - - void importSingleTab(); - void importMultiTab(); - void importRegisterOptions(); - void importAutoIncrement(); - -private: - void verifyRegList(QList list1, QList list2); -}; diff --git a/tests/importexport/tst_mbcregisterfilter.cpp b/tests/importexport/tst_mbcregisterfilter.cpp deleted file mode 100644 index 536f67ce..00000000 --- a/tests/importexport/tst_mbcregisterfilter.cpp +++ /dev/null @@ -1,82 +0,0 @@ - -#include "tst_mbcregisterfilter.h" - -#include "models/mbcregisterfilter.h" -#include "models/mbcregistermodel.h" - -#include - -void TestMbcRegisterFilter::init() -{ - _pMbcRegisterModel = new MbcRegisterModel(); - - _pFilterProxy = new MbcRegisterFilter(); - _pFilterProxy->setSourceModel(_pMbcRegisterModel); - - QList mbcRegisterList; - QStringList tabList = QStringList() << QStringLiteral("tab1") << QStringLiteral("tab2"); - - mbcRegisterList.append(MbcRegisterData(40001, ModbusDataType::Type::UNSIGNED_16, "Test1", 0, true, 0)); - mbcRegisterList.append(MbcRegisterData(40002, ModbusDataType::Type::UNSIGNED_16, "Test2", 0, true, 0)); - mbcRegisterList.append(MbcRegisterData(41002, ModbusDataType::Type::UNSIGNED_16, "Test3", 1, true, 0)); - mbcRegisterList.append(MbcRegisterData(41003, ModbusDataType::Type::UNSIGNED_16, "Test4", 1, true, 0)); - - _pMbcRegisterModel->fill(mbcRegisterList, tabList); -} - -void TestMbcRegisterFilter::cleanup() -{ - delete _pFilterProxy; - delete _pMbcRegisterModel; -} - -void TestMbcRegisterFilter::noFilter() -{ - QVERIFY(_pFilterProxy->filterAcceptsRow(0, QModelIndex())); - QVERIFY(_pFilterProxy->filterAcceptsRow(1, QModelIndex())); - QVERIFY(_pFilterProxy->filterAcceptsRow(2, QModelIndex())); - QVERIFY(_pFilterProxy->filterAcceptsRow(3, QModelIndex())); -} - -void TestMbcRegisterFilter::tabFilter() -{ - _pFilterProxy->setTab("tab1"); - - QVERIFY(_pFilterProxy->filterAcceptsRow(0, QModelIndex())); - QVERIFY(_pFilterProxy->filterAcceptsRow(1, QModelIndex())); - QVERIFY(_pFilterProxy->filterAcceptsRow(2, QModelIndex()) == false); - QVERIFY(_pFilterProxy->filterAcceptsRow(3, QModelIndex()) == false); -} - -void TestMbcRegisterFilter::textFilter() -{ - _pFilterProxy->setTextFilter("Test4"); - - QVERIFY(_pFilterProxy->filterAcceptsRow(0, QModelIndex()) == false); - QVERIFY(_pFilterProxy->filterAcceptsRow(1, QModelIndex()) == false); - QVERIFY(_pFilterProxy->filterAcceptsRow(2, QModelIndex()) == false); - QVERIFY(_pFilterProxy->filterAcceptsRow(3, QModelIndex())); -} - -void TestMbcRegisterFilter::textAddressFilter() -{ - _pFilterProxy->setTextFilter("4100"); - - QVERIFY(_pFilterProxy->filterAcceptsRow(0, QModelIndex()) == false); - QVERIFY(_pFilterProxy->filterAcceptsRow(1, QModelIndex()) == false); - QVERIFY(_pFilterProxy->filterAcceptsRow(2, QModelIndex())); - QVERIFY(_pFilterProxy->filterAcceptsRow(3, QModelIndex())); -} - -void TestMbcRegisterFilter::tabTextFilter() -{ - _pFilterProxy->setTextFilter("2"); - _pFilterProxy->setTab("tab1"); - - QVERIFY(_pFilterProxy->filterAcceptsRow(0, QModelIndex()) == false); - QVERIFY(_pFilterProxy->filterAcceptsRow(1, QModelIndex())); - QVERIFY(_pFilterProxy->filterAcceptsRow(2, QModelIndex()) == false); - QVERIFY(_pFilterProxy->filterAcceptsRow(3, QModelIndex()) == false); -} - -QTEST_GUILESS_MAIN(TestMbcRegisterFilter) diff --git a/tests/importexport/tst_mbcregisterfilter.h b/tests/importexport/tst_mbcregisterfilter.h deleted file mode 100644 index 044b9d4c..00000000 --- a/tests/importexport/tst_mbcregisterfilter.h +++ /dev/null @@ -1,27 +0,0 @@ - -#include - -/* Forward declaration */ -class MbcRegisterModel; -class MbcRegisterFilter; - - -class TestMbcRegisterFilter: public QObject -{ - Q_OBJECT -private slots: - void init(); - void cleanup(); - - void noFilter(); - void tabFilter(); - void textFilter(); - void textAddressFilter(); - void tabTextFilter(); - -private: - MbcRegisterModel* _pMbcRegisterModel; - - MbcRegisterFilter* _pFilterProxy; - -}; diff --git a/tests/models/CMakeLists.txt b/tests/models/CMakeLists.txt index 8196eb31..e2e83315 100644 --- a/tests/models/CMakeLists.txt +++ b/tests/models/CMakeLists.txt @@ -1,5 +1,3 @@ add_xtest(tst_diagnostic) add_xtest(tst_diagnosticmodel) add_xtest(tst_graphdata) -add_xtest_mock(tst_mbcregistermodel) -add_xtest(tst_mbcupdatemodel) \ No newline at end of file diff --git a/tests/models/tst_mbcregistermodel.cpp b/tests/models/tst_mbcregistermodel.cpp deleted file mode 100644 index 6e826c2d..00000000 --- a/tests/models/tst_mbcregistermodel.cpp +++ /dev/null @@ -1,502 +0,0 @@ - -#include "tst_mbcregistermodel.h" - -#include "models/mbcregistermodel.h" - -#include "gmock/gmock.h" -#include -#include -#include - -#include "../mocks/gmockutils.h" - -using ::testing::Return; -using namespace testing; - -static const quint32 cColumnSelected = 0; -static const quint32 cColumnAddress = 1; -static const quint32 cColumnText = 2; -static const quint32 cColumnType = 3; -static const quint32 cColumnTab = 4; -static const quint32 cColumnDecimals = 5; -static const quint32 cColumnCnt = 6; - -void TestMbcRegisterModel::init() -{ - // IMPORTANT: This must be called before any mock object constructors - GMockUtils::InitGoogleMock(); -} - -void TestMbcRegisterModel::cleanup() -{ - -} - -void TestMbcRegisterModel::rowCount() -{ - MbcRegisterModel * pMbcRegisterModel = new MbcRegisterModel(); - - QCOMPARE(pMbcRegisterModel->rowCount(), 0); - - fillModel(pMbcRegisterModel); - - QVERIFY(pMbcRegisterModel->rowCount() != 0); - - /* tested thoroughly in fill test case */ -} - - -void TestMbcRegisterModel::columnCount() -{ - MbcRegisterModel * pMbcRegisterModel = new MbcRegisterModel(); - - QCOMPARE(pMbcRegisterModel->columnCount(QModelIndex()), cColumnCnt); -} - -void TestMbcRegisterModel::headerData() -{ - MbcRegisterModel * pMbcRegisterModel = new MbcRegisterModel(); - - QCOMPARE(pMbcRegisterModel->headerData(cColumnSelected, Qt::Horizontal, Qt::DisplayRole).toString(), QString("")); - QCOMPARE(pMbcRegisterModel->headerData(cColumnAddress, Qt::Horizontal, Qt::DisplayRole).toString(), QString("Address")); - QCOMPARE(pMbcRegisterModel->headerData(cColumnText, Qt::Horizontal, Qt::DisplayRole).toString(), QString("Text")); - QCOMPARE(pMbcRegisterModel->headerData(cColumnType, Qt::Horizontal, Qt::DisplayRole).toString(), QString("Type")); - QCOMPARE(pMbcRegisterModel->headerData(cColumnTab, Qt::Horizontal, Qt::DisplayRole).toString(), QString("Tab")); - QCOMPARE(pMbcRegisterModel->headerData(cColumnDecimals, Qt::Horizontal, Qt::DisplayRole).toString(), QString("Decimals")); - - QCOMPARE(pMbcRegisterModel->headerData(cColumnCnt, Qt::Horizontal, Qt::DisplayRole), QVariant()); -} - -void TestMbcRegisterModel::flagsEnabled() -{ - MbcRegisterModel * pMbcRegisterModel = new MbcRegisterModel(); - - fillModel(pMbcRegisterModel); - - QModelIndex modelIdx = pMbcRegisterModel->index(0,0); - Qt::ItemFlags enabledFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; - - QCOMPARE(pMbcRegisterModel->flags(QModelIndex()), Qt::NoItemFlags); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(0, cColumnSelected)), Qt::ItemIsUserCheckable | enabledFlags); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(0, cColumnType)), enabledFlags); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(0, cColumnAddress)), enabledFlags); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(0, cColumnText)), enabledFlags); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(0, cColumnTab)), enabledFlags); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(0, cColumnDecimals)), enabledFlags); -} - -void TestMbcRegisterModel::flagsDisabled() -{ - MbcRegisterModel * pMbcRegisterModel = new MbcRegisterModel(); - - QList mbcRegisterList = QList() - << MbcRegisterData(40001, ModbusDataType::Type::UNSIGNED_16, "Test1", 0, false, 0) /* Not readable */ - << MbcRegisterData(40002, ModbusDataType::Type::UNSIGNED_16, "Test2", 0, true, 0); - QStringList tabList = QStringList() << QString("Tab0"); - - pMbcRegisterModel->fill(mbcRegisterList, tabList); - - QModelIndex modelIdx = pMbcRegisterModel->index(0,0); - Qt::ItemFlags disabledFlags = Qt::NoItemFlags; - - QCOMPARE(pMbcRegisterModel->flags(QModelIndex()), Qt::NoItemFlags); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(0, cColumnSelected)), Qt::ItemIsUserCheckable | disabledFlags); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(0, cColumnType)), disabledFlags); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(0, cColumnAddress)), disabledFlags); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(0, cColumnText)), disabledFlags); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(0, cColumnTab)), disabledFlags); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(0, cColumnDecimals)), disabledFlags); - -} - -void TestMbcRegisterModel::setData() -{ - MbcRegisterModel * pMbcRegisterModel = new MbcRegisterModel(); - fillModel(pMbcRegisterModel); - - QSignalSpy spy(pMbcRegisterModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector))); - - /* Check failures */ - QCOMPARE(pMbcRegisterModel->setData(QModelIndex(), QVariant(), Qt::CheckStateRole), false); - QCOMPARE(spy.count(), 0); - - // At least 2 rows required for this test - QVERIFY(pMbcRegisterModel->rowCount() >= 2); - - QModelIndex modelIdxFirstRow = pMbcRegisterModel->index(0, cColumnSelected); - QModelIndex modelIdxSecondRow = pMbcRegisterModel->index(1, cColumnSelected); - - QCOMPARE(pMbcRegisterModel->data(modelIdxFirstRow, Qt::CheckStateRole), Qt::Unchecked); - QCOMPARE(pMbcRegisterModel->data(modelIdxSecondRow, Qt::CheckStateRole), Qt::Unchecked); - - QCOMPARE(pMbcRegisterModel->setData(modelIdxFirstRow, QVariant(Qt::Checked), Qt::CheckStateRole), true); - QCOMPARE(spy.count(), 1); - QList arguments = spy.takeFirst(); - QCOMPARE(qvariant_cast(arguments.at(0)).row(), 0); /* First argument (start index) */ - QCOMPARE(qvariant_cast(arguments.at(1)).row(), 1); /* Second argument (end index) */ - - QCOMPARE(pMbcRegisterModel->data(modelIdxFirstRow, Qt::CheckStateRole), Qt::Checked); - QCOMPARE(pMbcRegisterModel->data(modelIdxSecondRow, Qt::CheckStateRole), Qt::Unchecked); -} - -void TestMbcRegisterModel::fillData() -{ - MbcRegisterModel * pMbcRegisterModel = new MbcRegisterModel(); - QSignalSpy resetSignalSpy(pMbcRegisterModel, SIGNAL(modelReset())); - - /*-- Test fill and expected signals --*/ - - QCOMPARE(pMbcRegisterModel->rowCount(), 0); - - fillModel(pMbcRegisterModel); - - QVERIFY(pMbcRegisterModel->rowCount() != 0); - QCOMPARE(resetSignalSpy.count(), 0); - - QList mbcRegisterList = QList() - << MbcRegisterData(40001, ModbusDataType::Type::UNSIGNED_16, "Test1", 0, true, 0) - << MbcRegisterData(40002, ModbusDataType::Type::SIGNED_32, "Test2", 1, true, 0) - << MbcRegisterData(40004, ModbusDataType::Type::UNSIGNED_16, "Test4", 1, true, 0) - << MbcRegisterData(40005, ModbusDataType::Type::SIGNED_16, "Test5", 0, true, 2) - << MbcRegisterData(40010, ModbusDataType::Type::UNSIGNED_16, "Test10", 2, true, 3) - << MbcRegisterData(40011, ModbusDataType::Type::SIGNED_16, "Test11", 2, false, 0) // Disabled: not readable - << MbcRegisterData(40002, ModbusDataType::Type::SIGNED_16, "Test6", 0, true, 0) - << MbcRegisterData(40004, ModbusDataType::Type::SIGNED_16, "Test13", 0, true, 0); - - QStringList tabList = QStringList() << QString("Tab0") << QString("Tab1") << QString("Tab2"); - QSignalSpy rowsInsertedSpy(pMbcRegisterModel, SIGNAL(rowsInserted(const QModelIndex, int, int))); - - pMbcRegisterModel->fill(mbcRegisterList, tabList); - - QCOMPARE(pMbcRegisterModel->rowCount(), mbcRegisterList.size()); - QCOMPARE(resetSignalSpy.count(), 1); - QCOMPARE(rowsInsertedSpy.count(), 1); - - QList arguments = rowsInsertedSpy.takeFirst(); - QCOMPARE(arguments.at(1), 0); - QCOMPARE(arguments.at(2), mbcRegisterList.size() - 1); - - /*-- Test result of fill with data function --*/ - - QModelIndex modelIdx = pMbcRegisterModel->index(0, 0); - - const Qt::ItemFlags enabledFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; - const Qt::ItemFlags disabledFlags = Qt::NoItemFlags; - - int row = 0; - - row = 0; - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(row, cColumnSelected), Qt::ToolTipRole).toString(), ""); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(row, cColumnAddress)), enabledFlags); // flags - - row = 1; - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(row, cColumnSelected), Qt::ToolTipRole).toString(), ""); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(row, cColumnAddress)), enabledFlags); // flags - - row = 2; - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(row, cColumnSelected), Qt::ToolTipRole).toString(), ""); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(row, cColumnAddress)), enabledFlags); // flags - - row = 3; - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(row, cColumnSelected), Qt::ToolTipRole).toString(), ""); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(row, cColumnAddress)), enabledFlags); // flags - - row = 4; - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(row, cColumnSelected), Qt::ToolTipRole).toString(), ""); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(row, cColumnAddress)), enabledFlags); // flags - - row = 5; - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(row, cColumnSelected), Qt::ToolTipRole).toString(), "Not readable"); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(row, cColumnAddress)), disabledFlags); // flags - - row = 6; - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(row, cColumnSelected), Qt::ToolTipRole).toString(), ""); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(row, cColumnAddress)), enabledFlags); // flags - - row = 7; - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(row, cColumnSelected), Qt::ToolTipRole).toString(), ""); - QCOMPARE(pMbcRegisterModel->flags(modelIdx.sibling(row, cColumnAddress)), enabledFlags); // flags - - - /* Loop when possible */ - for (int rowIdx = 0; rowIdx < mbcRegisterList.size(); rowIdx++) - { - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(rowIdx, cColumnSelected), Qt::CheckStateRole), Qt::Unchecked); - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(rowIdx, cColumnAddress), Qt::DisplayRole), mbcRegisterList[rowIdx].registerAddress()); - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(rowIdx, cColumnText), Qt::DisplayRole), mbcRegisterList[rowIdx].name()); - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(rowIdx, cColumnTab), Qt::DisplayRole), tabList[mbcRegisterList[rowIdx].tabIdx()]); - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(rowIdx, cColumnDecimals), Qt::DisplayRole), mbcRegisterList[rowIdx].decimals()); - - auto type = ModbusDataType::typeString(mbcRegisterList[rowIdx].type()); - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(rowIdx, cColumnType), Qt::DisplayRole), type); - } -} - -void TestMbcRegisterModel::reset() -{ - MbcRegisterModel * pMbcRegisterModel = new MbcRegisterModel(); - QSignalSpy resetSignalSpy(pMbcRegisterModel, SIGNAL(modelReset())); - - fillModel(pMbcRegisterModel); - QVERIFY(pMbcRegisterModel->rowCount() != 0); - - pMbcRegisterModel->reset(); - - QCOMPARE(pMbcRegisterModel->rowCount(), 0); - QCOMPARE(resetSignalSpy.count(), 1); -} - -void TestMbcRegisterModel::selectedRegisterListAndCount() -{ - MbcRegisterModel * pMbcRegisterModel = new MbcRegisterModel(); - - QList mbcRegisterList = QList() - << MbcRegisterData(40001, ModbusDataType::Type::UNSIGNED_16, "Test1", 0, true, 0) - << MbcRegisterData(40002, ModbusDataType::Type::UNSIGNED_16, "Test2", 0, true, 0); - QStringList tabList = QStringList() << QString("Tab0"); - - pMbcRegisterModel->fill(mbcRegisterList, tabList); - - // At least 2 rows required for this test - QVERIFY(pMbcRegisterModel->rowCount() >= 2); - - QList graphListRef; - GraphData graphData; - graphData.setActive(true); - graphData.setLabel("Test1"); - graphData.setExpression(QStringLiteral("${40001}")); - graphListRef.append(graphData); - - graphData.setActive(true); - graphData.setLabel("Test2"); - graphData.setExpression(QStringLiteral("${40002}")); - graphListRef.append(graphData); - - QList graphList; - QModelIndex modelIdx; - - // Start all unchecked - QCOMPARE(pMbcRegisterModel->selectedRegisterCount(), 0); - - // Check first - modelIdx = pMbcRegisterModel->index(0, cColumnSelected); - QCOMPARE(pMbcRegisterModel->setData(modelIdx, QVariant(Qt::Checked), Qt::CheckStateRole), true); - - QCOMPARE(pMbcRegisterModel->selectedRegisterCount(), 1); - QCOMPARE(pMbcRegisterModel->selectedRegisterCount(), pMbcRegisterModel->selectedRegisterList().size()); - - graphList = pMbcRegisterModel->selectedRegisterList(); - QCOMPARE(graphList[0].isActive(), graphListRef[0].isActive()); - QCOMPARE(graphList[0].label(), graphListRef[0].label()); - QCOMPARE(graphList[0].expression(), graphListRef[0].expression()); - - // Check second - modelIdx = pMbcRegisterModel->index(1, cColumnSelected); - QCOMPARE(pMbcRegisterModel->setData(modelIdx, QVariant(Qt::Checked), Qt::CheckStateRole), true); - - QCOMPARE(pMbcRegisterModel->selectedRegisterCount(), 2); - QCOMPARE(pMbcRegisterModel->selectedRegisterCount(), pMbcRegisterModel->selectedRegisterList().size()); - - graphList = pMbcRegisterModel->selectedRegisterList(); - QCOMPARE(graphList[0].isActive(), graphListRef[0].isActive()); - QCOMPARE(graphList[0].label(), graphListRef[0].label()); - QCOMPARE(graphList[0].expression(), graphListRef[0].expression()); - - QCOMPARE(graphList[1].isActive(), graphListRef[1].isActive()); - QCOMPARE(graphList[1].label(), graphListRef[1].label()); - QCOMPARE(graphList[1].expression(), graphListRef[1].expression()); - - // Uncheck first - modelIdx = pMbcRegisterModel->index(0, cColumnSelected); - QCOMPARE(pMbcRegisterModel->setData(modelIdx, QVariant(Qt::Unchecked), Qt::CheckStateRole), true); - - QCOMPARE(pMbcRegisterModel->selectedRegisterCount(), 1); - QCOMPARE(pMbcRegisterModel->selectedRegisterCount(), pMbcRegisterModel->selectedRegisterList().size()); - - graphList = pMbcRegisterModel->selectedRegisterList(); - QCOMPARE(graphList[0].isActive(), graphListRef[1].isActive()); - QCOMPARE(graphList[0].label(), graphListRef[1].label()); - QCOMPARE(graphList[0].expression(), graphListRef[1].expression()); - - // Uncheck second - modelIdx = pMbcRegisterModel->index(1, cColumnSelected); - QCOMPARE(pMbcRegisterModel->setData(modelIdx, QVariant(Qt::Unchecked), Qt::CheckStateRole), true); - - QCOMPARE(pMbcRegisterModel->selectedRegisterCount(), 0); - QCOMPARE(pMbcRegisterModel->selectedRegisterCount(), pMbcRegisterModel->selectedRegisterList().size()); -} - -void TestMbcRegisterModel::selectedRegisterListAndCount32() -{ - MbcRegisterModel * pMbcRegisterModel = new MbcRegisterModel(); - - QList mbcRegisterList = QList() - << MbcRegisterData(40001, ModbusDataType::Type::UNSIGNED_32, "Test1", 0, true, 0); - QStringList tabList = QStringList() << QString("Tab0"); - - pMbcRegisterModel->fill(mbcRegisterList, tabList); - - QVERIFY(pMbcRegisterModel->rowCount() >= 1); - - QList graphList; - QModelIndex modelIdx; - - modelIdx = pMbcRegisterModel->index(0, cColumnSelected); - QCOMPARE(pMbcRegisterModel->setData(modelIdx, QVariant(Qt::Checked), Qt::CheckStateRole), true); - - QCOMPARE(pMbcRegisterModel->selectedRegisterCount(), 1); - QCOMPARE(pMbcRegisterModel->selectedRegisterCount(), pMbcRegisterModel->selectedRegisterList().size()); - - graphList = pMbcRegisterModel->selectedRegisterList(); - QCOMPARE(graphList[0].isActive(), true); - QCOMPARE(graphList[0].label(), "Test1"); - QCOMPARE(graphList[0].expression(), "${40001:32b}"); -} - -void TestMbcRegisterModel::selectedRegisterListDecimals() -{ - MbcRegisterModel * pMbcRegisterModel = new MbcRegisterModel(); - - QList mbcRegisterList = QList() - << MbcRegisterData(40001, ModbusDataType::Type::UNSIGNED_16, "Test1", 0, true, 0) - << MbcRegisterData(40002, ModbusDataType::Type::UNSIGNED_16, "Test2", 0, true, 1) - << MbcRegisterData(40003, ModbusDataType::Type::UNSIGNED_16, "Test3", 0, true, 2); - QStringList tabList = QStringList() << QString("Tab0"); - - pMbcRegisterModel->fill(mbcRegisterList, tabList); - - QVERIFY(pMbcRegisterModel->rowCount() >= 3); - - QList graphList; - QModelIndex modelIdx; - - modelIdx = pMbcRegisterModel->index(0, cColumnSelected); - QCOMPARE(pMbcRegisterModel->setData(modelIdx, QVariant(Qt::Checked), Qt::CheckStateRole), true); - - modelIdx = pMbcRegisterModel->index(1, cColumnSelected); - QCOMPARE(pMbcRegisterModel->setData(modelIdx, QVariant(Qt::Checked), Qt::CheckStateRole), true); - - modelIdx = pMbcRegisterModel->index(2, cColumnSelected); - QCOMPARE(pMbcRegisterModel->setData(modelIdx, QVariant(Qt::Checked), Qt::CheckStateRole), true); - - QCOMPARE(pMbcRegisterModel->selectedRegisterCount(), 3); - QCOMPARE(pMbcRegisterModel->selectedRegisterCount(), pMbcRegisterModel->selectedRegisterList().size()); - - graphList = pMbcRegisterModel->selectedRegisterList(); - QCOMPARE(graphList[0].isActive(), true); - QCOMPARE(graphList[0].expression(), "${40001}"); - - graphList = pMbcRegisterModel->selectedRegisterList(); - QCOMPARE(graphList[1].isActive(), true); - QCOMPARE(graphList[1].expression(), "${40002}/10"); - - graphList = pMbcRegisterModel->selectedRegisterList(); - QCOMPARE(graphList[2].isActive(), true); - QCOMPARE(graphList[2].expression(), "${40003}/100"); -} - -void TestMbcRegisterModel::selectAllWhenUnchecked() -{ - MbcRegisterModel* pMbcRegisterModel = new MbcRegisterModel(); - fillModel(pMbcRegisterModel); - - QVERIFY(pMbcRegisterModel->rowCount() == 2); - - QList indexList; - for (int idx = 0; idx < pMbcRegisterModel->rowCount(); idx++) - { - indexList.append(pMbcRegisterModel->index(idx, MbcRegisterModel::cColumnSelected)); - } - pMbcRegisterModel->setSelectionstate(indexList, Qt::Checked); - - QCOMPARE(pMbcRegisterModel->selectedRegisterCount(), 2); - - QModelIndex modelIdx = pMbcRegisterModel->index(0, 0); - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(0, cColumnSelected), Qt::CheckStateRole), Qt::Checked); - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(1, cColumnSelected), Qt::CheckStateRole), Qt::Checked); -} - -void TestMbcRegisterModel::selectAllWhenChecked() -{ - MbcRegisterModel* pMbcRegisterModel = new MbcRegisterModel(); - fillModel(pMbcRegisterModel); - QVERIFY(pMbcRegisterModel->rowCount() == 2); - - QModelIndex modelIdx = pMbcRegisterModel->index(0, 0); - pMbcRegisterModel->setData(modelIdx.sibling(0, cColumnSelected), QVariant(Qt::Checked), Qt::CheckStateRole); - pMbcRegisterModel->setData(modelIdx.sibling(1, cColumnSelected), QVariant(Qt::Checked), Qt::CheckStateRole); - QCOMPARE(pMbcRegisterModel->selectedRegisterCount(), 2); - - QList indexList; - for (int idx = 0; idx < pMbcRegisterModel->rowCount(); idx++) - { - indexList.append(pMbcRegisterModel->index(idx, MbcRegisterModel::cColumnSelected)); - } - pMbcRegisterModel->setSelectionstate(indexList, Qt::Unchecked); - - QCOMPARE(pMbcRegisterModel->selectedRegisterCount(), 0); - - modelIdx = pMbcRegisterModel->index(0, 0); - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(0, cColumnSelected), Qt::CheckStateRole), Qt::Unchecked); - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(1, cColumnSelected), Qt::CheckStateRole), Qt::Unchecked); -} - -void TestMbcRegisterModel::selectAllWhenMixedChecked() -{ - MbcRegisterModel* pMbcRegisterModel = new MbcRegisterModel(); - fillModel(pMbcRegisterModel); - QVERIFY(pMbcRegisterModel->rowCount() == 2); - - QModelIndex modelIdx = pMbcRegisterModel->index(0, 0); - pMbcRegisterModel->setData(modelIdx.sibling(0, cColumnSelected), QVariant(Qt::Unchecked), Qt::CheckStateRole); - pMbcRegisterModel->setData(modelIdx.sibling(1, cColumnSelected), QVariant(Qt::Checked), Qt::CheckStateRole); - - QList indexList; - for (int idx = 0; idx < pMbcRegisterModel->rowCount(); idx++) - { - indexList.append(pMbcRegisterModel->index(idx, MbcRegisterModel::cColumnSelected)); - } - pMbcRegisterModel->setSelectionstate(indexList, Qt::Checked); - - QCOMPARE(pMbcRegisterModel->selectedRegisterCount(), 2); - - modelIdx = pMbcRegisterModel->index(0, 0); - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(0, cColumnSelected), Qt::CheckStateRole), Qt::Checked); - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(1, cColumnSelected), Qt::CheckStateRole), Qt::Checked); -} - -void TestMbcRegisterModel::selectAllSkipNonReadable() -{ - MbcRegisterModel* pMbcRegisterModel = new MbcRegisterModel(); - QList mbcRegisterList = - QList() << MbcRegisterData(40001, ModbusDataType::Type::UNSIGNED_16, "Test1", 0, true, 0) - << MbcRegisterData(40002, ModbusDataType::Type::UNSIGNED_16, "Test2", 0, false, 0); - QStringList tabList = QStringList() << QString("Tab0"); - - pMbcRegisterModel->fill(mbcRegisterList, tabList); - - QList indexList; - for (int idx = 0; idx < pMbcRegisterModel->rowCount(); idx++) - { - indexList.append(pMbcRegisterModel->index(idx, MbcRegisterModel::cColumnSelected)); - } - pMbcRegisterModel->setSelectionstate(indexList, Qt::Checked); - - QCOMPARE(pMbcRegisterModel->selectedRegisterCount(), 1); - - QModelIndex modelIdx = pMbcRegisterModel->index(0, 0); - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(0, cColumnSelected), Qt::CheckStateRole), Qt::Checked); - QCOMPARE(pMbcRegisterModel->data(modelIdx.sibling(1, cColumnSelected), Qt::CheckStateRole), Qt::Unchecked); -} - -void TestMbcRegisterModel::fillModel(MbcRegisterModel * pMbcRegisterModel) -{ - QList mbcRegisterList = QList() - << MbcRegisterData(40001, ModbusDataType::Type::UNSIGNED_16, "Test1", 0, true, 0) - << MbcRegisterData(40002, ModbusDataType::Type::UNSIGNED_16, "Test2", 0, true, 0); - QStringList tabList = QStringList() << QString("Tab0"); - - pMbcRegisterModel->fill(mbcRegisterList, tabList); -} - -QTEST_GUILESS_MAIN(TestMbcRegisterModel) diff --git a/tests/models/tst_mbcregistermodel.h b/tests/models/tst_mbcregistermodel.h deleted file mode 100644 index de48f6c6..00000000 --- a/tests/models/tst_mbcregistermodel.h +++ /dev/null @@ -1,40 +0,0 @@ - -#ifndef TEST_MBCREGISTERMODEL_H__ -#define TEST_MBCREGISTERMODEL_H__ - -#include - -/* Forward declaration */ -class MbcRegisterModel; - -class TestMbcRegisterModel: public QObject -{ - Q_OBJECT -private slots: - void init(); - void cleanup(); - - void rowCount(); - void columnCount(); - void headerData(); - void flagsEnabled(); - void flagsDisabled(); - void setData(); - void fillData(); - void reset(); - void selectedRegisterListAndCount(); - void selectedRegisterListAndCount32(); - void selectedRegisterListDecimals(); - - void selectAllWhenUnchecked(); - void selectAllWhenChecked(); - void selectAllWhenMixedChecked(); - void selectAllSkipNonReadable(); - -private: - - void fillModel(MbcRegisterModel * pMbcRegisterModel); - -}; - -#endif /* TEST_MBCREGISTERMODEL_H__ */ diff --git a/tests/models/tst_mbcupdatemodel.cpp b/tests/models/tst_mbcupdatemodel.cpp deleted file mode 100644 index 3a9a1df5..00000000 --- a/tests/models/tst_mbcupdatemodel.cpp +++ /dev/null @@ -1,148 +0,0 @@ - -#include "tst_mbcupdatemodel.h" - -#include "models/graphdatamodel.h" -#include "models/mbcupdatemodel.h" -#include "models/settingsmodel.h" - -#include -#include - -void TestMbcUpdateModel::init() -{ - _pSettingsModel = new SettingsModel; - _pGraphDataModel = new GraphDataModel(_pSettingsModel); -} - -void TestMbcUpdateModel::cleanup() -{ - delete _pGraphDataModel; - delete _pSettingsModel; -} - -void TestMbcUpdateModel::rowCount() -{ - MbcUpdateModel* pMbcUpdateModel = new MbcUpdateModel(_pGraphDataModel); - - QCOMPARE(pMbcUpdateModel->rowCount(), 0); - - _pGraphDataModel->add(); - - QVERIFY(pMbcUpdateModel->rowCount() == 1); -} - -void TestMbcUpdateModel::noUpdate() -{ - _pGraphDataModel->add(); - _pGraphDataModel->setExpression(0, "${40001}"); - _pGraphDataModel->setLabel(0, "Register 40001"); - - MbcUpdateModel* pMbcUpdateModel = new MbcUpdateModel(_pGraphDataModel); - - QList mbcRegisterList(1); - mbcRegisterList[0].setRegisterAddress(40001); - mbcRegisterList[0].setName("Register 40001"); - - pMbcUpdateModel->setMbcRegisters(mbcRegisterList); - - QModelIndex modelIdx = pMbcUpdateModel->index(0, 0); - QString actExpression = - pMbcUpdateModel->data(modelIdx.sibling(0, MbcUpdateModel::cColumnUpdateExpression), Qt::DisplayRole).toString(); - QVERIFY(actExpression.isEmpty()); - - QString actText = - pMbcUpdateModel->data(modelIdx.sibling(0, MbcUpdateModel::cColumnUpdateText), Qt::DisplayRole).toString(); - QVERIFY(actText.isEmpty()); - - QCOMPARE(pMbcUpdateModel->data(modelIdx.sibling(0, 0), Qt::ToolTipRole).toString(), ""); - - Qt::ItemFlags expFlags = Qt::NoItemFlags; - QCOMPARE(pMbcUpdateModel->flags(modelIdx.sibling(0, 0)), expFlags); -} - -void TestMbcUpdateModel::tooMuchDifference() -{ - _pGraphDataModel->add(); - _pGraphDataModel->setExpression(0, "${40001}"); - _pGraphDataModel->setLabel(0, "Register 40001"); - - MbcUpdateModel* pMbcUpdateModel = new MbcUpdateModel(_pGraphDataModel); - - QList mbcRegisterList(1); - mbcRegisterList[0].setRegisterAddress(40002); - mbcRegisterList[0].setName("Register 40002"); - - pMbcUpdateModel->setMbcRegisters(mbcRegisterList); - - QModelIndex modelIdx = pMbcUpdateModel->index(0, 0); - QString actExpression = - pMbcUpdateModel->data(modelIdx.sibling(0, MbcUpdateModel::cColumnUpdateExpression), Qt::DisplayRole).toString(); - QVERIFY(actExpression.isEmpty()); - - QString actText = - pMbcUpdateModel->data(modelIdx.sibling(0, MbcUpdateModel::cColumnUpdateText), Qt::DisplayRole).toString(); - QVERIFY(actText.isEmpty()); - - QCOMPARE(pMbcUpdateModel->data(modelIdx.sibling(0, 0), Qt::ToolTipRole).toString(), ""); -} - -void TestMbcUpdateModel::updateText() -{ - _pGraphDataModel->add(); - _pGraphDataModel->setExpression(0, "${40001}"); - _pGraphDataModel->setLabel(0, "Register 40001"); - - MbcUpdateModel* pMbcUpdateModel = new MbcUpdateModel(_pGraphDataModel); - - QList mbcRegisterList(1); - mbcRegisterList[0].setRegisterAddress(40001); - mbcRegisterList[0].setName("Register"); - - pMbcUpdateModel->setMbcRegisters(mbcRegisterList); - - QModelIndex modelIdx = pMbcUpdateModel->index(0, 0); - QString actExpression = - pMbcUpdateModel->data(modelIdx.sibling(0, MbcUpdateModel::cColumnUpdateExpression), Qt::DisplayRole).toString(); - QVERIFY(actExpression.isEmpty()); - - QString actText = - pMbcUpdateModel->data(modelIdx.sibling(0, MbcUpdateModel::cColumnUpdateText), Qt::DisplayRole).toString(); - QCOMPARE(actText, mbcRegisterList[0].name()); - - QCOMPARE(pMbcUpdateModel->data(modelIdx.sibling(0, 0), Qt::ToolTipRole).toString(), "Update of text detected"); - - Qt::ItemFlags expFlags = Qt::ItemIsEnabled; - QCOMPARE(pMbcUpdateModel->flags(modelIdx.sibling(0, 0)), expFlags); -} - -void TestMbcUpdateModel::updateExpression() -{ - _pGraphDataModel->add(); - _pGraphDataModel->setExpression(0, "${40001}"); - _pGraphDataModel->setLabel(0, "Register 40001"); - - MbcUpdateModel* pMbcUpdateModel = new MbcUpdateModel(_pGraphDataModel); - - QList mbcRegisterList(1); - mbcRegisterList[0].setRegisterAddress(40002); - mbcRegisterList[0].setName("Register 40001"); - - pMbcUpdateModel->setMbcRegisters(mbcRegisterList); - - QModelIndex modelIdx = pMbcUpdateModel->index(0, 0); - QString actExpression = - pMbcUpdateModel->data(modelIdx.sibling(0, MbcUpdateModel::cColumnUpdateExpression), Qt::DisplayRole).toString(); - QCOMPARE(actExpression, mbcRegisterList[0].toExpression()); - - QString actText = - pMbcUpdateModel->data(modelIdx.sibling(0, MbcUpdateModel::cColumnUpdateText), Qt::DisplayRole).toString(); - QVERIFY(actText.isEmpty()); - - QCOMPARE(pMbcUpdateModel->data(modelIdx.sibling(0, 0), Qt::ToolTipRole).toString(), - "Update of expression detected"); - - Qt::ItemFlags expFlags = Qt::ItemIsEnabled; - QCOMPARE(pMbcUpdateModel->flags(modelIdx.sibling(0, 0)), expFlags); -} - -QTEST_GUILESS_MAIN(TestMbcUpdateModel) diff --git a/tests/models/tst_mbcupdatemodel.h b/tests/models/tst_mbcupdatemodel.h deleted file mode 100644 index 4420a330..00000000 --- a/tests/models/tst_mbcupdatemodel.h +++ /dev/null @@ -1,29 +0,0 @@ - -#ifndef TEST_MBCUPDATEMODEL_H__ -#define TEST_MBCUPDATEMODEL_H__ - -#include - -/* Forward declaration */ -class GraphDataModel; -class SettingsModel; - -class TestMbcUpdateModel : public QObject -{ - Q_OBJECT -private slots: - void init(); - void cleanup(); - - void rowCount(); - void noUpdate(); - void tooMuchDifference(); - void updateText(); - void updateExpression(); - -private: - SettingsModel* _pSettingsModel; - GraphDataModel* _pGraphDataModel; -}; - -#endif /* TEST_MBCUPDATEMODEL_H__ */