diff --git a/libnymea-modbus/tools/connectiontool/modbusrtu.py b/libnymea-modbus/tools/connectiontool/modbusrtu.py
index 0cb7630..eaa0a5e 100644
--- a/libnymea-modbus/tools/connectiontool/modbusrtu.py
+++ b/libnymea-modbus/tools/connectiontool/modbusrtu.py
@@ -79,7 +79,7 @@ def writePropertyGetSetMethodImplementationsRtu(fileDescriptor, className, regis
def writePropertyUpdateMethodImplementationsRtu(fileDescriptor, className, registerDefinitions):
for registerDefinition in registerDefinitions:
- if 'readSchedule' in registerDefinition and registerDefinition['readSchedule'] == 'init':
+ if not 'readSchedule' in registerDefinition or registerDefinition['readSchedule'] == 'init':
continue
propertyName = registerDefinition['id']
diff --git a/mennekes/ModbusRTU_AmtronCompact2-0s_Description_v1-2.pdf b/mennekes/ModbusRTU_AmtronCompact2-0s_Description_v1-2.pdf
new file mode 100644
index 0000000..29f9813
Binary files /dev/null and b/mennekes/ModbusRTU_AmtronCompact2-0s_Description_v1-2.pdf differ
diff --git a/mennekes/README.md b/mennekes/README.md
index 091497c..afb5f94 100644
--- a/mennekes/README.md
+++ b/mennekes/README.md
@@ -2,21 +2,24 @@
Connects nymea to a MENNEKES wallboxes. Currently supported models are:
-* Amtron Xtra
-* Amtron Premium
-* Amtron Professional
-* Amtron Charge Control
+* AMTRON Xtra
+* AMTRON Premium
+* AMTRON Professional
+* AMTRON Charge Control
* Amedio Professional
+* AMTRON Compact 2.0s
# Requirements
-nymea uses the Modbus TCP connection to connect to the wallbox.
+nymea uses the Modbus RTU (AMTRON Compact 2.0s) or Modbus TCP (all other models) connection to connect to the wallbox.
> The Modbus TCP connection needs to be enabled manually on the Wallbox.
For the Amtron Charge Control and Premium models, log in to the wallbox's web interface as operator. The login credentials can be obtained
from the user manual of the wallbox. Once logged in, navigate to the Load Management tab and set the Modbus TCP Server to On.
+For the AMTRON Compact 2.0s, DIP switch 4 and 5 on Bank 51 must be set to ON in order to allow nymea controlling the wallbox.
+
## More
It is highly recommended to update the wallbox to the latest firmware which can be downloaded from [here](https://www.chargeupyourday.de/services/software-updates/).
diff --git a/mennekes/amtron-compact20-registers.json b/mennekes/amtron-compact20-registers.json
new file mode 100644
index 0000000..fa8bad7
--- /dev/null
+++ b/mennekes/amtron-compact20-registers.json
@@ -0,0 +1,324 @@
+{
+ "className": "AmtronCompact20",
+ "protocol": "RTU",
+ "endianness": "BigEndian",
+ "errorLimitUntilNotReachable": 20,
+ "checkReachableRegister": "cpSignalState",
+ "enums": [
+ {
+ "name": "CPSignalState",
+ "values": [
+ {
+ "key": "A1",
+ "value": 10
+ },
+ {
+ "key": "B1",
+ "value": 11
+ },
+ {
+ "key": "C1",
+ "value": 12
+ },
+ {
+ "key": "D1",
+ "value": 13
+ },
+ {
+ "key": "E",
+ "value": 14
+ },
+ {
+ "key": "F",
+ "value": 15
+ },
+ {
+ "key": "A2",
+ "value": 26
+ },
+ {
+ "key": "B2",
+ "value": 27
+ },
+ {
+ "key": "C2",
+ "value": 28
+ },
+ {
+ "key": "D2",
+ "value": 29
+ }
+ ]
+ },
+ {
+ "name": "EvseState",
+ "values": [
+ {
+ "key": "NotInitialized",
+ "value": 0
+ },
+ {
+ "key": "Idle",
+ "value": 1
+ },
+ {
+ "key": "EvConnected",
+ "value": 2
+ },
+ {
+ "key": "PreconditionsValidButNotCharging",
+ "value": 3
+ },
+ {
+ "key": "ReadyToCharge",
+ "value": 4
+ },
+ {
+ "key": "Charging",
+ "value": 5
+ },
+ {
+ "key": "Error",
+ "value": 6
+ },
+ {
+ "key": "ServiceMode",
+ "value": 7
+ }
+ ]
+ },
+ {
+ "name": "PhaseMode",
+ "values": [
+ {
+ "key": "All",
+ "value": 0
+ },
+ {
+ "key": "Single",
+ "value": 1
+ }
+ ]
+ },
+ {
+ "name": "SolarChargingMode",
+ "values": [
+ {
+ "key": "Off",
+ "value": 0
+ },
+ {
+ "key": "Standard",
+ "value": 1
+ },
+ {
+ "key": "Sunshine",
+ "value": 2
+ },
+ {
+ "key": "SunshinePlus",
+ "value": 3
+ }
+ ]
+ }
+ ],
+ "blocks": [
+ {
+ "id": "session",
+ "readSchedule": "udpate",
+ "registers": [
+ {
+ "id": "maxCurrentSession",
+ "address": 2816,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Max current for session",
+ "defaultValue": 32,
+ "access": "RO"
+ },
+ {
+ "id": "chargedEnergySession",
+ "address": 2818,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Charged energy session",
+ "defaultValue": 0,
+ "access": "RO"
+ },
+ {
+ "id": "sessionDuration",
+ "address": 2820,
+ "size": 2,
+ "type": "uint32",
+ "registerType": "holdingRegister",
+ "description": "Session duration",
+ "defaultValue": 0,
+ "access": "RO"
+ },
+ {
+ "id": "detectedEVPhases",
+ "address": 2822,
+ "size": 1,
+ "type": "uint16",
+ "registerType": "holdingRegister",
+ "description": "Detected EV phases",
+ "defaultValue": 0,
+ "access": "RO"
+ }
+ ]
+ },
+ {
+ "id": "functions",
+ "readSchedule": "update",
+ "registers": [
+ {
+ "id": "solarChargingMode",
+ "address": 3331,
+ "size": 1,
+ "type": "uint16",
+ "registerType": "holdingRegister",
+ "description": "Solar charging mode (LED)",
+ "enum": "SolarChargingMode",
+ "defaultValue": "SolarChargingModeOff",
+ "access": "RW"
+ },
+ {
+ "id": "requestedPhases",
+ "address": 3332,
+ "size": 1,
+ "type": "uint16",
+ "readSchedule": "update",
+ "registerType": "holdingRegister",
+ "description": "Requested phases",
+ "enum": "PhaseMode",
+ "defaultValue": "PhaseModeAll",
+ "access": "RW"
+ },
+ {
+ "id": "chargingReleaseEnergyManager",
+ "address": 3333,
+ "size": 1,
+ "type": "uint16",
+ "readSchedule": "update",
+ "registerType": "holdingRegister",
+ "description": "Charging release energy manager",
+ "defaultValue": 0,
+ "access": "RW"
+ }
+ ]
+ }
+ ],
+ "registers": [
+ {
+ "id": "firmwareVersion",
+ "address": 1,
+ "size": 8,
+ "type": "string",
+ "readSchedule": "init",
+ "registerType": "holdingRegister",
+ "description": "Firmware version",
+ "access": "RO"
+ },
+ {
+ "id": "serial",
+ "address": 19,
+ "size": 8,
+ "type": "string",
+ "readSchedule": "init",
+ "registerType": "holdingRegister",
+ "description": "Serial number",
+ "access": "RO"
+ },
+ {
+ "id": "evseState",
+ "address": 256,
+ "size": 1,
+ "type": "uint16",
+ "readSchedule": "update",
+ "registerType": "holdingRegister",
+ "description": "EVSE state",
+ "enum": "EvseState",
+ "defaultValue": "EvseStateNotInitialized",
+ "access": "RO"
+ },
+ {
+ "id": "cpSignalState",
+ "address": 264,
+ "size": 1,
+ "type": "uint16",
+ "readSchedule": "update",
+ "registerType": "holdingRegister",
+ "description": "CP signal state",
+ "enum": "CPSignalState",
+ "defaultValue": "CPSignalStateA1",
+ "access": "RO"
+ },
+ {
+ "id": "chargingCurrentEnergyManager",
+ "address": 770,
+ "size": 2,
+ "type": "float",
+ "readSchedule": "update",
+ "registerType": "holdingRegister",
+ "description": "Charging current energy manager",
+ "defaultValue": 32,
+ "access": "RW"
+ },
+ {
+ "id": "maxCurrentEVSE",
+ "address": 774,
+ "size": 2,
+ "type": "float",
+ "readSchedule": "update",
+ "registerType": "holdingRegister",
+ "description": "Max current EVSE",
+ "defaultValue": 32,
+ "access": "R"
+ },
+ {
+ "id": "powerOverall",
+ "address": 1298,
+ "size": 2,
+ "type": "float",
+ "readSchedule": "update",
+ "registerType": "holdingRegister",
+ "description": "Overall power on all phases",
+ "defaultValue": 0,
+ "access": "RO"
+ },
+ {
+ "id": "heartbeat",
+ "address": 3328,
+ "size": 1,
+ "type": "uint16",
+ "registerType": "holdingRegister",
+ "description": "Heartbeat",
+ "access": "WO"
+ },
+ {
+ "id": "switchedPhases",
+ "address": 3586,
+ "size": 1,
+ "type": "uint16",
+ "readSchedule": "update",
+ "registerType": "holdingRegister",
+ "description": "Switched phases",
+ "enum": "PhaseMode",
+ "defaultValue": "PhaseModeAll",
+ "access": "RO"
+ },
+ {
+ "id": "chargedEnergyTotal",
+ "address": 4096,
+ "size": 2,
+ "type": "float",
+ "readSchedule": "update",
+ "registerType": "holdingRegister",
+ "description": "Charged energy total",
+ "defaultValue": 0,
+ "access": "RO"
+ }
+ ]
+}
diff --git a/mennekes/amtroncompact20discovery.cpp b/mennekes/amtroncompact20discovery.cpp
new file mode 100644
index 0000000..39672b8
--- /dev/null
+++ b/mennekes/amtroncompact20discovery.cpp
@@ -0,0 +1,100 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+*
+* 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
+*
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "amtroncompact20discovery.h"
+#include "extern-plugininfo.h"
+
+#include
+
+QList slaveIdCandidates = {50, 11, 12, 13, 14};
+
+AmtronCompact20Discovery::AmtronCompact20Discovery(ModbusRtuHardwareResource *modbusRtuResource, QObject *parent):
+ QObject{parent},
+ m_modbusRtuResource(modbusRtuResource)
+{
+
+}
+
+void AmtronCompact20Discovery::startDiscovery()
+{
+ qCInfo(dcMennekes()()) << "Discovery: Searching for Amtron Compact 2.0 wallboxes on modbus RTU...";
+
+ QList candidateMasters;
+ foreach (ModbusRtuMaster *master, m_modbusRtuResource->modbusRtuMasters()) {
+ if (master->baudrate() == 57600 && master->dataBits() == 8 && master->stopBits() == 2 && master->parity() == QSerialPort::NoParity) {
+ candidateMasters.append(master);
+ }
+ }
+
+ if (candidateMasters.isEmpty()) {
+ qCWarning(dcMennekes()) << "No usable modbus RTU master found.";
+ emit discoveryFinished(false);
+ return;
+ }
+
+ foreach (ModbusRtuMaster *master, candidateMasters) {
+ if (master->connected()) {
+ tryConnect(master, 0);
+ } else {
+ qCWarning(dcMennekes()) << "Modbus RTU master" << master->modbusUuid().toString() << "is not connected.";
+ }
+ }
+}
+
+QList AmtronCompact20Discovery::discoveryResults() const
+{
+ return m_discoveryResults;
+}
+
+void AmtronCompact20Discovery::tryConnect(ModbusRtuMaster *master, quint16 slaveIdIndex)
+{
+ quint8 slaveId = slaveIdCandidates.at(slaveIdIndex);
+ qCDebug(dcMennekes()) << "Scanning modbus RTU master" << master->modbusUuid() << "Slave ID:" << slaveId;
+
+ ModbusRtuReply *reply = master->readInputRegister(slaveId, 0x13, 8);
+ connect(reply, &ModbusRtuReply::finished, this, [=](){
+
+ if (reply->error() == ModbusRtuReply::NoError) {
+
+ QString serialNumber = ModbusDataUtils::convertToString(reply->result(), ModbusDataUtils::ByteOrderBigEndian).remove(QRegExp("^_*"));
+ qCDebug(dcMennekes()) << "Test reply finished!" << reply->error() << serialNumber;
+
+ Result result {master->modbusUuid(), serialNumber, slaveId};
+ m_discoveryResults.append(result);
+
+ }
+
+ if (slaveIdIndex < slaveIdCandidates.count() - 1) {
+ tryConnect(master, slaveIdIndex+1);
+ } else {
+ emit discoveryFinished(true);
+ }
+ });
+}
diff --git a/mennekes/amtroncompact20discovery.h b/mennekes/amtroncompact20discovery.h
new file mode 100644
index 0000000..e8f50e2
--- /dev/null
+++ b/mennekes/amtroncompact20discovery.h
@@ -0,0 +1,65 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+*
+* 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 AMTRONCOMPACT20DISCOVERY_H
+#define AMTRONCOMPACT20DISCOVERY_H
+
+#include
+#include
+
+class AmtronCompact20Discovery : public QObject
+{
+ Q_OBJECT
+public:
+ explicit AmtronCompact20Discovery(ModbusRtuHardwareResource *modbusRtuResource, QObject *parent = nullptr);
+
+ struct Result {
+ QUuid modbusRtuMasterId;
+ QString serialNumber;
+ quint16 slaveId;
+ };
+
+ void startDiscovery();
+
+ QList discoveryResults() const;
+
+signals:
+ void discoveryFinished(bool modbusRtuMasterAvailable);
+
+private slots:
+ void tryConnect(ModbusRtuMaster *master, quint16 slaveIdIndex);
+
+private:
+ ModbusRtuHardwareResource *m_modbusRtuResource = nullptr;
+
+ QList m_discoveryResults;
+};
+
+#endif // AMTRONCOMPACT20DISCOVERY_H
diff --git a/mennekes/integrationpluginmennekes.cpp b/mennekes/integrationpluginmennekes.cpp
index 20b871a..2a136a0 100644
--- a/mennekes/integrationpluginmennekes.cpp
+++ b/mennekes/integrationpluginmennekes.cpp
@@ -32,6 +32,7 @@
#include "plugininfo.h"
#include "amtronecudiscovery.h"
#include "amtronhcc3discovery.h"
+#include "amtroncompact20discovery.h"
#include
#include
@@ -43,13 +44,14 @@ IntegrationPluginMennekes::IntegrationPluginMennekes()
void IntegrationPluginMennekes::discoverThings(ThingDiscoveryInfo *info)
{
- if (!hardwareManager()->networkDeviceDiscovery()->available()) {
- qCWarning(dcMennekes()) << "The network discovery is not available on this platform.";
- info->finish(Thing::ThingErrorUnsupportedFeature, QT_TR_NOOP("The network device discovery is not available."));
- return;
- }
if (info->thingClassId() == amtronECUThingClassId) {
+ if (!hardwareManager()->networkDeviceDiscovery()->available()) {
+ qCWarning(dcMennekes()) << "The network discovery is not available on this platform.";
+ info->finish(Thing::ThingErrorUnsupportedFeature, QT_TR_NOOP("The network device discovery is not available."));
+ return;
+ }
+
AmtronECUDiscovery *discovery = new AmtronECUDiscovery(hardwareManager()->networkDeviceDiscovery(), info);
connect(discovery, &AmtronECUDiscovery::discoveryFinished, info, [=](){
foreach (const AmtronECUDiscovery::Result &result, discovery->discoveryResults()) {
@@ -87,6 +89,12 @@ void IntegrationPluginMennekes::discoverThings(ThingDiscoveryInfo *info)
discovery->startDiscovery();
} else if (info->thingClassId() == amtronHCC3ThingClassId) {
+ if (!hardwareManager()->networkDeviceDiscovery()->available()) {
+ qCWarning(dcMennekes()) << "The network discovery is not available on this platform.";
+ info->finish(Thing::ThingErrorUnsupportedFeature, QT_TR_NOOP("The network device discovery is not available."));
+ return;
+ }
+
AmtronHCC3Discovery *discovery = new AmtronHCC3Discovery(hardwareManager()->networkDeviceDiscovery(), info);
connect(discovery, &AmtronHCC3Discovery::discoveryFinished, info, [=](){
foreach (const AmtronHCC3Discovery::AmtronDiscoveryResult &result, discovery->discoveryResults()) {
@@ -116,6 +124,36 @@ void IntegrationPluginMennekes::discoverThings(ThingDiscoveryInfo *info)
info->finish(Thing::ThingErrorNoError);
});
+ discovery->startDiscovery();
+ } else if (info->thingClassId() == amtronCompact20ThingClassId) {
+ AmtronCompact20Discovery *discovery = new AmtronCompact20Discovery(hardwareManager()->modbusRtuResource(), info);
+ connect(discovery, &AmtronCompact20Discovery::discoveryFinished, info, [this, info, discovery](bool modbusMasterAvailable){
+ if (!modbusMasterAvailable) {
+ 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, 2 stop bits and no parity first."));
+ return;
+ }
+
+ qCInfo(dcMennekes()) << "Discovery results:" << discovery->discoveryResults().count();
+
+ foreach (const AmtronCompact20Discovery::Result &result, discovery->discoveryResults()) {
+ ThingDescriptor descriptor(amtronCompact20ThingClassId, "AMTRON Compact 2.0s", QString("Slave ID: %1, Serial: %2").arg(result.slaveId).arg(result.serialNumber));
+
+ ParamList params{
+ {amtronCompact20ThingModbusMasterUuidParamTypeId, result.modbusRtuMasterId},
+ {amtronCompact20ThingSlaveAddressParamTypeId, 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();
}
}
@@ -222,9 +260,17 @@ void IntegrationPluginMennekes::setupThing(ThingSetupInfo *info)
}
});
}
-
return;
+ }
+ if (info->thing()->thingClassId() == amtronCompact20ThingClassId) {
+ if (m_amtronCompact20Connections.contains(thing)) {
+ qCDebug(dcMennekes()) << "Reconfiguring existing thing" << thing->name();
+ m_amtronCompact20Connections.take(thing)->deleteLater();
+ }
+
+ setupAmtronCompact20Connection(info);
+ return;
}
}
@@ -243,6 +289,11 @@ void IntegrationPluginMennekes::postSetupThing(Thing *thing)
qCDebug(dcMennekes()) << "Updating connection" << connection->hostAddress().toString();
connection->update();
}
+ foreach(AmtronCompact20ModbusRtuConnection *connection, m_amtronCompact20Connections) {
+ qCDebug(dcMennekes()) << "Updating connection" << connection->modbusRtuMaster()->serialPort() << connection->slaveId();
+ connection->update();
+ connection->setHeartbeat(0x55AA);
+ }
});
m_pluginTimer->start();
@@ -324,6 +375,57 @@ void IntegrationPluginMennekes::executeAction(ThingActionInfo *info)
});
}
}
+
+ if (info->thing()->thingClassId() == amtronCompact20ThingClassId) {
+ AmtronCompact20ModbusRtuConnection *amtronCompact20Connection = m_amtronCompact20Connections.value(info->thing());
+
+ if (info->action().actionTypeId() == amtronCompact20PowerActionTypeId) {
+ bool power = info->action().paramValue(amtronCompact20PowerActionPowerParamTypeId).toBool();
+
+ ModbusRtuReply *reply = amtronCompact20Connection->setChargingReleaseEnergyManager(power ? 1 : 0);
+ connect(reply, &ModbusRtuReply::finished, info, [info, reply, power](){
+ if (reply->error() == ModbusRtuReply::NoError) {
+ info->thing()->setStateValue(amtronCompact20PowerStateTypeId, power);
+ info->finish(Thing::ThingErrorNoError);
+ } else {
+ qCWarning(dcMennekes()) << "Error setting charge state:" << reply->error() << reply->errorString();
+ info->finish(Thing::ThingErrorHardwareFailure);
+ }
+ });
+ }
+ if (info->action().actionTypeId() == amtronCompact20MaxChargingCurrentActionTypeId) {
+ int maxChargingCurrent = info->action().paramValue(amtronCompact20MaxChargingCurrentActionMaxChargingCurrentParamTypeId).toInt();
+ float value = maxChargingCurrent;
+
+ // Note: in firmwares up to 1.0.2 there's an issue that it cannot be exactly 6A, must be 6.01 or so
+ if (maxChargingCurrent == 6) {
+ value = 6.01;
+ }
+
+ ModbusRtuReply *reply = amtronCompact20Connection->setChargingCurrentEnergyManager(value);
+ connect(reply, &ModbusRtuReply::finished, info, [info, reply, maxChargingCurrent](){
+ if (reply->error() == ModbusRtuReply::NoError) {
+ info->thing()->setStateValue(amtronCompact20MaxChargingCurrentStateTypeId, maxChargingCurrent);
+ info->finish(Thing::ThingErrorNoError);
+ } else {
+ info->finish(Thing::ThingErrorHardwareFailure);
+ }
+ });
+ }
+ if (info->action().actionTypeId() == amtronCompact20DesiredPhaseCountActionTypeId) {
+ int desiredPhaseCount = info->action().paramValue(amtronCompact20DesiredPhaseCountActionDesiredPhaseCountParamTypeId).toInt();
+
+ ModbusRtuReply *reply = amtronCompact20Connection->setRequestedPhases(desiredPhaseCount == 1 ? AmtronCompact20ModbusRtuConnection::PhaseModeSingle : AmtronCompact20ModbusRtuConnection::PhaseModeAll);
+ connect(reply, &ModbusRtuReply::finished, info, [info, reply, desiredPhaseCount](){
+ if (reply->error() == ModbusRtuReply::NoError) {
+ info->thing()->setStateValue(amtronCompact20DesiredPhaseCountStateTypeId, desiredPhaseCount);
+ info->finish(Thing::ThingErrorNoError);
+ } else {
+ info->finish(Thing::ThingErrorHardwareFailure);
+ }
+ });
+ }
+ }
}
void IntegrationPluginMennekes::thingRemoved(Thing *thing)
@@ -338,6 +440,11 @@ void IntegrationPluginMennekes::thingRemoved(Thing *thing)
delete connection;
}
+ if (thing->thingClassId() == amtronCompact20ThingClassId && m_amtronCompact20Connections.contains(thing)) {
+ AmtronCompact20ModbusRtuConnection *connection = m_amtronCompact20Connections.take(thing);
+ delete connection;
+ }
+
// Unregister related hardware resources
if (m_monitors.contains(thing))
hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing));
@@ -383,6 +490,18 @@ void IntegrationPluginMennekes::updateECUPhaseCount(Thing *thing)
thing->setStateValue(amtronECUPhaseCountStateTypeId, phaseCount);
}
+void IntegrationPluginMennekes::updateCompact20PhaseCount(Thing *thing)
+{
+ AmtronCompact20ModbusRtuConnection *connection = m_amtronCompact20Connections.value(thing);
+
+ // Using detected phases if detection completed (0 = undetected). Could be 1, 2 or 3
+ if (connection->detectedEVPhases() > 0) {
+ thing->setStateValue(amtronCompact20PhaseCountStateTypeId, connection->detectedEVPhases());
+ } else {
+ thing->setStateValue(amtronCompact20PhaseCountStateTypeId, connection->switchedPhases() == AmtronCompact20ModbusRtuConnection::PhaseModeAll ? 3 : 1);
+ }
+}
+
void IntegrationPluginMennekes::setupAmtronECUConnection(ThingSetupInfo *info)
{
Thing *thing = info->thing();
@@ -634,6 +753,173 @@ void IntegrationPluginMennekes::setupAmtronHCC3Connection(ThingSetupInfo *info)
amtronHCC3Connection->connectDevice();
}
+void IntegrationPluginMennekes::setupAmtronCompact20Connection(ThingSetupInfo *info)
+{
+ Thing *thing = info->thing();
+
+ uint slaveId = thing->paramValue(amtronCompact20ThingSlaveAddressParamTypeId).toUInt();
+ if (slaveId > 254 || slaveId == 0) {
+ qCWarning(dcMennekes()) << "Setup failed, slave ID is not valid" << slaveId;
+ info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("The Modbus address not valid. It must be a value between 1 and 254."));
+ return;
+ }
+
+ QUuid uuid = thing->paramValue(amtronCompact20ThingModbusMasterUuidParamTypeId).toUuid();
+ if (!hardwareManager()->modbusRtuResource()->hasModbusRtuMaster(uuid)) {
+ qCWarning(dcMennekes()) << "Setup failed, hardware manager not available";
+ info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("The Modbus RTU resource is not available."));
+ return;
+ }
+
+ AmtronCompact20ModbusRtuConnection *compact20Connection = new AmtronCompact20ModbusRtuConnection(hardwareManager()->modbusRtuResource()->getModbusRtuMaster(uuid), slaveId, this);
+ connect(info, &ThingSetupInfo::aborted, compact20Connection, &ModbusRtuMaster::deleteLater);
+ m_amtronCompact20Connections.insert(thing, compact20Connection);
+
+ connect(info, &ThingSetupInfo::aborted, this, [=](){
+ m_amtronCompact20Connections.take(info->thing())->deleteLater();
+ });
+
+ connect(compact20Connection, &AmtronCompact20ModbusRtuConnection::reachableChanged, thing, [compact20Connection, thing](bool reachable){
+ qCDebug(dcMennekes()) << "Reachable state changed" << reachable;
+ if (reachable) {
+ compact20Connection->initialize();
+ } else {
+ thing->setStateValue("connected", false);
+ }
+ });
+
+ connect(compact20Connection, &AmtronCompact20ModbusRtuConnection::initializationFinished, info, [=](bool success){
+ qCDebug(dcMennekes()) << "Initialisation finished" << success;
+ if (info->isInitialSetup() && !success) {
+ m_amtronCompact20Connections.take(info->thing())->deleteLater();
+ info->finish(Thing::ThingErrorHardwareNotAvailable);
+ return;
+ }
+
+ info->finish(Thing::ThingErrorNoError);
+
+ if (success) {
+ qCDebug(dcMennekes) << "Firmware version:" << compact20Connection->firmwareVersion();
+ info->thing()->setStateValue(amtronCompact20CurrentVersionStateTypeId, compact20Connection->firmwareVersion());
+ info->thing()->setStateValue(amtronCompact20PowerStateTypeId, compact20Connection->chargingReleaseEnergyManager() == 1);
+ info->thing()->setStateValue(amtronCompact20MaxChargingCurrentStateTypeId, qRound(compact20Connection->chargingCurrentEnergyManager()));
+ }
+ });
+
+ connect(compact20Connection, &AmtronCompact20ModbusRtuConnection::reachableChanged, thing, [=](bool reachable){
+ thing->setStateValue(amtronCompact20ConnectedStateTypeId, reachable);
+ });
+
+
+ connect(compact20Connection, &AmtronCompact20ModbusRtuConnection::updateFinished, thing, [this, compact20Connection, thing](){
+ qCDebug(dcMennekes()) << "Update finished:" << thing->name() << compact20Connection;
+ updateCompact20PhaseCount(thing);
+
+ quint16 maxCurrentEVSE = compact20Connection->maxCurrentEVSE();
+ quint16 maxCurrentSession = compact20Connection->maxCurrentSession();
+ if (maxCurrentSession > 0 && maxCurrentEVSE > 0) {
+ thing->setStateMaxValue(amtronCompact20MaxChargingCurrentStateTypeId, qMin(maxCurrentEVSE, maxCurrentSession));
+ } else if (maxCurrentSession > 0){
+ thing->setStateMaxValue(amtronCompact20MaxChargingCurrentStateTypeId, maxCurrentSession);
+ } else if (maxCurrentEVSE) {
+ thing->setStateMaxValue(amtronCompact20MaxChargingCurrentStateTypeId, maxCurrentEVSE);
+ }
+ });
+
+ connect(compact20Connection, &AmtronCompact20ModbusRtuConnection::cpSignalStateChanged, thing, [thing](AmtronCompact20ModbusRtuConnection::CPSignalState cpSignalState){
+ qCDebug(dcMennekes()) << "CP signal state changed:" << thing->name() << cpSignalState;
+ // Note: using EVSE state register instead
+// switch (cpSignalState) {
+// case AmtronCompact20ModbusRtuConnection::CPSignalStateA1:
+// case AmtronCompact20ModbusRtuConnection::CPSignalStateA2:
+// thing->setStateValue(amtronCompact20PluggedInStateTypeId, false);
+// thing->setStateValue(amtronCompact20ChargingStateTypeId, false);
+// break;
+// case AmtronCompact20ModbusRtuConnection::CPSignalStateB1:
+// case AmtronCompact20ModbusRtuConnection::CPSignalStateB2:
+// thing->setStateValue(amtronCompact20PluggedInStateTypeId, true);
+// thing->setStateValue(amtronCompact20ChargingStateTypeId, false);
+// break;
+// case AmtronCompact20ModbusRtuConnection::CPSignalStateC1:
+// case AmtronCompact20ModbusRtuConnection::CPSignalStateC2:
+// case AmtronCompact20ModbusRtuConnection::CPSignalStateD1:
+// case AmtronCompact20ModbusRtuConnection::CPSignalStateD2:
+// thing->setStateValue(amtronCompact20PluggedInStateTypeId, true);
+// thing->setStateValue(amtronCompact20ChargingStateTypeId, true);
+// break;
+// case AmtronCompact20ModbusRtuConnection::CPSignalStateE:
+// case AmtronCompact20ModbusRtuConnection::CPSignalStateF:
+// qCWarning(dcMennekes()) << "Wallbox in Error state!";
+// thing->setStateValue(amtronCompact20PluggedInStateTypeId, false);
+// thing->setStateValue(amtronCompact20ChargingStateTypeId, false);
+// break;
+// }
+ });
+
+ connect(compact20Connection, &AmtronCompact20ModbusRtuConnection::evseStateChanged, thing, [thing](AmtronCompact20ModbusRtuConnection::EvseState evseState){
+ qCDebug(dcMennekes()) << "EVSE state changed:" << thing->name() << evseState;
+ switch (evseState) {
+ case AmtronCompact20ModbusRtuConnection::EvseStateNotInitialized:
+ case AmtronCompact20ModbusRtuConnection::EvseStateIdle:
+ thing->setStateValue(amtronCompact20PluggedInStateTypeId, false);
+ thing->setStateValue(amtronCompact20ChargingStateTypeId, false);
+ break;
+ case AmtronCompact20ModbusRtuConnection::EvseStateEvConnected:
+ case AmtronCompact20ModbusRtuConnection::EvseStatePreconditionsValidButNotCharging:
+ case AmtronCompact20ModbusRtuConnection::EvseStateReadyToCharge:
+ thing->setStateValue(amtronCompact20PluggedInStateTypeId, true);
+ thing->setStateValue(amtronCompact20ChargingStateTypeId, false);
+ break;
+ case AmtronCompact20ModbusRtuConnection::EvseStateCharging:
+ thing->setStateValue(amtronCompact20PluggedInStateTypeId, true);
+ thing->setStateValue(amtronCompact20ChargingStateTypeId, true);
+ break;
+ case AmtronCompact20ModbusRtuConnection::EvseStateError:
+ case AmtronCompact20ModbusRtuConnection::EvseStateServiceMode:
+ thing->setStateValue(amtronCompact20PluggedInStateTypeId, false);
+ thing->setStateValue(amtronCompact20ChargingStateTypeId, false);
+ break;
+ }
+ });
+
+ connect(compact20Connection, &AmtronCompact20ModbusRtuConnection::chargingCurrentEnergyManagerChanged, thing, [thing](float chargingCurrent){
+ qCInfo(dcMennekes()) << thing->name() << "charging current energy manager changed:" << chargingCurrent;
+ if (chargingCurrent >= 6) {
+ thing->setStateValue(amtronCompact20MaxChargingCurrentStateTypeId, qRound(chargingCurrent));
+ }
+ });
+
+ connect(compact20Connection, &AmtronCompact20ModbusRtuConnection::switchedPhasesChanged, thing, [thing](AmtronCompact20ModbusRtuConnection::PhaseMode phaseMode){
+ qCInfo(dcMennekes()) << thing->name() << "switched EV phases changed:" << phaseMode;
+ });
+ connect(compact20Connection, &AmtronCompact20ModbusRtuConnection::detectedEVPhasesChanged, thing, [thing](quint16 detectedEvPhases){
+ qCInfo(dcMennekes()) << thing->name() << "detected EV phases changed:" << detectedEvPhases;
+ });
+
+ connect(compact20Connection, &AmtronCompact20ModbusRtuConnection::requestedPhasesChanged, thing, [thing](AmtronCompact20ModbusRtuConnection::PhaseMode phaseMode){
+ thing->setStateValue(amtronCompact20DesiredPhaseCountStateTypeId, phaseMode == AmtronCompact20ModbusRtuConnection::PhaseModeAll ? 3 : 1);
+ });
+
+ connect(compact20Connection, &AmtronCompact20ModbusRtuConnection::powerOverallChanged, thing, [thing](double powerOverall){
+ // The wallbox may measure non
+ if (powerOverall < 20) {
+ powerOverall = 0;
+ }
+ thing->setStateValue(amtronCompact20CurrentPowerStateTypeId, powerOverall);
+ });
+ connect(compact20Connection, &AmtronCompact20ModbusRtuConnection::chargedEnergyTotalChanged, thing, [thing](double chargedEnergyTotal){
+ thing->setStateValue(amtronCompact20TotalEnergyConsumedStateTypeId, chargedEnergyTotal);
+ });
+ connect(compact20Connection, &AmtronCompact20ModbusRtuConnection::chargedEnergySessionChanged, thing, [thing](double chargedEnergySession){
+ thing->setStateValue(amtronCompact20SessionEnergyStateTypeId, chargedEnergySession);
+ });
+
+ connect(compact20Connection, &AmtronCompact20ModbusRtuConnection::chargingReleaseEnergyManagerChanged, this, [thing](quint16 chargingReleaseEnergyManager){
+ thing->setStateValue(amtronCompact20PowerStateTypeId, chargingReleaseEnergyManager == 1);
+ });
+
+}
+
bool IntegrationPluginMennekes::ensureAmtronECUVersion(AmtronECUModbusTcpConnection *connection, const QString &version)
{
QByteArray deviceVersion = QByteArray::fromHex(QByteArray::number(connection->firmwareVersion(), 16));
diff --git a/mennekes/integrationpluginmennekes.h b/mennekes/integrationpluginmennekes.h
index caaa1b3..85c9a13 100644
--- a/mennekes/integrationpluginmennekes.h
+++ b/mennekes/integrationpluginmennekes.h
@@ -39,6 +39,7 @@
#include "amtronecumodbustcpconnection.h"
#include "amtronhcc3modbustcpconnection.h"
+#include "amtroncompact20modbusrtuconnection.h"
class IntegrationPluginMennekes: public IntegrationPlugin
{
@@ -58,16 +59,19 @@ public:
private slots:
void updateECUPhaseCount(Thing *thing);
+ void updateCompact20PhaseCount(Thing *thing);
private:
void setupAmtronECUConnection(ThingSetupInfo *info);
void setupAmtronHCC3Connection(ThingSetupInfo *info);
+ void setupAmtronCompact20Connection(ThingSetupInfo *info);
bool ensureAmtronECUVersion(AmtronECUModbusTcpConnection *connection, const QString &version);
PluginTimer *m_pluginTimer = nullptr;
QHash m_amtronECUConnections;
QHash m_amtronHCC3Connections;
+ QHash m_amtronCompact20Connections;
QHash m_monitors;
};
diff --git a/mennekes/integrationpluginmennekes.json b/mennekes/integrationpluginmennekes.json
index dc3be8a..8d164f2 100644
--- a/mennekes/integrationpluginmennekes.json
+++ b/mennekes/integrationpluginmennekes.json
@@ -210,6 +210,130 @@
"writable": true
}
]
+ },
+ {
+ "name": "amtronCompact20",
+ "displayName": "AMTRON Compact 2.0s",
+ "id": "5c9c3b51-26e0-4f92-b6cf-d77bcae3d47c",
+ "createMethods": ["discovery", "user"],
+ "interfaces": ["evcharger", "smartmeterconsumer", "connectable"],
+ "paramTypes": [
+ {
+ "id": "f98609c4-c7e7-49df-aebf-34122974c019",
+ "name": "slaveAddress",
+ "displayName": "Modbus slave address",
+ "type": "uint",
+ "defaultValue": 1
+ },
+ {
+ "id": "b73ce51f-792a-4875-a169-76ab16597081",
+ "name": "modbusMasterUuid",
+ "displayName": "Modbus RTU master",
+ "type": "QUuid",
+ "defaultValue": ""
+ }
+ ],
+ "stateTypes": [
+ {
+ "id": "8ad20255-7407-4e89-9eb8-62a7c32036b7",
+ "name": "connected",
+ "displayName": "Connected",
+ "type": "bool",
+ "defaultValue": false,
+ "cached": false
+ },
+ {
+ "id": "25717de6-dd6c-4f06-a0fc-ca11bbef1598",
+ "name": "currentVersion",
+ "displayName": "Firmware version",
+ "type": "QString",
+ "defaultValue": ""
+ },
+ {
+ "id": "1ad8712a-bca1-44db-9134-47fcac88e400",
+ "name": "pluggedIn",
+ "displayName": "Plugged in",
+ "type": "bool",
+ "defaultValue": false,
+ "cached": false
+ },
+ {
+ "id": "fc8f3b5f-f122-430c-855e-eaf5cff4d2ca",
+ "name": "charging",
+ "displayName": "Charging",
+ "type": "bool",
+ "defaultValue": false,
+ "cached": false
+ },
+ {
+ "id": "b415c330-9295-41f2-b117-14b9fc0b2ed9",
+ "name": "phaseCount",
+ "displayName": "Charging phases",
+ "type": "uint",
+ "minValue": 1,
+ "maxValue": 3,
+ "defaultValue": 1
+ },
+ {
+ "id": "64b64747-7a67-419c-88d1-c63872ef83b7",
+ "name": "desiredPhaseCount",
+ "displayName": "Desired phase count",
+ "displayNameAction": "Set desired phase count",
+ "type": "uint",
+ "possibleValues": [1, 3],
+ "minValue": 1,
+ "maxValue": 3,
+ "defaultValue": 3,
+ "writable": true
+ },
+ {
+ "id": "5a8d2ec1-a044-4d67-b3f2-38a26916e747",
+ "name": "currentPower",
+ "displayName": "Active power",
+ "type": "double",
+ "unit": "Watt",
+ "defaultValue": 0,
+ "cached": false
+ },
+ {
+ "id": "89f26bbd-32d8-4b46-bbb0-f01ba713c5d5",
+ "name": "totalEnergyConsumed",
+ "displayName": "Total consumed energy",
+ "type": "double",
+ "unit": "KiloWattHour",
+ "defaultValue": 0.0,
+ "cached": true
+ },
+ {
+ "id": "9eee7ef4-3e35-4ca8-b6a4-cbb6cf7f901d",
+ "name": "power",
+ "displayName": "Charging enabled",
+ "displayNameAction": "Set charging enabled",
+ "type": "bool",
+ "defaultValue": false,
+ "writable": true
+ },
+ {
+ "id": "ff9b92ca-1e95-4588-ad94-70883062f3f1",
+ "name": "maxChargingCurrent",
+ "displayName": "Maximum charging current",
+ "displayNameAction": "Set maximum charging current",
+ "type": "uint",
+ "unit": "Ampere",
+ "minValue": 6,
+ "maxValue": 32,
+ "defaultValue": 6,
+ "writable": true
+ },
+ {
+ "id": "359336ee-8777-4dd3-9d7a-eb15b0cc6ebc",
+ "name": "sessionEnergy",
+ "displayName": "Session energy",
+ "type": "double",
+ "unit": "KiloWattHour",
+ "defaultValue": 0
+ }
+ ]
}
]
}
diff --git a/mennekes/mennekes.pro b/mennekes/mennekes.pro
index 6f0dc22..7bb3c77 100644
--- a/mennekes/mennekes.pro
+++ b/mennekes/mennekes.pro
@@ -2,16 +2,20 @@ include(../plugins.pri)
# Generate modbus connection
MODBUS_CONNECTIONS += amtron-ecu-registers.json \
- amtron-hcc3-registers.json
+ amtron-hcc3-registers.json \
+ amtron-compact20-registers.json
+
#MODBUS_TOOLS_CONFIG += VERBOSE
include(../modbus.pri)
HEADERS += \
+ amtroncompact20discovery.h \
amtronecudiscovery.h \
amtronhcc3discovery.h \
integrationpluginmennekes.h
SOURCES += \
+ amtroncompact20discovery.cpp \
amtronecudiscovery.cpp \
amtronhcc3discovery.cpp \
integrationpluginmennekes.cpp
diff --git a/mennekes/translations/c7c3c65c-a0cc-4ab1-90d8-4ad05bfcdc38-en_US.ts b/mennekes/translations/c7c3c65c-a0cc-4ab1-90d8-4ad05bfcdc38-en_US.ts
index 3179782..ff0994f 100644
--- a/mennekes/translations/c7c3c65c-a0cc-4ab1-90d8-4ad05bfcdc38-en_US.ts
+++ b/mennekes/translations/c7c3c65c-a0cc-4ab1-90d8-4ad05bfcdc38-en_US.ts
@@ -4,70 +4,107 @@
IntegrationPluginMennekes
-
+
+
The network device discovery is not available.
-
-
+
+ No modbus RTU master with appropriate settings found. Please set up a modbus RTU master with a baudrate of 57600, 8 data bis, 2 stop bits and no parity first.
+
+
+
+
+
The MAC address is not known. Please reconfigure the thing.
-
-
+
+
The host address is not known yet. Trying later again.
-
-
+
+
Error communicating with the wallbox.
-
+
The firmware version of this wallbox is too old. Please upgrade the firmware to at least version 5.22.
+
+
+ The Modbus address not valid. It must be a value between 1 and 254.
+
+
+
+
+ The Modbus RTU resource is not available.
+
+
Mennekes
-
+
AMTRON Charge Control/Professional
The name of the ThingClass ({fb48e067-2237-4eaf-8d2c-681d406395fc})
-
+
+ AMTRON Compact 2.0
+ The name of the ThingClass ({5c9c3b51-26e0-4f92-b6cf-d77bcae3d47c})
+
+
+
+
AMTRON XTRA/Premium
The name of the ThingClass ({01995c4f-a7b5-4bdd-9333-486390ff75fd})
-
-
+
+
+
Active power
- The name of the StateType ({96b9c121-3caf-44fe-8380-483b9b40dbd9}) of ThingClass amtronHCC3
+ The name of the StateType ({5a8d2ec1-a044-4d67-b3f2-38a26916e747}) of ThingClass amtronCompact20
+----------
+The name of the StateType ({96b9c121-3caf-44fe-8380-483b9b40dbd9}) of ThingClass amtronHCC3
----------
The name of the StateType ({8b2eb039-b4e3-49ae-94fc-a8b825fd8d9b}) of ThingClass amtronECU
-
+
+
+
Charging
- The name of the StateType ({c8c812c6-dd56-425c-8dd1-8dd621bd3a11}) of ThingClass amtronECU
+ The name of the StateType ({fc8f3b5f-f122-430c-855e-eaf5cff4d2ca}) of ThingClass amtronCompact20
+----------
+The name of the StateType ({982af18d-dbfb-4dd8-b5b3-4d22c64642a6}) of ThingClass amtronHCC3
+----------
+The name of the StateType ({c8c812c6-dd56-425c-8dd1-8dd621bd3a11}) of ThingClass amtronECU
-
-
-
-
+
+
+
+
+
+
Charging enabled
- The name of the ParamType (ThingClass: amtronHCC3, ActionType: power, ID: {130585ca-14e9-45b7-87d7-c0d935228104})
+ The name of the ParamType (ThingClass: amtronCompact20, ActionType: power, ID: {9eee7ef4-3e35-4ca8-b6a4-cbb6cf7f901d})
+----------
+The name of the StateType ({9eee7ef4-3e35-4ca8-b6a4-cbb6cf7f901d}) of ThingClass amtronCompact20
+----------
+The name of the ParamType (ThingClass: amtronHCC3, ActionType: power, ID: {130585ca-14e9-45b7-87d7-c0d935228104})
----------
The name of the StateType ({130585ca-14e9-45b7-87d7-c0d935228104}) of ThingClass amtronHCC3
----------
@@ -77,23 +114,50 @@ The name of the StateType ({53dc845a-a397-4c90-890b-fd50512666f4}) of ThingClass
-
-
+
+ Charging phases
+ The name of the StateType ({b415c330-9295-41f2-b117-14b9fc0b2ed9}) of ThingClass amtronCompact20
+
+
+
+
+
+
Connected
- The name of the StateType ({899e270f-7666-44b3-8509-0dad43ac9c4c}) of ThingClass amtronHCC3
+ The name of the StateType ({8ad20255-7407-4e89-9eb8-62a7c32036b7}) of ThingClass amtronCompact20
+----------
+The name of the StateType ({899e270f-7666-44b3-8509-0dad43ac9c4c}) of ThingClass amtronHCC3
----------
The name of the StateType ({352be84a-f5c6-434d-8a92-a4065a24ff0a}) of ThingClass amtronECU
-
+
+
Connected phases
- The name of the StateType ({a51d0beb-f4fd-4279-85b5-b436b283a86e}) of ThingClass amtronECU
+ The name of the StateType ({05c095b6-2395-4bbf-8d14-a77576ce7717}) of ThingClass amtronHCC3
+----------
+The name of the StateType ({a51d0beb-f4fd-4279-85b5-b436b283a86e}) of ThingClass amtronECU
-
-
+
+
+ Desired phase count
+ The name of the ParamType (ThingClass: amtronCompact20, ActionType: desiredPhaseCount, ID: {64b64747-7a67-419c-88d1-c63872ef83b7})
+----------
+The name of the StateType ({64b64747-7a67-419c-88d1-c63872ef83b7}) of ThingClass amtronCompact20
+
+
+
+
+ Firmware version
+ The name of the StateType ({25717de6-dd6c-4f06-a0fc-ca11bbef1598}) of ThingClass amtronCompact20
+
+
+
+
+
MAC address
The name of the ParamType (ThingClass: amtronHCC3, Type: thing, ID: {6112045e-e472-4475-bc11-f373e9c39cdd})
----------
@@ -101,18 +165,24 @@ The name of the ParamType (ThingClass: amtronECU, Type: thing, ID: {0b9c1466-5eb
-
+
MENNEKES
The name of the vendor ({7c585571-e3a3-458c-a598-e11f510cbc10})
-
-
-
-
+
+
+
+
+
+
Maximum charging current
- The name of the ParamType (ThingClass: amtronHCC3, ActionType: maxChargingCurrent, ID: {87b4e9cb-e57b-461a-90f9-207bb5dab44c})
+ The name of the ParamType (ThingClass: amtronCompact20, ActionType: maxChargingCurrent, ID: {ff9b92ca-1e95-4588-ad94-70883062f3f1})
+----------
+The name of the StateType ({ff9b92ca-1e95-4588-ad94-70883062f3f1}) of ThingClass amtronCompact20
+----------
+The name of the ParamType (ThingClass: amtronHCC3, ActionType: maxChargingCurrent, ID: {87b4e9cb-e57b-461a-90f9-207bb5dab44c})
----------
The name of the StateType ({87b4e9cb-e57b-461a-90f9-207bb5dab44c}) of ThingClass amtronHCC3
----------
@@ -122,46 +192,85 @@ The name of the StateType ({fb12ff61-f88a-4bfc-930f-a4a55b342d1b}) of ThingClass
-
+
Mennekes
The name of the plugin Mennekes ({c7c3c65c-a0cc-4ab1-90d8-4ad05bfcdc38})
-
+
+ Modbus RTU master
+ The name of the ParamType (ThingClass: amtronCompact20, Type: thing, ID: {b73ce51f-792a-4875-a169-76ab16597081})
+
+
+
+
+ Modbus slave address
+ The name of the ParamType (ThingClass: amtronCompact20, Type: thing, ID: {f98609c4-c7e7-49df-aebf-34122974c019})
+
+
+
+
+
+
Plugged in
- The name of the StateType ({c93d7377-8a4a-4c35-9876-1032d8b309e3}) of ThingClass amtronECU
+ The name of the StateType ({1ad8712a-bca1-44db-9134-47fcac88e400}) of ThingClass amtronCompact20
+----------
+The name of the StateType ({fed5a1ba-48f5-41ef-98f7-9356bcae7612}) of ThingClass amtronHCC3
+----------
+The name of the StateType ({c93d7377-8a4a-4c35-9876-1032d8b309e3}) of ThingClass amtronECU
-
+
+
+
Session energy
- The name of the StateType ({2ce6b363-5b8d-4703-8376-611a0e573f71}) of ThingClass amtronECU
+ The name of the StateType ({359336ee-8777-4dd3-9d7a-eb15b0cc6ebc}) of ThingClass amtronCompact20
+----------
+The name of the StateType ({c5882da3-963b-4cb3-ba1a-44d16d219e7e}) of ThingClass amtronHCC3
+----------
+The name of the StateType ({2ce6b363-5b8d-4703-8376-611a0e573f71}) of ThingClass amtronECU
-
-
+
+
+
Set charging enabled
- The name of the ActionType ({130585ca-14e9-45b7-87d7-c0d935228104}) of ThingClass amtronHCC3
+ The name of the ActionType ({9eee7ef4-3e35-4ca8-b6a4-cbb6cf7f901d}) of ThingClass amtronCompact20
+----------
+The name of the ActionType ({130585ca-14e9-45b7-87d7-c0d935228104}) of ThingClass amtronHCC3
----------
The name of the ActionType ({53dc845a-a397-4c90-890b-fd50512666f4}) of ThingClass amtronECU
-
-
+
+ Set desired phase count
+ The name of the ActionType ({64b64747-7a67-419c-88d1-c63872ef83b7}) of ThingClass amtronCompact20
+
+
+
+
+
+
Set maximum charging current
- The name of the ActionType ({87b4e9cb-e57b-461a-90f9-207bb5dab44c}) of ThingClass amtronHCC3
+ The name of the ActionType ({ff9b92ca-1e95-4588-ad94-70883062f3f1}) of ThingClass amtronCompact20
+----------
+The name of the ActionType ({87b4e9cb-e57b-461a-90f9-207bb5dab44c}) of ThingClass amtronHCC3
----------
The name of the ActionType ({fb12ff61-f88a-4bfc-930f-a4a55b342d1b}) of ThingClass amtronECU
-
-
+
+
+
Total consumed energy
- The name of the StateType ({3d1384fc-8b46-42b0-b043-23279d8c7665}) of ThingClass amtronHCC3
+ The name of the StateType ({89f26bbd-32d8-4b46-bbb0-f01ba713c5d5}) of ThingClass amtronCompact20
+----------
+The name of the StateType ({3d1384fc-8b46-42b0-b043-23279d8c7665}) of ThingClass amtronHCC3
----------
The name of the StateType ({5b8bfdf0-eaa6-41d0-8f2f-119b06aed181}) of ThingClass amtronECU
diff --git a/schrack/ciondiscovery.cpp b/schrack/ciondiscovery.cpp
index 63e1619..5924e59 100644
--- a/schrack/ciondiscovery.cpp
+++ b/schrack/ciondiscovery.cpp
@@ -1,6 +1,36 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+*
+* 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
+*
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
#include "ciondiscovery.h"
-#include"extern-plugininfo.h"
+#include "extern-plugininfo.h"
#include