From 01262b43e9db22030e322832ed22b1e630d4fa68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Thu, 4 Feb 2021 18:05:47 +0100 Subject: [PATCH] Add basic structure of the resource and start implement modbus rtu master --- ...odbusrtuhardwareresourceimplementation.cpp | 11 +- .../modbusrtuhardwareresourceimplementation.h | 7 +- .../hardwaremanagerimplementation.cpp | 6 + libnymea-core/hardwaremanagerimplementation.h | 2 + libnymea-core/libnymea-core.pro | 12 +- libnymea-core/modbus/modbusrtumanager.cpp | 28 +++ libnymea-core/modbus/modbusrtumanager.h | 16 ++ libnymea-core/modbus/modbusrtumasterimpl.cpp | 218 ++++++++++++++++++ libnymea-core/modbus/modbusrtumasterimpl.h | 83 +++++++ libnymea-core/modbus/modbusrtureplyimpl.cpp | 94 ++++++++ ...dbusrtumaster.cpp => modbusrtureplyimpl.h} | 39 +++- .../modbus/modbusrtuhardwareresource.cpp | 2 +- .../modbus/modbusrtuhardwareresource.h | 6 + libnymea/hardware/modbus/modbusrtumaster.h | 70 ++++++ .../hardware/modbus/modbusrtureply.h | 42 +++- libnymea/hardwaremanager.h | 2 + libnymea/libnymea.pro | 2 + 17 files changed, 618 insertions(+), 22 deletions(-) create mode 100644 libnymea-core/modbus/modbusrtumasterimpl.cpp create mode 100644 libnymea-core/modbus/modbusrtumasterimpl.h create mode 100644 libnymea-core/modbus/modbusrtureplyimpl.cpp rename libnymea-core/modbus/{modbusrtumaster.cpp => modbusrtureplyimpl.h} (60%) create mode 100644 libnymea/hardware/modbus/modbusrtumaster.h rename libnymea-core/modbus/modbusrtumaster.h => libnymea/hardware/modbus/modbusrtureply.h (63%) diff --git a/libnymea-core/hardware/modbus/modbusrtuhardwareresourceimplementation.cpp b/libnymea-core/hardware/modbus/modbusrtuhardwareresourceimplementation.cpp index 26d347ec..902d75ba 100644 --- a/libnymea-core/hardware/modbus/modbusrtuhardwareresourceimplementation.cpp +++ b/libnymea-core/hardware/modbus/modbusrtuhardwareresourceimplementation.cpp @@ -31,17 +31,24 @@ #include "modbusrtuhardwareresourceimplementation.h" #include "loggingcategories.h" #include "nymeasettings.h" +#include "modbus/modbusrtumanager.h" NYMEA_LOGGING_CATEGORY(dcModbusRtuResource, "ModbusRtuResource") namespace nymeaserver { -ModbusRtuHardwareResourceImplementation::ModbusRtuHardwareResourceImplementation(QObject *parent) : - ModbusRtuHardwareResource(parent) +ModbusRtuHardwareResourceImplementation::ModbusRtuHardwareResourceImplementation(ModbusRtuManager *modbusRtuManager, QObject *parent) : + ModbusRtuHardwareResource(parent), + m_modbusRtuManager(modbusRtuManager) { } +//QList ModbusRtuHardwareResourceImplementation::modbusRtuMasters() const +//{ +// return m_modbusRtuManager->modbusRtuMasters(); +//} + bool ModbusRtuHardwareResourceImplementation::available() const { return m_available; diff --git a/libnymea-core/hardware/modbus/modbusrtuhardwareresourceimplementation.h b/libnymea-core/hardware/modbus/modbusrtuhardwareresourceimplementation.h index 8fd10b2d..ef33dd69 100644 --- a/libnymea-core/hardware/modbus/modbusrtuhardwareresourceimplementation.h +++ b/libnymea-core/hardware/modbus/modbusrtuhardwareresourceimplementation.h @@ -33,6 +33,7 @@ #include +#include "modbus/modbusrtumanager.h" #include "hardware/modbus/modbusrtuhardwareresource.h" namespace nymeaserver { @@ -41,7 +42,9 @@ class ModbusRtuHardwareResourceImplementation : public ModbusRtuHardwareResource { Q_OBJECT public: - explicit ModbusRtuHardwareResourceImplementation(QObject *parent = nullptr); + explicit ModbusRtuHardwareResourceImplementation(ModbusRtuManager *modbusRtuManager, QObject *parent = nullptr); + + //QList modbusRtuMasters() const override; bool available() const override; bool enabled() const override; @@ -50,11 +53,11 @@ public slots: bool enable(); bool disable(); - protected: void setEnabled(bool enabled) override; private: + ModbusRtuManager *m_modbusRtuManager = nullptr; bool m_available = false; bool m_enabled = false; diff --git a/libnymea-core/hardwaremanagerimplementation.cpp b/libnymea-core/hardwaremanagerimplementation.cpp index 8d19558c..754924f0 100644 --- a/libnymea-core/hardwaremanagerimplementation.cpp +++ b/libnymea-core/hardwaremanagerimplementation.cpp @@ -43,6 +43,7 @@ #include "hardware/network/mqtt/mqttproviderimplementation.h" #include "hardware/i2c/i2cmanagerimplementation.h" #include "hardware/zigbee/zigbeehardwareresourceimplementation.h" +#include "hardware/modbus/modbusrtuhardwareresourceimplementation.h" namespace nymeaserver { @@ -142,6 +143,11 @@ ZigbeeHardwareResource *HardwareManagerImplementation::zigbeeResource() return m_zigbeeResource; } +ModbusRtuHardwareResouce *HardwareManagerImplementation::modbusRtuResource() +{ + return m_modbusRtuResource; +} + void HardwareManagerImplementation::thingsLoaded() { m_zigbeeResource->thingsLoaded(); diff --git a/libnymea-core/hardwaremanagerimplementation.h b/libnymea-core/hardwaremanagerimplementation.h index 8a67e54e..3d799adf 100644 --- a/libnymea-core/hardwaremanagerimplementation.h +++ b/libnymea-core/hardwaremanagerimplementation.h @@ -61,6 +61,7 @@ public: MqttProvider *mqttProvider() override; I2CManager *i2cManager() override; ZigbeeHardwareResource *zigbeeResource() override; + ModbusRtuHardwareResouce *modbusRtuResource() override; public slots: void thingsLoaded(); @@ -79,6 +80,7 @@ private: MqttProvider *m_mqttProvider = nullptr; I2CManager *m_i2cManager = nullptr; ZigbeeHardwareResourceImplementation *m_zigbeeResource = nullptr; + ModbusRtuHardwareResouce *m_modbusRtuResource = nullptr; }; } diff --git a/libnymea-core/libnymea-core.pro b/libnymea-core/libnymea-core.pro index 6847069d..c427f3d6 100644 --- a/libnymea-core/libnymea-core.pro +++ b/libnymea-core/libnymea-core.pro @@ -40,7 +40,7 @@ CONFIG(withoutpython) { # Let's check if the package exists, not the qt version packagesExist(Qt5SerialBus) { DEFINES += WITH_QTSERIALBUS - Qt += serialbus + Qt += serialbus serialport } else { message("Qt5SerialBus not available") } @@ -55,7 +55,6 @@ RESOURCES += $$top_srcdir/icons.qrc \ HEADERS += nymeacore.h \ - hardware/modbus/modbusrtuhardwareresourceimplementation.h \ integrations/apikeysprovidersloader.h \ integrations/plugininfocache.h \ integrations/python/pyapikeystorage.h \ @@ -70,7 +69,8 @@ HEADERS += nymeacore.h \ jsonrpc/modbusrtuhandler.h \ jsonrpc/zigbeehandler.h \ modbus/modbusrtumanager.h \ - modbus/modbusrtumaster.h \ + modbus/modbusrtumasterimpl.h \ + modbus/modbusrtureplyimpl.h \ ruleengine/ruleengine.h \ ruleengine/rule.h \ ruleengine/stateevaluator.h \ @@ -133,6 +133,7 @@ HEADERS += nymeacore.h \ hardware/bluetoothlowenergy/bluetoothlowenergymanagerimplementation.h \ hardware/bluetoothlowenergy/bluetoothlowenergydeviceimplementation.h \ hardware/bluetoothlowenergy/bluetoothdiscoveryreplyimplementation.h \ + hardware/modbus/modbusrtuhardwareresourceimplementation.h \ hardware/network/networkaccessmanagerimpl.h \ hardware/network/upnp/upnpdiscoveryimplementation.h \ hardware/network/upnp/upnpdiscoveryrequest.h \ @@ -153,7 +154,6 @@ HEADERS += nymeacore.h \ SOURCES += nymeacore.cpp \ - hardware/modbus/modbusrtuhardwareresourceimplementation.cpp \ integrations/apikeysprovidersloader.cpp \ integrations/plugininfocache.cpp \ integrations/thingmanagerimplementation.cpp \ @@ -162,7 +162,8 @@ SOURCES += nymeacore.cpp \ jsonrpc/modbusrtuhandler.cpp \ jsonrpc/zigbeehandler.cpp \ modbus/modbusrtumanager.cpp \ - modbus/modbusrtumaster.cpp \ + modbus/modbusrtumasterimpl.cpp \ + modbus/modbusrtureplyimpl.cpp \ ruleengine/ruleengine.cpp \ ruleengine/rule.cpp \ ruleengine/stateevaluator.cpp \ @@ -224,6 +225,7 @@ SOURCES += nymeacore.cpp \ hardware/bluetoothlowenergy/bluetoothlowenergymanagerimplementation.cpp \ hardware/bluetoothlowenergy/bluetoothlowenergydeviceimplementation.cpp \ hardware/bluetoothlowenergy/bluetoothdiscoveryreplyimplementation.cpp \ + hardware/modbus/modbusrtuhardwareresourceimplementation.cpp \ hardware/network/networkaccessmanagerimpl.cpp \ hardware/network/upnp/upnpdiscoveryimplementation.cpp \ hardware/network/upnp/upnpdiscoveryrequest.cpp \ diff --git a/libnymea-core/modbus/modbusrtumanager.cpp b/libnymea-core/modbus/modbusrtumanager.cpp index af2edba9..12d51bfc 100644 --- a/libnymea-core/modbus/modbusrtumanager.cpp +++ b/libnymea-core/modbus/modbusrtumanager.cpp @@ -41,4 +41,32 @@ ModbusRtuManager::ModbusRtuManager(QObject *parent) : QObject(parent) } +QList ModbusRtuManager::modbusRtuMasters() const +{ + return m_modbusRtuMasters.values(); +} + +bool ModbusRtuManager::hasModbusRtuMaster(const QUuid &modbusUuid) const +{ + return m_modbusRtuMasters.value(modbusUuid) != nullptr; +} + +ModbusRtuMaster *ModbusRtuManager::getModbusRtuMaster(const QUuid &modbusUuid) +{ + if (hasModbusRtuMaster(modbusUuid)) { + return m_modbusRtuMasters.value(modbusUuid); + } + + return nullptr; +} + +void ModbusRtuManager::init() +{ + // Load uart configurations + + // Init modbus rtu masters + + // Connect signals +} + } diff --git a/libnymea-core/modbus/modbusrtumanager.h b/libnymea-core/modbus/modbusrtumanager.h index 47ddfdbb..f31dca9a 100644 --- a/libnymea-core/modbus/modbusrtumanager.h +++ b/libnymea-core/modbus/modbusrtumanager.h @@ -32,6 +32,9 @@ #define MODBUSRTUMANAGER_H #include +#include + +#include "hardware/modbus/modbusrtumaster.h" namespace nymeaserver { @@ -40,8 +43,21 @@ class ModbusRtuManager : public QObject Q_OBJECT public: explicit ModbusRtuManager(QObject *parent = nullptr); + ~ModbusRtuManager() = default; + + QList modbusRtuMasters() const; + bool hasModbusRtuMaster(const QUuid &modbusUuid) const; + ModbusRtuMaster *getModbusRtuMaster(const QUuid &modbusUuid); + + void init(); signals: + void modbusRtuMasterAdded(ModbusRtuMaster *modbusRtuMaster); + void modbusRtuMasterRemoved(ModbusRtuMaster *modbusRtuMaster); + void modbusRtuMasterChanged(ModbusRtuMaster *modbusRtuMaster); + +private: + QHash m_modbusRtuMasters; }; diff --git a/libnymea-core/modbus/modbusrtumasterimpl.cpp b/libnymea-core/modbus/modbusrtumasterimpl.cpp new file mode 100644 index 00000000..ba6c3406 --- /dev/null +++ b/libnymea-core/modbus/modbusrtumasterimpl.cpp @@ -0,0 +1,218 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2021, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea. +* This project including source code and documentation is protected by +* copyright law, and remains the property of nymea GmbH. All rights, including +* reproduction, publication, editing and translation, are reserved. The use of +* this project is subject to the terms of a license agreement to be concluded +* with nymea GmbH in accordance with the terms of use of nymea GmbH, available +* under https://nymea.io/license +* +* GNU Lesser General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the +* terms of the GNU Lesser General Public License as published by the Free +* Software Foundation; version 3. This project is distributed in the hope that +* it will be useful, but WITHOUT ANY WARRANTY; without even the implied +* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this project. If not, see . +* +* For any further details and any questions please contact us under +* contact@nymea.io or see our FAQ/Licensing Information on +* https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "modbusrtumasterimpl.h" +#include "modbusrtureplyimpl.h" + +#ifdef WITH_QTSERIALBUS +#include +#include +#endif + +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) : + ModbusRtuMaster(parent), + m_modbusUuid(modbusUuid) +{ +#ifdef WITH_QTSERIALBUS + m_modbus = new QModbusRtuSerialMaster(this); + m_modbus->setConnectionParameter(QModbusDevice::SerialPortNameParameter, serialPort); + m_modbus->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, baudrate); + m_modbus->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, dataBits); + m_modbus->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, stopBits); + m_modbus->setConnectionParameter(QModbusDevice::SerialParityParameter, parity); + + connect(m_modbus, &QModbusTcpClient::stateChanged, this, [=](QModbusDevice::State state){ + qCDebug(dcModbusRtu()) << "Connection state changed" << m_modbusUuid.toString() << serialPort << state; + }); + //connect(m_modbus, &QModbusRtuSerialMaster::errorOccurred, this, &ModbusRtuMaster::onModbusErrorOccurred); + +// m_reconnectTimer = new QTimer(this); +// m_reconnectTimer->setSingleShot(true); +// connect(m_reconnectTimer, &QTimer::timeout, this, &ModbusRTUMaster::onReconnectTimer); + +#endif +} + +QUuid ModbusRtuMasterImpl::modbusUuid() const +{ + return m_modbusUuid; +} + +QString ModbusRtuMasterImpl::serialPort() const +{ + return m_serialPort; +} + +bool ModbusRtuMasterImpl::connected() const +{ + return m_connected; +} + +ModbusRtuReply *ModbusRtuMasterImpl::readCoil(uint slaveAddress, uint registerAddress, uint size) +{ +#ifndef WITH_QTSERIALBUS + Q_UNUSED(slaveAddress) + Q_UNUSED(registerAddress) + Q_UNUSED(size) + return nullptr; +#else + + QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::Coils, registerAddress, size); + QModbusReply *modbusReply = m_modbus->sendReadRequest(request, slaveAddress); + + // TODO: fill data and return reply + ModbusRtuReplyImpl *reply = new ModbusRtuReplyImpl(slaveAddress, registerAddress, this); + connect(modbusReply, &QModbusReply::finished, modbusReply, [=](){ + if (modbusReply->error() != QModbusDevice::NoError) { + qCWarning(dcModbusRtu()) << "Read coil request finished with error" << modbusReply->error() << modbusReply->errorString(); + + } + }); + return qobject_cast(reply); +#endif +} + +ModbusRtuReply *ModbusRtuMasterImpl::readDiscreteInput(uint slaveAddress, uint registerAddress, uint size) +{ +#ifndef WITH_QTSERIALBUS + Q_UNUSED(slaveAddress) + Q_UNUSED(registerAddress) + Q_UNUSED(size) + return nullptr; +#else + // TODO: + Q_UNUSED(slaveAddress) + Q_UNUSED(registerAddress) + Q_UNUSED(size) + return nullptr; +#endif +} + +ModbusRtuReply *ModbusRtuMasterImpl::readInputRegister(uint slaveAddress, uint registerAddress, uint size) +{ +#ifndef WITH_QTSERIALBUS + Q_UNUSED(slaveAddress) + Q_UNUSED(registerAddress) + Q_UNUSED(size) + return nullptr; +#else + // TODO: + Q_UNUSED(slaveAddress) + Q_UNUSED(registerAddress) + Q_UNUSED(size) + return nullptr; +#endif +} + +ModbusRtuReply *ModbusRtuMasterImpl::readHoldingRegister(uint slaveAddress, uint registerAddress, uint size) +{ +#ifndef WITH_QTSERIALBUS + Q_UNUSED(slaveAddress) + Q_UNUSED(registerAddress) + Q_UNUSED(size) + return nullptr; +#else + // TODO: + Q_UNUSED(slaveAddress) + Q_UNUSED(registerAddress) + Q_UNUSED(size) + return nullptr; +#endif +} + +ModbusRtuReply *ModbusRtuMasterImpl::writeCoil(uint slaveAddress, uint registerAddress, bool status) +{ +#ifndef WITH_QTSERIALBUS + Q_UNUSED(slaveAddress) + Q_UNUSED(registerAddress) + Q_UNUSED(size) + return nullptr; +#else + // TODO: + Q_UNUSED(slaveAddress) + Q_UNUSED(registerAddress) + Q_UNUSED(status) + return nullptr; +#endif +} + +ModbusRtuReply *ModbusRtuMasterImpl::writeCoils(uint slaveAddress, uint registerAddress, const QVector &values) +{ +#ifndef WITH_QTSERIALBUS + Q_UNUSED(slaveAddress) + Q_UNUSED(registerAddress) + Q_UNUSED(values) + return nullptr; +#else + // TODO: + Q_UNUSED(slaveAddress) + Q_UNUSED(registerAddress) + Q_UNUSED(values) + return nullptr; +#endif +} + +ModbusRtuReply *ModbusRtuMasterImpl::writeHoldingRegister(uint slaveAddress, uint registerAddress, quint16 value) +{ +#ifndef WITH_QTSERIALBUS + Q_UNUSED(slaveAddress) + Q_UNUSED(registerAddress) + Q_UNUSED(value) + return nullptr; +#else + // TODO: + Q_UNUSED(slaveAddress) + Q_UNUSED(registerAddress) + Q_UNUSED(value) + return nullptr; +#endif +} + +ModbusRtuReply *ModbusRtuMasterImpl::writeHoldingRegisters(uint slaveAddress, uint registerAddress, const QVector &values) +{ +#ifndef WITH_QTSERIALBUS + Q_UNUSED(slaveAddress) + Q_UNUSED(registerAddress) + Q_UNUSED(values) + return nullptr; +#else + // TODO: + Q_UNUSED(slaveAddress) + Q_UNUSED(registerAddress) + Q_UNUSED(values) + return nullptr; +#endif +} + +} diff --git a/libnymea-core/modbus/modbusrtumasterimpl.h b/libnymea-core/modbus/modbusrtumasterimpl.h new file mode 100644 index 00000000..b47f6b7a --- /dev/null +++ b/libnymea-core/modbus/modbusrtumasterimpl.h @@ -0,0 +1,83 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2021, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea. +* This project including source code and documentation is protected by +* copyright law, and remains the property of nymea GmbH. All rights, including +* reproduction, publication, editing and translation, are reserved. The use of +* this project is subject to the terms of a license agreement to be concluded +* with nymea GmbH in accordance with the terms of use of nymea GmbH, available +* under https://nymea.io/license +* +* GNU Lesser General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the +* terms of the GNU Lesser General Public License as published by the Free +* Software Foundation; version 3. This project is distributed in the hope that +* it will be useful, but WITHOUT ANY WARRANTY; without even the implied +* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this project. If not, see . +* +* For any further details and any questions please contact us under +* contact@nymea.io or see our FAQ/Licensing Information on +* https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef MODBUSRTUMASTERIMPL_H +#define MODBUSRTUMASTERIMPL_H + +#include + +#ifdef WITH_QTSERIALBUS +#include +#include +#endif + +#include "hardware/modbus/modbusrtumaster.h" + +namespace nymeaserver { + +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); + ~ModbusRtuMasterImpl() override = default; + + QUuid modbusUuid() const override; + + QString serialPort() const override; + + bool connected() const override; + + // Requests + ModbusRtuReply *readCoil(uint slaveAddress, uint registerAddress, uint size = 1) override; + ModbusRtuReply *readDiscreteInput(uint slaveAddress, uint registerAddress, uint size = 1) override; + ModbusRtuReply *readInputRegister(uint slaveAddress, uint registerAddress, uint size = 1) override; + ModbusRtuReply *readHoldingRegister(uint slaveAddress, uint registerAddress, uint size = 1) override; + + ModbusRtuReply *writeCoil(uint slaveAddress, uint registerAddress, bool status) override; + ModbusRtuReply *writeCoils(uint slaveAddress, uint registerAddress, const QVector &values) override; + + ModbusRtuReply *writeHoldingRegister(uint slaveAddress, uint registerAddress, quint16 value) override; + ModbusRtuReply *writeHoldingRegisters(uint slaveAddress, uint registerAddress, const QVector &values) override; + +private: + QUuid m_modbusUuid; + +#ifdef WITH_QTSERIALBUS + QModbusRtuSerialMaster *m_modbus = nullptr; +#endif + + QString m_serialPort; + bool m_connected = false; +}; + +} + +#endif // MODBUSRTUMASTERIMPL_H diff --git a/libnymea-core/modbus/modbusrtureplyimpl.cpp b/libnymea-core/modbus/modbusrtureplyimpl.cpp new file mode 100644 index 00000000..ff14b0f6 --- /dev/null +++ b/libnymea-core/modbus/modbusrtureplyimpl.cpp @@ -0,0 +1,94 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2021, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea. +* This project including source code and documentation is protected by +* copyright law, and remains the property of nymea GmbH. All rights, including +* reproduction, publication, editing and translation, are reserved. The use of +* this project is subject to the terms of a license agreement to be concluded +* with nymea GmbH in accordance with the terms of use of nymea GmbH, available +* under https://nymea.io/license +* +* GNU Lesser General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the +* terms of the GNU Lesser General Public License as published by the Free +* Software Foundation; version 3. This project is distributed in the hope that +* it will be useful, but WITHOUT ANY WARRANTY; without even the implied +* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this project. If not, see . +* +* For any further details and any questions please contact us under +* contact@nymea.io or see our FAQ/Licensing Information on +* https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "modbusrtureplyimpl.h" + + +namespace nymeaserver { + +ModbusRtuReplyImpl::ModbusRtuReplyImpl(uint slaveAddress, uint registerAddress, QObject *parent) : + ModbusRtuReply(parent), + m_slaveAddress(slaveAddress), + m_registerAddress(registerAddress) +{ + +} + +bool ModbusRtuReplyImpl::isFinished() const +{ + return m_finished; +} + +void ModbusRtuReplyImpl::setFinished(bool finished) +{ + m_finished = finished; +} + +uint ModbusRtuReplyImpl::slaveAddress() const +{ + return m_slaveAddress; +} + +uint ModbusRtuReplyImpl::registerAddress() const +{ + return m_registerAddress; +} + +QString ModbusRtuReplyImpl::errorString() const +{ + return m_errorString; +} + +void ModbusRtuReplyImpl::setErrorString(const QString &errorString) +{ + m_errorString = errorString; +} + +ModbusRtuReply::Error ModbusRtuReplyImpl::error() const +{ + return m_error; +} + +void ModbusRtuReplyImpl::setError(ModbusRtuReply::Error error) +{ + m_error = error; +} + +QVector ModbusRtuReplyImpl::result() const +{ + return m_result; +} + +void ModbusRtuReplyImpl::setResult(const QVector &result) +{ + m_result = result; +} + +} diff --git a/libnymea-core/modbus/modbusrtumaster.cpp b/libnymea-core/modbus/modbusrtureplyimpl.h similarity index 60% rename from libnymea-core/modbus/modbusrtumaster.cpp rename to libnymea-core/modbus/modbusrtureplyimpl.h index 69f98b13..10da27c5 100644 --- a/libnymea-core/modbus/modbusrtumaster.cpp +++ b/libnymea-core/modbus/modbusrtureplyimpl.h @@ -28,13 +28,46 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include "modbusrtumaster.h" +#ifndef MODBUSRTUREPLYIMPL_H +#define MODBUSRTUREPLYIMPL_H + +#include + +#include "hardware/modbus/modbusrtureply.h" namespace nymeaserver { -ModbusRtuMaster::ModbusRtuMaster(QObject *parent) : QObject(parent) +class ModbusRtuReplyImpl : public ModbusRtuReply { + Q_OBJECT +public: + explicit ModbusRtuReplyImpl(uint slaveAddress, uint registerAddress, QObject *parent = nullptr); + + bool isFinished() const override; + void setFinished(bool finished); + + uint slaveAddress() const override; + uint registerAddress() const override; + + QString errorString() const override; + void setErrorString(const QString &errorString); + + ModbusRtuReply::Error error() const override; + void setError(ModbusRtuReply::Error error); + + QVector result() const override; + void setResult(const QVector &result); + +private: + bool m_finished = false; + uint m_slaveAddress; + uint m_registerAddress; + Error m_error = UnknownError; + QString m_errorString; + QVector m_result; + +}; } -} +#endif // MODBUSRTUREPLYIMPL_H diff --git a/libnymea/hardware/modbus/modbusrtuhardwareresource.cpp b/libnymea/hardware/modbus/modbusrtuhardwareresource.cpp index 2b9be8a4..15756334 100644 --- a/libnymea/hardware/modbus/modbusrtuhardwareresource.cpp +++ b/libnymea/hardware/modbus/modbusrtuhardwareresource.cpp @@ -31,7 +31,7 @@ #include "modbusrtuhardwareresource.h" ModbusRtuHardwareResource::ModbusRtuHardwareResource(QObject *parent) : - HardwareResource("Modbus RTU client resource", parent) + HardwareResource("Modbus RTU resource", parent) { } diff --git a/libnymea/hardware/modbus/modbusrtuhardwareresource.h b/libnymea/hardware/modbus/modbusrtuhardwareresource.h index a6cfc497..0767e7e5 100644 --- a/libnymea/hardware/modbus/modbusrtuhardwareresource.h +++ b/libnymea/hardware/modbus/modbusrtuhardwareresource.h @@ -31,7 +31,10 @@ #ifndef MODBUSRTUHARDWARERESOURCE_H #define MODBUSRTUHARDWARERESOURCE_H +#include #include + +#include "modbusrtumaster.h" #include "hardwareresource.h" class ModbusRtuHardwareResource : public HardwareResource @@ -40,6 +43,9 @@ class ModbusRtuHardwareResource : public HardwareResource public: explicit ModbusRtuHardwareResource(QObject *parent = nullptr); virtual ~ModbusRtuHardwareResource() = default; + //virtual QList modbusRtuMasters() const = 0; + +protected: signals: diff --git a/libnymea/hardware/modbus/modbusrtumaster.h b/libnymea/hardware/modbus/modbusrtumaster.h new file mode 100644 index 00000000..754ccfb2 --- /dev/null +++ b/libnymea/hardware/modbus/modbusrtumaster.h @@ -0,0 +1,70 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2021, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea. +* This project including source code and documentation is protected by +* copyright law, and remains the property of nymea GmbH. All rights, including +* reproduction, publication, editing and translation, are reserved. The use of +* this project is subject to the terms of a license agreement to be concluded +* with nymea GmbH in accordance with the terms of use of nymea GmbH, available +* under https://nymea.io/license +* +* GNU Lesser General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the +* terms of the GNU Lesser General Public License as published by the Free +* Software Foundation; version 3. This project is distributed in the hope that +* it will be useful, but WITHOUT ANY WARRANTY; without even the implied +* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this project. If not, see . +* +* For any further details and any questions please contact us under +* contact@nymea.io or see our FAQ/Licensing Information on +* https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef MODBUSRTUMASTER_H +#define MODBUSRTUMASTER_H + +#include +#include + +#include "modbusrtureply.h" + +class ModbusRtuMaster : public QObject +{ + Q_OBJECT +public: + // Properties + virtual QUuid modbusUuid() const = 0; + virtual QString serialPort() const = 0; + + virtual bool connected() const = 0; + + // Requests + virtual ModbusRtuReply *readCoil(uint slaveAddress, uint registerAddress, uint size = 1) = 0; + virtual ModbusRtuReply *readDiscreteInput(uint slaveAddress, uint registerAddress, uint size = 1) = 0; + virtual ModbusRtuReply *readInputRegister(uint slaveAddress, uint registerAddress, uint size = 1) = 0; + virtual ModbusRtuReply *readHoldingRegister(uint slaveAddress, uint registerAddress, uint size = 1) = 0; + + virtual ModbusRtuReply *writeCoil(uint slaveAddress, uint registerAddress, bool status) = 0; + virtual ModbusRtuReply *writeCoils(uint slaveAddress, uint registerAddress, const QVector &values) = 0; + + virtual ModbusRtuReply *writeHoldingRegister(uint slaveAddress, uint registerAddress, quint16 value) = 0; + virtual ModbusRtuReply *writeHoldingRegisters(uint slaveAddress, uint registerAddress, const QVector &values) = 0; + +protected: + explicit ModbusRtuMaster(QObject *parent = nullptr) : QObject(parent) { }; + virtual ~ModbusRtuMaster() = default; + +signals: + void connectedChanged(bool connected); + +}; + +#endif // MODBUSRTUMASTER_H diff --git a/libnymea-core/modbus/modbusrtumaster.h b/libnymea/hardware/modbus/modbusrtureply.h similarity index 63% rename from libnymea-core/modbus/modbusrtumaster.h rename to libnymea/hardware/modbus/modbusrtureply.h index 8cc42e52..eec9f8ab 100644 --- a/libnymea-core/modbus/modbusrtumaster.h +++ b/libnymea/hardware/modbus/modbusrtureply.h @@ -28,23 +28,47 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#ifndef MODBUSRTUMASTER_H -#define MODBUSRTUMASTER_H +#ifndef MODBUSRTUREPLY_H +#define MODBUSRTUREPLY_H #include +#include -namespace nymeaserver { - -class ModbusRtuMaster : public QObject +class ModbusRtuReply : public QObject { Q_OBJECT public: - explicit ModbusRtuMaster(QObject *parent = nullptr); + enum Error { + NoError, + ReadError, + WriteError, + ConnectionError, + ConfigurationError, + TimeoutError, + ProtocolError, + ReplyAbortedError, + UnknownError + }; + Q_ENUM(Error) + + virtual bool isFinished() const = 0; + + virtual uint slaveAddress() const = 0; + virtual uint registerAddress() const = 0; + + virtual QString errorString() const = 0; + virtual ModbusRtuReply::Error error() const = 0; + + virtual QVector result() const = 0; + +protected: + explicit ModbusRtuReply(QObject *parent = nullptr) : QObject(parent) { }; + virtual ~ModbusRtuReply() = default; signals: + void finished(); + void errorOccurred(ModbusRtuReply::Error error); }; -} - -#endif // MODBUSRTUMASTER_H +#endif // MODBUSRTUREPLY_H diff --git a/libnymea/hardwaremanager.h b/libnymea/hardwaremanager.h index 745a4ca9..711a0995 100644 --- a/libnymea/hardwaremanager.h +++ b/libnymea/hardwaremanager.h @@ -44,6 +44,7 @@ class MqttProvider; class I2CManager; class ZigbeeHardwareResource; class HardwareResource; +class ModbusRtuHardwareResouce; class HardwareManager : public QObject { @@ -63,6 +64,7 @@ public: virtual MqttProvider *mqttProvider() = 0; virtual I2CManager *i2cManager() = 0; virtual ZigbeeHardwareResource *zigbeeResource() = 0; + virtual ModbusRtuHardwareResouce *modbusRtuResource() = 0; protected: void setResourceEnabled(HardwareResource* resource, bool enabled); diff --git a/libnymea/libnymea.pro b/libnymea/libnymea.pro index b9de355e..0b6382c6 100644 --- a/libnymea/libnymea.pro +++ b/libnymea/libnymea.pro @@ -14,6 +14,8 @@ QMAKE_LFLAGS += -fPIC HEADERS += \ hardware/modbus/modbusrtuhardwareresource.h \ + hardware/modbus/modbusrtumaster.h \ + hardware/modbus/modbusrtureply.h \ hardware/zigbee/zigbeehandler.h \ hardware/zigbee/zigbeehardwareresource.h \ integrations/browseractioninfo.h \