Add timeout and number of retries to modbus master settings

This commit is contained in:
Simon Stürz 2021-04-26 19:36:00 +02:00 committed by Michael Zanetti
parent 2bf8a664dd
commit be09502da8
9 changed files with 180 additions and 14 deletions

View File

@ -96,7 +96,7 @@ ModbusRtuMasters *ModbusRtuManager::modbusRtuMasters() const
return m_modbusRtuMasters;
}
int ModbusRtuManager::addModbusRtuMaster(const QString &serialPort, qint32 baudrate, SerialPort::SerialPortParity parity, SerialPort::SerialPortDataBits dataBits, SerialPort::SerialPortStopBits stopBits)
int ModbusRtuManager::addModbusRtuMaster(const QString &serialPort, qint32 baudrate, SerialPort::SerialPortParity parity, SerialPort::SerialPortDataBits dataBits, SerialPort::SerialPortStopBits stopBits, int numberOfRetries, int timeout)
{
QVariantMap params;
params.insert("serialPort", serialPort);
@ -104,6 +104,9 @@ int ModbusRtuManager::addModbusRtuMaster(const QString &serialPort, qint32 baudr
params.insert("parity", QMetaEnum::fromType<SerialPort::SerialPortParity>().valueToKey(parity));
params.insert("dataBits", QMetaEnum::fromType<SerialPort::SerialPortDataBits>().valueToKey(dataBits));
params.insert("stopBits", QMetaEnum::fromType<SerialPort::SerialPortStopBits>().valueToKey(stopBits));
params.insert("numberOfRetries", numberOfRetries);
params.insert("timeout", timeout);
return m_engine->jsonRpcClient()->sendCommand("ModbusRtu.AddModbusRtuMaster", params, this, "addModbusRtuMasterResponse");
}
@ -114,7 +117,7 @@ int ModbusRtuManager::removeModbusRtuMaster(const QUuid &modbusUuid)
return m_engine->jsonRpcClient()->sendCommand("ModbusRtu.RemoveModbusRtuMaster", params, this, "removeModbusRtuMasterResponse");
}
int ModbusRtuManager::reconfigureModbusRtuMaster(const QUuid &modbusUuid, const QString &serialPort, qint32 baudrate, SerialPort::SerialPortParity parity, SerialPort::SerialPortDataBits dataBits, SerialPort::SerialPortStopBits stopBits)
int ModbusRtuManager::reconfigureModbusRtuMaster(const QUuid &modbusUuid, const QString &serialPort, qint32 baudrate, SerialPort::SerialPortParity parity, SerialPort::SerialPortDataBits dataBits, SerialPort::SerialPortStopBits stopBits, int numberOfRetries, int timeout)
{
QVariantMap params;
params.insert("modbusUuid", modbusUuid);
@ -123,6 +126,9 @@ int ModbusRtuManager::reconfigureModbusRtuMaster(const QUuid &modbusUuid, const
params.insert("parity", QMetaEnum::fromType<SerialPort::SerialPortParity>().valueToKey(parity));
params.insert("dataBits", QMetaEnum::fromType<SerialPort::SerialPortDataBits>().valueToKey(dataBits));
params.insert("stopBits", QMetaEnum::fromType<SerialPort::SerialPortStopBits>().valueToKey(stopBits));
params.insert("numberOfRetries", numberOfRetries);
params.insert("timeout", timeout);
return m_engine->jsonRpcClient()->sendCommand("ModbusRtu.ReconfigureModbusRtuMaster", params, this, "reconfigureModbusRtuMasterResponse");
}
@ -145,6 +151,8 @@ ModbusRtuMaster *ModbusRtuManager::unpackModbusRtuMaster(const QVariantMap &modb
modbusMaster->setParity(SerialPort::stringToSerialPortParity(modbusRtuMasterMap.value("parity").toString()));
modbusMaster->setStopBits(SerialPort::stringToSerialPortStopBits(modbusRtuMasterMap.value("stopBits").toString()));
modbusMaster->setDataBits(SerialPort::stringToSerialPortDataBits(modbusRtuMasterMap.value("dataBits").toString()));
modbusMaster->setNumberOfRetries(modbusRtuMasterMap.value("numberOfRetries").toUInt());
modbusMaster->setTimeout(modbusRtuMasterMap.value("timeout").toUInt());
return modbusMaster;
}
@ -195,9 +203,10 @@ void ModbusRtuManager::notificationReceived(const QVariantMap &notification)
currentModbusRtuMaster->setParity(modbusRtuMaster->parity());
currentModbusRtuMaster->setDataBits(modbusRtuMaster->dataBits());
currentModbusRtuMaster->setStopBits(modbusRtuMaster->stopBits());
currentModbusRtuMaster->setNumberOfRetries(modbusRtuMaster->numberOfRetries());
currentModbusRtuMaster->setTimeout(modbusRtuMaster->timeout());
currentModbusRtuMaster->setConnected(modbusRtuMaster->connected());
modbusRtuMaster->deleteLater();
return;
}
}

