diff --git a/libnymea-core/jsonrpc/modbusrtuhandler.cpp b/libnymea-core/jsonrpc/modbusrtuhandler.cpp index a218fd73..5f0f702f 100644 --- a/libnymea-core/jsonrpc/modbusrtuhandler.cpp +++ b/libnymea-core/jsonrpc/modbusrtuhandler.cpp @@ -79,7 +79,8 @@ ModbusRtuHandler::ModbusRtuHandler(ModbusRtuManager *modbusRtuManager, QObject * // GetModbusRtuMasters params.clear(); returns.clear(); description = "Get the list of configured modbus RTU masters."; - returns.insert("modbusRtuMasters", QVariantList() << objectRef("ModbusRtuMaster")); + returns.insert("o:modbusRtuMasters", QVariantList() << objectRef("ModbusRtuMaster")); + returns.insert("modbusError", enumRef()); registerMethod("GetModbusRtuMasters", description, params, returns); // ModbusRtuMasterAdded notification @@ -144,7 +145,6 @@ ModbusRtuHandler::ModbusRtuHandler(ModbusRtuManager *modbusRtuManager, QObject * emit SerialPortRemoved(params); }); - // Modbus manager connect(modbusRtuManager, &ModbusRtuManager::modbusRtuMasterAdded, this, [=](ModbusRtuMaster *modbusRtuMaster){ QVariantMap params; @@ -188,11 +188,19 @@ JsonReply *ModbusRtuHandler::GetModbusRtuMasters(const QVariantMap ¶ms) Q_UNUSED(params) QVariantMap returnMap; - QVariantList modbusList; - foreach (ModbusRtuMaster *modbusMaster, m_modbusRtuManager->modbusRtuMasters()) { - modbusList << packModbusRtuMaster(modbusMaster); + + if (m_modbusRtuManager->supported()) { + QVariantList modbusList; + foreach (ModbusRtuMaster *modbusMaster, m_modbusRtuManager->modbusRtuMasters()) { + modbusList << packModbusRtuMaster(modbusMaster); + } + returnMap.insert("modbusRtuMasters", modbusList); + returnMap.insert("modbusError", enumValueName(ModbusRtuManager::ModbusRtuErrorNoError)); + } else { + returnMap.insert("modbusError", enumValueName(ModbusRtuManager::ModbusRtuErrorNotSupported)); } - returnMap.insert("modbusRtuMasters", modbusList); + + return createReply(returnMap); } @@ -211,7 +219,6 @@ JsonReply *ModbusRtuHandler::AddModbusRtuMaster(const QVariantMap ¶ms) if (result.first == ModbusRtuManager::ModbusRtuErrorNoError) { returnMap.insert("modbusUuid", result.second); } - return createReply(returnMap); } diff --git a/libnymea-core/modbus/modbusrtumanager.cpp b/libnymea-core/modbus/modbusrtumanager.cpp index 55b20a37..20de42c6 100644 --- a/libnymea-core/modbus/modbusrtumanager.cpp +++ b/libnymea-core/modbus/modbusrtumanager.cpp @@ -70,6 +70,15 @@ SerialPortMonitor *ModbusRtuManager::serialPortMonitor() const return m_serialPortMonitor; } +bool ModbusRtuManager::supported() const +{ +#ifdef WITH_QTSERIALBUS + return true; +#else + return false; +#endif +} + QList ModbusRtuManager::modbusRtuMasters() const { return m_modbusRtuMasters.values(); @@ -91,6 +100,11 @@ ModbusRtuMaster *ModbusRtuManager::getModbusRtuMaster(const QUuid &modbusUuid) QPair ModbusRtuManager::addNewModbusRtuMaster(const QString &serialPort, qint32 baudrate, QSerialPort::Parity parity, QSerialPort::DataBits dataBits, QSerialPort::StopBits stopBits) { + if (!supported()) { + qCWarning(dcModbusRtu()) << "Cannot add new modbus RTU master because serialbus is not suppoerted on this platform."; + return QPair(ModbusRtuErrorNotSupported, QUuid()); + } + // Check if the serial port exists if (!m_serialPortMonitor->serialPortAvailable(serialPort)) { qCWarning(dcModbusRtu()) << "Cannot add new modbus RTU master because the serial port" << serialPort << "is not available any more"; @@ -105,6 +119,7 @@ QPair ModbusRtuManager::addNewModbusRt // Note: We could add the modbus master event if a connection is currently not possible...not sure yet if (!modbusMaster->connectDevice()) { qCWarning(dcModbusRtu()) << "Failed to add new modbus RTU master. Could not connect to" << modbus << parity << dataBits << stopBits; + modbusMaster->deleteLater(); return QPair(ModbusRtuErrorConnectionFailed, QUuid()); } @@ -117,6 +132,11 @@ QPair ModbusRtuManager::addNewModbusRt ModbusRtuManager::ModbusRtuError ModbusRtuManager::reconfigureModbusRtuMaster(const QUuid &modbusUuid, const QString &serialPort, qint32 baudrate, QSerialPort::Parity parity, QSerialPort::DataBits dataBits, QSerialPort::StopBits stopBits) { + if (!supported()) { + qCWarning(dcModbusRtu()) << "Cannot reconfigure modbus RTU master because serialbus is not suppoerted on this platform."; + return ModbusRtuErrorNotSupported; + } + if (!m_modbusRtuMasters.contains(modbusUuid)) { qCWarning(dcModbusRtu()) << "Could not reconfigure modbus RTU master because no resource could be found with uuid" << modbusUuid.toString(); return ModbusRtuErrorUuidNotFound; @@ -137,6 +157,7 @@ ModbusRtuManager::ModbusRtuError ModbusRtuManager::reconfigureModbusRtuMaster(co // Connect again if (!modbusMaster->connectDevice()) { qCWarning(dcModbusRtu()) << "Failed to connect to" << m_modbusRtuMasters.value(modbusUuid); + // FIXME: check if we should reload the old configuration emit modbusRtuMasterChanged(m_modbusRtuMasters.value(modbusUuid)); return ModbusRtuErrorConnectionFailed; } @@ -144,11 +165,17 @@ ModbusRtuManager::ModbusRtuError ModbusRtuManager::reconfigureModbusRtuMaster(co emit modbusRtuMasterChanged(m_modbusRtuMasters.value(modbusUuid)); qCDebug(dcModbusRtu()) << "Reconfigured successfully" << m_modbusRtuMasters.value(modbusUuid); + saveModbusRtuMaster(modbusMaster); return ModbusRtuErrorNoError; } ModbusRtuManager::ModbusRtuError ModbusRtuManager::removeModbusRtuMaster(const QUuid &modbusUuid) { + if (!supported()) { + qCWarning(dcModbusRtu()) << "Cannot remove modbus RTU master because serialbus is not suppoerted on this platform."; + return ModbusRtuErrorNotSupported; + } + if (!m_modbusRtuMasters.contains(modbusUuid)) { qCWarning(dcModbusRtu()) << "Could not remove modbus RTU master because no resource could be found with uuid" << modbusUuid.toString(); return ModbusRtuErrorUuidNotFound; @@ -159,6 +186,14 @@ ModbusRtuManager::ModbusRtuError ModbusRtuManager::removeModbusRtuMaster(const Q modbusMaster->disconnectDevice(); modbusMaster->deleteLater(); + // Remove from settings + NymeaSettings settings(NymeaSettings::SettingsRoleModbusRtu); + settings.beginGroup("ModbusRtuMasters"); + settings.beginGroup(modbusUuid.toString()); + settings.remove(""); + settings.endGroup(); // modbusUuid + settings.endGroup(); // ModbusRtuMasters + emit modbusRtuMasterRemoved(modbusMaster); return ModbusRtuErrorNoError; @@ -166,9 +201,11 @@ ModbusRtuManager::ModbusRtuError ModbusRtuManager::removeModbusRtuMaster(const Q void ModbusRtuManager::loadRtuMasters() { + if (!supported()) + return; + NymeaSettings settings(NymeaSettings::SettingsRoleModbusRtu); qCDebug(dcModbusRtu()) << "Loading modbus RTU resources from" << settings.fileName(); - settings.beginGroup("ModbusRtuMasters"); foreach (const QString &uuidString, settings.childGroups()) { settings.beginGroup(uuidString); diff --git a/libnymea-core/modbus/modbusrtumanager.h b/libnymea-core/modbus/modbusrtumanager.h index c0776ac0..67adf82f 100644 --- a/libnymea-core/modbus/modbusrtumanager.h +++ b/libnymea-core/modbus/modbusrtumanager.h @@ -52,6 +52,8 @@ public: ModbusRtuErrorNotAvailable, ModbusRtuErrorUuidNotFound, ModbusRtuErrorHardwareNotFound, + ModbusRtuErrorResourceBusy, + ModbusRtuErrorNotSupported, ModbusRtuErrorConnectionFailed }; Q_ENUM(ModbusRtuError) @@ -61,6 +63,8 @@ public: SerialPortMonitor *serialPortMonitor() const; + bool supported() const; + QList modbusRtuMasters() const; bool hasModbusRtuMaster(const QUuid &modbusUuid) const; ModbusRtuMaster *getModbusRtuMaster(const QUuid &modbusUuid); diff --git a/libnymea-core/modbus/modbusrtumasterimpl.cpp b/libnymea-core/modbus/modbusrtumasterimpl.cpp index ac8189b6..27f2d773 100644 --- a/libnymea-core/modbus/modbusrtumasterimpl.cpp +++ b/libnymea-core/modbus/modbusrtumasterimpl.cpp @@ -69,8 +69,10 @@ ModbusRtuMasterImpl::ModbusRtuMasterImpl(const QUuid &modbusUuid, const QString }); connect(m_modbus, &QModbusRtuSerialMaster::errorOccurred, this, [=](QModbusDevice::Error error){ - qCDebug(dcModbusRtu()) << "Error occured for modbus RTU master" << m_modbusUuid.toString() << m_serialPort << error << m_modbus->errorString(); - // TODO: check if disconnected... + qCWarning(dcModbusRtu()) << "Error occured for modbus RTU master" << m_modbusUuid.toString() << m_serialPort << error << m_modbus->errorString(); + if (error != QModbusDevice::NoError) { + disconnectDevice(); + } }); #endif }