Add timeout and number of retries to the modbus RTU master and propagate the settings to the API
This commit is contained in:
parent
16382eb620
commit
11f62d0555
@ -53,6 +53,9 @@ ModbusRtuHandler::ModbusRtuHandler(ModbusRtuManager *modbusRtuManager, QObject *
|
||||
modbusRtuMasterDescription.insert("parity", enumRef<SerialPort::SerialPortParity>());
|
||||
modbusRtuMasterDescription.insert("stopBits", enumRef<SerialPort::SerialPortStopBits>());
|
||||
modbusRtuMasterDescription.insert("dataBits", enumRef<SerialPort::SerialPortDataBits>());
|
||||
modbusRtuMasterDescription.insert("numberOfRetries", enumValueName(Uint));
|
||||
modbusRtuMasterDescription.insert("timeout", enumValueName(Uint));
|
||||
|
||||
registerObject("ModbusRtuMaster", modbusRtuMasterDescription);
|
||||
|
||||
QVariantMap params, returns;
|
||||
@ -91,24 +94,26 @@ ModbusRtuHandler::ModbusRtuHandler(ModbusRtuManager *modbusRtuManager, QObject *
|
||||
|
||||
// ModbusRtuMasterRemoved notification
|
||||
params.clear();
|
||||
description = "Emitted whenever a new modbus RTU master has been removed from the system.";
|
||||
description = "Emitted whenever a modbus RTU master has been removed from the system.";
|
||||
params.insert("modbusUuid", enumValueName(Uuid));
|
||||
registerNotification("ModbusRtuMasterRemoved", description, params);
|
||||
|
||||
// ModbusRtuMasterChanged notification
|
||||
params.clear();
|
||||
description = "Emitted whenever a new modbus RTU master has been changed to the system.";
|
||||
description = "Emitted whenever a modbus RTU master has been changed in the system.";
|
||||
params.insert("modbusRtuMaster", objectRef("ModbusRtuMaster"));
|
||||
registerNotification("ModbusRtuMasterChanged", description, params);
|
||||
|
||||
// AddModbusRtuMaster
|
||||
params.clear(); returns.clear();
|
||||
description = "Add a new modbus RTU master with the given configuration.";
|
||||
description = "Add a new modbus RTU master with the given configuration. The timeout value is in milli seconds and the minimum value is 10 ms.";
|
||||
params.insert("serialPort", enumValueName(String));
|
||||
params.insert("baudrate", enumValueName(Uint));
|
||||
params.insert("parity", enumRef<SerialPort::SerialPortParity>());
|
||||
params.insert("dataBits", enumRef<SerialPort::SerialPortDataBits>());
|
||||
params.insert("stopBits", enumRef<SerialPort::SerialPortStopBits>());
|
||||
params.insert("numberOfRetries", enumValueName(Uint));
|
||||
params.insert("timeout", enumValueName(Uint));
|
||||
returns.insert("o:modbusUuid", enumValueName(Uuid));
|
||||
returns.insert("modbusError", enumRef<ModbusRtuManager::ModbusRtuError>());
|
||||
registerMethod("AddModbusRtuMaster", description, params, returns);
|
||||
@ -129,6 +134,8 @@ ModbusRtuHandler::ModbusRtuHandler(ModbusRtuManager *modbusRtuManager, QObject *
|
||||
params.insert("parity", enumRef<SerialPort::SerialPortParity>());
|
||||
params.insert("dataBits", enumRef<SerialPort::SerialPortDataBits>());
|
||||
params.insert("stopBits", enumRef<SerialPort::SerialPortStopBits>());
|
||||
params.insert("numberOfRetries", enumValueName(Uint));
|
||||
params.insert("timeout", enumValueName(Uint));
|
||||
returns.insert("modbusError", enumRef<ModbusRtuManager::ModbusRtuError>());
|
||||
registerMethod("ReconfigureModbusRtuMaster", description, params, returns);
|
||||
|
||||
@ -211,10 +218,16 @@ JsonReply *ModbusRtuHandler::AddModbusRtuMaster(const QVariantMap ¶ms)
|
||||
QSerialPort::Parity parity = static_cast<QSerialPort::Parity>(enumNameToValue<SerialPort::SerialPortParity>(params.value("parity").toString()));
|
||||
QSerialPort::StopBits stopBits = static_cast<QSerialPort::StopBits>(enumNameToValue<SerialPort::SerialPortStopBits>(params.value("stopBits").toString()));
|
||||
QSerialPort::DataBits dataBits = static_cast<QSerialPort::DataBits>(enumNameToValue<SerialPort::SerialPortDataBits>(params.value("dataBits").toString()));
|
||||
|
||||
QPair<ModbusRtuManager::ModbusRtuError, QUuid> result = m_modbusRtuManager->addNewModbusRtuMaster(serialPort, baudrate, parity, dataBits, stopBits);
|
||||
uint numberOfRetries = params.value("numberOfRetries").toUInt();
|
||||
uint timeout = params.value("timeout").toUInt();
|
||||
|
||||
QVariantMap returnMap;
|
||||
if (timeout < 10) {
|
||||
returnMap.insert("modbusError", enumValueName<ModbusRtuManager::ModbusRtuError>(ModbusRtuManager::ModbusRtuErrorInvalidTimeoutValue));
|
||||
return createReply(returnMap);
|
||||
}
|
||||
|
||||
QPair<ModbusRtuManager::ModbusRtuError, QUuid> result = m_modbusRtuManager->addNewModbusRtuMaster(serialPort, baudrate, parity, dataBits, stopBits, numberOfRetries, timeout);
|
||||
returnMap.insert("modbusError", enumValueName<ModbusRtuManager::ModbusRtuError>(result.first));
|
||||
if (result.first == ModbusRtuManager::ModbusRtuErrorNoError) {
|
||||
returnMap.insert("modbusUuid", result.second);
|
||||
@ -240,9 +253,16 @@ JsonReply *ModbusRtuHandler::ReconfigureModbusRtuMaster(const QVariantMap ¶m
|
||||
QSerialPort::Parity parity = static_cast<QSerialPort::Parity>(enumNameToValue<SerialPort::SerialPortParity>(params.value("parity").toString()));
|
||||
QSerialPort::StopBits stopBits = static_cast<QSerialPort::StopBits>(enumNameToValue<SerialPort::SerialPortStopBits>(params.value("stopBits").toString()));
|
||||
QSerialPort::DataBits dataBits = static_cast<QSerialPort::DataBits>(enumNameToValue<SerialPort::SerialPortDataBits>(params.value("dataBits").toString()));
|
||||
uint numberOfRetries = params.value("numberOfRetries").toUInt();
|
||||
uint timeout = params.value("timeout").toUInt();
|
||||
|
||||
ModbusRtuManager::ModbusRtuError result = m_modbusRtuManager->reconfigureModbusRtuMaster(modbusUuid, serialPort, baudrate, parity, dataBits, stopBits);
|
||||
QVariantMap returnMap;
|
||||
if (timeout < 10) {
|
||||
returnMap.insert("modbusError", enumValueName<ModbusRtuManager::ModbusRtuError>(ModbusRtuManager::ModbusRtuErrorInvalidTimeoutValue));
|
||||
return createReply(returnMap);
|
||||
}
|
||||
|
||||
ModbusRtuManager::ModbusRtuError result = m_modbusRtuManager->reconfigureModbusRtuMaster(modbusUuid, serialPort, baudrate, parity, dataBits, stopBits, numberOfRetries, timeout);
|
||||
returnMap.insert("modbusError", enumValueName<ModbusRtuManager::ModbusRtuError>(result));
|
||||
return createReply(returnMap);
|
||||
}
|
||||
@ -258,6 +278,8 @@ QVariantMap ModbusRtuHandler::packModbusRtuMaster(ModbusRtuMaster *modbusRtuMast
|
||||
modbusRtuMasterMap.insert("parity", enumValueName<SerialPort::SerialPortParity>(static_cast<SerialPort::SerialPortParity>(modbusRtuMaster->parity())));
|
||||
modbusRtuMasterMap.insert("stopBits", enumValueName<SerialPort::SerialPortStopBits>(static_cast<SerialPort::SerialPortStopBits>(modbusRtuMaster->stopBits())));
|
||||
modbusRtuMasterMap.insert("dataBits", enumValueName<SerialPort::SerialPortDataBits>(static_cast<SerialPort::SerialPortDataBits>(modbusRtuMaster->dataBits())));
|
||||
modbusRtuMasterMap.insert("numberOfRetries", modbusRtuMaster->numberOfRetries());
|
||||
modbusRtuMasterMap.insert("timeout", modbusRtuMaster->timeout());
|
||||
return modbusRtuMasterMap;
|
||||
}
|
||||
|
||||
|
||||
@ -98,7 +98,7 @@ ModbusRtuMaster *ModbusRtuManager::getModbusRtuMaster(const QUuid &modbusUuid)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QPair<ModbusRtuManager::ModbusRtuError, QUuid> ModbusRtuManager::addNewModbusRtuMaster(const QString &serialPort, qint32 baudrate, QSerialPort::Parity parity, QSerialPort::DataBits dataBits, QSerialPort::StopBits stopBits)
|
||||
QPair<ModbusRtuManager::ModbusRtuError, QUuid> ModbusRtuManager::addNewModbusRtuMaster(const QString &serialPort, qint32 baudrate, QSerialPort::Parity parity, QSerialPort::DataBits dataBits, QSerialPort::StopBits stopBits, int numberOfRetries, int timeout)
|
||||
{
|
||||
if (!supported()) {
|
||||
qCWarning(dcModbusRtu()) << "Cannot add new modbus RTU master because serialbus is not suppoerted on this platform.";
|
||||
@ -112,7 +112,7 @@ QPair<ModbusRtuManager::ModbusRtuError, QUuid> ModbusRtuManager::addNewModbusRt
|
||||
}
|
||||
|
||||
QUuid modbusUuid = QUuid::createUuid();
|
||||
ModbusRtuMasterImpl *modbusMaster = new ModbusRtuMasterImpl(modbusUuid, serialPort, baudrate, parity, dataBits, stopBits, this);
|
||||
ModbusRtuMasterImpl *modbusMaster = new ModbusRtuMasterImpl(modbusUuid, serialPort, baudrate, parity, dataBits, stopBits, numberOfRetries, timeout, this);
|
||||
ModbusRtuMaster *modbus = qobject_cast<ModbusRtuMaster *>(modbusMaster);
|
||||
qCDebug(dcModbusRtu()) << "Adding new" << modbus << parity << dataBits << stopBits;
|
||||
|
||||
@ -130,7 +130,7 @@ QPair<ModbusRtuManager::ModbusRtuError, QUuid> ModbusRtuManager::addNewModbusRt
|
||||
return QPair<ModbusRtuError, QUuid>(ModbusRtuErrorNoError, modbusUuid);
|
||||
}
|
||||
|
||||
ModbusRtuManager::ModbusRtuError ModbusRtuManager::reconfigureModbusRtuMaster(const QUuid &modbusUuid, const QString &serialPort, qint32 baudrate, QSerialPort::Parity parity, QSerialPort::DataBits dataBits, QSerialPort::StopBits stopBits)
|
||||
ModbusRtuManager::ModbusRtuError ModbusRtuManager::reconfigureModbusRtuMaster(const QUuid &modbusUuid, const QString &serialPort, qint32 baudrate, QSerialPort::Parity parity, QSerialPort::DataBits dataBits, QSerialPort::StopBits stopBits, int numberOfRetries, int timeout)
|
||||
{
|
||||
if (!supported()) {
|
||||
qCWarning(dcModbusRtu()) << "Cannot reconfigure modbus RTU master because serialbus is not suppoerted on this platform.";
|
||||
@ -142,6 +142,7 @@ ModbusRtuManager::ModbusRtuError ModbusRtuManager::reconfigureModbusRtuMaster(co
|
||||
return ModbusRtuErrorUuidNotFound;
|
||||
}
|
||||
|
||||
// Take the modbus masters
|
||||
ModbusRtuMasterImpl *modbusMaster = qobject_cast<ModbusRtuMasterImpl *>(m_modbusRtuMasters.value(modbusUuid));
|
||||
|
||||
// Disconnect
|
||||
@ -153,6 +154,8 @@ ModbusRtuManager::ModbusRtuError ModbusRtuManager::reconfigureModbusRtuMaster(co
|
||||
modbusMaster->setParity(parity);
|
||||
modbusMaster->setDataBits(dataBits);
|
||||
modbusMaster->setStopBits(stopBits);
|
||||
modbusMaster->setNumberOfRetries(numberOfRetries);
|
||||
modbusMaster->setTimeout(timeout);
|
||||
|
||||
// Connect again
|
||||
if (!modbusMaster->connectDevice()) {
|
||||
@ -214,9 +217,11 @@ void ModbusRtuManager::loadRtuMasters()
|
||||
QSerialPort::Parity parity = static_cast<QSerialPort::Parity>(settings.value("parity").toInt());
|
||||
QSerialPort::DataBits dataBits = static_cast<QSerialPort::DataBits>(settings.value("dataBits").toInt());
|
||||
QSerialPort::StopBits stopBits = static_cast<QSerialPort::StopBits>(settings.value("stopBits").toInt());
|
||||
int numberOfRetries = settings.value("numberOfRetries").toInt();
|
||||
int timeout = settings.value("timeout").toInt();
|
||||
settings.endGroup(); // uuid
|
||||
|
||||
addModbusRtuMasterInternally(new ModbusRtuMasterImpl(QUuid(uuidString), serialPort, baudrate, parity, dataBits, stopBits, this));
|
||||
addModbusRtuMasterInternally(new ModbusRtuMasterImpl(QUuid(uuidString), serialPort, baudrate, parity, dataBits, stopBits, numberOfRetries, timeout, this));
|
||||
}
|
||||
|
||||
settings.endGroup(); // ModbusRtuMasters
|
||||
@ -233,6 +238,8 @@ void ModbusRtuManager::saveModbusRtuMaster(ModbusRtuMaster *modbusRtuMaster)
|
||||
settings.setValue("parity", static_cast<int>(modbusRtuMaster->parity()));
|
||||
settings.setValue("dataBits", static_cast<int>(modbusRtuMaster->dataBits()));
|
||||
settings.setValue("stopBits", static_cast<int>(modbusRtuMaster->stopBits()));
|
||||
settings.setValue("numberOfRetries", modbusRtuMaster->numberOfRetries());
|
||||
settings.setValue("timeout", modbusRtuMaster->timeout());
|
||||
settings.endGroup(); // uuid
|
||||
settings.endGroup(); // ModbusRtuMasters
|
||||
}
|
||||
|
||||
@ -54,6 +54,7 @@ public:
|
||||
ModbusRtuErrorHardwareNotFound,
|
||||
ModbusRtuErrorResourceBusy,
|
||||
ModbusRtuErrorNotSupported,
|
||||
ModbusRtuErrorInvalidTimeoutValue,
|
||||
ModbusRtuErrorConnectionFailed
|
||||
};
|
||||
Q_ENUM(ModbusRtuError)
|
||||
@ -69,8 +70,8 @@ public:
|
||||
bool hasModbusRtuMaster(const QUuid &modbusUuid) const;
|
||||
ModbusRtuMaster *getModbusRtuMaster(const QUuid &modbusUuid);
|
||||
|
||||
QPair<ModbusRtuError, QUuid> addNewModbusRtuMaster(const QString &serialPort, qint32 baudrate, QSerialPort::Parity parity, QSerialPort::DataBits dataBits, QSerialPort::StopBits stopBits);
|
||||
ModbusRtuError reconfigureModbusRtuMaster(const QUuid &modbusUuid, const QString &serialPort, qint32 baudrate, QSerialPort::Parity parity, QSerialPort::DataBits dataBits, QSerialPort::StopBits stopBits);
|
||||
QPair<ModbusRtuError, QUuid> addNewModbusRtuMaster(const QString &serialPort, qint32 baudrate, QSerialPort::Parity parity, QSerialPort::DataBits dataBits, QSerialPort::StopBits stopBits, int numberOfRetries, int timeout);
|
||||
ModbusRtuError reconfigureModbusRtuMaster(const QUuid &modbusUuid, const QString &serialPort, qint32 baudrate, QSerialPort::Parity parity, QSerialPort::DataBits dataBits, QSerialPort::StopBits stopBits, int numberOfRetries, int timeout);
|
||||
ModbusRtuError removeModbusRtuMaster(const QUuid &modbusUuid);
|
||||
|
||||
signals:
|
||||
|
||||
@ -42,14 +42,16 @@ Q_DECLARE_LOGGING_CATEGORY(dcModbusRtu)
|
||||
|
||||
namespace nymeaserver {
|
||||
|
||||
ModbusRtuMasterImpl::ModbusRtuMasterImpl(const QUuid &modbusUuid, const QString &serialPort, qint32 baudrate, QSerialPort::Parity parity, QSerialPort::DataBits dataBits, QSerialPort::StopBits stopBits, QObject *parent) :
|
||||
ModbusRtuMasterImpl::ModbusRtuMasterImpl(const QUuid &modbusUuid, const QString &serialPort, qint32 baudrate, QSerialPort::Parity parity, QSerialPort::DataBits dataBits, QSerialPort::StopBits stopBits, int numberOfRetries, int timeout, QObject *parent) :
|
||||
ModbusRtuMaster(parent),
|
||||
m_modbusUuid(modbusUuid),
|
||||
m_serialPort(serialPort),
|
||||
m_baudrate(baudrate),
|
||||
m_parity(parity),
|
||||
m_dataBits(dataBits),
|
||||
m_stopBits(stopBits)
|
||||
m_stopBits(stopBits),
|
||||
m_numberOfRetries(numberOfRetries),
|
||||
m_timeout(timeout)
|
||||
{
|
||||
#ifdef WITH_QTSERIALBUS
|
||||
m_modbus = new QModbusRtuSerialMaster(this);
|
||||
@ -58,6 +60,8 @@ ModbusRtuMasterImpl::ModbusRtuMasterImpl(const QUuid &modbusUuid, const QString
|
||||
m_modbus->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, m_dataBits);
|
||||
m_modbus->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, m_stopBits);
|
||||
m_modbus->setConnectionParameter(QModbusDevice::SerialParityParameter, m_parity);
|
||||
m_modbus->setNumberOfRetries(m_numberOfRetries);
|
||||
m_modbus->setTimeout(m_timeout);
|
||||
|
||||
connect(m_modbus, &QModbusTcpClient::stateChanged, this, [=](QModbusDevice::State state){
|
||||
qCDebug(dcModbusRtu()) << "Connection state changed" << m_modbusUuid.toString() << m_serialPort << state;
|
||||
@ -171,6 +175,8 @@ bool ModbusRtuMasterImpl::connectDevice()
|
||||
m_modbus->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, m_dataBits);
|
||||
m_modbus->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, m_stopBits);
|
||||
m_modbus->setConnectionParameter(QModbusDevice::SerialParityParameter, m_parity);
|
||||
m_modbus->setNumberOfRetries(m_numberOfRetries);
|
||||
m_modbus->setTimeout(m_timeout);
|
||||
return m_modbus->connectDevice();
|
||||
#else
|
||||
qCWarning(dcModbusRtu()) << "Modbus is not available on this platform.";
|
||||
@ -187,6 +193,37 @@ void ModbusRtuMasterImpl::disconnectDevice()
|
||||
#endif
|
||||
}
|
||||
|
||||
int ModbusRtuMasterImpl::numberOfRetries() const
|
||||
{
|
||||
return m_numberOfRetries;
|
||||
}
|
||||
|
||||
void ModbusRtuMasterImpl::setNumberOfRetries(int numberOfRetries)
|
||||
{
|
||||
if (m_numberOfRetries == numberOfRetries)
|
||||
return;
|
||||
|
||||
m_numberOfRetries = numberOfRetries;
|
||||
emit numberOfRetriesChanged(m_numberOfRetries);
|
||||
|
||||
m_modbus->setNumberOfRetries(m_numberOfRetries);
|
||||
}
|
||||
|
||||
int ModbusRtuMasterImpl::timeout() const
|
||||
{
|
||||
return m_timeout;
|
||||
}
|
||||
|
||||
void ModbusRtuMasterImpl::setTimeout(int timeout)
|
||||
{
|
||||
if (m_timeout == timeout)
|
||||
return;
|
||||
|
||||
m_timeout = timeout;
|
||||
emit timeoutChanged(m_timeout);
|
||||
m_modbus->setTimeout(m_timeout);
|
||||
}
|
||||
|
||||
ModbusRtuReply *ModbusRtuMasterImpl::readCoil(int slaveAddress, int registerAddress, quint16 size)
|
||||
{
|
||||
#ifdef WITH_QTSERIALBUS
|
||||
|
||||
@ -46,7 +46,7 @@ class ModbusRtuMasterImpl : public ModbusRtuMaster
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ModbusRtuMasterImpl(const QUuid &modbusUuid, const QString &serialPort, qint32 baudrate, QSerialPort::Parity parity, QSerialPort::DataBits dataBits, QSerialPort::StopBits stopBits, QObject *parent = nullptr);
|
||||
explicit ModbusRtuMasterImpl(const QUuid &modbusUuid, const QString &serialPort, qint32 baudrate, QSerialPort::Parity parity, QSerialPort::DataBits dataBits, QSerialPort::StopBits stopBits, int numberOfRetries, int timeout, QObject *parent = nullptr);
|
||||
~ModbusRtuMasterImpl() override = default;
|
||||
|
||||
QUuid modbusUuid() const override;
|
||||
@ -71,6 +71,12 @@ public:
|
||||
bool connectDevice();
|
||||
void disconnectDevice();
|
||||
|
||||
int numberOfRetries() const override;
|
||||
void setNumberOfRetries(int numberOfRetries);
|
||||
|
||||
int timeout() const override;
|
||||
void setTimeout(int timeout);
|
||||
|
||||
// Requests
|
||||
ModbusRtuReply *readCoil(int slaveAddress, int registerAddress, quint16 size = 1) override;
|
||||
ModbusRtuReply *readDiscreteInput(int slaveAddress, int registerAddress, quint16 size = 1) override;
|
||||
@ -93,6 +99,8 @@ private:
|
||||
QSerialPort::Parity m_parity;
|
||||
QSerialPort::DataBits m_dataBits;
|
||||
QSerialPort::StopBits m_stopBits;
|
||||
int m_numberOfRetries = 3;
|
||||
int m_timeout = 100;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -49,6 +49,8 @@ public:
|
||||
virtual QSerialPort::Parity parity() const = 0;
|
||||
virtual QSerialPort::DataBits dataBits() const = 0;
|
||||
virtual QSerialPort::StopBits stopBits() = 0;
|
||||
virtual int numberOfRetries() const = 0;
|
||||
virtual int timeout() const = 0;
|
||||
|
||||
virtual bool connected() const = 0;
|
||||
|
||||
@ -72,6 +74,8 @@ signals:
|
||||
void parityChanged(QSerialPort::Parity parity);
|
||||
void dataBitsChanged(QSerialPort::DataBits dataBits);
|
||||
void stopBitsChanged(QSerialPort::StopBits stopBits);
|
||||
void numberOfRetriesChanged(int numberOfRetries);
|
||||
void timeoutChanged(int timeout);
|
||||
|
||||
};
|
||||
|
||||
@ -81,7 +85,9 @@ inline QDebug operator<<(QDebug debug, ModbusRtuMaster *modbusRtuMaster) {
|
||||
debug.nospace() << ", BaudRate: " << modbusRtuMaster->baudrate();
|
||||
debug.nospace() << ", " << modbusRtuMaster->dataBits();
|
||||
debug.nospace() << ", " << modbusRtuMaster->stopBits();
|
||||
debug.nospace() << ", " << modbusRtuMaster->parity() << ") ";
|
||||
debug.nospace() << ", " << modbusRtuMaster->parity();
|
||||
debug.nospace() << ", Retries:" << modbusRtuMaster->numberOfRetries();
|
||||
debug.nospace() << ", Timeout:" << modbusRtuMaster->numberOfRetries() << "ms)";
|
||||
return debug.space();
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user