View File

@ -63,9 +63,9 @@ public:
SerialPorts *serialPorts() const;
ModbusRtuMasters *modbusRtuMasters() const;
Q_INVOKABLE int addModbusRtuMaster(const QString &serialPort, qint32 baudrate, SerialPort::SerialPortParity parity, SerialPort::SerialPortDataBits dataBits, SerialPort::SerialPortStopBits stopBits);
Q_INVOKABLE int addModbusRtuMaster(const QString &serialPort, qint32 baudrate, SerialPort::SerialPortParity parity, SerialPort::SerialPortDataBits dataBits, SerialPort::SerialPortStopBits stopBits, int numberOfRetries, int timeout);
Q_INVOKABLE int removeModbusRtuMaster(const QUuid &modbusUuid);
Q_INVOKABLE int reconfigureModbusRtuMaster(const QUuid &modbusUuid, const QString &serialPort, qint32 baudrate, SerialPort::SerialPortParity parity, SerialPort::SerialPortDataBits dataBits, SerialPort::SerialPortStopBits stopBits);
Q_INVOKABLE int reconfigureModbusRtuMaster(const QUuid &modbusUuid, const QString &serialPort, qint32 baudrate, SerialPort::SerialPortParity parity, SerialPort::SerialPortDataBits dataBits, SerialPort::SerialPortStopBits stopBits, int numberOfRetries, int timeout);
signals:
void engineChanged();

View File

@ -115,6 +115,34 @@ void ModbusRtuMaster::setStopBits(SerialPort::SerialPortStopBits stopBits)
emit stopBitsChanged(m_stopBits);
}
uint ModbusRtuMaster::numberOfRetries() const
{
return m_numberOfRetries;
}
void ModbusRtuMaster::setNumberOfRetries(uint numberOfRetries)
{
if (m_numberOfRetries == numberOfRetries)
return;
m_numberOfRetries = numberOfRetries;
emit numberOfRetriesChanged(m_numberOfRetries);
}
uint ModbusRtuMaster::timeout() const
{
return m_timeout;
}
void ModbusRtuMaster::setTimeout(uint timeout)
{
if (m_timeout == timeout)
return;
m_timeout = timeout;
emit timeoutChanged(m_timeout);
}
bool ModbusRtuMaster::connected() const
{
return m_connected;

View File

@ -45,6 +45,8 @@ class ModbusRtuMaster : public QObject
Q_PROPERTY(SerialPort::SerialPortParity parity READ parity NOTIFY parityChanged)
Q_PROPERTY(SerialPort::SerialPortDataBits dataBits READ dataBits NOTIFY dataBitsChanged)
Q_PROPERTY(SerialPort::SerialPortStopBits stopBits READ stopBits NOTIFY stopBitsChanged)
Q_PROPERTY(uint numberOfRetries READ numberOfRetries WRITE setNumberOfRetries NOTIFY numberOfRetriesChanged)
Q_PROPERTY(uint timeout READ timeout WRITE setTimeout NOTIFY timeoutChanged)
Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
public:
@ -68,6 +70,12 @@ public:
SerialPort::SerialPortStopBits stopBits() const;
void setStopBits(SerialPort::SerialPortStopBits stopBits);
uint numberOfRetries() const;
void setNumberOfRetries(uint numberOfRetries);
uint timeout() const;
void setTimeout(uint timeout);
bool connected() const;
void setConnected(bool connected);
@ -78,6 +86,8 @@ signals:
void parityChanged(SerialPort::SerialPortParity parity);
void dataBitsChanged(SerialPort::SerialPortDataBits dataBits);
void stopBitsChanged(SerialPort::SerialPortStopBits stopBits);
void numberOfRetriesChanged(uint numberOfRetries);
void timeoutChanged(uint timeout);
private:
QUuid m_modbusUuid;
@ -86,6 +96,8 @@ private:
SerialPort::SerialPortParity m_parity;
SerialPort::SerialPortDataBits m_dataBits;
SerialPort::SerialPortStopBits m_stopBits;
uint m_numberOfRetries = 3;
uint m_timeout = 100;
bool m_connected = false;
};

View File

