From e5f3dbedc48277a58679e33d45b7f9ef99711ff5 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Tue, 7 Mar 2023 14:34:48 +0100 Subject: [PATCH] Imporove discovery for Schrack --- schrack/ciondiscovery.cpp | 66 +++++++++++++++++++++++++++ schrack/ciondiscovery.h | 64 ++++++++++++++++++++++++++ schrack/integrationpluginschrack.cpp | 9 +--- schrack/integrationpluginschrack.json | 9 ---- schrack/schrack.pro | 2 + 5 files changed, 134 insertions(+), 16 deletions(-) create mode 100644 schrack/ciondiscovery.cpp create mode 100644 schrack/ciondiscovery.h diff --git a/schrack/ciondiscovery.cpp b/schrack/ciondiscovery.cpp new file mode 100644 index 0000000..c2094f7 --- /dev/null +++ b/schrack/ciondiscovery.cpp @@ -0,0 +1,66 @@ +#include "ciondiscovery.h" + +#include"extern-plugininfo.h" + +CionDiscovery::CionDiscovery(ModbusRtuHardwareResource *modbusRtuResource, QObject *parent) + : QObject{parent}, + m_modbusRtuResource{modbusRtuResource} +{ + +} + +void CionDiscovery::startDiscovery() +{ + qCInfo(dcSchrack()) << "Discovery: Searching for Schrack i-CHARGE wallboxes on modbus RTU..."; + + QList candidateMasters; + foreach (ModbusRtuMaster *master, m_modbusRtuResource->modbusRtuMasters()) { + if (master->baudrate() == 57600 && master->dataBits() == 8 && master->stopBits() == 1 && master->parity() == QSerialPort::NoParity) { + candidateMasters.append(master); + } + } + + if (candidateMasters.isEmpty()) { + qCWarning(dcSchrack()) << "No usable modbus RTU master found."; + emit discoveryFinished(false); + return; + } + + foreach (ModbusRtuMaster *master, candidateMasters) { + if (master->connected()) { + tryConnect(master, 1); + } else { + qCWarning(dcSchrack()) << "Modbus RTU master" << master->modbusUuid().toString() << "is not connected."; + } + } +} + +QList CionDiscovery::discoveryResults() const +{ + return m_discoveryResults; +} + +void CionDiscovery::tryConnect(ModbusRtuMaster *master, quint16 slaveId) +{ + qCDebug(dcSchrack()) << "Scanning modbus RTU master" << master->modbusUuid() << "Slave ID:" << slaveId; + + ModbusRtuReply *reply = master->readInputRegister(slaveId, 4); + connect(reply, &ModbusRtuReply::finished, this, [=](){ + qCDebug(dcSchrack()) << "Test reply finished!" << reply->error() << reply->result(); + if (reply->error() == ModbusRtuReply::NoError && reply->result().length() > 0) { + quint16 version = reply->result().first(); + if (version >= 0x0100) { + qCDebug(dcSchrack()) << QString("Version is 0x%1").arg(version, 0, 16); + Result result {master->modbusUuid(), version, slaveId}; + m_discoveryResults.append(result); + } else { + qCDebug(dcAmperfied()) << "Version must be at least 1.0.0 (0x0100)"; + } + } + if (slaveId < 20) { + tryConnect(master, slaveId+1); + } else { + emit discoveryFinished(true); + } + }); +} diff --git a/schrack/ciondiscovery.h b/schrack/ciondiscovery.h new file mode 100644 index 0000000..5e9f388 --- /dev/null +++ b/schrack/ciondiscovery.h @@ -0,0 +1,64 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2023, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea. +* This project including source code and documentation is protected by +* copyright law, and remains the property of nymea GmbH. All rights, including +* reproduction, publication, editing and translation, are reserved. The use of +* this project is subject to the terms of a license agreement to be concluded +* with nymea GmbH in accordance with the terms of use of nymea GmbH, available +* under https://nymea.io/license +* +* GNU Lesser General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the +* terms of the GNU Lesser General Public License as published by the Free +* Software Foundation; version 3. This project is distributed in the hope that +* it will be useful, but WITHOUT ANY WARRANTY; without even the implied +* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this project. If not, see . +* +* For any further details and any questions please contact us under +* contact@nymea.io or see our FAQ/Licensing Information on +* https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef CIONDISCOVERY_H +#define CIONDISCOVERY_H + +#include +#include + +class CionDiscovery : public QObject +{ + Q_OBJECT +public: + explicit CionDiscovery(ModbusRtuHardwareResource *modbusRtuResource, QObject *parent = nullptr); + struct Result { + QUuid modbusRtuMasterId; + quint16 firmwareVersion; + quint16 slaveId; + }; + + void startDiscovery(); + + QList discoveryResults() const; + +signals: + void discoveryFinished(bool modbusRtuMasterAvailable); + +private slots: + void tryConnect(ModbusRtuMaster *master, quint16 slaveId); + +private: + ModbusRtuHardwareResource *m_modbusRtuResource = nullptr; + + QList m_discoveryResults; +}; + +#endif // CIONDISCOVERY_H diff --git a/schrack/integrationpluginschrack.cpp b/schrack/integrationpluginschrack.cpp index aa5877b..72b5169 100644 --- a/schrack/integrationpluginschrack.cpp +++ b/schrack/integrationpluginschrack.cpp @@ -48,16 +48,11 @@ void IntegrationPluginSchrack::discoverThings(ThingDiscoveryInfo *info) return; } - uint slaveAddress = info->params().paramValue(cionDiscoverySlaveAddressParamTypeId).toUInt(); - if (slaveAddress > 254 || slaveAddress == 0) { - info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("The Modbus slave address must be a value between 1 and 254.")); - return; - } - foreach (ModbusRtuMaster *modbusMaster, hardwareManager()->modbusRtuResource()->modbusRtuMasters()) { qCDebug(dcSchrack()) << "Found RTU master resource" << modbusMaster << "connected" << modbusMaster->connected(); - if (!modbusMaster->connected()) + if (!modbusMaster->connected()) { continue; + } ThingDescriptor descriptor(info->thingClassId(), "i-CHARGE CION", QString::number(slaveAddress) + " " + modbusMaster->serialPort()); ParamList params; diff --git a/schrack/integrationpluginschrack.json b/schrack/integrationpluginschrack.json index 341a700..0c6c339 100644 --- a/schrack/integrationpluginschrack.json +++ b/schrack/integrationpluginschrack.json @@ -15,15 +15,6 @@ "id": "075d389d-3330-4d0b-9649-9f085120ca40", "createMethods": ["discovery"], "interfaces": ["evcharger", "connectable"], - "discoveryParamTypes": [ - { - "id": "8004705f-0e13-4713-b75e-49d115cd9517", - "name": "slaveAddress", - "displayName": "Slave address", - "type": "int", - "defaultValue": 1 - } - ], "paramTypes": [ { "id": "dac10e08-734c-4e71-a5d6-0d2a1f416ca6", diff --git a/schrack/schrack.pro b/schrack/schrack.pro index 94fae58..2b8023c 100644 --- a/schrack/schrack.pro +++ b/schrack/schrack.pro @@ -6,8 +6,10 @@ MODBUS_CONNECTIONS += cion-registers.json include(../modbus.pri) SOURCES += \ + ciondiscovery.cpp \ integrationpluginschrack.cpp HEADERS += \ + ciondiscovery.h \ integrationpluginschrack.h