diff --git a/debian/control b/debian/control
index b329878..d90f9f9 100644
--- a/debian/control
+++ b/debian/control
@@ -120,6 +120,16 @@ Description: nymea integration plugin for Huawei FusionSolar energy devices
based on Modbus TCP.
+Package: nymea-plugin-kostal
+Architecture: any
+Multi-Arch: same
+Section: libs
+Depends: ${shlibs:Depends},
+ ${misc:Depends}
+Description: nymea.io plugin for Kostal Solar inverters
+ This package will install the nymea.io plugin for Kostal Solar inverters
+
+
Package: nymea-plugin-modbuscommander
Architecture: any
Section: libs
diff --git a/debian/nymea-plugin-kostal.install.in b/debian/nymea-plugin-kostal.install.in
new file mode 100644
index 0000000..464f022
--- /dev/null
+++ b/debian/nymea-plugin-kostal.install.in
@@ -0,0 +1,2 @@
+usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/libnymea_integrationpluginkostal.so
+kostal/translations/*qm usr/share/nymea/translations/
diff --git a/kostal/integrationpluginkostal.cpp b/kostal/integrationpluginkostal.cpp
new file mode 100644
index 0000000..cea7a27
--- /dev/null
+++ b/kostal/integrationpluginkostal.cpp
@@ -0,0 +1,447 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+*
+* Copyright 2013 - 2022, 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 "integrationpluginkostal.h"
+
+#include "network/networkdevicediscovery.h"
+#include "hardwaremanager.h"
+#include "plugininfo.h"
+
+IntegrationPluginKostal::IntegrationPluginKostal()
+{
+
+}
+
+void IntegrationPluginKostal::discoverThings(ThingDiscoveryInfo *info)
+{
+ if (!hardwareManager()->networkDeviceDiscovery()->available()) {
+ qCWarning(dcKostal()) << "The network discovery is not available on this platform.";
+ info->finish(Thing::ThingErrorUnsupportedFeature, QT_TR_NOOP("The network device discovery is not available."));
+ return;
+ }
+
+ NetworkDeviceDiscoveryReply *discoveryReply = hardwareManager()->networkDeviceDiscovery()->discover();
+ connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){
+ foreach (const NetworkDeviceInfo &networkDeviceInfo, discoveryReply->networkDeviceInfos()) {
+
+ qCDebug(dcKostal()) << "Found" << networkDeviceInfo;
+
+ QString title;
+ if (networkDeviceInfo.hostName().isEmpty()) {
+ title = networkDeviceInfo.address().toString();
+ } else {
+ title = networkDeviceInfo.hostName() + " (" + networkDeviceInfo.address().toString() + ")";
+ }
+
+ QString description;
+ if (networkDeviceInfo.macAddressManufacturer().isEmpty()) {
+ description = networkDeviceInfo.macAddress();
+ } else {
+ description = networkDeviceInfo.macAddress() + " (" + networkDeviceInfo.macAddressManufacturer() + ")";
+ }
+
+ ThingDescriptor descriptor(kostalInverterThingClassId, title, description);
+ ParamList params;
+ params << Param(kostalInverterThingIpAddressParamTypeId, networkDeviceInfo.address().toString());
+ params << Param(kostalInverterThingMacAddressParamTypeId, networkDeviceInfo.macAddress());
+ descriptor.setParams(params);
+
+ // Check if we already have set up this device
+ Things existingThings = myThings().filterByParam(kostalInverterThingMacAddressParamTypeId, networkDeviceInfo.macAddress());
+ if (existingThings.count() == 1) {
+ qCDebug(dcKostal()) << "This connection already exists in the system:" << networkDeviceInfo;
+ descriptor.setThingId(existingThings.first()->id());
+ }
+
+ info->addThingDescriptor(descriptor);
+ }
+
+ info->finish(Thing::ThingErrorNoError);
+ });
+}
+
+void IntegrationPluginKostal::startMonitoringAutoThings()
+{
+
+}
+
+void IntegrationPluginKostal::setupThing(ThingSetupInfo *info)
+{
+ Thing *thing = info->thing();
+ qCDebug(dcKostal()) << "Setup" << thing << thing->params();
+
+ if (thing->thingClassId() == kostalInverterThingClassId) {
+ QHostAddress hostAddress = QHostAddress(thing->paramValue(kostalInverterThingIpAddressParamTypeId).toString());
+ if (hostAddress.isNull()) {
+ info->finish(Thing::ThingErrorInvalidParameter, QT_TR_NOOP("No IP address given"));
+ return;
+ }
+
+ uint port = thing->paramValue(kostalInverterThingPortParamTypeId).toUInt();
+ quint16 slaveId = thing->paramValue(kostalInverterThingSlaveIdParamTypeId).toUInt();
+
+ KostalModbusTcpConnection *kostalConnection = new KostalModbusTcpConnection(hostAddress, port, slaveId, this);
+ connect(kostalConnection, &KostalModbusTcpConnection::initializationFinished, this, [this, thing, kostalConnection, info]{
+ qCDebug(dcKostal()) << "Connection init" << kostalConnection;
+
+ // FIXME: check if success
+
+ m_kostalConnections.insert(thing, kostalConnection);
+ info->finish(Thing::ThingErrorNoError);
+
+ // Set connected true
+ thing->setStateValue(kostalInverterConnectedStateTypeId, true);
+ foreach (Thing *childThing, myThings().filterByParentId(thing->id())) {
+ if (childThing->thingClassId() == kostalBatteryThingClassId) {
+ childThing->setStateValue(kostalBatteryConnectedStateTypeId, true);
+ } else if (childThing->thingClassId() == kostalMeterThingClassId) {
+ childThing->setStateValue(kostalMeterConnectedStateTypeId, true);
+ }
+ }
+
+ connect(kostalConnection, &KostalModbusTcpConnection::totalAcPowerChanged, this, [thing](float totalAcPower){
+ qCDebug(dcKostal()) << thing << "total AC power changed" << totalAcPower << "W";
+ thing->setStateValue(kostalInverterCurrentPowerStateTypeId, - totalAcPower);
+ });
+
+ connect(kostalConnection, &KostalModbusTcpConnection::totalYieldChanged, this, [thing](float totalYield){
+ qCDebug(dcKostal()) << thing << "total yeald changed" << totalYield << "Wh";
+ thing->setStateValue(kostalInverterTotalEnergyProducedStateTypeId, totalYield / 1000.0); // kWh
+ });
+
+ // Current
+ connect(kostalConnection, &KostalModbusTcpConnection::currentPhase1Changed, this, [thing](float currentPhase1){
+ qCDebug(dcKostal()) << thing << "current phase 1 changed" << currentPhase1 << "A";
+ thing->setStateValue(kostalInverterPhaseACurrentStateTypeId, currentPhase1); // A
+ });
+
+ connect(kostalConnection, &KostalModbusTcpConnection::currentPhase2Changed, this, [thing](float currentPhase2){
+ qCDebug(dcKostal()) << thing << "current phase 2 changed" << currentPhase2 << "A";
+ thing->setStateValue(kostalInverterPhaseBCurrentStateTypeId, currentPhase2); // A
+ });
+
+ connect(kostalConnection, &KostalModbusTcpConnection::currentPhase3Changed, this, [thing](float currentPhase3){
+ qCDebug(dcKostal()) << thing << "current phase 3 changed" << currentPhase3 << "A";
+ thing->setStateValue(kostalInverterPhaseCCurrentStateTypeId, currentPhase3); // A
+ });
+
+ // Voltage
+ connect(kostalConnection, &KostalModbusTcpConnection::voltagePhase1Changed, this, [thing](float voltagePhase1){
+ qCDebug(dcKostal()) << thing << "voltage phase 1 changed" << voltagePhase1 << "V";
+ thing->setStateValue(kostalInverterVoltagePhaseAStateTypeId, voltagePhase1);
+ });
+
+ connect(kostalConnection, &KostalModbusTcpConnection::voltagePhase2Changed, this, [thing](float voltagePhase2){
+ qCDebug(dcKostal()) << thing << "voltage phase 2 changed" << voltagePhase2 << "V";
+ thing->setStateValue(kostalInverterVoltagePhaseBStateTypeId, voltagePhase2);
+ });
+
+ connect(kostalConnection, &KostalModbusTcpConnection::voltagePhase3Changed, this, [thing](float voltagePhase3){
+ qCDebug(dcKostal()) << thing << "voltage phase 3 changed" << voltagePhase3 << "V";
+ thing->setStateValue(kostalInverterVoltagePhaseCStateTypeId, voltagePhase3);
+ });
+
+ // Current power
+ connect(kostalConnection, &KostalModbusTcpConnection::activePowerPhase1Changed, this, [thing](float activePowerPhase1){
+ qCDebug(dcKostal()) << thing << "active power phase 1 changed" << activePowerPhase1 << "W";
+ thing->setStateValue(kostalInverterCurrentPowerPhaseAStateTypeId, activePowerPhase1);
+ });
+
+ connect(kostalConnection, &KostalModbusTcpConnection::activePowerPhase2Changed, this, [thing](float activePowerPhase2){
+ qCDebug(dcKostal()) << thing << "active power phase 2 changed" << activePowerPhase2 << "W";
+ thing->setStateValue(kostalInverterCurrentPowerPhaseBStateTypeId, activePowerPhase2);
+ });
+
+ connect(kostalConnection, &KostalModbusTcpConnection::activePowerPhase3Changed, this, [thing](float activePowerPhase3){
+ qCDebug(dcKostal()) << thing << "active power phase 3 changed" << activePowerPhase3 << "W";
+ thing->setStateValue(kostalInverterCurrentPowerPhaseCStateTypeId, activePowerPhase3);
+ });
+
+ connect(kostalConnection, &KostalModbusTcpConnection::gridFrequencyInverterChanged, this, [thing](float gridFrequencyInverter){
+ qCDebug(dcKostal()) << thing << "grid frequency changed" << gridFrequencyInverter << "Hz";
+ thing->setStateValue(kostalInverterFrequencyStateTypeId, gridFrequencyInverter);
+ });
+
+
+ // Update registers
+ kostalConnection->update();
+ });
+
+ connect(kostalConnection, &KostalModbusTcpConnection::connectionStateChanged, this, [this, thing, kostalConnection](bool status){
+ qCDebug(dcKostal()) << "Connected changed to" << status << "for" << thing;
+ if (status) {
+ // Connected true will be set after successfull init
+ kostalConnection->initialize();
+ } else {
+ thing->setStateValue(kostalInverterConnectedStateTypeId, false);
+ foreach (Thing *childThing, myThings().filterByParentId(thing->id())) {
+ if (childThing->thingClassId() == kostalBatteryThingClassId) {
+ childThing->setStateValue(kostalBatteryConnectedStateTypeId, false);
+ } else if (childThing->thingClassId() == kostalMeterThingClassId) {
+ childThing->setStateValue(kostalMeterConnectedStateTypeId, false);
+ }
+ }
+ }
+ });
+
+ kostalConnection->connectDevice();
+ return;
+ }
+
+ if (thing->thingClassId() == kostalMeterThingClassId) {
+ // Get the parent thing and the associated connection
+ Thing *connectionThing = myThings().findById(thing->parentId());
+ if (!connectionThing) {
+ qCWarning(dcKostal()) << "Failed to set up kostal energy meter because the parent thing with ID" << thing->parentId().toString() << "could not be found.";
+ info->finish(Thing::ThingErrorHardwareNotAvailable);
+ return;
+ }
+
+ KostalModbusTcpConnection *kostalConnection = m_kostalConnections.value(connectionThing);
+ if (!kostalConnection) {
+ qCWarning(dcKostal()) << "Failed to set up kostal energy meter because the connection for" << connectionThing << "does not exist.";
+ info->finish(Thing::ThingErrorHardwareNotAvailable);
+ return;
+ }
+
+ // Note: The connected state will be handled in the parent inverter thing
+
+ // Update the meter data from the kostal connection containing all information
+
+ connect(kostalConnection, &KostalModbusTcpConnection::powerMeterTotalActivePowerChanged, this, [thing](float powerMeterTotalActivePower){
+ qCDebug(dcKostal()) << thing << "total active power changed" << powerMeterTotalActivePower << "W";
+ thing->setStateValue(kostalMeterCurrentPowerStateTypeId, powerMeterTotalActivePower);
+ });
+
+ // TODO: set toal energy consumed/produced
+
+ connect(kostalConnection, &KostalModbusTcpConnection::powerMeterTotalActivePowerChanged, this, [thing](float powerMeterTotalActivePower){
+ qCDebug(dcKostal()) << thing << "total active power changed" << powerMeterTotalActivePower << "W";
+ thing->setStateValue(kostalMeterCurrentPowerStateTypeId, powerMeterTotalActivePower);
+ });
+
+ // Current
+ connect(kostalConnection, &KostalModbusTcpConnection::powerMeterCurrentPhase1Changed, this, [thing](float powerMeterCurrentPhase1){
+ qCDebug(dcKostal()) << thing << "current phase 1 changed" << powerMeterCurrentPhase1 << "A";
+ thing->setStateValue(kostalMeterCurrentPhaseAStateTypeId, powerMeterCurrentPhase1);
+ });
+
+ connect(kostalConnection, &KostalModbusTcpConnection::powerMeterCurrentPhase2Changed, this, [thing](float powerMeterCurrentPhase2){
+ qCDebug(dcKostal()) << thing << "current phase 2 changed" << powerMeterCurrentPhase2 << "A";
+ thing->setStateValue(kostalMeterCurrentPhaseBStateTypeId, powerMeterCurrentPhase2);
+ });
+
+ connect(kostalConnection, &KostalModbusTcpConnection::powerMeterCurrentPhase3Changed, this, [thing](float powerMeterCurrentPhase3){
+ qCDebug(dcKostal()) << thing << "current phase 3 changed" << powerMeterCurrentPhase3 << "A";
+ thing->setStateValue(kostalMeterCurrentPhaseCStateTypeId, powerMeterCurrentPhase3);
+ });
+
+ // Voltage
+ connect(kostalConnection, &KostalModbusTcpConnection::powerMeterVoltagePhase1Changed, this, [thing](float powerMeterVoltagePhase1){
+ qCDebug(dcKostal()) << thing << "voltage phase 1 changed" << powerMeterVoltagePhase1 << "V";
+ thing->setStateValue(kostalMeterVoltagePhaseAStateTypeId, powerMeterVoltagePhase1);
+ });
+
+ connect(kostalConnection, &KostalModbusTcpConnection::powerMeterVoltagePhase2Changed, this, [thing](float powerMeterVoltagePhase2){
+ qCDebug(dcKostal()) << thing << "voltage phase 2 changed" << powerMeterVoltagePhase2 << "V";
+ thing->setStateValue(kostalMeterVoltagePhaseBStateTypeId, powerMeterVoltagePhase2);
+ });
+
+ connect(kostalConnection, &KostalModbusTcpConnection::powerMeterVoltagePhase3Changed, this, [thing](float powerMeterVoltagePhase3){
+ qCDebug(dcKostal()) << thing << "voltage phase 3 changed" << powerMeterVoltagePhase3 << "V";
+ thing->setStateValue(kostalMeterVoltagePhaseCStateTypeId, powerMeterVoltagePhase3);
+ });
+
+ // Power
+ connect(kostalConnection, &KostalModbusTcpConnection::powerMeterActivePowerPhase1Changed, this, [thing](float powerMeterActivePowerPhase1){
+ qCDebug(dcKostal()) << thing << "power phase 1 changed" << powerMeterActivePowerPhase1 << "W";
+ thing->setStateValue(kostalMeterCurrentPowerPhaseAStateTypeId, powerMeterActivePowerPhase1);
+ });
+
+ connect(kostalConnection, &KostalModbusTcpConnection::powerMeterActivePowerPhase2Changed, this, [thing](float powerMeterActivePowerPhase2){
+ qCDebug(dcKostal()) << thing << "power phase 2 changed" << powerMeterActivePowerPhase2 << "W";
+ thing->setStateValue(kostalMeterCurrentPowerPhaseBStateTypeId, powerMeterActivePowerPhase2);
+ });
+
+ connect(kostalConnection, &KostalModbusTcpConnection::powerMeterActivePowerPhase3Changed, this, [thing](float powerMeterActivePowerPhase3){
+ qCDebug(dcKostal()) << thing << "power phase 3 changed" << powerMeterActivePowerPhase3 << "W";
+ thing->setStateValue(kostalMeterCurrentPowerPhaseCStateTypeId, powerMeterActivePowerPhase3);
+ });
+
+ connect(kostalConnection, &KostalModbusTcpConnection::gridFrequencyPowerMeterChanged, this, [thing](float gridFrequency){
+ qCDebug(dcKostal()) << thing << "grid frequency changed" << gridFrequency << "Hz";
+ thing->setStateValue(kostalMeterFrequencyStateTypeId, gridFrequency);
+ });
+
+ info->finish(Thing::ThingErrorNoError);
+ }
+
+ if (thing->thingClassId() == kostalBatteryThingClassId) {
+ // Get the parent thing and the associated connection
+ Thing *connectionThing = myThings().findById(thing->parentId());
+ if (!connectionThing) {
+ qCWarning(dcKostal()) << "Failed to set up kostal battery because the parent thing with ID" << thing->parentId().toString() << "could not be found.";
+ info->finish(Thing::ThingErrorHardwareNotAvailable);
+ return;
+ }
+
+ KostalModbusTcpConnection *kostalConnection = m_kostalConnections.value(connectionThing);
+ if (!kostalConnection) {
+ qCWarning(dcKostal()) << "Failed to set up kostal battery because the connection for" << connectionThing << "does not exist.";
+ info->finish(Thing::ThingErrorHardwareNotAvailable);
+ return;
+ }
+
+ // Note: The connected state will be handled in the parent inverter thing
+
+ connect(kostalConnection, &KostalModbusTcpConnection::batteryStateOfChargeChanged, this, [thing](quint16 batteryStateOfCharge){
+ qCDebug(dcKostal()) << thing << "battery SoC changed" << batteryStateOfCharge << "%";
+ thing->setStateValue(kostalBatteryBatteryLevelStateTypeId, batteryStateOfCharge);
+ thing->setStateValue(kostalBatteryBatteryCriticalStateTypeId, batteryStateOfCharge < 5);
+ });
+
+
+ connect(kostalConnection, &KostalModbusTcpConnection::batteryActualPowerChanged, this, [thing](float batteryActualPower){
+ qCDebug(dcKostal()) << thing << "battery charge current changed" << batteryActualPower << "W";
+ thing->setStateValue(kostalBatteryCurrentPowerStateTypeId, batteryActualPower);
+ if (batteryActualPower == 0) {
+ thing->setStateValue(kostalBatteryChargingStateStateTypeId, "idle");
+ } else if (batteryActualPower > 0) {
+ thing->setStateValue(kostalBatteryChargingStateStateTypeId, "discharging");
+ } else if (batteryActualPower < 0) {
+ thing->setStateValue(kostalBatteryChargingStateStateTypeId, "charging");
+ }
+ });
+
+ connect(kostalConnection, &KostalModbusTcpConnection::batteryWorkCapacityChanged, this, [thing](quint32 batteryWorkCapacity){
+ qCDebug(dcKostal()) << thing << "battery work capacity changed" << batteryWorkCapacity << "Wh";
+ thing->setStateValue(kostalBatteryCapacityStateTypeId, batteryWorkCapacity / 1000.0); // kWh
+ });
+
+ info->finish(Thing::ThingErrorNoError);
+ }
+}
+
+void IntegrationPluginKostal::postSetupThing(Thing *thing)
+{
+ if (thing->thingClassId() == kostalInverterThingClassId) {
+
+ KostalModbusTcpConnection *kostalConnection = m_kostalConnections.value(thing);
+
+ // Check if we have to create the meter for the Kostal inverter
+ if (myThings().filterByParentId(thing->id()).filterByThingClassId(kostalMeterThingClassId).isEmpty()) {
+
+ qCDebug(dcKostal()) << "--> Read block \"powerMeterValues\" registers from:" << 220 << "size:" << 38;
+ QModbusReply *reply = kostalConnection->readBlockPowerMeterValues();
+ if (reply) {
+ if (!reply->isFinished()) {
+ connect(reply, &QModbusReply::finished, this, [=](){
+ if (reply->error() == QModbusDevice::NoError) {
+ const QModbusDataUnit unit = reply->result();
+ const QVector blockValues = unit.values();
+
+ bool notZero = false;
+ for (int i = 0; i < blockValues.size(); i++) {
+ if (blockValues.at(i) != 0) {
+ notZero = true;
+ break;
+ }
+ }
+
+ if (notZero) {
+ qCDebug(dcKostal()) << "There is a meter connected but not set up yet. Creating a meter...";
+ // No meter thing created for this inverter, lets create one with the inverter as parent
+ ThingClass meterThingClass = thingClass(kostalMeterThingClassId);
+ ThingDescriptor descriptor(kostalMeterThingClassId, meterThingClass.name(), QString(), thing->id());
+ // No params required, all we need is the connection
+ emit autoThingsAppeared(ThingDescriptors() << descriptor);
+ } else {
+ qCDebug(dcKostal()) << "There is no meter connected to the inverter" << thing;
+ }
+ }
+ });
+
+ connect(reply, &QModbusReply::errorOccurred, this, [reply] (QModbusDevice::Error error){
+ qCWarning(dcKostal()) << "Modbus reply error occurred while updating block \"powerMeterValues\" registers" << error << reply->errorString();
+ emit reply->finished();
+ });
+ }
+ } else {
+ qCWarning(dcKostal()) << "Error occurred while reading block \"powerMeterValues\" registers";
+ }
+ }
+
+ // Check if we have to create the battery for the Kostal inverter
+ if (myThings().filterByParentId(thing->id()).filterByThingClassId(kostalBatteryThingClassId).isEmpty()) {
+ if (kostalConnection->batteryType() == KostalModbusTcpConnection::BatteryTypeNoBattery) {
+ qCDebug(dcKostal()) << "There is no battery connected to the inverter" << thing;
+ return;
+ }
+
+ qCDebug(dcKostal()) << "There is a battery connected but not set up yet. Creating a battery" << kostalConnection->batteryType();
+ ThingClass batteryThingClass = thingClass(kostalBatteryThingClassId);
+ ThingDescriptor descriptor(kostalBatteryThingClassId, kostalConnection->batteryManufacturer() + " - " + kostalConnection->batteryModelId(), QString(), thing->id());
+ // No params required, all we need is the connection
+ emit autoThingsAppeared(ThingDescriptors() << descriptor);
+ }
+
+ if (!m_pluginTimer) {
+ qCDebug(dcKostal()) << "Starting plugin timer...";
+ m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(4);
+ connect(m_pluginTimer, &PluginTimer::timeout, this, [this] {
+ foreach(KostalModbusTcpConnection *connection, m_kostalConnections) {
+ if (connection->connected()) {
+ connection->update();
+ }
+ }
+ });
+ }
+ }
+}
+
+void IntegrationPluginKostal::thingRemoved(Thing *thing)
+{
+ if (thing->thingClassId() == kostalInverterThingClassId && m_kostalConnections.contains(thing)) {
+ KostalModbusTcpConnection *connection = m_kostalConnections.take(thing);
+ delete connection;
+ }
+
+ if (myThings().isEmpty() && m_pluginTimer) {
+ hardwareManager()->pluginTimerManager()->unregisterTimer(m_pluginTimer);
+ m_pluginTimer = nullptr;
+ }
+}
+
+void IntegrationPluginKostal::executeAction(ThingActionInfo *info)
+{
+ info->finish(Thing::ThingErrorNoError);
+}
+
+
diff --git a/kostal/integrationpluginkostal.h b/kostal/integrationpluginkostal.h
new file mode 100644
index 0000000..866ab1d
--- /dev/null
+++ b/kostal/integrationpluginkostal.h
@@ -0,0 +1,67 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+*
+* Copyright 2013 - 2022, 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 INTEGRATIONPLUGINKOSTAL_H
+#define INTEGRATIONPLUGINKOSTAL_H
+
+#include
+#include
+
+#include "kostalmodbustcpconnection.h"
+
+class IntegrationPluginKostal: public IntegrationPlugin
+{
+ Q_OBJECT
+
+ Q_PLUGIN_METADATA(IID "io.nymea.IntegrationPlugin" FILE "integrationpluginkostal.json")
+ Q_INTERFACES(IntegrationPlugin)
+
+public:
+ /** Constructor */
+ explicit IntegrationPluginKostal();
+
+ void discoverThings(ThingDiscoveryInfo *info) override;
+ void startMonitoringAutoThings() override;
+ void setupThing(ThingSetupInfo *info) override;
+ void postSetupThing(Thing *thing) override;
+ void thingRemoved(Thing *thing) override;
+ void executeAction(ThingActionInfo *info) override;
+
+private:
+ PluginTimer *m_pluginTimer = nullptr;
+ QHash m_kostalConnections;
+
+
+
+};
+
+#endif // INTEGRATIONPLUGINKOSTAL_H
+
+
diff --git a/kostal/integrationpluginkostal.json b/kostal/integrationpluginkostal.json
new file mode 100644
index 0000000..dfd6487
--- /dev/null
+++ b/kostal/integrationpluginkostal.json
@@ -0,0 +1,405 @@
+{
+ "name": "Kostal",
+ "displayName": "Kostal",
+ "id": "51a2c7d5-084d-4474-a65a-e0447ab9ac45",
+ "vendors": [
+ {
+ "name": "kostal",
+ "displayName": "KOSTAL Solar Electric",
+ "id": "862d1ebf-cb78-4c55-89b2-819fddfd9acd",
+ "thingClasses": [
+ {
+ "name": "kostalInverter",
+ "displayName": "KOSTAL Inverter",
+ "id": "7dc6db14-6f5a-4ac8-9684-4c6a526bd0de",
+ "createMethods": ["discovery", "user"],
+ "interfaces": ["solarinverter", "connectable"],
+ "providedInterfaces": [ "energymeter", "energystorage"],
+ "paramTypes": [
+ {
+ "id": "f1c43b1e-cffe-4d30-bda0-c23ed648dd71",
+ "name": "ipAddress",
+ "displayName": "IP address",
+ "type": "QString",
+ "inputType": "IPv4Address",
+ "defaultValue": "127.0.0.1"
+ },
+ {
+ "id": "906f6099-d0e1-4297-a2b3-f8ec4482c578",
+ "name":"macAddress",
+ "displayName": "MAC address",
+ "type": "QString",
+ "inputType": "MacAddress",
+ "defaultValue": ""
+ },
+ {
+ "id": "9d2175af-afb9-4b31-b3dc-e53a369bad9e",
+ "name":"port",
+ "displayName": "Port",
+ "type": "int",
+ "defaultValue": 1502
+ },
+ {
+ "id": "b3e04cb0-8f9a-4c9f-9c67-5c08da0273e3",
+ "name":"slaveId",
+ "displayName": "Slave ID",
+ "type": "int",
+ "defaultValue": 71
+ }
+ ],
+ "stateTypes": [
+ {
+ "id": "8d64954a-855d-44ea-8bc9-88a71ab47b6b",
+ "name": "connected",
+ "displayName": "Connected",
+ "displayNameEvent": "Connected changed",
+ "type": "bool",
+ "defaultValue": false,
+ "cached": false
+ },
+ {
+ "id": "bd68fa44-2628-4e4e-ac9b-5f2cf563eb4d",
+ "name": "currentPower",
+ "displayName": "Active power",
+ "displayNameEvent": "Active power changed",
+ "type": "double",
+ "unit": "Watt",
+ "defaultValue": 0,
+ "cached": false
+ },
+ {
+ "id": "5c1546d2-92be-4809-bc56-8bbdaab436d2",
+ "name": "totalEnergyProduced",
+ "displayName": "Total AC energy",
+ "displayNameEvent": "Total AC energy changed",
+ "type": "double",
+ "unit": "KiloWattHour",
+ "defaultValue": 0.0,
+ "cached": true
+ },
+ {
+ "id": "567bb3c2-4a0c-4194-a86e-b8dc29815092",
+ "name": "phaseACurrent",
+ "displayName": "Phase A current",
+ "displayNameEvent": "Phase A current changed",
+ "type": "double",
+ "unit": "Ampere",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "84e9282a-b72b-4dbf-9e4b-99083e5539a5",
+ "name": "phaseBCurrent",
+ "displayName": "Phase B current",
+ "displayNameEvent": "Phase B current changed",
+ "type": "double",
+ "unit": "Ampere",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "4f7c308f-2cb2-4327-8a68-77222f920e61",
+ "name": "phaseCCurrent",
+ "displayName": "Phase C current",
+ "displayNameEvent": "Phase C current changed",
+ "type": "double",
+ "unit": "Ampere",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "7fcade2d-9243-4694-a29f-36a517f54844",
+ "name": "voltagePhaseA",
+ "displayName": "Voltage phase A",
+ "displayNameEvent": "Voltage phase A changed",
+ "type": "double",
+ "unit": "Volt",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "8f1b229d-af39-47ec-b005-eecd6f174294",
+ "name": "voltagePhaseB",
+ "displayName": "Voltage phase B",
+ "displayNameEvent": "Voltage phase B changed",
+ "type": "double",
+ "unit": "Volt",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "51e0d1c7-e75a-4bc4-a7e4-6170a959e6cc",
+ "name": "voltagePhaseC",
+ "displayName": "Voltage phase C",
+ "displayNameEvent": "Voltage phase C changed",
+ "type": "double",
+ "unit": "Volt",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "aed44263-d15e-46d6-b6a3-66005ceb53c9",
+ "name": "currentPowerPhaseA",
+ "displayName": "Current power phase A",
+ "displayNameEvent": "Current power phase A changed",
+ "type": "double",
+ "unit": "Watt",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "8d8cd634-00dd-46c8-b34b-bbff552d0121",
+ "name": "currentPowerPhaseB",
+ "displayName": "Current power phase B",
+ "displayNameEvent": "Current power phase B changed",
+ "type": "double",
+ "unit": "Watt",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "95f1ad78-0cb1-44cf-87b2-03e28b115f00",
+ "name": "currentPowerPhaseC",
+ "displayName": "Current power phase C",
+ "displayNameEvent": "Current power phase C changed",
+ "type": "double",
+ "unit": "Watt",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "634a4659-5c73-40e9-a77d-4f2e555d05bb",
+ "name": "frequency",
+ "displayName": "Frequency",
+ "displayNameEvent": "Frequency changed",
+ "type": "double",
+ "unit": "Hertz",
+ "defaultValue": 0.00,
+ "cached": false
+ }
+ ],
+ "actionTypes": [ ]
+ },
+ {
+ "name": "kostalMeter",
+ "displayName": "KOSTAL Meter",
+ "id": "61af1e07-6a59-4465-a563-3cbf4a9fcbc3",
+ "createMethods": ["auto"],
+ "interfaces": [ "energymeter", "connectable"],
+ "paramTypes": [
+ ],
+ "stateTypes": [
+ {
+ "id": "5c510989-d6e1-4b06-b10f-f8b9e52a254c",
+ "name": "connected",
+ "displayName": "Connected",
+ "displayNameEvent": "Connected changed",
+ "type": "bool",
+ "defaultValue": false,
+ "cached": false
+ },
+ {
+ "id": "992b0da8-e6bd-47ab-af60-be8802fc7ecf",
+ "name": "currentPower",
+ "displayName": "Total real power",
+ "displayNameEvent": "Total real power changed",
+ "type": "double",
+ "unit": "Watt",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "902ce047-ef6b-4868-9f7c-61a2ebe61a5b",
+ "name": "totalEnergyProduced",
+ "displayName": "AC energy",
+ "displayNameEvent": "AC energy changed",
+ "type": "double",
+ "unit": "KiloWattHour",
+ "defaultValue": 0.00,
+ "cached": true
+ },
+ {
+ "id": "f40e8bd9-db0e-4f69-8fa1-f1cfd4b144f3",
+ "name": "totalEnergyConsumed",
+ "displayName": "Total real energy imported",
+ "displayNameEvent": "Total real energy imported changed",
+ "type": "double",
+ "unit": "KiloWattHour",
+ "defaultValue": 0.00,
+ "cached": true
+ },
+ {
+ "id": "1681ee7d-5d22-4794-8cfe-febaa1ddf29f",
+ "name": "currentPhaseA",
+ "displayName": "Phase A current",
+ "displayNameEvent": "Phase A current changed",
+ "type": "double",
+ "unit": "Ampere",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "b54e7182-6cb2-4184-96c5-2324e8139b6e",
+ "name": "currentPhaseB",
+ "displayName": "Phase B current",
+ "displayNameEvent": "Phase B current changed",
+ "type": "double",
+ "unit": "Ampere",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "546eeb76-b17f-4c51-a9fa-01e7403913cd",
+ "name": "currentPhaseC",
+ "displayName": "Phase C current",
+ "displayNameEvent": "Phase C current changed",
+ "type": "double",
+ "unit": "Ampere",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "2b1250eb-4c22-4025-ba7c-c3e8f27af3dc",
+ "name": "currentPowerPhaseA",
+ "displayName": "Current power phase A",
+ "displayNameEvent": "Current power phase A changed",
+ "type": "double",
+ "unit": "Watt",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "0c43d20d-843c-4edd-9955-dafab6caecf6",
+ "name": "currentPowerPhaseB",
+ "displayName": "Current power phase B",
+ "displayNameEvent": "Current power phase B changed",
+ "type": "double",
+ "unit": "Watt",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "a1e46df0-43e5-42f0-846a-5d2f24808a67",
+ "name": "currentPowerPhaseC",
+ "displayName": "Current power phase C",
+ "displayNameEvent": "Current power phase C changed",
+ "type": "double",
+ "unit": "Watt",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "10a34381-cfb1-4aeb-a25f-e6b0d8b96510",
+ "name": "voltagePhaseA",
+ "displayName": "Voltage phase A",
+ "displayNameEvent": "Voltage phase A changed",
+ "type": "double",
+ "unit": "Volt",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "b0be1395-c7d2-449e-9632-5b6bf3298797",
+ "name": "voltagePhaseB",
+ "displayName": "Voltage phase B",
+ "displayNameEvent": "Voltage phase B changed",
+ "type": "double",
+ "unit": "Volt",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "b422d7a9-4c43-4827-be39-e4694f2cab64",
+ "name": "voltagePhaseC",
+ "displayName": "Voltage phase C",
+ "displayNameEvent": "Voltage phase C changed",
+ "type": "double",
+ "unit": "Volt",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "7c86ea72-505b-4924-80ef-3cf3ff31a380",
+ "name": "frequency",
+ "displayName": "Frequency",
+ "displayNameEvent": "Frequency changed",
+ "type": "double",
+ "unit": "Hertz",
+ "defaultValue": 0.00,
+ "cached": false
+ }
+ ],
+ "actionTypes": [ ]
+ },
+ {
+ "name": "kostalBattery",
+ "displayName": "KOSTAL Battery",
+ "id": "d6dbdfe8-adbb-47d8-840d-9b787683fc69",
+ "createMethods": ["auto"],
+ "interfaces": [ "energystorage", "connectable"],
+ "paramTypes": [
+ ],
+ "stateTypes": [
+ {
+ "id": "4a5a5a38-b623-4024-b557-410a46ebc495",
+ "name": "connected",
+ "displayName": "Connected",
+ "displayNameEvent": "Connected changed",
+ "type": "bool",
+ "defaultValue": false,
+ "cached": false
+ },
+ {
+ "id": "897616db-e815-4cda-b890-13b37a94ad17",
+ "name": "batteryCritical",
+ "displayName": "Battery critical",
+ "displayNameEvent": "Battery critical changed",
+ "type": "bool",
+ "defaultValue": false
+ },
+ {
+ "id": "a4b0c8c9-44f0-43e2-ab25-63fdc9772fb8",
+ "name": "batteryLevel",
+ "displayName": "Battery level",
+ "displayNameEvent": "Battery level changed",
+ "type": "int",
+ "unit": "Percentage",
+ "minValue": 0,
+ "maxValue": 100,
+ "defaultValue": 0
+ },
+ {
+ "id": "6d72ccea-7761-4f00-b43f-463d05cbe559",
+ "name": "currentPower",
+ "displayName": "Total real power",
+ "displayNameEvent": "Total real power changed",
+ "type": "double",
+ "unit": "Watt",
+ "defaultValue": 0.00,
+ "cached": false
+ },
+ {
+ "id": "98099dbd-3f66-43b3-8192-f2e3fdcd5d62",
+ "name": "capacity",
+ "displayName": "Capacity",
+ "displayNameEvent": "Capacity changed",
+ "type": "double",
+ "unit": "KiloWattHour",
+ "defaultValue": 0.00
+ },
+ {
+ "id": "829173e8-7535-4aba-b403-d498ff68250e",
+ "name": "chargingState",
+ "displayName": "Charging state",
+ "displayNameEvent": "Charging state changed",
+ "type": "QString",
+ "possibleValues": ["idle", "charging", "discharging"],
+ "defaultValue": "idle"
+ }
+ ],
+ "actionTypes": [ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/kostal/kostal-registers.json b/kostal/kostal-registers.json
new file mode 100644
index 0000000..df21a96
--- /dev/null
+++ b/kostal/kostal-registers.json
@@ -0,0 +1,965 @@
+{
+ "className": "Kostal",
+ "protocol": "TCP",
+ "endianness": "LittleEndian",
+ "enums": [
+ {
+ "name": "ByteOrder",
+ "values": [
+ {
+ "key": "LittleEndian",
+ "value": 0
+ },
+ {
+ "key": "BigEndian",
+ "value": 1
+ }
+ ]
+ },
+ {
+ "name": "InverterState",
+ "values": [
+ {
+ "key": "Off",
+ "value": 0
+ },
+ {
+ "key": "Init",
+ "value": 1
+ },
+ {
+ "key": "IsoMeas",
+ "value": 2
+ },
+ {
+ "key": "GridCheck",
+ "value": 3
+ },
+ {
+ "key": "StartUp",
+ "value": 4
+ },
+ {
+ "key": "FeedIn",
+ "value": 6
+ },
+ {
+ "key": "Throttled",
+ "value": 7
+ },
+ {
+ "key": "ExtSwitchOff",
+ "value": 8
+ },
+ {
+ "key": "Update",
+ "value": 9
+ },
+ {
+ "key": "Standby",
+ "value": 10
+ },
+ {
+ "key": "GridSync",
+ "value": 11
+ },
+ {
+ "key": "GridPreCheck",
+ "value": 12
+ },
+ {
+ "key": "GridSwitchOff",
+ "value": 13
+ },
+ {
+ "key": "Overheating",
+ "value": 14
+ },
+ {
+ "key": "Shutdown",
+ "value": 15
+ },
+ {
+ "key": "ImproperDcVoltage",
+ "value": 16
+ },
+ {
+ "key": "Esb",
+ "value": 17
+ },
+ {
+ "key": "Unknown",
+ "value": 18
+ }
+ ]
+ },
+ {
+ "name": "EnergyManagementState",
+ "values": [
+ {
+ "key": "Idle",
+ "value": 0
+ },
+ {
+ "key": "EmergencyBatteryCharge",
+ "value": 2
+ },
+ {
+ "key": "WinterModeStep1",
+ "value": 8
+ },
+ {
+ "key": "WinterModeStep2",
+ "value": 16
+ }
+ ]
+ },
+ {
+ "name": "BatteryType",
+ "values": [
+ {
+ "key": "NoBattery",
+ "value": 0
+ },
+ {
+ "key": "SonyMurata",
+ "value": 2
+ },
+ {
+ "key": "BydBbox",
+ "value": 4
+ }
+ ]
+ }
+ ],
+ "blocks": [
+ {
+ "id": "basics",
+ "readSchedule": "init",
+ "registers": [
+ {
+ "id": "modbusUnitId",
+ "address": 4,
+ "size": 1,
+ "type": "uint16",
+ "registerType": "holdingRegister",
+ "description": "MODBUS Unit-ID",
+ "defaultValue": "1",
+ "access": "RO"
+ },
+ {
+ "id": "modbusByteOrder",
+ "address": 5,
+ "size": 1,
+ "type": "uint16",
+ "enum": "ByteOrder",
+ "registerType": "holdingRegister",
+ "description": "MODBUS Byte Order Note",
+ "defaultValue": "ByteOrderLittleEndian",
+ "access": "RO"
+ },
+ {
+ "id": "inverterArticleNumber",
+ "address": 6,
+ "size": 8,
+ "type": "string",
+ "registerType": "holdingRegister",
+ "description": "Inverter article number",
+ "access": "RO"
+ },
+ {
+ "id": "inverterSerialNumber1",
+ "address": 14,
+ "size": 8,
+ "type": "string",
+ "registerType": "holdingRegister",
+ "description": "Inverter serial number 1",
+ "access": "RO"
+ }
+ ]
+ },
+ {
+ "id": "information",
+ "readSchedule": "init",
+ "registers": [
+ {
+ "id": "hardwareVersion",
+ "address": 36,
+ "size": 2,
+ "type": "uint32",
+ "registerType": "holdingRegister",
+ "description": "Hardware-Version",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "softwareVersionMainController",
+ "address": 38,
+ "size": 8,
+ "type": "string",
+ "registerType": "holdingRegister",
+ "description": "Software-Version Maincontroller (MC)",
+ "access": "RO"
+ },
+ {
+ "id": "softwareVersionIoController",
+ "address": 46,
+ "size": 8,
+ "type": "string",
+ "registerType": "holdingRegister",
+ "description": "Software-Version IO-Controller (IOC)",
+ "access": "RO"
+ },
+ {
+ "id": "powerId",
+ "address": 54,
+ "size": 1,
+ "type": "uint16",
+ "registerType": "holdingRegister",
+ "description": "Power-ID",
+ "defaultValue": "0",
+ "access": "RO"
+ }
+ ]
+ },
+ {
+ "id": "consumptions",
+ "readSchedule": "update",
+ "registers": [
+ {
+ "id": "energyManagementState",
+ "address": 104,
+ "size": 2,
+ "type": "uint32",
+ "enum": "EnergyManagementState",
+ "registerType": "holdingRegister",
+ "description": "State of energy manager",
+ "defaultValue": "EnergyManagementStateIdle",
+ "access": "RO"
+ },
+ {
+ "id": "homeOwnConsumptionFromBattery",
+ "address": 106,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Home own consumption from battery",
+ "unit": "W",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "homeOwnConsumptionFromGrid",
+ "address": 108,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Home own consumption from grid",
+ "unit": "W",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "totalHomeConsumptionFromBattery",
+ "address": 110,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Total home consumption Battery",
+ "unit": "Wh",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "totalHomeConsumptionFromGrid",
+ "address": 112,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Total home consumption grid",
+ "unit": "Wh",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "totalHomeConsumptionFromPv",
+ "address": 114,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Total home consumption from PV",
+ "unit": "Wh",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "homeOwnConsumptionPv",
+ "address": 116,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Home own consumption from PV",
+ "unit": "W",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "totalHomeConsumption",
+ "address": 118,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Total home consumption",
+ "unit": "Wh",
+ "defaultValue": "0",
+ "access": "RO"
+ }
+ ]
+ },
+ {
+ "id": "inverterValues",
+ "readSchedule": "update",
+ "registers": [
+ {
+ "id": "gridFrequencyInverter",
+ "address": 152,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Grid frequency inverter",
+ "unit": "Hz",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "currentPhase1",
+ "address": 154,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Current phase 1",
+ "unit": "A",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "activePowerPhase1",
+ "address": 156,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Active power phase 1",
+ "unit": "W",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "voltagePhase1",
+ "address": 158,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Voltage phase 1",
+ "unit": "V",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "currentPhase2",
+ "address": 160,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Current phase 2",
+ "unit": "A",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "activePowerPhase2",
+ "address": 162,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Active power phase 2",
+ "unit": "W",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "voltagePhase2",
+ "address": 164,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Voltage phase 2",
+ "unit": "V",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "currentPhase3",
+ "address": 166,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Current phase 3",
+ "unit": "A",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "activePowerPhase3",
+ "address": 168,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Active power phase 3",
+ "unit": "W",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "voltagePhase3",
+ "address": 170,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Voltage phase 3",
+ "unit": "V",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "totalAcPower",
+ "address": 172,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Total AC power",
+ "unit": "W",
+ "defaultValue": "0",
+ "access": "RO"
+ }
+ ]
+ },
+ {
+ "id": "powerMeterValues",
+ "readSchedule": "update",
+ "registers": [
+ {
+ "id": "gridFrequencyPowerMeter",
+ "address": 220,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Grid frequency (powermeter)",
+ "unit": "Hz",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "powerMeterCurrentPhase1",
+ "address": 222,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Current phase 1 (powermeter)",
+ "unit": "A",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "powerMeterActivePowerPhase1",
+ "address": 224,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Active power phase 1 (powermeter)",
+ "unit": "W",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "powerMeterReactivePowerPhase1",
+ "address": 226,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Reactive power phase 1 (powermeter)",
+ "unit": "var",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "powerMeterApparentPowerPhase1",
+ "address": 228,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Apparent power phase 1 (powermeter)",
+ "unit": "VA",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "powerMeterVoltagePhase1",
+ "address": 230,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Voltage phase 1 (powermeter)",
+ "unit": "V",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "powerMeterCurrentPhase2",
+ "address": 232,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Current phase 2 (powermeter)",
+ "unit": "A",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "powerMeterActivePowerPhase2",
+ "address": 234,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Active power phase 2 (powermeter)",
+ "unit": "W",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "powerMeterReactivePowerPhase2",
+ "address": 236,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Reactive power phase 2 (powermeter)",
+ "unit": "var",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "powerMeterApparentPowerPhase2",
+ "address": 238,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Apparent power phase 2 (powermeter)",
+ "unit": "VA",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "powerMeterVoltagePhase2",
+ "address": 240,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Voltage phase 2 (powermeter)",
+ "unit": "V",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "powerMeterCurrentPhase3",
+ "address": 242,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Current phase 3 (powermeter)",
+ "unit": "A",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "powerMeterActivePowerPhase3",
+ "address": 244,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Active power phase 3 (powermeter)",
+ "unit": "W",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "powerMeterReactivePowerPhase3",
+ "address": 246,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Reactive power phase 3 (powermeter)",
+ "unit": "var",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "powerMeterApparentPowerPhase3",
+ "address": 248,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Apparent power phase 3 (powermeter)",
+ "unit": "VA",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "powerMeterVoltagePhase3",
+ "address": 250,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Voltage phase 3 (powermeter)",
+ "unit": "V",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "powerMeterTotalActivePower",
+ "address": 252,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Total active power (powermeter)",
+ "unit": "W",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "powerMeterTotalReactivePower",
+ "address": 254,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Total reactive power (powermeter)",
+ "unit": "var",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "powerMeterTotalApparentPower",
+ "address": 256,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "description": "Total apparent power (powermeter)",
+ "unit": "VA",
+ "defaultValue": "0",
+ "access": "RO"
+ }
+ ]
+ },
+ {
+ "id": "yield",
+ "readSchedule": "update",
+ "registers": [
+ {
+ "id": "totalYield",
+ "address": 320,
+ "size": 2,
+ "type": "float",
+ "description": "Total yield",
+ "registerType": "holdingRegister",
+ "defaultValue": "0",
+ "unit": "Wh",
+ "access": "RO"
+ },
+ {
+ "id": "dailyYield",
+ "address": 322,
+ "size": 2,
+ "type": "float",
+ "description": "Daily yield",
+ "registerType": "holdingRegister",
+ "defaultValue": "0",
+ "unit": "Wh",
+ "access": "RO"
+ },
+ {
+ "id": "yearlyYield",
+ "address": 324,
+ "size": 2,
+ "type": "float",
+ "description": "Yearly yield",
+ "registerType": "holdingRegister",
+ "defaultValue": "0",
+ "unit": "Wh",
+ "access": "RO"
+ },
+ {
+ "id": "MonthlyYield",
+ "address": 326,
+ "size": 2,
+ "type": "float",
+ "description": "Monthly yield",
+ "registerType": "holdingRegister",
+ "defaultValue": "0",
+ "unit": "Wh",
+ "access": "RO"
+ }
+ ]
+ }
+ ],
+ "registers": [
+ {
+ "id": "bidirectionalConverterNumber",
+ "address": 30,
+ "size": 1,
+ "type": "uint16",
+ "readSchedule": "init",
+ "registerType": "holdingRegister",
+ "description": "Number of bidirectional converter",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "acPhasesNumber",
+ "address": 32,
+ "size": 1,
+ "type": "uint16",
+ "readSchedule": "init",
+ "registerType": "holdingRegister",
+ "description": "Number of bidirectional converter",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "numberPvStrings",
+ "address": 34,
+ "size": 1,
+ "type": "uint16",
+ "readSchedule": "init",
+ "registerType": "holdingRegister",
+ "description": "Number of PV strings",
+ "unit": "",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "inverterState",
+ "address": 56,
+ "size": 1,
+ "type": "uint16",
+ "readSchedule": "update",
+ "registerType": "holdingRegister",
+ "description": "Inverter state",
+ "defaultValue": "InverterStateUnknown",
+ "enum": "InverterState",
+ "access": "RO"
+ },
+ {
+ "id": "totalDcPower",
+ "address": 100,
+ "size": 2,
+ "type": "float",
+ "readSchedule": "update",
+ "registerType": "holdingRegister",
+ "description": "Total DC power",
+ "unit": "W",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "batteryChargeCurrent",
+ "address": 190,
+ "size": 2,
+ "type": "float",
+ "readSchedule": "update",
+ "registerType": "holdingRegister",
+ "description": "Battery charge current",
+ "unit": "A",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "numberOfBytteryCycles",
+ "address": 194,
+ "size": 2,
+ "type": "float",
+ "readSchedule": "update",
+ "registerType": "holdingRegister",
+ "description": "Number of battery cycles",
+ "unit": "",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "actualBatteryChargeCurrent",
+ "address": 200,
+ "size": 2,
+ "type": "float",
+ "readSchedule": "update",
+ "registerType": "holdingRegister",
+ "description": "Actual battery charge (-) / discharge (+) current",
+ "unit": "A",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "batteryTemperature",
+ "address": 214,
+ "size": 2,
+ "type": "float",
+ "registerType": "holdingRegister",
+ "readSchedule": "update",
+ "description": "Battery temperature",
+ "unit": "°C",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "batteryVoltage",
+ "address": 216,
+ "size": 2,
+ "type": "float",
+ "readSchedule": "update",
+ "registerType": "holdingRegister",
+ "description": "Battery voltage",
+ "unit": "V",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "batteryStateOfCharge",
+ "address": 514,
+ "size": 1,
+ "type": "uint16",
+ "readSchedule": "update",
+ "registerType": "holdingRegister",
+ "description": "Battery SoC",
+ "unit": "%",
+ "access": "RO"
+ },
+ {
+ "id": "batteryManufacturer",
+ "address": 517,
+ "size": 8,
+ "type": "string",
+ "readSchedule": "init",
+ "registerType": "holdingRegister",
+ "description": "Battery Manufacturer",
+ "access": "RO"
+ },
+ {
+ "id": "batteryModelId",
+ "address": 525,
+ "size": 2,
+ "type": "uint32",
+ "readSchedule": "init",
+ "description": "Battery model ID",
+ "registerType": "holdingRegister",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "batterySerialNumber",
+ "address": 527,
+ "size": 2,
+ "type": "uint32",
+ "readSchedule": "init",
+ "description": "Battery serial number",
+ "registerType": "holdingRegister",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "batteryWorkCapacity",
+ "address": 529,
+ "size": 2,
+ "type": "uint32",
+ "readSchedule": "init",
+ "description": "Battery work capacity",
+ "registerType": "holdingRegister",
+ "defaultValue": "0",
+ "unit": "Wh",
+ "access": "RO"
+ },
+ {
+ "id": "inverterManufacturer",
+ "address": 535,
+ "size": 16,
+ "type": "string",
+ "readSchedule": "init",
+ "registerType": "holdingRegister",
+ "description": "Inverter manufacturer",
+ "access": "RO"
+ },
+ {
+ "id": "inverterSerialNumber2",
+ "address": 559,
+ "size": 16,
+ "type": "string",
+ "readSchedule": "init",
+ "registerType": "holdingRegister",
+ "description": "Inverter serial number 2",
+ "access": "RO"
+ },
+ {
+ "id": "energyScaleFactor",
+ "address": 579,
+ "size": 1,
+ "type": "int16",
+ "readSchedule": "init",
+ "description": "Energy scale factor",
+ "registerType": "holdingRegister",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "batteryActualPower",
+ "address": 582,
+ "size": 1,
+ "type": "int16",
+ "readSchedule": "update",
+ "registerType": "holdingRegister",
+ "description": "Actual battery charge/discharge power",
+ "unit": "W",
+ "defaultValue": "0",
+ "access": "RO"
+ },
+ {
+ "id": "batteryType",
+ "address": 588,
+ "size": 1,
+ "type": "uint16",
+ "enum": "BatteryType",
+ "readSchedule": "init",
+ "registerType": "holdingRegister",
+ "description": "Battery type",
+ "defaultValue": "BatteryTypeNoBattery",
+ "access": "RO"
+ },
+ {
+ "id": "productName",
+ "address": 768,
+ "size": 32,
+ "type": "string",
+ "readSchedule": "init",
+ "registerType": "holdingRegister",
+ "description": "Productname",
+ "access": "RO"
+ },
+ {
+ "id": "totalEnergyAcToGrid",
+ "address": 1064,
+ "size": 2,
+ "type": "int32",
+ "scaleFactor": "energyScaleFactor",
+ "registerType": "holdingRegister",
+ "readSchedule": "update",
+ "description": "Total energy AC-side to grid",
+ "unit": "Wh",
+ "defaultValue": "0",
+ "access": "RO"
+ }
+ ]
+}
diff --git a/kostal/kostal.pro b/kostal/kostal.pro
new file mode 100644
index 0000000..b5d31e6
--- /dev/null
+++ b/kostal/kostal.pro
@@ -0,0 +1,12 @@
+include(../plugins.pri)
+
+# Generate modbus connection
+MODBUS_CONNECTIONS += kostal-registers.json
+#MODBUS_TOOLS_CONFIG += VERBOSE
+include(../modbus.pri)
+
+HEADERS += \
+ integrationpluginkostal.h
+
+SOURCES += \
+ integrationpluginkostal.cpp
diff --git a/kostal/translations/51a2c7d5-084d-4474-a65a-e0447ab9ac45-en_US.ts b/kostal/translations/51a2c7d5-084d-4474-a65a-e0447ab9ac45-en_US.ts
new file mode 100644
index 0000000..47c0a0c
--- /dev/null
+++ b/kostal/translations/51a2c7d5-084d-4474-a65a-e0447ab9ac45-en_US.ts
@@ -0,0 +1,479 @@
+
+
+
+
+ IntegrationPluginKostal
+
+
+ The network device discovery is not available.
+
+
+
+
+ No IP address given
+
+
+
+
+ Kostal
+
+
+
+ AC energy
+ The name of the ParamType (ThingClass: kostalInverter, EventType: totalEnergyProduced, ID: {5c1546d2-92be-4809-bc56-8bbdaab436d2})
+----------
+The name of the StateType ({5c1546d2-92be-4809-bc56-8bbdaab436d2}) of ThingClass kostalInverter
+
+
+
+
+ AC energy changed
+ The name of the EventType ({5c1546d2-92be-4809-bc56-8bbdaab436d2}) of ThingClass kostalInverter
+
+
+
+
+
+
+
+
+
+ Connected
+ The name of the ParamType (ThingClass: kostalBattery, EventType: connected, ID: {4a5a5a38-b623-4024-b557-410a46ebc495})
+----------
+The name of the StateType ({4a5a5a38-b623-4024-b557-410a46ebc495}) of ThingClass kostalBattery
+----------
+The name of the ParamType (ThingClass: kostalMeter, EventType: connected, ID: {5c510989-d6e1-4b06-b10f-f8b9e52a254c})
+----------
+The name of the StateType ({5c510989-d6e1-4b06-b10f-f8b9e52a254c}) of ThingClass kostalMeter
+----------
+The name of the ParamType (ThingClass: kostalInverter, EventType: connected, ID: {8d64954a-855d-44ea-8bc9-88a71ab47b6b})
+----------
+The name of the StateType ({8d64954a-855d-44ea-8bc9-88a71ab47b6b}) of ThingClass kostalInverter
+
+
+
+
+
+
+ Connected changed
+ The name of the EventType ({4a5a5a38-b623-4024-b557-410a46ebc495}) of ThingClass kostalBattery
+----------
+The name of the EventType ({5c510989-d6e1-4b06-b10f-f8b9e52a254c}) of ThingClass kostalMeter
+----------
+The name of the EventType ({8d64954a-855d-44ea-8bc9-88a71ab47b6b}) of ThingClass kostalInverter
+
+
+
+
+
+ Current power phase A
+ The name of the ParamType (ThingClass: kostalMeter, EventType: currentPowerPhaseA, ID: {2b1250eb-4c22-4025-ba7c-c3e8f27af3dc})
+----------
+The name of the StateType ({2b1250eb-4c22-4025-ba7c-c3e8f27af3dc}) of ThingClass kostalMeter
+
+
+
+
+ Current power phase A changed
+ The name of the EventType ({2b1250eb-4c22-4025-ba7c-c3e8f27af3dc}) of ThingClass kostalMeter
+
+
+
+
+
+ Current power phase B
+ The name of the ParamType (ThingClass: kostalMeter, EventType: currentPowerPhaseB, ID: {0c43d20d-843c-4edd-9955-dafab6caecf6})
+----------
+The name of the StateType ({0c43d20d-843c-4edd-9955-dafab6caecf6}) of ThingClass kostalMeter
+
+
+
+
+ Current power phase B changed
+ The name of the EventType ({0c43d20d-843c-4edd-9955-dafab6caecf6}) of ThingClass kostalMeter
+
+
+
+
+
+ Current power phase C
+ The name of the ParamType (ThingClass: kostalMeter, EventType: currentPowerPhaseC, ID: {a1e46df0-43e5-42f0-846a-5d2f24808a67})
+----------
+The name of the StateType ({a1e46df0-43e5-42f0-846a-5d2f24808a67}) of ThingClass kostalMeter
+
+
+
+
+ Current power phase C changed
+ The name of the EventType ({a1e46df0-43e5-42f0-846a-5d2f24808a67}) of ThingClass kostalMeter
+
+
+
+
+
+ Energy consumend phase A
+ The name of the ParamType (ThingClass: kostalMeter, EventType: energyConsumedPhaseA, ID: {5c4de028-5b97-47c9-a5a4-dd1081b9b59b})
+----------
+The name of the StateType ({5c4de028-5b97-47c9-a5a4-dd1081b9b59b}) of ThingClass kostalMeter
+
+
+
+
+ Energy consumend phase A changed
+ The name of the EventType ({5c4de028-5b97-47c9-a5a4-dd1081b9b59b}) of ThingClass kostalMeter
+
+
+
+
+
+ Energy consumend phase B
+ The name of the ParamType (ThingClass: kostalMeter, EventType: energyConsumedPhaseB, ID: {d9f3ee48-8fa6-463e-bc12-86c9361e01e0})
+----------
+The name of the StateType ({d9f3ee48-8fa6-463e-bc12-86c9361e01e0}) of ThingClass kostalMeter
+
+
+
+
+ Energy consumend phase B changed
+ The name of the EventType ({d9f3ee48-8fa6-463e-bc12-86c9361e01e0}) of ThingClass kostalMeter
+
+
+
+
+
+ Energy consumend phase C
+ The name of the ParamType (ThingClass: kostalMeter, EventType: energyConsumedPhaseC, ID: {ccc38dd9-9e8e-48ce-9076-d3ef934cfbf2})
+----------
+The name of the StateType ({ccc38dd9-9e8e-48ce-9076-d3ef934cfbf2}) of ThingClass kostalMeter
+
+
+
+
+ Energy consumend phase C changed
+ The name of the EventType ({ccc38dd9-9e8e-48ce-9076-d3ef934cfbf2}) of ThingClass kostalMeter
+
+
+
+
+
+ Energy produced phase A
+ The name of the ParamType (ThingClass: kostalMeter, EventType: energyProducedPhaseA, ID: {2185140f-1a73-47da-974a-ebc943613648})
+----------
+The name of the StateType ({2185140f-1a73-47da-974a-ebc943613648}) of ThingClass kostalMeter
+
+
+
+
+ Energy produced phase A changed
+ The name of the EventType ({2185140f-1a73-47da-974a-ebc943613648}) of ThingClass kostalMeter
+
+
+
+
+
+ Energy produced phase B
+ The name of the ParamType (ThingClass: kostalMeter, EventType: energyProducedPhaseB, ID: {580811fc-419a-4be1-802d-c9eaa4765f65})
+----------
+The name of the StateType ({580811fc-419a-4be1-802d-c9eaa4765f65}) of ThingClass kostalMeter
+
+
+
+
+ Energy produced phase B changed
+ The name of the EventType ({580811fc-419a-4be1-802d-c9eaa4765f65}) of ThingClass kostalMeter
+
+
+
+
+
+ Energy produced phase C
+ The name of the ParamType (ThingClass: kostalMeter, EventType: energyProducedPhaseC, ID: {df9f65fd-0cad-447f-b5a9-22daf9f020bf})
+----------
+The name of the StateType ({df9f65fd-0cad-447f-b5a9-22daf9f020bf}) of ThingClass kostalMeter
+
+
+
+
+ Energy produced phase C changed
+ The name of the EventType ({df9f65fd-0cad-447f-b5a9-22daf9f020bf}) of ThingClass kostalMeter
+
+
+
+
+
+
+
+ Frequency
+ The name of the ParamType (ThingClass: kostalMeter, EventType: frequency, ID: {7c86ea72-505b-4924-80ef-3cf3ff31a380})
+----------
+The name of the StateType ({7c86ea72-505b-4924-80ef-3cf3ff31a380}) of ThingClass kostalMeter
+----------
+The name of the ParamType (ThingClass: kostalInverter, EventType: frequency, ID: {9493939e-601b-460a-ab48-91772b4db823})
+----------
+The name of the StateType ({9493939e-601b-460a-ab48-91772b4db823}) of ThingClass kostalInverter
+
+
+
+
+
+ Frequency changed
+ The name of the EventType ({7c86ea72-505b-4924-80ef-3cf3ff31a380}) of ThingClass kostalMeter
+----------
+The name of the EventType ({9493939e-601b-460a-ab48-91772b4db823}) of ThingClass kostalInverter
+
+
+
+
+
+
+ IP address
+ The name of the ParamType (ThingClass: kostalBattery, Type: thing, ID: {7c803cd7-7159-447f-8794-4b35eadeab06})
+----------
+The name of the ParamType (ThingClass: kostalMeter, Type: thing, ID: {61c6a9fe-93c8-41fa-a7bf-113d3425c1cc})
+----------
+The name of the ParamType (ThingClass: kostalInverter, Type: thing, ID: {f1c43b1e-cffe-4d30-bda0-c23ed648dd71})
+
+
+
+
+ KOSTAL Battery
+ The name of the ThingClass ({d6dbdfe8-adbb-47d8-840d-9b787683fc69})
+
+
+
+
+ KOSTAL Inverter
+ The name of the ThingClass ({7dc6db14-6f5a-4ac8-9684-4c6a526bd0de})
+
+
+
+
+ KOSTAL Meter
+ The name of the ThingClass ({61af1e07-6a59-4465-a563-3cbf4a9fcbc3})
+
+
+
+
+ KOSTAL Solar Electric
+ The name of the vendor ({862d1ebf-cb78-4c55-89b2-819fddfd9acd})
+
+
+
+
+ Kostal
+ The name of the plugin Kostal ({51a2c7d5-084d-4474-a65a-e0447ab9ac45})
+
+
+
+
+
+
+ MAC address
+ The name of the ParamType (ThingClass: kostalBattery, Type: thing, ID: {b20845d1-4f09-4d68-b37c-6350bc33c1fa})
+----------
+The name of the ParamType (ThingClass: kostalMeter, Type: thing, ID: {e69acdd3-ba4f-41a9-b89e-89ed108aa850})
+----------
+The name of the ParamType (ThingClass: kostalInverter, Type: thing, ID: {906f6099-d0e1-4297-a2b3-f8ec4482c578})
+
+
+
+
+
+
+
+ Phase A current
+ The name of the ParamType (ThingClass: kostalMeter, EventType: currentPhaseA, ID: {1681ee7d-5d22-4794-8cfe-febaa1ddf29f})
+----------
+The name of the StateType ({1681ee7d-5d22-4794-8cfe-febaa1ddf29f}) of ThingClass kostalMeter
+----------
+The name of the ParamType (ThingClass: kostalInverter, EventType: phaseACurrent, ID: {567bb3c2-4a0c-4194-a86e-b8dc29815092})
+----------
+The name of the StateType ({567bb3c2-4a0c-4194-a86e-b8dc29815092}) of ThingClass kostalInverter
+
+
+
+
+
+ Phase A current changed
+ The name of the EventType ({1681ee7d-5d22-4794-8cfe-febaa1ddf29f}) of ThingClass kostalMeter
+----------
+The name of the EventType ({567bb3c2-4a0c-4194-a86e-b8dc29815092}) of ThingClass kostalInverter
+
+
+
+
+
+
+
+ Phase B current
+ The name of the ParamType (ThingClass: kostalMeter, EventType: currentPhaseB, ID: {b54e7182-6cb2-4184-96c5-2324e8139b6e})
+----------
+The name of the StateType ({b54e7182-6cb2-4184-96c5-2324e8139b6e}) of ThingClass kostalMeter
+----------
+The name of the ParamType (ThingClass: kostalInverter, EventType: phaseBCurrent, ID: {84e9282a-b72b-4dbf-9e4b-99083e5539a5})
+----------
+The name of the StateType ({84e9282a-b72b-4dbf-9e4b-99083e5539a5}) of ThingClass kostalInverter
+
+
+
+
+
+ Phase B current changed
+ The name of the EventType ({b54e7182-6cb2-4184-96c5-2324e8139b6e}) of ThingClass kostalMeter
+----------
+The name of the EventType ({84e9282a-b72b-4dbf-9e4b-99083e5539a5}) of ThingClass kostalInverter
+
+
+
+
+
+
+
+ Phase C current
+ The name of the ParamType (ThingClass: kostalMeter, EventType: currentPhaseC, ID: {546eeb76-b17f-4c51-a9fa-01e7403913cd})
+----------
+The name of the StateType ({546eeb76-b17f-4c51-a9fa-01e7403913cd}) of ThingClass kostalMeter
+----------
+The name of the ParamType (ThingClass: kostalInverter, EventType: phaseCCurrent, ID: {4f7c308f-2cb2-4327-8a68-77222f920e61})
+----------
+The name of the StateType ({4f7c308f-2cb2-4327-8a68-77222f920e61}) of ThingClass kostalInverter
+
+
+
+
+
+ Phase C current changed
+ The name of the EventType ({546eeb76-b17f-4c51-a9fa-01e7403913cd}) of ThingClass kostalMeter
+----------
+The name of the EventType ({4f7c308f-2cb2-4327-8a68-77222f920e61}) of ThingClass kostalInverter
+
+
+
+
+ Port
+ The name of the ParamType (ThingClass: kostalInverter, Type: thing, ID: {9d2175af-afb9-4b31-b3dc-e53a369bad9e})
+
+
+
+
+ Slave ID
+ The name of the ParamType (ThingClass: kostalInverter, Type: thing, ID: {b3e04cb0-8f9a-4c9f-9c67-5c08da0273e3})
+
+
+
+
+
+
+
+ Total AC current
+ The name of the ParamType (ThingClass: kostalMeter, EventType: totalCurrent, ID: {bf0195a3-3ff4-4828-b64d-1707b458679e})
+----------
+The name of the StateType ({bf0195a3-3ff4-4828-b64d-1707b458679e}) of ThingClass kostalMeter
+----------
+The name of the ParamType (ThingClass: kostalInverter, EventType: totalCurrent, ID: {d11b8e29-44e9-4b5c-bb4e-aa2ca87db5d3})
+----------
+The name of the StateType ({d11b8e29-44e9-4b5c-bb4e-aa2ca87db5d3}) of ThingClass kostalInverter
+
+
+
+
+
+ Total AC current changed
+ The name of the EventType ({bf0195a3-3ff4-4828-b64d-1707b458679e}) of ThingClass kostalMeter
+----------
+The name of the EventType ({d11b8e29-44e9-4b5c-bb4e-aa2ca87db5d3}) of ThingClass kostalInverter
+
+
+
+
+
+ Total real energy exported
+ The name of the ParamType (ThingClass: kostalMeter, EventType: totalEnergyProduced, ID: {d551a8b0-734a-41e9-a1a2-e58de13d0191})
+----------
+The name of the StateType ({d551a8b0-734a-41e9-a1a2-e58de13d0191}) of ThingClass kostalMeter
+
+
+
+
+ Total real energy exported changed
+ The name of the EventType ({d551a8b0-734a-41e9-a1a2-e58de13d0191}) of ThingClass kostalMeter
+
+
+
+
+
+ Total real energy imported
+ The name of the ParamType (ThingClass: kostalMeter, EventType: totalEnergyConsumed, ID: {5f88e230-906b-4185-9a4d-db96d447e8ea})
+----------
+The name of the StateType ({5f88e230-906b-4185-9a4d-db96d447e8ea}) of ThingClass kostalMeter
+
+
+
+
+ Total real energy imported changed
+ The name of the EventType ({5f88e230-906b-4185-9a4d-db96d447e8ea}) of ThingClass kostalMeter
+
+
+
+
+
+ Total real power
+ The name of the ParamType (ThingClass: kostalMeter, EventType: currentPower, ID: {992b0da8-e6bd-47ab-af60-be8802fc7ecf})
+----------
+The name of the StateType ({992b0da8-e6bd-47ab-af60-be8802fc7ecf}) of ThingClass kostalMeter
+
+
+
+
+ Total real power changed
+ The name of the EventType ({992b0da8-e6bd-47ab-af60-be8802fc7ecf}) of ThingClass kostalMeter
+
+
+
+
+
+ Voltage phase A
+ The name of the ParamType (ThingClass: kostalMeter, EventType: voltagePhaseA, ID: {10a34381-cfb1-4aeb-a25f-e6b0d8b96510})
+----------
+The name of the StateType ({10a34381-cfb1-4aeb-a25f-e6b0d8b96510}) of ThingClass kostalMeter
+
+
+
+
+ Voltage phase A changed
+ The name of the EventType ({10a34381-cfb1-4aeb-a25f-e6b0d8b96510}) of ThingClass kostalMeter
+
+
+
+
+
+ Voltage phase B
+ The name of the ParamType (ThingClass: kostalMeter, EventType: voltagePhaseB, ID: {b0be1395-c7d2-449e-9632-5b6bf3298797})
+----------
+The name of the StateType ({b0be1395-c7d2-449e-9632-5b6bf3298797}) of ThingClass kostalMeter
+
+
+
+
+ Voltage phase B changed
+ The name of the EventType ({b0be1395-c7d2-449e-9632-5b6bf3298797}) of ThingClass kostalMeter
+
+
+
+
+
+ Voltage phase C
+ The name of the ParamType (ThingClass: kostalMeter, EventType: voltagePhaseC, ID: {b422d7a9-4c43-4827-be39-e4694f2cab64})
+----------
+The name of the StateType ({b422d7a9-4c43-4827-be39-e4694f2cab64}) of ThingClass kostalMeter
+
+
+
+
+ Voltage phase C changed
+ The name of the EventType ({b422d7a9-4c43-4827-be39-e4694f2cab64}) of ThingClass kostalMeter
+
+
+
+
diff --git a/nymea-plugins-modbus.pro b/nymea-plugins-modbus.pro
index 63ea758..fa6b837 100644
--- a/nymea-plugins-modbus.pro
+++ b/nymea-plugins-modbus.pro
@@ -11,6 +11,7 @@ PLUGIN_DIRS = \
huawei \
idm \
inepro \
+ kostal \
modbuscommander \
mtec \
mypv \