@ -61,6 +61,10 @@ QVariant ModbusRtuMasters::data(const QModelIndex &index, int role) const
return m_modbusRtuMasters.at(index.row())->dataBits();
case RoleStopBits:
return m_modbusRtuMasters.at(index.row())->stopBits();
case RoleNumberOfRetries:
return m_modbusRtuMasters.at(index.row())->numberOfRetries();
case RoleTimeout:
return m_modbusRtuMasters.at(index.row())->timeout();
case RoleConnected:
return m_modbusRtuMasters.at(index.row())->connected();
}
@ -76,6 +80,8 @@ QHash<int, QByteArray> ModbusRtuMasters::roleNames() const
roles.insert(RoleParity, "parity");
roles.insert(RoleDataBits, "dataBits");
roles.insert(RoleStopBits, "stopBits");
roles.insert(RoleNumberOfRetries, "numberOfRetries");
roles.insert(RoleTimeout, "timeout");
roles.insert(RoleConnected, "connected");
return roles;
}
@ -114,6 +120,19 @@ void ModbusRtuMasters::addModbusRtuMaster(ModbusRtuMaster *modbusRtuMaster)
emit dataChanged(idx, idx, {RoleStopBits});
});
connect(modbusRtuMaster, &ModbusRtuMaster::numberOfRetriesChanged, this, [=](uint numberOfRetries) {
Q_UNUSED(numberOfRetries)
QModelIndex idx = index(m_modbusRtuMasters.indexOf(modbusRtuMaster), 0);
emit dataChanged(idx, idx, {RoleNumberOfRetries});
});
connect(modbusRtuMaster, &ModbusRtuMaster::timeoutChanged, this, [=](uint timeout) {
Q_UNUSED(timeout)
QModelIndex idx = index(m_modbusRtuMasters.indexOf(modbusRtuMaster), 0);
emit dataChanged(idx, idx, {RoleTimeout});
});
connect(modbusRtuMaster, &ModbusRtuMaster::connectedChanged, this, [=](bool connected) {
Q_UNUSED(connected)
QModelIndex idx = index(m_modbusRtuMasters.indexOf(modbusRtuMaster), 0);

View File

@ -49,6 +49,8 @@ public:
RoleParity,
RoleDataBits,
RoleStopBits,
RoleNumberOfRetries,
RoleTimeout,
RoleConnected
};
Q_ENUM(Roles)

View File

@ -93,8 +93,8 @@ SettingsPageBase {
id: d
property int pendingCommandId: -1
function addModbusRtuMaster(serialPort, baudRate, parity, dataBits, stopBits) {
d.pendingCommandId = root.modbusRtuManager.addModbusRtuMaster(serialPort, baudRate, parity, dataBits, stopBits)
function addModbusRtuMaster(serialPort, baudRate, parity, dataBits, stopBits, numberOfRetries, timeout) {
d.pendingCommandId = root.modbusRtuManager.addModbusRtuMaster(serialPort, baudRate, parity, dataBits, stopBits, numberOfRetries, timeout)
}
}
@ -228,6 +228,36 @@ SettingsPageBase {
}
}
RowLayout {
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
Label {
text: qsTr("Number of request retries:")
Layout.fillWidth: true
}
TextField {
id: numberOfRetriesText
inputMethodHints: Qt.ImhDigitsOnly
text: "3"
validator: IntValidator { bottom: 0; top: 100 }
}
}
RowLayout {
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
Label {
text: qsTr("Request timeout [ms]:")
Layout.fillWidth: true
}
TextField {
id: timeoutText
inputMethodHints: Qt.ImhDigitsOnly
text: "100"
validator: IntValidator { bottom: 10; top: 100000 }
}
}
Button {
Layout.fillWidth: true
Layout.leftMargin: app.margins
@ -239,9 +269,12 @@ SettingsPageBase {
var parity = serialPortParityModel.get(parityComboBox.currentIndex).value
var dataBits = serialPortDataBitsModel.get(dataBitsComboBox.currentIndex).value
var stopBits = serialPortStopBitsModel.get(stopBitsComboBox.currentIndex).value
console.log("Adding modbus RTU with", serialPort.systemLocation, baudrate, parity, dataBits, stopBits)
var numberOfRetries = numberOfRetriesText.text
var timeout = timeoutText.text
d.addModbusRtuMaster(serialPort.systemLocation, baudrate, parity, dataBits, stopBits)
console.log("Adding modbus RTU with", serialPort.systemLocation, baudrate, parity, dataBits, stopBits, numberOfRetries, timeout)
d.addModbusRtuMaster(serialPort.systemLocation, baudrate, parity, dataBits, stopBits, numberOfRetries, timeout)
}
}
}

View File

