Schrack: Improve discovery
parent
e5f3dbedc4
commit
26a2aeab51
|
|
@ -0,0 +1,12 @@
|
||||||
|
# Schrack CION
|
||||||
|
|
||||||
|
This plugin adds support for the Schrack CION wallbox to nymea.
|
||||||
|
|
||||||
|
The wallbox needs to be connected to the nymea system using an RS485 interface which needs to be configured as a Modbus RTU interface with the following parameters:
|
||||||
|
* Baudrate: 57600
|
||||||
|
* Data bits: 8
|
||||||
|
* Stop bit: 1
|
||||||
|
* Parity: None
|
||||||
|
|
||||||
|
Once the Modbus RTU interface is configured, the Wallbox can be added to nymea. nymea will try to discover the wallbox on the first 10 slave ids. This means, the DIP switches on the Wallbox are required to be configred for a modbus Slave ID from 1 to 10.
|
||||||
|
|
||||||
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
#include"extern-plugininfo.h"
|
#include"extern-plugininfo.h"
|
||||||
|
|
||||||
|
#include <modbusdatautils.h>
|
||||||
|
|
||||||
|
|
||||||
CionDiscovery::CionDiscovery(ModbusRtuHardwareResource *modbusRtuResource, QObject *parent)
|
CionDiscovery::CionDiscovery(ModbusRtuHardwareResource *modbusRtuResource, QObject *parent)
|
||||||
: QObject{parent},
|
: QObject{parent},
|
||||||
m_modbusRtuResource{modbusRtuResource}
|
m_modbusRtuResource{modbusRtuResource}
|
||||||
|
|
@ -44,20 +47,27 @@ void CionDiscovery::tryConnect(ModbusRtuMaster *master, quint16 slaveId)
|
||||||
{
|
{
|
||||||
qCDebug(dcSchrack()) << "Scanning modbus RTU master" << master->modbusUuid() << "Slave ID:" << slaveId;
|
qCDebug(dcSchrack()) << "Scanning modbus RTU master" << master->modbusUuid() << "Slave ID:" << slaveId;
|
||||||
|
|
||||||
ModbusRtuReply *reply = master->readInputRegister(slaveId, 4);
|
ModbusRtuReply *reply = master->readHoldingRegister(slaveId, 832, 16);
|
||||||
connect(reply, &ModbusRtuReply::finished, this, [=](){
|
connect(reply, &ModbusRtuReply::finished, this, [=](){
|
||||||
qCDebug(dcSchrack()) << "Test reply finished!" << reply->error() << reply->result();
|
|
||||||
if (reply->error() == ModbusRtuReply::NoError && reply->result().length() > 0) {
|
if (reply->error() == ModbusRtuReply::NoError) {
|
||||||
quint16 version = reply->result().first();
|
|
||||||
if (version >= 0x0100) {
|
QString firmwareVersion = ModbusDataUtils::convertToString(reply->result());
|
||||||
qCDebug(dcSchrack()) << QString("Version is 0x%1").arg(version, 0, 16);
|
qCDebug(dcSchrack()) << "Test reply finished!" << reply->error() << firmwareVersion;
|
||||||
Result result {master->modbusUuid(), version, slaveId};
|
|
||||||
|
// Version numbers seem to be wild west... We can't really understand what's in there...
|
||||||
|
// So let's assume this is a schrack if reading alone succeeded and it is a valid string and 18 to 32 chars long...
|
||||||
|
// Examples of how this looks like:
|
||||||
|
// EBE 1.2: "V1.2 15.02.2021"
|
||||||
|
// ICC: "003090056-01 20220913"
|
||||||
|
QRegExp re = QRegExp("[A-Z0-9\\.- ]{18,32}");
|
||||||
|
if (re.exactMatch(firmwareVersion)) {
|
||||||
|
Result result {master->modbusUuid(), firmwareVersion, slaveId};
|
||||||
m_discoveryResults.append(result);
|
m_discoveryResults.append(result);
|
||||||
} else {
|
|
||||||
qCDebug(dcAmperfied()) << "Version must be at least 1.0.0 (0x0100)";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (slaveId < 20) {
|
|
||||||
|
if (slaveId < 10) {
|
||||||
tryConnect(master, slaveId+1);
|
tryConnect(master, slaveId+1);
|
||||||
} else {
|
} else {
|
||||||
emit discoveryFinished(true);
|
emit discoveryFinished(true);
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ public:
|
||||||
explicit CionDiscovery(ModbusRtuHardwareResource *modbusRtuResource, QObject *parent = nullptr);
|
explicit CionDiscovery(ModbusRtuHardwareResource *modbusRtuResource, QObject *parent = nullptr);
|
||||||
struct Result {
|
struct Result {
|
||||||
QUuid modbusRtuMasterId;
|
QUuid modbusRtuMasterId;
|
||||||
quint16 firmwareVersion;
|
QString firmwareVersion;
|
||||||
quint16 slaveId;
|
quint16 slaveId;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@
|
||||||
#include "integrationpluginschrack.h"
|
#include "integrationpluginschrack.h"
|
||||||
#include "plugininfo.h"
|
#include "plugininfo.h"
|
||||||
|
|
||||||
|
#include "ciondiscovery.h"
|
||||||
|
|
||||||
IntegrationPluginSchrack::IntegrationPluginSchrack()
|
IntegrationPluginSchrack::IntegrationPluginSchrack()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -42,27 +44,36 @@ void IntegrationPluginSchrack::init()
|
||||||
|
|
||||||
void IntegrationPluginSchrack::discoverThings(ThingDiscoveryInfo *info)
|
void IntegrationPluginSchrack::discoverThings(ThingDiscoveryInfo *info)
|
||||||
{
|
{
|
||||||
qCDebug(dcSchrack()) << "Discovering modbus RTU resources...";
|
CionDiscovery *discovery = new CionDiscovery(hardwareManager()->modbusRtuResource(), info);
|
||||||
if (hardwareManager()->modbusRtuResource()->modbusRtuMasters().isEmpty()) {
|
|
||||||
info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("No Modbus RTU interface available. Please set up a Modbus RTU interface first."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (ModbusRtuMaster *modbusMaster, hardwareManager()->modbusRtuResource()->modbusRtuMasters()) {
|
connect(discovery, &CionDiscovery::discoveryFinished, info, [this, info, discovery](bool modbusMasterAvailable){
|
||||||
qCDebug(dcSchrack()) << "Found RTU master resource" << modbusMaster << "connected" << modbusMaster->connected();
|
if (!modbusMasterAvailable) {
|
||||||
if (!modbusMaster->connected()) {
|
info->finish(Thing::ThingErrorHardwareNotAvailable, QT_TR_NOOP("No modbus RTU master with appropriate settings found. Please set up a modbus RTU master with a baudrate of 57600, 8 data bis, 1 stop bit and no parity first."));
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ThingDescriptor descriptor(info->thingClassId(), "i-CHARGE CION", QString::number(slaveAddress) + " " + modbusMaster->serialPort());
|
qCInfo(dcSchrack()) << "Discovery results:" << discovery->discoveryResults().count();
|
||||||
ParamList params;
|
|
||||||
params << Param(cionThingSlaveAddressParamTypeId, slaveAddress);
|
|
||||||
params << Param(cionThingModbusMasterUuidParamTypeId, modbusMaster->modbusUuid());
|
|
||||||
descriptor.setParams(params);
|
|
||||||
info->addThingDescriptor(descriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
info->finish(Thing::ThingErrorNoError);
|
foreach (const CionDiscovery::Result &result, discovery->discoveryResults()) {
|
||||||
|
ThingDescriptor descriptor(cionThingClassId, "Schrack CION", QString("Slave ID: %1, Version: %2").arg(result.slaveId).arg(result.firmwareVersion));
|
||||||
|
|
||||||
|
ParamList params{
|
||||||
|
{cionThingModbusMasterUuidParamTypeId, result.modbusRtuMasterId},
|
||||||
|
{cionThingSlaveAddressParamTypeId, result.slaveId}
|
||||||
|
};
|
||||||
|
descriptor.setParams(params);
|
||||||
|
|
||||||
|
Thing *existingThing = myThings().findByParams(params);
|
||||||
|
if (existingThing) {
|
||||||
|
descriptor.setThingId(existingThing->id());
|
||||||
|
}
|
||||||
|
info->addThingDescriptor(descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
info->finish(Thing::ThingErrorNoError);
|
||||||
|
});
|
||||||
|
|
||||||
|
discovery->startDiscovery();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IntegrationPluginSchrack::setupThing(ThingSetupInfo *info)
|
void IntegrationPluginSchrack::setupThing(ThingSetupInfo *info)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue