diff --git a/modbus/modbusrtumaster.cpp b/modbus/modbusrtumaster.cpp index 4329a0d..068af41 100644 --- a/modbus/modbusrtumaster.cpp +++ b/modbus/modbusrtumaster.cpp @@ -45,8 +45,7 @@ ModbusRTUMaster::ModbusRTUMaster(QString serialPort, uint baudrate, QSerialPort: m_modbusRtuSerialMaster->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, dataBits); m_modbusRtuSerialMaster->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, stopBits); m_modbusRtuSerialMaster->setConnectionParameter(QModbusDevice::SerialParityParameter, parity); - //m_modbusRtuSerialMaster->setTimeout(100); - //m_modbusRtuSerialMaster->setNumberOfRetries(1); + connect(m_modbusRtuSerialMaster, &QModbusTcpClient::stateChanged, this, &ModbusRTUMaster::onModbusStateChanged); connect(m_modbusRtuSerialMaster, &QModbusRtuSerialMaster::errorOccurred, this, &ModbusRTUMaster::onModbusErrorOccurred); @@ -70,7 +69,7 @@ ModbusRTUMaster::~ModbusRTUMaster() bool ModbusRTUMaster::connectDevice() { - qCDebug(dcModbusRTU()) << "Setting up TCP connecion"; + qCDebug(dcModbusRTU()) << "Setting up RTU client connecion"; if (!m_modbusRtuSerialMaster) return false; @@ -88,6 +87,16 @@ void ModbusRTUMaster::setTimeout(int timeout) m_modbusRtuSerialMaster->setTimeout(timeout); } +int ModbusRTUMaster::timeout() +{ + return m_modbusRtuSerialMaster->timeout(); +} + +int ModbusRTUMaster::numberOfReties() +{ + return m_modbusRtuSerialMaster->numberOfRetries(); +} + QString ModbusRTUMaster::serialPort() { return m_modbusRtuSerialMaster->connectionParameter(QModbusDevice::SerialPortNameParameter).toString(); @@ -380,11 +389,15 @@ QUuid ModbusRTUMaster::readHoldingRegister(uint slaveAddress, uint registerAddre void ModbusRTUMaster::onModbusErrorOccurred(QModbusDevice::Error error) { qCWarning(dcModbusRTU()) << "An error occured" << error; + if (error == QModbusDevice::Error::ConnectionError) { + emit connectionStateChanged(false); + } } void ModbusRTUMaster::onModbusStateChanged(QModbusDevice::State state) { + qCWarning(dcModbusRTU()) << "State changed" << state; if (state == QModbusDevice::UnconnectedState) { //try to reconnect in 10 seconds m_reconnectTimer->start(10000); diff --git a/modbus/modbusrtumaster.h b/modbus/modbusrtumaster.h index 3a9b04c..f37da90 100644 --- a/modbus/modbusrtumaster.h +++ b/modbus/modbusrtumaster.h @@ -48,6 +48,9 @@ public: void setNumberOfRetries(int number); void setTimeout(int timeout); + int timeout(); + int numberOfReties(); + QUuid readCoil(uint slaveAddress, uint registerAddress, uint size = 1); QUuid readDiscreteInput(uint slaveAddress, uint registerAddress, uint size = 1); QUuid readInputRegister(uint slaveAddress, uint registerAddress, uint size = 1); diff --git a/modbuscommander/integrationpluginmodbuscommander.cpp b/modbuscommander/integrationpluginmodbuscommander.cpp index 7afcf96..cbb1c6b 100644 --- a/modbuscommander/integrationpluginmodbuscommander.cpp +++ b/modbuscommander/integrationpluginmodbuscommander.cpp @@ -37,107 +37,6 @@ IntegrationPluginModbusCommander::IntegrationPluginModbusCommander() { } -void IntegrationPluginModbusCommander::init() -{ - connect(this, &IntegrationPluginModbusCommander::configValueChanged, this, &IntegrationPluginModbusCommander::onPluginConfigurationChanged); - //QLoggingCategory::setFilterRules(QStringLiteral("qt.modbus* = false")); - - m_slaveAddressParamTypeId.insert(coilThingClassId, coilThingSlaveAddressParamTypeId); - m_slaveAddressParamTypeId.insert(inputRegisterThingClassId, inputRegisterThingSlaveAddressParamTypeId); - m_slaveAddressParamTypeId.insert(discreteInputThingClassId, discreteInputThingSlaveAddressParamTypeId); - m_slaveAddressParamTypeId.insert(holdingRegisterThingClassId, holdingRegisterThingSlaveAddressParamTypeId); - - m_registerAddressParamTypeId.insert(coilThingClassId, coilThingRegisterAddressParamTypeId); - m_registerAddressParamTypeId.insert(inputRegisterThingClassId, inputRegisterThingRegisterAddressParamTypeId); - m_registerAddressParamTypeId.insert(discreteInputThingClassId, discreteInputThingRegisterAddressParamTypeId); - m_registerAddressParamTypeId.insert(holdingRegisterThingClassId, holdingRegisterThingRegisterAddressParamTypeId); - - m_connectedStateTypeId.insert(coilThingClassId, coilConnectedStateTypeId); - m_connectedStateTypeId.insert(inputRegisterThingClassId, inputRegisterConnectedStateTypeId); - m_connectedStateTypeId.insert(discreteInputThingClassId, discreteInputConnectedStateTypeId); - m_connectedStateTypeId.insert(holdingRegisterThingClassId, holdingRegisterConnectedStateTypeId); - - m_valueStateTypeId.insert(coilThingClassId, coilValueStateTypeId); - m_valueStateTypeId.insert(inputRegisterThingClassId, inputRegisterValueStateTypeId); - m_valueStateTypeId.insert(discreteInputThingClassId, discreteInputValueStateTypeId); - m_valueStateTypeId.insert(holdingRegisterThingClassId, holdingRegisterValueStateTypeId); -} - - -void IntegrationPluginModbusCommander::setupThing(ThingSetupInfo *info) -{ - Thing *thing = info->thing(); - - if (thing->thingClassId() == modbusTCPClientThingClassId) { - QHostAddress hostAddress = QHostAddress(thing->paramValue(modbusTCPClientThingIpAddressParamTypeId).toString()); - uint port = thing->paramValue(modbusTCPClientThingPortParamTypeId).toUInt(); - - foreach (ModbusTCPMaster *modbusTCPMaster, m_modbusTCPMasters.values()) { - if ((modbusTCPMaster->hostAddress() == hostAddress) && (modbusTCPMaster->port() == port)){ - m_modbusTCPMasters.insert(thing, modbusTCPMaster); - return info->finish(Thing::ThingErrorNoError); - } - } - - ModbusTCPMaster *modbusTCPMaster = new ModbusTCPMaster(hostAddress, port, this); - connect(modbusTCPMaster, &ModbusTCPMaster::connectionStateChanged, this, &IntegrationPluginModbusCommander::onConnectionStateChanged); - connect(modbusTCPMaster, &ModbusTCPMaster::writeRequestExecuted, this, &IntegrationPluginModbusCommander::onRequestExecuted); - connect(modbusTCPMaster, &ModbusTCPMaster::writeRequestError, this, &IntegrationPluginModbusCommander::onRequestError); - connect(modbusTCPMaster, &ModbusTCPMaster::receivedCoil, this, &IntegrationPluginModbusCommander::onReceivedCoil); - connect(modbusTCPMaster, &ModbusTCPMaster::receivedDiscreteInput, this, &IntegrationPluginModbusCommander::onReceivedDiscreteInput); - connect(modbusTCPMaster, &ModbusTCPMaster::receivedHoldingRegister, this, &IntegrationPluginModbusCommander::onReceivedHoldingRegister); - connect(modbusTCPMaster, &ModbusTCPMaster::receivedInputRegister, this, &IntegrationPluginModbusCommander::onReceivedInputRegister); - connect(modbusTCPMaster, &ModbusTCPMaster::connectionStateChanged, info, [info, modbusTCPMaster, this] (bool connected) { - if (connected) { - info->finish(Thing::ThingErrorNoError); - m_modbusTCPMasters.insert(info->thing(), modbusTCPMaster); - } - }); - modbusTCPMaster->connectDevice(); - - } else if (thing->thingClassId() == modbusRTUClientThingClassId) { - - QString serialPort = thing->paramValue(modbusRTUClientThingSerialPortParamTypeId).toString(); - uint baudrate = thing->paramValue(modbusRTUClientThingBaudRateParamTypeId).toUInt(); - uint stopBits = thing->paramValue(modbusRTUClientThingStopBitsParamTypeId).toUInt(); - uint dataBits = thing->paramValue(modbusRTUClientThingDataBitsParamTypeId).toUInt(); - QSerialPort::Parity parity = QSerialPort::Parity::NoParity; - QString parityString = thing->paramValue(modbusRTUClientThingParityParamTypeId).toString(); - if (parityString.contains("No")) { - parity = QSerialPort::Parity::NoParity; - } else if (thing->paramValue(modbusRTUClientThingParityParamTypeId).toString().contains("Even")) { - parity = QSerialPort::Parity::EvenParity; - } else if (thing->paramValue(modbusRTUClientThingParityParamTypeId).toString().contains("Odd")) { - parity = QSerialPort::Parity::OddParity; - } - - ModbusRTUMaster *modbusRTUMaster = new ModbusRTUMaster(serialPort, baudrate, parity, dataBits, stopBits, this); - connect(modbusRTUMaster, &ModbusRTUMaster::connectionStateChanged, this, &IntegrationPluginModbusCommander::onConnectionStateChanged); - connect(modbusRTUMaster, &ModbusRTUMaster::requestExecuted, this, &IntegrationPluginModbusCommander::onRequestExecuted); - connect(modbusRTUMaster, &ModbusRTUMaster::requestError, this, &IntegrationPluginModbusCommander::onRequestError); - connect(modbusRTUMaster, &ModbusRTUMaster::receivedCoil, this, &IntegrationPluginModbusCommander::onReceivedCoil); - connect(modbusRTUMaster, &ModbusRTUMaster::receivedDiscreteInput, this, &IntegrationPluginModbusCommander::onReceivedDiscreteInput); - connect(modbusRTUMaster, &ModbusRTUMaster::receivedHoldingRegister, this, &IntegrationPluginModbusCommander::onReceivedHoldingRegister); - connect(modbusRTUMaster, &ModbusRTUMaster::receivedInputRegister, this, &IntegrationPluginModbusCommander::onReceivedInputRegister); - connect(modbusRTUMaster, &ModbusRTUMaster::connectionStateChanged, info, [info, modbusRTUMaster, this] (bool connected) { - if (connected) { - info->finish(Thing::ThingErrorNoError); - m_modbusRTUMasters.insert(info->thing(), modbusRTUMaster); - } - }); - modbusRTUMaster->connectDevice(); - - } else if ((thing->thingClassId() == coilThingClassId) - || (thing->thingClassId() == discreteInputThingClassId) - || (thing->thingClassId() == holdingRegisterThingClassId) - || (thing->thingClassId() == inputRegisterThingClassId)) { - info->finish(Thing::ThingErrorNoError); - - } else { - Q_ASSERT_X(false, "setupThing", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8()); - } -} - void IntegrationPluginModbusCommander::discoverThings(ThingDiscoveryInfo *info) { ThingClassId thingClassId = info->thingClassId(); @@ -145,7 +44,7 @@ void IntegrationPluginModbusCommander::discoverThings(ThingDiscoveryInfo *info) if (thingClassId == modbusRTUClientThingClassId) { Q_FOREACH(QSerialPortInfo port, QSerialPortInfo::availablePorts()) { //Serial port is not yet used, create now a new one - qCDebug(dcModbusCommander()) << "Found serial port:" << port.systemLocation(); + qCDebug(dcModbusCommander()) << "Found serial port:" << port.systemLocation() << "manufacturer" << port.manufacturer() << "description" << port.description() << "serial number" << port.serialNumber(); QString description = port.manufacturer() + " " + port.description(); ThingDescriptor thingDescriptor(thingClassId, "Modbus RTU interface "+port.portName(), description); ParamList parameters; @@ -153,6 +52,10 @@ void IntegrationPluginModbusCommander::discoverThings(ThingDiscoveryInfo *info) foreach (Thing *existingThing, myThings()) { if (existingThing->paramValue(modbusRTUClientThingSerialPortParamTypeId).toString() == serialPort) { thingDescriptor.setThingId(existingThing->id()); + // TODO fix rediscovery of USB to SerialPort converters + // QSerialPort doesn't give any information to rediscover the device + // Un and re-plugging an USB device changes the system location + // detecting if the device is usb and using libsub to get the serialnumber may be a solution break; } } @@ -229,11 +132,151 @@ void IntegrationPluginModbusCommander::discoverThings(ThingDiscoveryInfo *info) } } -void IntegrationPluginModbusCommander::postSetupThing(Thing *info) +void IntegrationPluginModbusCommander::init() { + connect(this, &IntegrationPluginModbusCommander::configValueChanged, this, &IntegrationPluginModbusCommander::onPluginConfigurationChanged); + + m_slaveAddressParamTypeId.insert(coilThingClassId, coilThingSlaveAddressParamTypeId); + m_slaveAddressParamTypeId.insert(inputRegisterThingClassId, inputRegisterThingSlaveAddressParamTypeId); + m_slaveAddressParamTypeId.insert(discreteInputThingClassId, discreteInputThingSlaveAddressParamTypeId); + m_slaveAddressParamTypeId.insert(holdingRegisterThingClassId, holdingRegisterThingSlaveAddressParamTypeId); + + m_registerAddressParamTypeId.insert(coilThingClassId, coilThingRegisterAddressParamTypeId); + m_registerAddressParamTypeId.insert(inputRegisterThingClassId, inputRegisterThingRegisterAddressParamTypeId); + m_registerAddressParamTypeId.insert(discreteInputThingClassId, discreteInputThingRegisterAddressParamTypeId); + m_registerAddressParamTypeId.insert(holdingRegisterThingClassId, holdingRegisterThingRegisterAddressParamTypeId); + + m_connectedStateTypeId.insert(modbusRTUClientThingClassId, modbusRTUClientConnectedStateTypeId); + m_connectedStateTypeId.insert(modbusTCPClientThingClassId, modbusTCPClientConnectedStateTypeId); + m_connectedStateTypeId.insert(coilThingClassId, coilConnectedStateTypeId); + m_connectedStateTypeId.insert(inputRegisterThingClassId, inputRegisterConnectedStateTypeId); + m_connectedStateTypeId.insert(discreteInputThingClassId, discreteInputConnectedStateTypeId); + m_connectedStateTypeId.insert(holdingRegisterThingClassId, holdingRegisterConnectedStateTypeId); + + m_valueStateTypeId.insert(coilThingClassId, coilValueStateTypeId); + m_valueStateTypeId.insert(inputRegisterThingClassId, inputRegisterValueStateTypeId); + m_valueStateTypeId.insert(discreteInputThingClassId, discreteInputValueStateTypeId); + m_valueStateTypeId.insert(holdingRegisterThingClassId, holdingRegisterValueStateTypeId); +} + +void IntegrationPluginModbusCommander::setupThing(ThingSetupInfo *info) +{ + Thing *thing = info->thing(); + + if (thing->thingClassId() == modbusTCPClientThingClassId) { + QHostAddress hostAddress = QHostAddress(thing->paramValue(modbusTCPClientThingIpAddressParamTypeId).toString()); + uint port = thing->paramValue(modbusTCPClientThingPortParamTypeId).toUInt(); + uint numberOfRetries = thing->setting(modbusTCPClientSettingsNumberOfRetriesParamTypeId).toUInt(); + uint timeout = thing->setting(modbusTCPClientSettingsTimeoutParamTypeId).toUInt(); + + foreach (ModbusTCPMaster *modbusTCPMaster, m_modbusTCPMasters.values()) { + if ((modbusTCPMaster->hostAddress() == hostAddress) && (modbusTCPMaster->port() == port)){ + m_modbusTCPMasters.insert(thing, modbusTCPMaster); + return info->finish(Thing::ThingErrorNoError); + } + } + + qCDebug(dcModbusCommander()) << "Setting up RTU client"; + qCDebug(dcModbusCommander()) << " address:" << hostAddress.toString(); + qCDebug(dcModbusCommander()) << " port:" << port; + qCDebug(dcModbusCommander()) << " number of retires:" << numberOfRetries; + qCDebug(dcModbusCommander()) << " timeout:" << timeout; + + ModbusTCPMaster *modbusTCPMaster = new ModbusTCPMaster(hostAddress, port, this); + connect(modbusTCPMaster, &ModbusTCPMaster::connectionStateChanged, this, &IntegrationPluginModbusCommander::onConnectionStateChanged); + connect(modbusTCPMaster, &ModbusTCPMaster::writeRequestExecuted, this, &IntegrationPluginModbusCommander::onRequestExecuted); + connect(modbusTCPMaster, &ModbusTCPMaster::writeRequestError, this, &IntegrationPluginModbusCommander::onRequestError); + connect(modbusTCPMaster, &ModbusTCPMaster::receivedCoil, this, &IntegrationPluginModbusCommander::onReceivedCoil); + connect(modbusTCPMaster, &ModbusTCPMaster::receivedDiscreteInput, this, &IntegrationPluginModbusCommander::onReceivedDiscreteInput); + connect(modbusTCPMaster, &ModbusTCPMaster::receivedHoldingRegister, this, &IntegrationPluginModbusCommander::onReceivedHoldingRegister); + connect(modbusTCPMaster, &ModbusTCPMaster::receivedInputRegister, this, &IntegrationPluginModbusCommander::onReceivedInputRegister); + connect(modbusTCPMaster, &ModbusTCPMaster::connectionStateChanged, info, [info, modbusTCPMaster, this] (bool connected) { + if (connected) { + info->finish(Thing::ThingErrorNoError); + m_modbusTCPMasters.insert(info->thing(), modbusTCPMaster); + } + }); + connect(thing, &Thing::settingChanged, thing, [thing, modbusTCPMaster] (const ParamTypeId ¶mTypeId, const QVariant &value) { + if (paramTypeId == modbusTCPClientSettingsNumberOfRetriesParamTypeId) { + qCDebug(dcModbusCommander()) << "Set number of reties" << thing->name() << value.toUInt(); + modbusTCPMaster->setNumberOfRetries(value.toUInt()); + } else if (paramTypeId == modbusTCPClientSettingsTimeoutParamTypeId) { + qCDebug(dcModbusCommander()) << "Set timeout " << thing->name() << value.toUInt(); + modbusTCPMaster->setTimeout(value.toUInt()); + } + }); + modbusTCPMaster->connectDevice(); + + } else if (thing->thingClassId() == modbusRTUClientThingClassId) { + + QString serialPort = thing->paramValue(modbusRTUClientThingSerialPortParamTypeId).toString(); + uint baudrate = thing->paramValue(modbusRTUClientThingBaudRateParamTypeId).toUInt(); + uint stopBits = thing->paramValue(modbusRTUClientThingStopBitsParamTypeId).toUInt(); + uint dataBits = thing->paramValue(modbusRTUClientThingDataBitsParamTypeId).toUInt(); + uint numberOfRetries = thing->setting(modbusRTUClientSettingsNumberOfRetriesParamTypeId).toUInt(); + uint timeout = thing->setting(modbusRTUClientSettingsTimeoutParamTypeId).toUInt(); + QSerialPort::Parity parity = QSerialPort::Parity::NoParity; + QString parityString = thing->paramValue(modbusRTUClientThingParityParamTypeId).toString(); + if (parityString.contains("No")) { + parity = QSerialPort::Parity::NoParity; + } else if (parityString.contains("Even")) { + parity = QSerialPort::Parity::EvenParity; + } else if (parityString.contains("Odd")) { + parity = QSerialPort::Parity::OddParity; + } + qCDebug(dcModbusCommander()) << "Setting up RTU client"; + qCDebug(dcModbusCommander()) << " baud:" << baudrate; + qCDebug(dcModbusCommander()) << " stop bits:" << baudrate; + qCDebug(dcModbusCommander()) << " data bits:" << baudrate; + qCDebug(dcModbusCommander()) << " parity:" << parityString; + qCDebug(dcModbusCommander()) << " number of retires:" << numberOfRetries; + qCDebug(dcModbusCommander()) << " timeout:" << timeout; + + ModbusRTUMaster *modbusRTUMaster = new ModbusRTUMaster(serialPort, baudrate, parity, dataBits, stopBits, this); + modbusRTUMaster->setTimeout(timeout); + modbusRTUMaster->setNumberOfRetries(numberOfRetries); + connect(modbusRTUMaster, &ModbusRTUMaster::connectionStateChanged, this, &IntegrationPluginModbusCommander::onConnectionStateChanged); + connect(modbusRTUMaster, &ModbusRTUMaster::requestExecuted, this, &IntegrationPluginModbusCommander::onRequestExecuted); + connect(modbusRTUMaster, &ModbusRTUMaster::requestError, this, &IntegrationPluginModbusCommander::onRequestError); + connect(modbusRTUMaster, &ModbusRTUMaster::receivedCoil, this, &IntegrationPluginModbusCommander::onReceivedCoil); + connect(modbusRTUMaster, &ModbusRTUMaster::receivedDiscreteInput, this, &IntegrationPluginModbusCommander::onReceivedDiscreteInput); + connect(modbusRTUMaster, &ModbusRTUMaster::receivedHoldingRegister, this, &IntegrationPluginModbusCommander::onReceivedHoldingRegister); + connect(modbusRTUMaster, &ModbusRTUMaster::receivedInputRegister, this, &IntegrationPluginModbusCommander::onReceivedInputRegister); + connect(modbusRTUMaster, &ModbusRTUMaster::connectionStateChanged, info, [info, modbusRTUMaster, this] (bool connected) { + if (connected) { + info->finish(Thing::ThingErrorNoError); + m_modbusRTUMasters.insert(info->thing(), modbusRTUMaster); + } + }); + connect(thing, &Thing::settingChanged, thing, [thing, modbusRTUMaster] (const ParamTypeId ¶mTypeId, const QVariant &value) { + if (paramTypeId == modbusRTUClientSettingsNumberOfRetriesParamTypeId) { + qCDebug(dcModbusCommander()) << "Set number of reties" << thing->name() << value.toUInt(); + modbusRTUMaster->setNumberOfRetries(value.toUInt()); + } else if (paramTypeId == modbusRTUClientSettingsTimeoutParamTypeId) { + qCDebug(dcModbusCommander()) << "Set timeout " << thing->name() << value.toUInt(); + modbusRTUMaster->setTimeout(value.toUInt()); + } + }); + modbusRTUMaster->connectDevice(); + + } else if ((thing->thingClassId() == coilThingClassId) + || (thing->thingClassId() == discreteInputThingClassId) + || (thing->thingClassId() == holdingRegisterThingClassId) + || (thing->thingClassId() == inputRegisterThingClassId)) { + info->finish(Thing::ThingErrorNoError); + + } else { + Q_ASSERT_X(false, "setupThing", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8()); + } +} + + +void IntegrationPluginModbusCommander::postSetupThing(Thing *thing) +{ + qCDebug(dcModbusCommander()) << "Post setup thing" << thing->name(); if (!m_refreshTimer) { - // Refresh timer for TCP read int refreshTime = configValue(modbusCommanderPluginUpdateIntervalParamTypeId).toInt(); + qCDebug(dcModbusCommander()) << "Starting refresh timer with interval" << refreshTime << "s"; m_refreshTimer = hardwareManager()->pluginTimerManager()->registerTimer(refreshTime); connect(m_refreshTimer, &PluginTimer::timeout, this, [this] { foreach (Thing *thing, myThings()) { @@ -247,11 +290,16 @@ void IntegrationPluginModbusCommander::postSetupThing(Thing *info) }); } - if ((info->thingClassId() == coilThingClassId) || - (info->thingClassId() == discreteInputThingClassId) || - (info->thingClassId() == holdingRegisterThingClassId) || - (info->thingClassId() == inputRegisterThingClassId)) { - readRegister(info); + if ((thing->thingClassId() == modbusRTUClientThingClassId) || + (thing->thingClassId() == modbusTCPClientThingClassId)) { + thing->setStateValue(m_connectedStateTypeId.value(thing->thingClassId()), true); + } else if ((thing->thingClassId() == coilThingClassId) || + (thing->thingClassId() == discreteInputThingClassId) || + (thing->thingClassId() == holdingRegisterThingClassId) || + (thing->thingClassId() == inputRegisterThingClassId)) { + readRegister(thing); + } else { + Q_ASSERT_X(false, "postSetupThing", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8()); } } @@ -259,27 +307,33 @@ void IntegrationPluginModbusCommander::postSetupThing(Thing *info) void IntegrationPluginModbusCommander::executeAction(ThingActionInfo *info) { Thing *thing = info->thing(); + Action action = info->action(); if (thing->thingClassId() == coilThingClassId) { - if (info->action().actionTypeId() == coilValueActionTypeId) { + if (action.actionTypeId() == coilValueActionTypeId) { writeRegister(thing, info); return; + } else { + Q_ASSERT_X(false, "Execute action", QString("Unhandled action type id: %1").arg(action.actionTypeId().toString()).toUtf8()); } } else if (thing->thingClassId() == holdingRegisterThingClassId) { - if (info->action().actionTypeId() == holdingRegisterValueActionTypeId) { + if (action.actionTypeId() == holdingRegisterValueActionTypeId) { writeRegister(thing, info); return; + } else { + Q_ASSERT_X(false, "Execute action", QString("Unhandled action type id: %1").arg(action.actionTypeId().toString()).toUtf8()); } + } else { + Q_ASSERT_X(false, "Execute action", QString("Unhandled thingClassId: %1").arg(thing->thingClassId().toString()).toUtf8()); } - qCWarning(dcModbusCommander()) << "Unhandled deviceclass/actiontype in executeAction!"; - info->finish(Thing::ThingErrorThingClassNotFound); } void IntegrationPluginModbusCommander::thingRemoved(Thing *thing) { + qCDebug(dcModbusCommander()) << "Removing thing" << thing->name(); if (thing->thingClassId() == modbusTCPClientThingClassId) { ModbusTCPMaster *modbus = m_modbusTCPMasters.take(thing); modbus->deleteLater(); @@ -289,6 +343,7 @@ void IntegrationPluginModbusCommander::thingRemoved(Thing *thing) } if (myThings().empty()) { + qCDebug(dcModbusCommander()) << "No more Modbus commander things, stopping timer"; hardwareManager()->pluginTimerManager()->unregisterTimer(m_refreshTimer); m_refreshTimer = nullptr; } @@ -298,10 +353,13 @@ void IntegrationPluginModbusCommander::onPluginConfigurationChanged(const ParamT { // Check refresh schedule if (paramTypeId == modbusCommanderPluginUpdateIntervalParamTypeId) {; + qCDebug(dcModbusCommander()) << "Update interval has changed to" << value.toUInt() << "s"; if (m_refreshTimer) { uint refreshTime = value.toUInt(); m_refreshTimer->stop(); m_refreshTimer->startTimer(refreshTime); + } else { + qCWarning(dcModbusCommander()) << "Update interval changed but refresh timer is not initialized"; } } } @@ -312,9 +370,11 @@ void IntegrationPluginModbusCommander::onConnectionStateChanged(bool status) if (m_modbusRTUMasters.values().contains(static_cast(modbus))) { Thing *thing = m_modbusRTUMasters.key(static_cast(modbus)); + qCDebug(dcModbusCommander()) << "Connections state changed" << thing->name() << status; thing->setStateValue(modbusRTUClientConnectedStateTypeId, status); } else if (m_modbusTCPMasters.values().contains(static_cast(modbus))) { Thing *thing = m_modbusTCPMasters.key(static_cast(modbus)); + qCDebug(dcModbusCommander()) << "Connections state changed" << thing->name() << status; thing->setStateValue(modbusTCPClientConnectedStateTypeId, status); } } diff --git a/modbuscommander/integrationpluginmodbuscommander.json b/modbuscommander/integrationpluginmodbuscommander.json index 579f712..51a13e9 100644 --- a/modbuscommander/integrationpluginmodbuscommander.json +++ b/modbuscommander/integrationpluginmodbuscommander.json @@ -24,6 +24,22 @@ "displayName": "Modbus TCP client", "createMethods": ["user"], "interfaces": ["connectable"], + "settingsTypes": [ + { + "id": "a6aa4eff-205b-426d-ad05-90971a122138", + "name": "timeout", + "displayName": "Timeout", + "type": "uint", + "defaultValue": 100 + }, + { + "id": "b27c95c9-7584-46e1-9e62-89890c7bde67", + "name": "numberOfRetries", + "displayName": "Number of retries", + "type": "uint", + "defaultValue": 3 + } + ], "paramTypes": [ { "id": "2a3fcb23-931b-4ba1-b134-c49b656c76f7", @@ -57,6 +73,22 @@ "displayName": "Modbus RTU client", "createMethods": ["discovery", "user"], "interfaces": ["connectable"], + "settingsTypes": [ + { + "id": "b0af32f0-b8cc-4642-af5a-576732522b2c", + "name": "timeout", + "displayName": "Timeout", + "type": "uint", + "defaultValue": 100 + }, + { + "id": "c4f16d6c-c1f2-4862-b0bd-6fae7193eaa8", + "name": "numberOfRetries", + "displayName": "Number of retries", + "type": "uint", + "defaultValue": 3 + } + ], "paramTypes": [ { "id": "ed49f7d8-ab18-4c37-9b80-1004b75dcb91", @@ -98,7 +130,7 @@ "Even Parity", "Odd Parity" ], - "defaultValue": "Even Parity" + "defaultValue": "No Parity" } ], "stateTypes": [