@ -40,6 +40,7 @@ SettingsPageBase {
property ModbusRtuManager modbusRtuManager
property ModbusRtuMaster modbusRtuMaster
property ListModel serialPortBaudrateModel
property ListModel serialPortParityModel
property ListModel serialPortDataBitsModel
@ -70,7 +71,10 @@ SettingsPageBase {
iconName: "../images/stock_usb.svg"
text: model.description + (model.manufacturer === "" ? "" : " - " + model.manufacturer)
subText: model.systemLocation + (model.serialNumber === "" ? "" : " - " + model.serialNumber)
onClicked: pageStack.push(reconfigureNewModbusRtuMasterPage, { modbusRtuManager: modbusRtuManager, serialPort: modbusRtuManager.serialPorts.get(index), modbusRtuMaster: modbusRtuMaster })
onClicked: pageStack.push(reconfigureNewModbusRtuMasterPage, {
modbusRtuManager: modbusRtuManager,
serialPort: modbusRtuManager.serialPorts.get(index),
modbusRtuMaster: modbusRtuMaster })
}
}
@ -96,8 +100,8 @@ SettingsPageBase {
id: d
property int pendingCommandId: -1
function reconfigureModbusRtuMaster(modbusUuid, serialPort, baudRate, parity, dataBits, stopBits) {
d.pendingCommandId = root.modbusRtuManager.reconfigureModbusRtuMaster(modbusUuid, serialPort, baudRate, parity, dataBits, stopBits)
function reconfigureModbusRtuMaster(modbusUuid, serialPort, baudRate, parity, dataBits, stopBits, numberOfRetries, timeout) {
d.pendingCommandId = root.modbusRtuManager.reconfigureModbusRtuMaster(modbusUuid, serialPort, baudRate, parity, dataBits, stopBits, numberOfRetries, timeout)
}
}
@ -263,6 +267,44 @@ SettingsPageBase {
}
}
RowLayout {
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
Label {
text: qsTr("Number of request retries:")
Layout.fillWidth: true
}
TextField {
id: numberOfRetriesText
inputMethodHints: Qt.ImhDigitsOnly
text: "3"
validator: IntValidator { bottom: 0; top: 100 }
Component.onCompleted: {
numberOfRetriesText.text = modbusRtuMaster.numberOfRetries
}
}
}
RowLayout {
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
Label {
text: qsTr("Request timeout [ms]:")
Layout.fillWidth: true
}
TextField {
id: timeoutText
inputMethodHints: Qt.ImhDigitsOnly
text: "100"
validator: IntValidator { bottom: 10; top: 100000 }
Component.onCompleted: {
timeoutText.text = modbusRtuMaster.timeout
}
}
}
Button {
Layout.fillWidth: true
Layout.leftMargin: app.margins
@ -274,9 +316,11 @@ SettingsPageBase {
var parity = serialPortParityModel.get(parityComboBox.currentIndex).value
var dataBits = serialPortDataBitsModel.get(dataBitsComboBox.currentIndex).value
var stopBits = serialPortStopBitsModel.get(stopBitsComboBox.currentIndex).value
var numberOfRetries = numberOfRetriesText.text
var timeout = timeoutText.text
console.log("Reconfigure modbus RTU", modbusRtuMaster.modbusUuid, "with", serialPort.systemLocation, baudrate, parity, dataBits, stopBits)
d.reconfigureModbusRtuMaster(modbusRtuMaster.modbusUuid, serialPort.systemLocation, baudrate, parity, dataBits, stopBits)
console.log("Reconfigure modbus RTU", modbusRtuMaster.modbusUuid, "with", serialPort.systemLocation, baudrate, parity, dataBits, stopBits, numberOfRetries, timeout)
d.reconfigureModbusRtuMaster(modbusRtuMaster.modbusUuid, serialPort.systemLocation, baudrate, parity, dataBits, stopBits, numberOfRetries, timeout)
}
}
}

View File

@ -81,6 +81,9 @@ SettingsPageBase {
case "ModbusRtuErrorConnectionFailed":
props.text = qsTr("Unable to connect to the modbus RTU master.\n\nMaybe the hardware is already in use.");
break;
case "ModbusRtuInvalidTimeoutValue":
props.text = qsTr("The specified timeout value is not valid.\n\nPlease use a timeout value bigger or equal to 10 ms.");
break;
default:
props.errorCode = error;
}
@ -348,6 +351,22 @@ SettingsPageBase {
prominentSubText: false
}
NymeaSwipeDelegate {
Layout.fillWidth: true
text: qsTr("Number of request retries")
subText: modbusRtuMaster ? modbusRtuMaster.numberOfRetries : ""
progressive: false
prominentSubText: false
}
NymeaSwipeDelegate {
Layout.fillWidth: true
text: qsTr("Request timeout")
subText: modbusRtuMaster ? modbusRtuMaster.timeout + " ms" : ""
progressive: false
prominentSubText: false
}
Button {
id: reconfigureButton
Layout.fillWidth: true