Add modbus RTU hardware resource support
This commit is contained in:
parent
ab65f1a484
commit
64d24d4e74
@ -130,6 +130,9 @@
|
||||
#include "applogcontroller.h"
|
||||
#include "tagwatcher.h"
|
||||
#include "appdata.h"
|
||||
#include "modbus/modbusrtumanager.h"
|
||||
#include "modbus/modbusrtumasters.h"
|
||||
#include "types/serialportsproxy.h"
|
||||
|
||||
#include <QtQml/qqml.h>
|
||||
|
||||
@ -312,6 +315,13 @@ void registerQmlTypes() {
|
||||
qmlRegisterUncreatableType<ZigbeeNetwork>(uri, 1, 0, "ZigbeeNetwork", "Get it from the ZigbeeManager");
|
||||
qmlRegisterUncreatableType<ZigbeeNetworks>(uri, 1, 0, "ZigbeeNetworks", "Get it from the ZigbeeManager");
|
||||
|
||||
qmlRegisterType<ModbusRtuManager>(uri, 1, 0, "ModbusRtuManager");
|
||||
qmlRegisterUncreatableType<ModbusRtuMaster>(uri, 1, 0, "ModbusRtuMaster", "Get it from the ModbusRtuMasters");
|
||||
qmlRegisterUncreatableType<ModbusRtuMasters>(uri, 1, 0, "ModbusRtuMasters", "Get it from the ModbusRtuManager");
|
||||
qmlRegisterUncreatableType<SerialPort>(uri, 1, 0, "SerialPort", "Get it from the SerialPorts");
|
||||
qmlRegisterUncreatableType<SerialPorts>(uri, 1, 0, "SerialPorts", "Get it from the apropriate manager object.");
|
||||
qmlRegisterType<SerialPortsProxy>(uri, 1, 0, "SerialPortsProxy");
|
||||
|
||||
qmlRegisterType<NetworkManager>(uri, 1, 0, "NetworkManager");
|
||||
qmlRegisterUncreatableType<NetworkDevices>(uri, 1, 0, "NetworkDevices", "Get it from NetworkManager");
|
||||
qmlRegisterUncreatableType<WiredNetworkDevices>(uri, 1, 0, "WiredNetworkDevices", "Get it from NetworkManager");
|
||||
|
||||
@ -26,6 +26,12 @@ SOURCES += \
|
||||
$${PWD}/logging.cpp \
|
||||
$${PWD}/applogcontroller.cpp \
|
||||
$${PWD}/wifisetup/btwifisetup.cpp \
|
||||
$$PWD/modbus/modbusrtumanager.cpp \
|
||||
$$PWD/modbus/modbusrtumaster.cpp \
|
||||
$$PWD/modbus/modbusrtumasters.cpp \
|
||||
$$PWD/types/serialport.cpp \
|
||||
$$PWD/types/serialports.cpp \
|
||||
$$PWD/types/serialportsproxy.cpp \
|
||||
$${PWD}/configuration/networkmanager.cpp \
|
||||
$${PWD}/engine.cpp \
|
||||
$${PWD}/models/barseriesadapter.cpp \
|
||||
@ -174,6 +180,12 @@ HEADERS += \
|
||||
$${PWD}/logging.h \
|
||||
$${PWD}/applogcontroller.h \
|
||||
$${PWD}/wifisetup/btwifisetup.h \
|
||||
$$PWD/modbus/modbusrtumanager.h \
|
||||
$$PWD/modbus/modbusrtumaster.h \
|
||||
$$PWD/modbus/modbusrtumasters.h \
|
||||
$$PWD/types/serialport.h \
|
||||
$$PWD/types/serialports.h \
|
||||
$$PWD/types/serialportsproxy.h \
|
||||
$${PWD}/configuration/networkmanager.h \
|
||||
$${PWD}/engine.h \
|
||||
$${PWD}/models/barseriesadapter.h \
|
||||
|
||||
251
libnymea-app/modbus/modbusrtumanager.cpp
Normal file
251
libnymea-app/modbus/modbusrtumanager.cpp
Normal file
@ -0,0 +1,251 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU 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 General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 "modbusrtumanager.h"
|
||||
#include "engine.h"
|
||||
#include "modbusrtumaster.h"
|
||||
#include "modbusrtumasters.h"
|
||||
|
||||
#include "jsonrpc/jsonrpcclient.h"
|
||||
|
||||
#include <QMetaEnum>
|
||||
|
||||
ModbusRtuManager::ModbusRtuManager(QObject *parent) :
|
||||
JsonHandler(parent),
|
||||
m_serialPorts(new SerialPorts(this)),
|
||||
m_modbusRtuMasters(new ModbusRtuMasters(this))
|
||||
{
|
||||
qRegisterMetaType<SerialPort::SerialPortParity>();
|
||||
qRegisterMetaType<SerialPort::SerialPortDataBits>();
|
||||
qRegisterMetaType<SerialPort::SerialPortStopBits>();
|
||||
}
|
||||
|
||||
ModbusRtuManager::~ModbusRtuManager()
|
||||
{
|
||||
if (m_engine) {
|
||||
m_engine->jsonRpcClient()->unregisterNotificationHandler(this);
|
||||
}
|
||||
}
|
||||
|
||||
QString ModbusRtuManager::nameSpace() const
|
||||
{
|
||||
return "ModbusRtu";
|
||||
}
|
||||
|
||||
Engine *ModbusRtuManager::engine() const
|
||||
{
|
||||
return m_engine;
|
||||
}
|
||||
|
||||
void ModbusRtuManager::setEngine(Engine *engine)
|
||||
{
|
||||
if (m_engine == engine)
|
||||
return;
|
||||
|
||||
if (m_engine) {
|
||||
m_engine->jsonRpcClient()->unregisterNotificationHandler(this);
|
||||
}
|
||||
|
||||
m_engine = engine;
|
||||
emit engineChanged();
|
||||
|
||||
if (m_engine) {
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
||||
bool ModbusRtuManager::supported() const
|
||||
{
|
||||
return m_supported;
|
||||
}
|
||||
|
||||
SerialPorts *ModbusRtuManager::serialPorts() const
|
||||
{
|
||||
return m_serialPorts;
|
||||
}
|
||||
|
||||
ModbusRtuMasters *ModbusRtuManager::modbusRtuMasters() const
|
||||
{
|
||||
return m_modbusRtuMasters;
|
||||
}
|
||||
|
||||
int ModbusRtuManager::addModbusRtuMaster(const QString &serialPort, qint32 baudrate, SerialPort::SerialPortParity parity, SerialPort::SerialPortDataBits dataBits, SerialPort::SerialPortStopBits stopBits)
|
||||
{
|
||||
QVariantMap params;
|
||||
params.insert("serialPort", serialPort);
|
||||
params.insert("baudrate", baudrate);
|
||||
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));
|
||||
return m_engine->jsonRpcClient()->sendCommand("ModbusRtu.AddModbusRtuMaster", params, this, "addModbusRtuMasterResponse");
|
||||
}
|
||||
|
||||
int ModbusRtuManager::removeModbusRtuMaster(const QUuid &modbusUuid)
|
||||
{
|
||||
QVariantMap params;
|
||||
params.insert("modbusUuid", 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)
|
||||
{
|
||||
QVariantMap params;
|
||||
params.insert("modbusUuid", modbusUuid);
|
||||
params.insert("serialPort", serialPort);
|
||||
params.insert("baudrate", baudrate);
|
||||
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));
|
||||
return m_engine->jsonRpcClient()->sendCommand("ModbusRtu.ReconfigureModbusRtuMaster", params, this, "reconfigureModbusRtuMasterResponse");
|
||||
}
|
||||
|
||||
void ModbusRtuManager::init()
|
||||
{
|
||||
m_serialPorts->clear();
|
||||
m_modbusRtuMasters->clear();
|
||||
|
||||
m_engine->jsonRpcClient()->registerNotificationHandler(this, "notificationReceived");
|
||||
m_engine->jsonRpcClient()->sendCommand("ModbusRtu.GetModbusRtuMasters", this, "getModbusRtuMastersResponse");
|
||||
}
|
||||
|
||||
ModbusRtuMaster *ModbusRtuManager::unpackModbusRtuMaster(const QVariantMap &modbusRtuMasterMap)
|
||||
{
|
||||
ModbusRtuMaster *modbusMaster = new ModbusRtuMaster(this);
|
||||
modbusMaster->setModbusUuid(modbusRtuMasterMap.value("modbusUuid").toUuid());
|
||||
modbusMaster->setConnected(modbusRtuMasterMap.value("connected").toBool());
|
||||
modbusMaster->setSerialPort(modbusRtuMasterMap.value("serialPort").toString());
|
||||
modbusMaster->setBaudrate(modbusRtuMasterMap.value("baudrate").toInt());
|
||||
modbusMaster->setParity(SerialPort::stringToSerialPortParity(modbusRtuMasterMap.value("parity").toString()));
|
||||
modbusMaster->setStopBits(SerialPort::stringToSerialPortStopBits(modbusRtuMasterMap.value("stopBits").toString()));
|
||||
modbusMaster->setDataBits(SerialPort::stringToSerialPortDataBits(modbusRtuMasterMap.value("dataBits").toString()));
|
||||
return modbusMaster;
|
||||
}
|
||||
|
||||
void ModbusRtuManager::notificationReceived(const QVariantMap ¬ification)
|
||||
{
|
||||
QString notificationString = notification.value("notification").toString();
|
||||
qDebug() << "Received notification" << notificationString << endl << notification;
|
||||
if (notificationString == "ModbusRtu.SerialPortAdded") {
|
||||
QVariantMap serialPortMap = notification.value("params").toMap().value("serialPort").toMap();
|
||||
m_serialPorts->addSerialPort(SerialPort::unpackSerialPort(serialPortMap, m_serialPorts));
|
||||
return;
|
||||
}
|
||||
|
||||
if (notificationString == "ModbusRtu.SerialPortRemoved") {
|
||||
QVariantMap serialPortMap = notification.value("params").toMap().value("serialPort").toMap();
|
||||
SerialPort *serialPort = SerialPort::unpackSerialPort(serialPortMap, this);
|
||||
m_serialPorts->removeSerialPort(serialPort->systemLocation());
|
||||
serialPort->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
if (notificationString == "ModbusRtu.ModbusRtuMasterAdded") {
|
||||
QVariantMap modbusRtuMasterMap = notification.value("params").toMap().value("modbusRtuMaster").toMap();
|
||||
ModbusRtuMaster *modbusRtuMaster = unpackModbusRtuMaster(modbusRtuMasterMap);
|
||||
m_modbusRtuMasters->addModbusRtuMaster(modbusRtuMaster);
|
||||
return;
|
||||
}
|
||||
|
||||
if (notificationString == "ModbusRtu.ModbusRtuMasterRemoved") {
|
||||
QUuid modbusUuid = notification.value("params").toMap().value("modbusUuid").toUuid();
|
||||
m_modbusRtuMasters->removeModbusRtuMaster(modbusUuid);
|
||||
return;
|
||||
}
|
||||
|
||||
if (notificationString == "ModbusRtu.ModbusRtuMasterChanged") {
|
||||
QVariantMap modbusRtuMasterMap = notification.value("params").toMap().value("modbusRtuMaster").toMap();
|
||||
ModbusRtuMaster *modbusRtuMaster = unpackModbusRtuMaster(modbusRtuMasterMap);
|
||||
qDebug() << "Modbus master changed" << modbusRtuMaster;
|
||||
ModbusRtuMaster *currentModbusRtuMaster = m_modbusRtuMasters->getModbusRtuMaster(modbusRtuMaster->modbusUuid());
|
||||
if (!currentModbusRtuMaster) {
|
||||
qWarning() << "Got modbus changed signal but there is no such modbus interface. Ignoring notification";
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "Update modbus values" << currentModbusRtuMaster;
|
||||
currentModbusRtuMaster->setSerialPort(modbusRtuMaster->serialPort());
|
||||
currentModbusRtuMaster->setBaudrate(modbusRtuMaster->baudrate());
|
||||
currentModbusRtuMaster->setParity(modbusRtuMaster->parity());
|
||||
currentModbusRtuMaster->setDataBits(modbusRtuMaster->dataBits());
|
||||
currentModbusRtuMaster->setStopBits(modbusRtuMaster->stopBits());
|
||||
currentModbusRtuMaster->setConnected(modbusRtuMaster->connected());
|
||||
modbusRtuMaster->deleteLater();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ModbusRtuManager::getSerialPortsResponse(int commandId, const QVariantMap ¶ms)
|
||||
{
|
||||
qDebug() << "Get serial ports response" << commandId << params;
|
||||
m_serialPorts->clear();
|
||||
|
||||
foreach (const QVariant &serialPortVariant, params.value("serialPorts").toList()) {
|
||||
m_serialPorts->addSerialPort(SerialPort::unpackSerialPort(serialPortVariant.toMap(), m_serialPorts));
|
||||
}
|
||||
}
|
||||
|
||||
void ModbusRtuManager::getModbusRtuMastersResponse(int commandId, const QVariantMap ¶ms)
|
||||
{
|
||||
qDebug() << "Get modbus RTU masters response" << commandId << params;
|
||||
|
||||
QString error = params.value("modbusError").toString();
|
||||
if (error == "ModbusRtuErrorNoError") {
|
||||
m_supported = true;
|
||||
emit supportedChanged(m_supported);
|
||||
|
||||
m_modbusRtuMasters->clear();
|
||||
foreach (const QVariant &modbusRtuMasterVariant, params.value("modbusRtuMasters").toList()) {
|
||||
m_modbusRtuMasters->addModbusRtuMaster(unpackModbusRtuMaster(modbusRtuMasterVariant.toMap()));
|
||||
}
|
||||
|
||||
m_engine->jsonRpcClient()->sendCommand("ModbusRtu.GetSerialPorts", this, "getSerialPortsResponse");
|
||||
} else {
|
||||
qWarning() << "Modbus is not supported on this platform";
|
||||
}
|
||||
}
|
||||
|
||||
void ModbusRtuManager::addModbusRtuMasterResponse(int commandId, const QVariantMap ¶ms)
|
||||
{
|
||||
qDebug() << "Add modbus RTU master response" << commandId << params;
|
||||
emit addModbusRtuMasterReply(commandId, params.value("modbusError").toString(), params.value("modbusUuid").toUuid());
|
||||
}
|
||||
|
||||
void ModbusRtuManager::removeModbusRtuMasterResponse(int commandId, const QVariantMap ¶ms)
|
||||
{
|
||||
qDebug() << "Remove modbus RTU master response" << commandId << params;
|
||||
emit removeModbusRtuMasterReply(commandId, params.value("modbusError").toString());
|
||||
}
|
||||
|
||||
void ModbusRtuManager::reconfigureModbusRtuMasterResponse(int commandId, const QVariantMap ¶ms)
|
||||
{
|
||||
qDebug() << "Reconfigure modbus RTU master response" << commandId << params;
|
||||
emit reconfigureModbusRtuMasterReply(commandId, params.value("modbusError").toString());
|
||||
}
|
||||
98
libnymea-app/modbus/modbusrtumanager.h
Normal file
98
libnymea-app/modbus/modbusrtumanager.h
Normal file
@ -0,0 +1,98 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU 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 General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 MODBUSRTUMANAGER_H
|
||||
#define MODBUSRTUMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "types/serialports.h"
|
||||
#include "jsonrpc/jsonhandler.h"
|
||||
|
||||
class Engine;
|
||||
class JsonRpcClient;
|
||||
class ModbusRtuMaster;
|
||||
class ModbusRtuMasters;
|
||||
|
||||
class ModbusRtuManager : public JsonHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(Engine *engine READ engine WRITE setEngine NOTIFY engineChanged)
|
||||
Q_PROPERTY(SerialPorts *serialPorts READ serialPorts CONSTANT)
|
||||
Q_PROPERTY(ModbusRtuMasters *modbusRtuMasters READ modbusRtuMasters CONSTANT)
|
||||
Q_PROPERTY(bool supported READ supported NOTIFY supportedChanged)
|
||||
|
||||
public:
|
||||
explicit ModbusRtuManager(QObject *parent = nullptr);
|
||||
~ModbusRtuManager();
|
||||
|
||||
QString nameSpace() const override;
|
||||
|
||||
Engine *engine() const;
|
||||
void setEngine(Engine *engine);
|
||||
|
||||
bool supported() const;
|
||||
|
||||
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 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);
|
||||
|
||||
signals:
|
||||
void engineChanged();
|
||||
void supportedChanged(bool supported);
|
||||
void addModbusRtuMasterReply(int commandId, const QString &error, const QUuid &modbusUuid);
|
||||
void removeModbusRtuMasterReply(int commandId, const QString &error);
|
||||
void reconfigureModbusRtuMasterReply(int commandId, const QString &error);
|
||||
|
||||
private:
|
||||
Engine* m_engine = nullptr;
|
||||
SerialPorts *m_serialPorts = nullptr;
|
||||
ModbusRtuMasters *m_modbusRtuMasters = nullptr;
|
||||
bool m_supported = false;
|
||||
|
||||
void init();
|
||||
|
||||
ModbusRtuMaster *unpackModbusRtuMaster(const QVariantMap &modbusRtuMasterMap);
|
||||
|
||||
Q_INVOKABLE void notificationReceived(const QVariantMap ¬ification);
|
||||
|
||||
Q_INVOKABLE void getSerialPortsResponse(int commandId, const QVariantMap ¶ms);
|
||||
Q_INVOKABLE void getModbusRtuMastersResponse(int commandId, const QVariantMap ¶ms);
|
||||
Q_INVOKABLE void addModbusRtuMasterResponse(int commandId, const QVariantMap ¶ms);
|
||||
Q_INVOKABLE void removeModbusRtuMasterResponse(int commandId, const QVariantMap ¶ms);
|
||||
Q_INVOKABLE void reconfigureModbusRtuMasterResponse(int commandId, const QVariantMap ¶ms);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // MODBUSRTUMANAGER_H
|
||||
130
libnymea-app/modbus/modbusrtumaster.cpp
Normal file
130
libnymea-app/modbus/modbusrtumaster.cpp
Normal file
@ -0,0 +1,130 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU 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 General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 "modbusrtumaster.h"
|
||||
|
||||
ModbusRtuMaster::ModbusRtuMaster(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QUuid ModbusRtuMaster::modbusUuid() const
|
||||
{
|
||||
return m_modbusUuid;
|
||||
}
|
||||
|
||||
void ModbusRtuMaster::setModbusUuid(const QUuid &modbusUuid)
|
||||
{
|
||||
m_modbusUuid = modbusUuid;
|
||||
}
|
||||
|
||||
QString ModbusRtuMaster::serialPort() const
|
||||
{
|
||||
return m_serialPort;
|
||||
}
|
||||
|
||||
void ModbusRtuMaster::setSerialPort(const QString &serialPort)
|
||||
{
|
||||
if (m_serialPort == serialPort)
|
||||
return;
|
||||
|
||||
m_serialPort = serialPort;
|
||||
emit serialPortChanged(m_serialPort);
|
||||
}
|
||||
|
||||
qint32 ModbusRtuMaster::baudrate() const
|
||||
{
|
||||
return m_baudrate;
|
||||
}
|
||||
|
||||
void ModbusRtuMaster::setBaudrate(qint32 baudrate)
|
||||
{
|
||||
if (m_baudrate == baudrate)
|
||||
return;
|
||||
|
||||
m_baudrate = baudrate;
|
||||
emit baudrateChanged(m_baudrate);
|
||||
}
|
||||
|
||||
SerialPort::SerialPortParity ModbusRtuMaster::parity() const
|
||||
{
|
||||
return m_parity;
|
||||
}
|
||||
|
||||
void ModbusRtuMaster::setParity(SerialPort::SerialPortParity parity)
|
||||
{
|
||||
if (m_parity == parity)
|
||||
return;
|
||||
|
||||
m_parity = parity;
|
||||
emit parityChanged(m_parity);
|
||||
}
|
||||
|
||||
SerialPort::SerialPortDataBits ModbusRtuMaster::dataBits() const
|
||||
{
|
||||
return m_dataBits;
|
||||
}
|
||||
|
||||
void ModbusRtuMaster::setDataBits(SerialPort::SerialPortDataBits dataBits)
|
||||
{
|
||||
if (m_dataBits == dataBits)
|
||||
return;
|
||||
|
||||
m_dataBits = dataBits;
|
||||
emit dataBitsChanged(m_dataBits);
|
||||
}
|
||||
|
||||
SerialPort::SerialPortStopBits ModbusRtuMaster::stopBits() const
|
||||
{
|
||||
return m_stopBits;
|
||||
}
|
||||
|
||||
void ModbusRtuMaster::setStopBits(SerialPort::SerialPortStopBits stopBits)
|
||||
{
|
||||
if (m_stopBits == stopBits)
|
||||
return;
|
||||
|
||||
m_stopBits = stopBits;
|
||||
emit stopBitsChanged(m_stopBits);
|
||||
}
|
||||
|
||||
bool ModbusRtuMaster::connected() const
|
||||
{
|
||||
return m_connected;
|
||||
}
|
||||
|
||||
void ModbusRtuMaster::setConnected(bool connected)
|
||||
{
|
||||
if (m_connected == connected)
|
||||
return;
|
||||
|
||||
m_connected = connected;
|
||||
emit connectedChanged(m_connected);
|
||||
}
|
||||
93
libnymea-app/modbus/modbusrtumaster.h
Normal file
93
libnymea-app/modbus/modbusrtumaster.h
Normal file
@ -0,0 +1,93 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU 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 General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 <QUuid>
|
||||
#include <QObject>
|
||||
|
||||
#include "types/serialport.h"
|
||||
|
||||
class ModbusRtuMaster : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QUuid modbusUuid READ modbusUuid CONSTANT)
|
||||
Q_PROPERTY(QString serialPort READ serialPort NOTIFY serialPortChanged)
|
||||
Q_PROPERTY(qint32 baudrate READ baudrate NOTIFY baudrateChanged)
|
||||
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(bool connected READ connected NOTIFY connectedChanged)
|
||||
|
||||
public:
|
||||
explicit ModbusRtuMaster(QObject *parent = nullptr);
|
||||
|
||||
QUuid modbusUuid() const;
|
||||
void setModbusUuid(const QUuid &modbusUuid);
|
||||
|
||||
QString serialPort() const;
|
||||
void setSerialPort(const QString &serialPort);
|
||||
|
||||
qint32 baudrate() const;
|
||||
void setBaudrate(qint32 baudrate);
|
||||
|
||||
SerialPort::SerialPortParity parity() const;
|
||||
void setParity(SerialPort::SerialPortParity parity);
|
||||
|
||||
SerialPort::SerialPortDataBits dataBits() const;
|
||||
void setDataBits(SerialPort::SerialPortDataBits dataBits);
|
||||
|
||||
SerialPort::SerialPortStopBits stopBits() const;
|
||||
void setStopBits(SerialPort::SerialPortStopBits stopBits);
|
||||
|
||||
bool connected() const;
|
||||
void setConnected(bool connected);
|
||||
|
||||
signals:
|
||||
void connectedChanged(bool connected);
|
||||
void serialPortChanged(const QString &serialPort);
|
||||
void baudrateChanged(quint32 baudrate);
|
||||
void parityChanged(SerialPort::SerialPortParity parity);
|
||||
void dataBitsChanged(SerialPort::SerialPortDataBits dataBits);
|
||||
void stopBitsChanged(SerialPort::SerialPortStopBits stopBits);
|
||||
|
||||
private:
|
||||
QUuid m_modbusUuid;
|
||||
QString m_serialPort;
|
||||
qint32 m_baudrate;
|
||||
SerialPort::SerialPortParity m_parity;
|
||||
SerialPort::SerialPortDataBits m_dataBits;
|
||||
SerialPort::SerialPortStopBits m_stopBits;
|
||||
bool m_connected = false;
|
||||
|
||||
};
|
||||
|
||||
#endif // MODBUSRTUMASTER_H
|
||||
169
libnymea-app/modbus/modbusrtumasters.cpp
Normal file
169
libnymea-app/modbus/modbusrtumasters.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU 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 General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 "modbusrtumasters.h"
|
||||
|
||||
ModbusRtuMasters::ModbusRtuMasters(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QList<ModbusRtuMaster *> ModbusRtuMasters::modbusRtuMasters() const
|
||||
{
|
||||
return m_modbusRtuMasters;
|
||||
}
|
||||
|
||||
int ModbusRtuMasters::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return m_modbusRtuMasters.count();
|
||||
}
|
||||
|
||||
QVariant ModbusRtuMasters::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
switch (role) {
|
||||
case RoleUuid:
|
||||
return m_modbusRtuMasters.at(index.row())->modbusUuid();
|
||||
case RoleSerialPort:
|
||||
return m_modbusRtuMasters.at(index.row())->serialPort();
|
||||
case RoleBaudrate:
|
||||
return m_modbusRtuMasters.at(index.row())->baudrate();
|
||||
case RoleParity:
|
||||
return m_modbusRtuMasters.at(index.row())->parity();
|
||||
case RoleDataBits:
|
||||
return m_modbusRtuMasters.at(index.row())->dataBits();
|
||||
case RoleStopBits:
|
||||
return m_modbusRtuMasters.at(index.row())->stopBits();
|
||||
case RoleConnected:
|
||||
return m_modbusRtuMasters.at(index.row())->connected();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ModbusRtuMasters::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles.insert(RoleUuid, "modbusUuid");
|
||||
roles.insert(RoleSerialPort, "serialPort");
|
||||
roles.insert(RoleBaudrate, "baudrate");
|
||||
roles.insert(RoleParity, "parity");
|
||||
roles.insert(RoleDataBits, "dataBits");
|
||||
roles.insert(RoleStopBits, "stopBits");
|
||||
roles.insert(RoleConnected, "connected");
|
||||
return roles;
|
||||
}
|
||||
|
||||
void ModbusRtuMasters::addModbusRtuMaster(ModbusRtuMaster *modbusRtuMaster)
|
||||
{
|
||||
modbusRtuMaster->setParent(this);
|
||||
|
||||
connect(modbusRtuMaster, &ModbusRtuMaster::serialPortChanged, this, [=](const QString &serialPort) {
|
||||
Q_UNUSED(serialPort)
|
||||
QModelIndex idx = index(m_modbusRtuMasters.indexOf(modbusRtuMaster), 0);
|
||||
emit dataChanged(idx, idx, {RoleSerialPort});
|
||||
});
|
||||
|
||||
connect(modbusRtuMaster, &ModbusRtuMaster::baudrateChanged, this, [=](qint32 baudrate) {
|
||||
Q_UNUSED(baudrate)
|
||||
QModelIndex idx = index(m_modbusRtuMasters.indexOf(modbusRtuMaster), 0);
|
||||
emit dataChanged(idx, idx, {RoleBaudrate});
|
||||
});
|
||||
|
||||
connect(modbusRtuMaster, &ModbusRtuMaster::parityChanged, this, [=](SerialPort::SerialPortParity parity) {
|
||||
Q_UNUSED(parity)
|
||||
QModelIndex idx = index(m_modbusRtuMasters.indexOf(modbusRtuMaster), 0);
|
||||
emit dataChanged(idx, idx, {RoleParity});
|
||||
});
|
||||
|
||||
connect(modbusRtuMaster, &ModbusRtuMaster::dataBitsChanged, this, [=](SerialPort::SerialPortDataBits dataBits) {
|
||||
Q_UNUSED(dataBits)
|
||||
QModelIndex idx = index(m_modbusRtuMasters.indexOf(modbusRtuMaster), 0);
|
||||
emit dataChanged(idx, idx, {RoleDataBits});
|
||||
});
|
||||
|
||||
connect(modbusRtuMaster, &ModbusRtuMaster::stopBitsChanged, this, [=](SerialPort::SerialPortStopBits stopBites) {
|
||||
Q_UNUSED(stopBites)
|
||||
QModelIndex idx = index(m_modbusRtuMasters.indexOf(modbusRtuMaster), 0);
|
||||
emit dataChanged(idx, idx, {RoleStopBits});
|
||||
});
|
||||
|
||||
connect(modbusRtuMaster, &ModbusRtuMaster::connectedChanged, this, [=](bool connected) {
|
||||
Q_UNUSED(connected)
|
||||
QModelIndex idx = index(m_modbusRtuMasters.indexOf(modbusRtuMaster), 0);
|
||||
emit dataChanged(idx, idx, {RoleConnected});
|
||||
});
|
||||
|
||||
beginInsertRows(QModelIndex(), m_modbusRtuMasters.count(), m_modbusRtuMasters.count());
|
||||
m_modbusRtuMasters.append(modbusRtuMaster);
|
||||
endInsertRows();
|
||||
|
||||
emit countChanged();
|
||||
}
|
||||
|
||||
void ModbusRtuMasters::removeModbusRtuMaster(const QUuid &modbusUuid)
|
||||
{
|
||||
for (int i = 0; i < m_modbusRtuMasters.count(); i++) {
|
||||
if (m_modbusRtuMasters.at(i)->modbusUuid() == modbusUuid) {
|
||||
beginRemoveRows(QModelIndex(), i, i);
|
||||
m_modbusRtuMasters.takeAt(i)->deleteLater();
|
||||
endRemoveRows();
|
||||
emit countChanged();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModbusRtuMasters::clear()
|
||||
{
|
||||
beginResetModel();
|
||||
qDeleteAll(m_modbusRtuMasters);
|
||||
m_modbusRtuMasters.clear();
|
||||
endResetModel();
|
||||
emit countChanged();
|
||||
}
|
||||
|
||||
ModbusRtuMaster *ModbusRtuMasters::get(int index) const
|
||||
{
|
||||
if (index < 0 || index >= m_modbusRtuMasters.count()) {
|
||||
return nullptr;
|
||||
}
|
||||
return m_modbusRtuMasters.at(index);
|
||||
}
|
||||
|
||||
ModbusRtuMaster *ModbusRtuMasters::getModbusRtuMaster(const QUuid &modbusUuid) const
|
||||
{
|
||||
foreach (ModbusRtuMaster *modbusRtuMaster, m_modbusRtuMasters) {
|
||||
if (modbusRtuMaster->modbusUuid() == modbusUuid) {
|
||||
return modbusRtuMaster;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
81
libnymea-app/modbus/modbusrtumasters.h
Normal file
81
libnymea-app/modbus/modbusrtumasters.h
Normal file
@ -0,0 +1,81 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU 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 General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 MODBUSRTUMASTERS_H
|
||||
#define MODBUSRTUMASTERS_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QAbstractListModel>
|
||||
|
||||
#include "modbusrtumaster.h"
|
||||
|
||||
class ModbusRtuMasters : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
RoleUuid,
|
||||
RoleSerialPort,
|
||||
RoleBaudrate,
|
||||
RoleParity,
|
||||
RoleDataBits,
|
||||
RoleStopBits,
|
||||
RoleConnected
|
||||
};
|
||||
Q_ENUM(Roles)
|
||||
|
||||
explicit ModbusRtuMasters(QObject *parent = nullptr);
|
||||
virtual ~ModbusRtuMasters() override = default;
|
||||
|
||||
QList<ModbusRtuMaster *> modbusRtuMasters() const;
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
void addModbusRtuMaster(ModbusRtuMaster *modbusRtuMaster);
|
||||
void removeModbusRtuMaster(const QUuid &modbusUuid);
|
||||
|
||||
void clear();
|
||||
|
||||
Q_INVOKABLE virtual ModbusRtuMaster *get(int index) const;
|
||||
Q_INVOKABLE ModbusRtuMaster *getModbusRtuMaster(const QUuid &modbusUuid) const;
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
|
||||
private:
|
||||
QList<ModbusRtuMaster *> m_modbusRtuMasters;
|
||||
|
||||
};
|
||||
|
||||
#endif // MODBUSRTUMASTERS_H
|
||||
114
libnymea-app/types/serialport.cpp
Normal file
114
libnymea-app/types/serialport.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU 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 General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 "serialport.h"
|
||||
|
||||
SerialPort::SerialPort(const QString &systemLocation, const QString &manufacturer, const QString &description, const QString &serialNumber, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_systemLocation(systemLocation),
|
||||
m_manufacturer(manufacturer),
|
||||
m_description(description),
|
||||
m_serialNumber(serialNumber)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString SerialPort::systemLocation() const
|
||||
{
|
||||
return m_systemLocation;
|
||||
}
|
||||
|
||||
QString SerialPort::manufacturer() const
|
||||
{
|
||||
return m_manufacturer;
|
||||
}
|
||||
|
||||
QString SerialPort::description() const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
QString SerialPort::serialNumber() const
|
||||
{
|
||||
return m_serialNumber;
|
||||
}
|
||||
|
||||
SerialPort *SerialPort::unpackSerialPort(const QVariantMap &serialPortMap, QObject *parent)
|
||||
{
|
||||
return new SerialPort(serialPortMap.value("systemLocation").toString(),
|
||||
serialPortMap.value("manufacturer").toString(),
|
||||
serialPortMap.value("description").toString(),
|
||||
serialPortMap.value("serialNumber").toString(), parent);
|
||||
}
|
||||
|
||||
SerialPort::SerialPortParity SerialPort::stringToSerialPortParity(const QString &parityString)
|
||||
{
|
||||
if (parityString == "SerialPortParityNoParity") {
|
||||
return SerialPort::SerialPortParityNoParity;
|
||||
} else if (parityString == "SerialPortParityEvenParity") {
|
||||
return SerialPort::SerialPortParityEvenParity;
|
||||
} else if (parityString == "SerialPortParityOddParity") {
|
||||
return SerialPort::SerialPortParityOddParity;
|
||||
} else if (parityString == "SerialPortParitySpaceParity") {
|
||||
return SerialPort::SerialPortParitySpaceParity;
|
||||
} else if (parityString == "SerialPortParityMarkParity") {
|
||||
return SerialPort::SerialPortParityMarkParity;
|
||||
}
|
||||
|
||||
return SerialPort::SerialPortParityUnknownParity;
|
||||
}
|
||||
|
||||
SerialPort::SerialPortDataBits SerialPort::stringToSerialPortDataBits(const QString &dataBitsString)
|
||||
{
|
||||
if (dataBitsString == "SerialPortDataBitsData5") {
|
||||
return SerialPort::SerialPortDataBitsData5;
|
||||
} else if (dataBitsString == "SerialPortDataBitsData6") {
|
||||
return SerialPort::SerialPortDataBitsData6;
|
||||
} else if (dataBitsString == "SerialPortDataBitsData7") {
|
||||
return SerialPort::SerialPortDataBitsData7;
|
||||
} else if (dataBitsString == "SerialPortDataBitsData8") {
|
||||
return SerialPort::SerialPortDataBitsData7;
|
||||
}
|
||||
|
||||
return SerialPort::SerialPortDataBitsUnknownDataBits;
|
||||
}
|
||||
|
||||
SerialPort::SerialPortStopBits SerialPort::stringToSerialPortStopBits(const QString &stopBitsString)
|
||||
{
|
||||
if (stopBitsString == "SerialPortStopBitsOneStop") {
|
||||
return SerialPort::SerialPortStopBitsOneStop;
|
||||
} else if (stopBitsString == "SerialPortStopBitsOneAndHalfStop") {
|
||||
return SerialPort::SerialPortStopBitsOneAndHalfStop;
|
||||
} else if (stopBitsString == "SerialPortStopBitsTwoStop") {
|
||||
return SerialPort::SerialPortStopBitsTwoStop;
|
||||
}
|
||||
|
||||
return SerialPort::SerialPortStopBitsUnknownStopBits;
|
||||
}
|
||||
93
libnymea-app/types/serialport.h
Normal file
93
libnymea-app/types/serialport.h
Normal file
@ -0,0 +1,93 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU 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 General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 SERIALPORT_H
|
||||
#define SERIALPORT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariant>
|
||||
|
||||
class SerialPort : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString systemLocation READ systemLocation CONSTANT)
|
||||
Q_PROPERTY(QString manufacturer READ manufacturer CONSTANT)
|
||||
Q_PROPERTY(QString description READ description CONSTANT)
|
||||
Q_PROPERTY(QString serialNumber READ serialNumber CONSTANT)
|
||||
|
||||
public:
|
||||
enum SerialPortParity {
|
||||
SerialPortParityNoParity = 0,
|
||||
SerialPortParityEvenParity = 2,
|
||||
SerialPortParityOddParity = 3,
|
||||
SerialPortParitySpaceParity = 4,
|
||||
SerialPortParityMarkParity = 5,
|
||||
SerialPortParityUnknownParity = -1
|
||||
};
|
||||
Q_ENUM(SerialPortParity)
|
||||
|
||||
enum SerialPortDataBits {
|
||||
SerialPortDataBitsData5 = 5,
|
||||
SerialPortDataBitsData6 = 6,
|
||||
SerialPortDataBitsData7 = 7,
|
||||
SerialPortDataBitsData8 = 8,
|
||||
SerialPortDataBitsUnknownDataBits = -1
|
||||
};
|
||||
Q_ENUM(SerialPortDataBits)
|
||||
|
||||
enum SerialPortStopBits {
|
||||
SerialPortStopBitsOneStop = 1,
|
||||
SerialPortStopBitsOneAndHalfStop = 3,
|
||||
SerialPortStopBitsTwoStop = 2,
|
||||
SerialPortStopBitsUnknownStopBits = -1
|
||||
};
|
||||
Q_ENUM(SerialPortStopBits)
|
||||
|
||||
explicit SerialPort(const QString &systemLocation, const QString &manufacturer, const QString &description, const QString &serialNumber, QObject *parent = nullptr);
|
||||
|
||||
QString systemLocation() const;
|
||||
QString manufacturer() const;
|
||||
QString description() const;
|
||||
QString serialNumber() const;
|
||||
|
||||
static SerialPort *unpackSerialPort(const QVariantMap &serialPortMap, QObject *parent);
|
||||
static SerialPort::SerialPortParity stringToSerialPortParity(const QString &parityString);
|
||||
static SerialPort::SerialPortDataBits stringToSerialPortDataBits(const QString &dataBitsString);
|
||||
static SerialPort::SerialPortStopBits stringToSerialPortStopBits(const QString &stopBitsString);
|
||||
|
||||
private:
|
||||
QString m_systemLocation;
|
||||
QString m_manufacturer;
|
||||
QString m_description;
|
||||
QString m_serialNumber;
|
||||
|
||||
};
|
||||
|
||||
#endif // SERIALPORT_H
|
||||
109
libnymea-app/types/serialports.cpp
Normal file
109
libnymea-app/types/serialports.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU 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 General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 "serialports.h"
|
||||
|
||||
SerialPorts::SerialPorts(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int SerialPorts::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return m_serialPorts.count();
|
||||
}
|
||||
|
||||
QVariant SerialPorts::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
switch (role) {
|
||||
case RoleSystmLocation:
|
||||
return m_serialPorts.at(index.row())->systemLocation();
|
||||
case RoleManufacturer:
|
||||
return m_serialPorts.at(index.row())->manufacturer();
|
||||
case RoleDescription:
|
||||
return m_serialPorts.at(index.row())->description();
|
||||
case RoleSerialNumber:
|
||||
return m_serialPorts.at(index.row())->serialNumber();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> SerialPorts::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles.insert(RoleSystmLocation, "systemLocation");
|
||||
roles.insert(RoleManufacturer, "manufacturer");
|
||||
roles.insert(RoleDescription, "description");
|
||||
roles.insert(RoleSerialNumber, "serialNumber");
|
||||
return roles;
|
||||
}
|
||||
|
||||
void SerialPorts::addSerialPort(SerialPort *serialPort)
|
||||
{
|
||||
serialPort->setParent(this);
|
||||
|
||||
beginInsertRows(QModelIndex(), m_serialPorts.count(), m_serialPorts.count());
|
||||
m_serialPorts.append(serialPort);
|
||||
endInsertRows();
|
||||
|
||||
emit countChanged();
|
||||
}
|
||||
|
||||
void SerialPorts::removeSerialPort(const QString &systemLocation)
|
||||
{
|
||||
for (int i = 0; i < m_serialPorts.count(); i++) {
|
||||
if (m_serialPorts.at(i)->systemLocation() == systemLocation) {
|
||||
beginRemoveRows(QModelIndex(), i, i);
|
||||
m_serialPorts.takeAt(i)->deleteLater();
|
||||
endRemoveRows();
|
||||
emit countChanged();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPorts::clear()
|
||||
{
|
||||
beginResetModel();
|
||||
qDeleteAll(m_serialPorts);
|
||||
m_serialPorts.clear();
|
||||
endResetModel();
|
||||
emit countChanged();
|
||||
}
|
||||
|
||||
SerialPort *SerialPorts::get(int index) const
|
||||
{
|
||||
if (index < 0 || index >= m_serialPorts.count()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return m_serialPorts.at(index);
|
||||
}
|
||||
74
libnymea-app/types/serialports.h
Normal file
74
libnymea-app/types/serialports.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU 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 General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 SERIALPORTS_H
|
||||
#define SERIALPORTS_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QAbstractListModel>
|
||||
|
||||
#include "serialport.h"
|
||||
|
||||
class SerialPorts : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
RoleSystmLocation,
|
||||
RoleManufacturer,
|
||||
RoleDescription,
|
||||
RoleSerialNumber
|
||||
};
|
||||
Q_ENUM(Roles)
|
||||
|
||||
explicit SerialPorts(QObject *parent = nullptr);
|
||||
virtual ~SerialPorts() override = default;
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
void addSerialPort(SerialPort *serialPort);
|
||||
void removeSerialPort(const QString &systemLocation);
|
||||
|
||||
void clear();
|
||||
|
||||
Q_INVOKABLE virtual SerialPort *get(int index) const;
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
|
||||
protected:
|
||||
QList<SerialPort *> m_serialPorts;
|
||||
};
|
||||
|
||||
#endif // SERIALPORTS_H
|
||||
69
libnymea-app/types/serialportsproxy.cpp
Normal file
69
libnymea-app/types/serialportsproxy.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU 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 General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 "serialportsproxy.h"
|
||||
|
||||
SerialPortsProxy::SerialPortsProxy(QObject *parent) : QSortFilterProxyModel(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SerialPorts *SerialPortsProxy::serialPorts() const
|
||||
{
|
||||
return m_serialPorts;
|
||||
}
|
||||
|
||||
void SerialPortsProxy::setSerialPorts(SerialPorts *serialPorts)
|
||||
{
|
||||
if (m_serialPorts == serialPorts)
|
||||
return;
|
||||
|
||||
m_serialPorts = serialPorts;
|
||||
connect(m_serialPorts, &SerialPorts::countChanged, this, [this](){
|
||||
emit countChanged();
|
||||
});
|
||||
connect(m_serialPorts, &SerialPorts::countChanged, this, [this]() {
|
||||
sort(0, Qt::DescendingOrder);
|
||||
});
|
||||
|
||||
setSourceModel(serialPorts);
|
||||
setSortRole(SerialPorts::RoleSystmLocation);
|
||||
sort(0, Qt::DescendingOrder);
|
||||
emit countChanged();
|
||||
}
|
||||
|
||||
SerialPort *SerialPortsProxy::get(int index) const
|
||||
{
|
||||
if (index >= 0 && index < m_serialPorts->rowCount()) {
|
||||
return m_serialPorts->get(mapToSource(this->index(index, 0)).row());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
61
libnymea-app/types/serialportsproxy.h
Normal file
61
libnymea-app/types/serialportsproxy.h
Normal file
@ -0,0 +1,61 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU 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 General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 SERIALPORTSPROXY_H
|
||||
#define SERIALPORTSPROXY_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include "serialports.h"
|
||||
|
||||
class SerialPortsProxy : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||
|
||||
public:
|
||||
explicit SerialPortsProxy(QObject *parent = nullptr);
|
||||
|
||||
SerialPorts *serialPorts() const;
|
||||
void setSerialPorts(SerialPorts *serialPorts);
|
||||
|
||||
Q_INVOKABLE SerialPort* get(int index) const;
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
|
||||
private:
|
||||
SerialPorts *m_serialPorts = nullptr;
|
||||
|
||||
};
|
||||
|
||||
#endif // SERIALPORTSPROXY_H
|
||||
@ -259,5 +259,6 @@
|
||||
<file>ui/images/nymea-splash.svg</file>
|
||||
<file>ui/images/cleaning-robot.svg</file>
|
||||
<file>ui/images/chart.svg</file>
|
||||
<file>ui/images/modbus.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@ -246,5 +246,8 @@
|
||||
<file>ui/mainviews/dashboard/DashboardSceneDelegate.qml</file>
|
||||
<file>ui/mainviews/dashboard/DashboardWebViewDelegate.qml</file>
|
||||
<file>ui/components/SelectionTabs.qml</file>
|
||||
<file>ui/system/ModbusRtuSettingsPage.qml</file>
|
||||
<file>ui/system/ModbusRtuAddMasterPage.qml</file>
|
||||
<file>ui/system/ModbusRtuReconfigureMasterPage.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@ -186,6 +186,23 @@ Page {
|
||||
|
||||
}
|
||||
|
||||
Pane {
|
||||
Layout.fillWidth: true
|
||||
Material.elevation: layout.isGrid ? 1 : 0
|
||||
visible: engine.jsonRpcClient.ensureServerVersion("5.4")
|
||||
|
||||
padding: 0
|
||||
NymeaSwipeDelegate {
|
||||
width: parent.width
|
||||
iconName: "../images/modbus.svg"
|
||||
text: qsTr("Modbus RTU")
|
||||
subText: qsTr("Configure Modbus RTU master interfaces")
|
||||
prominentSubText: false
|
||||
wrapTexts: false
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("system/ModbusRtuSettingsPage.qml"))
|
||||
}
|
||||
}
|
||||
|
||||
Pane {
|
||||
Layout.fillWidth: true
|
||||
Material.elevation: layout.isGrid ? 1 : 0
|
||||
|
||||
224
nymea-app/ui/images/modbus.svg
Normal file
224
nymea-app/ui/images/modbus.svg
Normal file
@ -0,0 +1,224 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="96"
|
||||
height="96"
|
||||
id="svg4874"
|
||||
version="1.1"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
viewBox="0 0 96 96.000001"
|
||||
sodipodi:docname="modbus.svg">
|
||||
<defs
|
||||
id="defs4876" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="11.805916"
|
||||
inkscape:cx="32.313164"
|
||||
inkscape:cy="51.899226"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="g4780"
|
||||
showgrid="true"
|
||||
showborder="true"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:snap-bbox-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:snap-midpoints="true"
|
||||
inkscape:snap-object-midpoints="true"
|
||||
inkscape:snap-center="true"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:window-width="2880"
|
||||
inkscape:window-height="1663"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="76"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid5451"
|
||||
empspacing="8" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="8,-8.0000001"
|
||||
id="guide4063"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="4,-8.0000001"
|
||||
id="guide4065"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-8,88.000001"
|
||||
id="guide4067"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-8,92.000001"
|
||||
id="guide4069"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="104,4"
|
||||
id="guide4071"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-5,8.0000001"
|
||||
id="guide4073"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="92,-8.0000001"
|
||||
id="guide4075"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="88,-8.0000001"
|
||||
id="guide4077"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-8,84.000001"
|
||||
id="guide4074"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="12,-8.0000001"
|
||||
id="guide4076"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-5,12"
|
||||
id="guide4078"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="84,-9.0000001"
|
||||
id="guide4080"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="48,83.568528"
|
||||
orientation="1,0"
|
||||
id="guide4170"
|
||||
inkscape:locked="false" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata4879">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(67.857146,-78.50504)">
|
||||
<g
|
||||
transform="matrix(0,-1,-1,0,373.50506,516.50504)"
|
||||
id="g4845"
|
||||
style="display:inline">
|
||||
<g
|
||||
inkscape:export-ydpi="90"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="next01.png"
|
||||
transform="matrix(-0.9996045,0,0,1,575.94296,-611.00001)"
|
||||
id="g4778"
|
||||
inkscape:label="Layer 1">
|
||||
<g
|
||||
transform="matrix(-1,0,0,1,575.99999,611)"
|
||||
id="g4780"
|
||||
style="display:inline">
|
||||
<rect
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:4;marker:none;enable-background:accumulate"
|
||||
id="rect4782"
|
||||
width="96.037987"
|
||||
height="96"
|
||||
x="-438.00244"
|
||||
y="345.36221"
|
||||
transform="scale(-1,1)" />
|
||||
<path
|
||||
style="display:inline;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#808080;stroke-width:4.00079107;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 395.98583,366.36222 v 54"
|
||||
id="path837-3"
|
||||
inkscape:connector-type="polyline"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="display:inline;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#808080;stroke-width:4.00079107;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 393.98504,368.36261 -16.00633,-3.9e-4"
|
||||
id="path837-7"
|
||||
inkscape:connector-type="polyline"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="display:inline;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#808080;stroke-width:4.00079107;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 393.98504,418.36222 -16.00633,0"
|
||||
id="path837-7-5"
|
||||
inkscape:connector-type="polyline"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<rect
|
||||
style="display:inline;opacity:1;fill:none;fill-opacity:1;stroke:#808080;stroke-width:4.06083727;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
|
||||
id="rect899-3"
|
||||
width="17.93956"
|
||||
height="11.945124"
|
||||
x="-402.332"
|
||||
y="-371.97635"
|
||||
transform="matrix(0,-1,-1,0,0,0)" />
|
||||
<rect
|
||||
style="display:inline;opacity:1;fill:none;fill-opacity:1;stroke:#808080;stroke-width:4.06083727;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
|
||||
id="rect899-3-6"
|
||||
width="17.93956"
|
||||
height="11.945124"
|
||||
x="-427.30176"
|
||||
y="-371.97635"
|
||||
transform="matrix(0,-1,-1,0,0,0)" />
|
||||
<rect
|
||||
style="display:inline;opacity:1;fill:none;fill-opacity:1;stroke:#808080;stroke-width:4.06083727;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
|
||||
id="rect899-3-6-2"
|
||||
width="17.93956"
|
||||
height="11.945124"
|
||||
x="-377.332"
|
||||
y="-371.97635"
|
||||
transform="matrix(0,-1,-1,0,0,0)" />
|
||||
<path
|
||||
style="display:inline;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#808080;stroke-width:4.00079107;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 421.99612,393.36222 -44.01741,0"
|
||||
id="path837-7-5-9"
|
||||
inkscape:connector-type="polyline"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.0 KiB |
249
nymea-app/ui/system/ModbusRtuAddMasterPage.qml
Normal file
249
nymea-app/ui/system/ModbusRtuAddMasterPage.qml
Normal file
@ -0,0 +1,249 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, 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 General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU 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 General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
import QtQuick 2.8
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Controls.Material 2.1
|
||||
import QtQuick.Layouts 1.3
|
||||
import "../components"
|
||||
import Nymea 1.0
|
||||
|
||||
SettingsPageBase {
|
||||
id: root
|
||||
|
||||
property ModbusRtuManager modbusRtuManager
|
||||
property ListModel serialPortBaudrateModel
|
||||
property ListModel serialPortParityModel
|
||||
property ListModel serialPortDataBitsModel
|
||||
property ListModel serialPortStopBitsModel
|
||||
|
||||
header: NymeaHeader {
|
||||
text: qsTr("Add a new Modbus RTU master")
|
||||
backButtonVisible: true
|
||||
onBackPressed: pageStack.pop()
|
||||
}
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("Serial ports")
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: app.margins
|
||||
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
|
||||
wrapMode: Text.WordWrap
|
||||
text: modbusRtuManager.serialPorts.count !== 0 ? qsTr("Please select one of the following serial ports detected on the system.") : qsTr("There are no serial ports available.\n\nPlease make sure the modbus RTU interface is connected to the system.")
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: modbusRtuManager.serialPorts
|
||||
delegate: NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
iconName: "../images/stock_usb.svg"
|
||||
text: model.description + (model.manufacturer === "" ? "" : " - " + model.manufacturer)
|
||||
subText: model.systemLocation + (model.serialNumber === "" ? "" : " - " + model.serialNumber)
|
||||
onClicked: pageStack.push(configureNewModbusRtuMasterPage, { modbusRtuManager: modbusRtuManager, serialPort: modbusRtuManager.serialPorts.get(index) })
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: configureNewModbusRtuMasterPage
|
||||
|
||||
SettingsPageBase {
|
||||
id: root
|
||||
|
||||
property ModbusRtuManager modbusRtuManager
|
||||
property SerialPort serialPort
|
||||
busy: d.pendingCommandId != -1
|
||||
|
||||
header: NymeaHeader {
|
||||
text: qsTr("Configure modbus RTU master")
|
||||
backButtonVisible: true
|
||||
onBackPressed: pageStack.pop()
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property int pendingCommandId: -1
|
||||
|
||||
function addModbusRtuMaster(serialPort, baudRate, parity, dataBits, stopBits) {
|
||||
d.pendingCommandId = root.modbusRtuManager.addModbusRtuMaster(serialPort, baudRate, parity, dataBits, stopBits)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root.modbusRtuManager
|
||||
onAddModbusRtuMasterReply: {
|
||||
if (commandId === d.pendingCommandId) {
|
||||
d.pendingCommandId = -1
|
||||
if (modbusRtuManager.handleModbusError(error)) {
|
||||
pageStack.pop();
|
||||
pageStack.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("Serial port")
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("System location")
|
||||
subText: serialPort.systemLocation
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Description")
|
||||
subText: serialPort.description
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Manufacturer")
|
||||
subText: serialPort.manufacturer
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
visible: serialPort.manufacturer !== ""
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Serialnumber")
|
||||
subText: serialPort.serialNumber
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
visible: serialPort.serialNumber !== ""
|
||||
}
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("Configuration")
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
|
||||
Label {
|
||||
text: qsTr("Baud rate")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: baudRateComboBox
|
||||
Layout.minimumWidth: 250
|
||||
textRole: "text"
|
||||
enabled: !root.busy
|
||||
onActivated: console.log("Selected baud rate", currentText, model.get(currentIndex).value)
|
||||
model: serialPortBaudrateModel
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
|
||||
|
||||
Label {
|
||||
text: qsTr("Parity")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: parityComboBox
|
||||
textRole: "text"
|
||||
enabled: !root.busy
|
||||
Layout.minimumWidth: 250
|
||||
onActivated: console.log("Selected parity", currentText, model.get(currentIndex).value)
|
||||
model: serialPortParityModel
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
|
||||
|
||||
Label {
|
||||
text: qsTr("Data bits")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: dataBitsComboBox
|
||||
textRole: "text"
|
||||
enabled: !root.busy
|
||||
Layout.minimumWidth: 250
|
||||
onActivated: console.log("Selected data bits", currentText, model.get(currentIndex).value)
|
||||
model: serialPortDataBitsModel
|
||||
Component.onCompleted: {
|
||||
currentIndex = 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
|
||||
|
||||
Label {
|
||||
text: qsTr("Stop bits")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: stopBitsComboBox
|
||||
textRole: "text"
|
||||
enabled: !root.busy
|
||||
Layout.minimumWidth: 250
|
||||
onActivated: console.log("Selected stop bits", currentText, model.get(currentIndex).value)
|
||||
model: serialPortStopBitsModel
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: app.margins
|
||||
Layout.rightMargin: app.margins
|
||||
text: qsTr("Add")
|
||||
enabled: !root.busy
|
||||
onClicked: {
|
||||
var baudrate = serialPortBaudrateModel.get(baudRateComboBox.currentIndex).value
|
||||
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)
|
||||
|
||||
d.addModbusRtuMaster(serialPort.systemLocation, baudrate, parity, dataBits, stopBits)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
284
nymea-app/ui/system/ModbusRtuReconfigureMasterPage.qml
Normal file
284
nymea-app/ui/system/ModbusRtuReconfigureMasterPage.qml
Normal file
@ -0,0 +1,284 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, 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 General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU 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 General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
import QtQuick 2.8
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Controls.Material 2.1
|
||||
import QtQuick.Layouts 1.3
|
||||
import "../components"
|
||||
import Nymea 1.0
|
||||
|
||||
SettingsPageBase {
|
||||
id: root
|
||||
|
||||
property ModbusRtuManager modbusRtuManager
|
||||
property ModbusRtuMaster modbusRtuMaster
|
||||
property ListModel serialPortBaudrateModel
|
||||
property ListModel serialPortParityModel
|
||||
property ListModel serialPortDataBitsModel
|
||||
property ListModel serialPortStopBitsModel
|
||||
|
||||
header: NymeaHeader {
|
||||
text: qsTr("Reconfigure modbus RTU master")
|
||||
backButtonVisible: true
|
||||
onBackPressed: pageStack.pop()
|
||||
}
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("Serial ports")
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: app.margins
|
||||
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
|
||||
wrapMode: Text.WordWrap
|
||||
text: modbusRtuManager.serialPorts.count !== 0 ? qsTr("Please select one of the following serial ports detected on the system.") : qsTr("There are no serial ports available.\n\nPlease make sure the modbus RTU interface is connected to the system.")
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: modbusRtuManager.serialPorts
|
||||
delegate: NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
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 })
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: reconfigureNewModbusRtuMasterPage
|
||||
|
||||
SettingsPageBase {
|
||||
id: root
|
||||
|
||||
property ModbusRtuManager modbusRtuManager
|
||||
property SerialPort serialPort
|
||||
property ModbusRtuMaster modbusRtuMaster
|
||||
|
||||
busy: d.pendingCommandId != -1
|
||||
|
||||
header: NymeaHeader {
|
||||
text: qsTr("Reconfigure modbus RTU master")
|
||||
backButtonVisible: true
|
||||
onBackPressed: pageStack.pop()
|
||||
}
|
||||
|
||||
QtObject {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root.modbusRtuManager
|
||||
onReconfigureModbusRtuMasterReply: {
|
||||
if (commandId === d.pendingCommandId) {
|
||||
d.pendingCommandId = -1
|
||||
if (modbusRtuManager.handleModbusError(error)) {
|
||||
pageStack.pop();
|
||||
pageStack.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("UUID")
|
||||
subText: modbusRtuMaster.modbusUuid
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("Serial port")
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("System location")
|
||||
subText: serialPort.systemLocation
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Description")
|
||||
subText: serialPort.description
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Manufacturer")
|
||||
subText: serialPort.manufacturer
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
visible: serialPort.manufacturer !== ""
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Serialnumber")
|
||||
subText: serialPort.serialNumber
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
visible: serialPort.serialNumber !== ""
|
||||
}
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("Configuration")
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
|
||||
Label {
|
||||
text: qsTr("Baud rate")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: baudRateComboBox
|
||||
Layout.minimumWidth: 250
|
||||
enabled: !root.busy
|
||||
textRole: "text"
|
||||
model: serialPortBaudrateModel
|
||||
onActivated: console.log("Selected baudrate", currentText, model.get(currentIndex).value)
|
||||
Component.onCompleted: {
|
||||
for (var i = 0; i < serialPortBaudrateModel.count; i++) {
|
||||
if (serialPortBaudrateModel.get(i).value === modbusRtuMaster.baudrate) {
|
||||
currentIndex = i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
|
||||
|
||||
Label {
|
||||
text: qsTr("Parity")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: parityComboBox
|
||||
textRole: "text"
|
||||
enabled: !root.busy
|
||||
Layout.minimumWidth: 250
|
||||
onActivated: console.log("Selected parity", currentText, model.get(currentIndex).value)
|
||||
model: serialPortParityModel
|
||||
Component.onCompleted: {
|
||||
for (var i = 0; i < serialPortParityModel.count; i++) {
|
||||
if (serialPortParityModel.get(i).value === modbusRtuMaster.parity) {
|
||||
currentIndex = i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
|
||||
|
||||
Label {
|
||||
text: qsTr("Data bits")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: dataBitsComboBox
|
||||
textRole: "text"
|
||||
enabled: !root.busy
|
||||
Layout.minimumWidth: 250
|
||||
onActivated: console.log("Selected data bits", currentText, model.get(currentIndex).value)
|
||||
model: serialPortDataBitsModel
|
||||
Component.onCompleted: {
|
||||
for (var i = 0; i < serialPortDataBitsModel.count; i++) {
|
||||
if (serialPortDataBitsModel.get(i).value === modbusRtuMaster.dataBits) {
|
||||
currentIndex = i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
|
||||
|
||||
Label {
|
||||
text: qsTr("Stop bits")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: stopBitsComboBox
|
||||
textRole: "text"
|
||||
enabled: !root.busy
|
||||
Layout.minimumWidth: 250
|
||||
onActivated: console.log("Selected stop bits", currentText, model.get(currentIndex).value)
|
||||
model: serialPortStopBitsModel
|
||||
Component.onCompleted: {
|
||||
for (var i = 0; i < serialPortStopBitsModel.count; i++) {
|
||||
if (serialPortStopBitsModel.get(i).value === modbusRtuMaster.stopBits) {
|
||||
currentIndex = i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: app.margins
|
||||
Layout.rightMargin: app.margins
|
||||
text: qsTr("Apply")
|
||||
enabled: !root.busy
|
||||
onClicked: {
|
||||
var baudrate = serialPortBaudrateModel.get(baudRateComboBox.currentIndex).value
|
||||
var parity = serialPortParityModel.get(parityComboBox.currentIndex).value
|
||||
var dataBits = serialPortDataBitsModel.get(dataBitsComboBox.currentIndex).value
|
||||
var stopBits = serialPortStopBitsModel.get(stopBitsComboBox.currentIndex).value
|
||||
|
||||
console.log("Reconfigure modbus RTU", modbusRtuMaster.modbusUuid, "with", serialPort.systemLocation, baudrate, parity, dataBits, stopBits)
|
||||
d.reconfigureModbusRtuMaster(modbusRtuMaster.modbusUuid, serialPort.systemLocation, baudrate, parity, dataBits, stopBits)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
366
nymea-app/ui/system/ModbusRtuSettingsPage.qml
Normal file
366
nymea-app/ui/system/ModbusRtuSettingsPage.qml
Normal file
@ -0,0 +1,366 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU 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 General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
import QtQuick 2.8
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Controls.Material 2.1
|
||||
import QtQuick.Layouts 1.3
|
||||
import "../components"
|
||||
import Nymea 1.0
|
||||
|
||||
SettingsPageBase {
|
||||
id: root
|
||||
|
||||
header: NymeaHeader {
|
||||
text: qsTr("Modbus RTU")
|
||||
backButtonVisible: true
|
||||
onBackPressed: pageStack.pop()
|
||||
|
||||
HeaderButton {
|
||||
imageSource: "../images/add.svg"
|
||||
text: qsTr("Add Modbus RTU master")
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("ModbusRtuAddMasterPage.qml"), {
|
||||
modbusRtuManager: modbusRtuManager,
|
||||
serialPortBaudrateModel: serialPortBaudrateModel,
|
||||
serialPortParityModel: serialPortParityModel,
|
||||
serialPortDataBitsModel: serialPortDataBitsModel,
|
||||
serialPortStopBitsModel: serialPortStopBitsModel
|
||||
})
|
||||
enabled: modbusRtuManager.supported
|
||||
}
|
||||
}
|
||||
|
||||
ModbusRtuManager {
|
||||
id: modbusRtuManager
|
||||
engine: _engine
|
||||
|
||||
function handleModbusError(error) {
|
||||
var props = {};
|
||||
switch (error) {
|
||||
case "ModbusRtuErrorNoError":
|
||||
return true;
|
||||
case "ModbusRtuErrorNotAvailable":
|
||||
props.text = qsTr("The serial port is not available any more.");
|
||||
break;
|
||||
case "ModbusRtuErrorNotSupported":
|
||||
props.text = qsTr("Modbus is not supported on this platform.");
|
||||
break;
|
||||
case "ModbusRtuErrorHardwareNotFound":
|
||||
props.text = qsTr("The modbus RTU hardware could not be found.");
|
||||
break;
|
||||
case "ModbusRtuErrorUuidNotFound":
|
||||
props.text = qsTr("The selected modbus RTU master does not exist any more.");
|
||||
break;
|
||||
case "ModbusRtuErrorConnectionFailed":
|
||||
props.text = qsTr("Unable to connect to the modbus RTU master.\n\nMaybe the hardware is already in use.");
|
||||
break;
|
||||
default:
|
||||
props.errorCode = error;
|
||||
}
|
||||
var comp = Qt.createComponent("../components/ErrorDialog.qml")
|
||||
var popup = comp.createObject(app, props)
|
||||
popup.open();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("Modbus RTU masters")
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: serialPortBaudrateModel
|
||||
ListElement { value: 9600; text: qsTr("9600 Bd") }
|
||||
ListElement { value: 14400; text: qsTr("14400 Bd") }
|
||||
ListElement { value: 19200; text: qsTr("19200 Bd") }
|
||||
ListElement { value: 38400; text: qsTr("38400 Bd") }
|
||||
ListElement { value: 57600; text: qsTr("57600 Bd") }
|
||||
ListElement { value: 115200; text: qsTr("115200 Bd") }
|
||||
ListElement { value: 128000; text: qsTr("128000 Bd") }
|
||||
ListElement { value: 230400; text: qsTr("230400 Bd") }
|
||||
ListElement { value: 256000; text: qsTr("256000 Bd") }
|
||||
|
||||
function getText(baudrate) {
|
||||
for (var index = 0; index < serialPortBaudrateModel.count; index++) {
|
||||
if (serialPortBaudrateModel.get(index).value === baudrate) {
|
||||
return serialPortBaudrateModel.get(index).text
|
||||
}
|
||||
}
|
||||
|
||||
return qsTr("Unknown baud rate")
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: serialPortParityModel
|
||||
ListElement { value: SerialPort.SerialPortParityNoParity; text: qsTr("No parity") }
|
||||
ListElement { value: SerialPort.SerialPortParityEvenParity; text: qsTr("Even parity") }
|
||||
ListElement { value: SerialPort.SerialPortParityOddParity; text: qsTr("Odd parity") }
|
||||
ListElement { value: SerialPort.SerialPortParitySpaceParity; text: qsTr("Space parity") }
|
||||
ListElement { value: SerialPort.SerialPortParityMarkParity; text: qsTr("Mark parity") }
|
||||
|
||||
function getText(parity) {
|
||||
for (var index = 0; index < serialPortParityModel.count; index++) {
|
||||
if (serialPortParityModel.get(index).value === parity) {
|
||||
return serialPortParityModel.get(index).text
|
||||
}
|
||||
}
|
||||
|
||||
return qsTr("Unknown parity")
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: serialPortDataBitsModel
|
||||
ListElement { value: SerialPort.SerialPortDataBitsData5; text: qsTr("5 data bits") }
|
||||
ListElement { value: SerialPort.SerialPortDataBitsData6; text: qsTr("6 data bits") }
|
||||
ListElement { value: SerialPort.SerialPortDataBitsData7; text: qsTr("7 data bits") }
|
||||
ListElement { value: SerialPort.SerialPortDataBitsData8; text: qsTr("8 data bits") }
|
||||
|
||||
function getText(dataBits) {
|
||||
for (var index = 0; index < serialPortDataBitsModel.count; index++) {
|
||||
if (serialPortDataBitsModel.get(index).value === dataBits) {
|
||||
return serialPortDataBitsModel.get(index).text
|
||||
}
|
||||
}
|
||||
|
||||
return qsTr("Unknown data bits")
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: serialPortStopBitsModel
|
||||
ListElement { value: SerialPort.SerialPortStopBitsOneStop; text: qsTr("One stop bit") }
|
||||
ListElement { value: SerialPort.SerialPortStopBitsOneAndHalfStop; text: qsTr("One and a half stop bits") }
|
||||
ListElement { value: SerialPort.SerialPortStopBitsTwoStop; text: qsTr("Two stop bits") }
|
||||
|
||||
function getText(stopBits) {
|
||||
for (var index = 0; index < serialPortStopBitsModel.count; index++) {
|
||||
if (serialPortStopBitsModel.get(index).value === stopBits) {
|
||||
return serialPortStopBitsModel.get(index).text
|
||||
}
|
||||
}
|
||||
|
||||
return qsTr("Unknown stop bits")
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
|
||||
wrapMode: Text.WordWrap
|
||||
text: qsTr("In this section you can configure system wide modbus RTU master connections which can be used in different plugins.")
|
||||
visible: modbusRtuManager.supported
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
|
||||
wrapMode: Text.WordWrap
|
||||
text: qsTr("There are no modbus RTU masters set up yet.")
|
||||
visible: modbusRtuManager.modbusRtuMasters.count === 0 && modbusRtuManager.supported
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
|
||||
wrapMode: Text.WordWrap
|
||||
text: qsTr("Modbus RTU is not supported on this platorm.")
|
||||
visible: !modbusRtuManager.supported
|
||||
}
|
||||
|
||||
// Modbus RTU masters
|
||||
Repeater {
|
||||
enabled: modbusRtuManager.supported
|
||||
model: modbusRtuManager.modbusRtuMasters
|
||||
delegate: NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
iconName: "../images/modbus.svg"
|
||||
text: model.serialPort + " " + model.baudrate
|
||||
subText: model.connected ? qsTr("Connected") : qsTr("Disconnected")
|
||||
onClicked: pageStack.push(modbusDetailsComponent, { modbusRtuManager: modbusRtuManager, modbusRtuMaster: modbusRtuManager.modbusRtuMasters.get(index) })
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: modbusDetailsComponent
|
||||
|
||||
SettingsPageBase {
|
||||
id: root
|
||||
|
||||
property ModbusRtuManager modbusRtuManager
|
||||
property ModbusRtuMaster modbusRtuMaster
|
||||
|
||||
busy: d.pendingCommandId !== -1
|
||||
|
||||
header: NymeaHeader {
|
||||
text: qsTr("Modbus RTU master")
|
||||
backButtonVisible: true
|
||||
onBackPressed: pageStack.pop()
|
||||
|
||||
HeaderButton {
|
||||
imageSource: "../images/delete.svg"
|
||||
text: qsTr("Remove modbus RTU master")
|
||||
enabled: modbusRtuManager.supported
|
||||
onClicked: {
|
||||
var dialog = removeModbusMasterDialogComponent.createObject(app, {modbusRtuMaster: root.modbusRtuMaster})
|
||||
dialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: removeModbusMasterDialogComponent
|
||||
|
||||
MeaDialog {
|
||||
id: removeModbusMasterDialog
|
||||
|
||||
property ModbusRtuMaster modbusRtuMaster
|
||||
|
||||
headerIcon: "../images/modbus.svg"
|
||||
title: qsTr("Remove modbus RTU master")
|
||||
text: qsTr("Are you sure you want to remove this modbus RTU master?")
|
||||
standardButtons: Dialog.Ok | Dialog.Cancel
|
||||
|
||||
Label {
|
||||
text: qsTr("Please note that all related things will stop working until you assign a new modbus RTU master to them.")
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
d.removeModbusRtuMaster(modbusRtuMaster.modbusUuid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property int pendingCommandId: -1
|
||||
|
||||
function removeModbusRtuMaster(modbusUuid) {
|
||||
d.pendingCommandId = root.modbusRtuManager.removeModbusRtuMaster(modbusUuid)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root.modbusRtuManager
|
||||
onRemoveModbusRtuMasterReply: {
|
||||
if (commandId === d.pendingCommandId) {
|
||||
d.pendingCommandId = -1
|
||||
if (modbusRtuManager.handleModbusError(error)) {
|
||||
// FIXME: the page does not work if I pop the page here
|
||||
//pageStack.pop()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("Information")
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("UUID")
|
||||
subText: modbusRtuMaster ? modbusRtuMaster.modbusUuid : ""
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("System location")
|
||||
subText: modbusRtuMaster ? modbusRtuMaster.serialPort : ""
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Connection status")
|
||||
subText: modbusRtuMaster && modbusRtuMaster.connected ? qsTr("Connected") : qsTr("Disconnected")
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Baud rate")
|
||||
subText: modbusRtuMaster ? serialPortBaudrateModel.getText(modbusRtuMaster.baudrate) : ""
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Parity")
|
||||
subText: modbusRtuMaster ? serialPortParityModel.getText(modbusRtuMaster.parity) : ""
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Data bits")
|
||||
subText: modbusRtuMaster ? serialPortDataBitsModel.getText(modbusRtuMaster.dataBits) : ""
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
NymeaSwipeDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Stop bits")
|
||||
subText: modbusRtuMaster ? serialPortStopBitsModel.getText(modbusRtuMaster.stopBits) : ""
|
||||
progressive: false
|
||||
prominentSubText: false
|
||||
}
|
||||
|
||||
Button {
|
||||
id: reconfigureButton
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: app.margins
|
||||
Layout.rightMargin: app.margins
|
||||
text: qsTr("Reconfigure")
|
||||
enabled: !root.busy
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("ModbusRtuReconfigureMasterPage.qml"), {
|
||||
modbusRtuManager: modbusRtuManager,
|
||||
modbusRtuMaster: root.modbusRtuMaster,
|
||||
serialPortBaudrateModel: serialPortBaudrateModel,
|
||||
serialPortParityModel: serialPortParityModel,
|
||||
serialPortDataBitsModel: serialPortDataBitsModel,
|
||||
serialPortStopBitsModel: serialPortStopBitsModel
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user