[kostalinverter] Add Second Generation (Piko10-20) type inverters (#8574)

* Binding redesigned 20200923 by Örjan Backsell

Signed-off-by: basse04 orjan.backsell@gmail.com
Also-by: Christian Schneider <>
Also-by: René Stakemeier <>
Also-by: Christoph Weitkamp <>


This is the upgraded version of Kostal Inverter extended with
functionality for the Inverter type of Second generation PIKO 10-20
[kostalinverter], regarded OH3.
[WIP]

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20200923 by Örjan Backsell

Signed-off-by: basse04 orjan.backsell@gmail.com
Also-by: Christian Schneider <>
Also-by: René Stakemeier <>
Also-by: Christoph Weitkamp <>


This is the upgraded version of Kostal Inverter extended with
functionality for the Inverter type of Second generation PIKO 10-20
[kostalinverter] regarded oH3
[WIP]

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20200923 by Örjan Backsell

Signed-off-by: basse04 orjan.backsell@gmail.com
Also-by: Christian Schneider <>
Also-by: René Stakemeier <>
Also-by: Christoph Weitkamp <>


This is the upgraded version of Kostal Inverter extended with
functionality for the Inverter type of Second generation PIKO 10-20
[kostalinverter] regarded oH3
[WIP]

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20200923 by Örjan Backsell

Signed-off-by: basse04 orjan.backsell@gmail.com
Also-by: Christian Schneider <>
Also-by: René Stakemeier <>
Also-by: Christoph Weitkamp <>


This is the upgraded version of Kostal Inverter extended with
functionality for the Inverter type of Second generation PIKO 10-20
[kostalinverter] regarded oH3
[WIP]

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20200924 by Örjan Backsell

Signed-off-by: basse04 orjan.backsell@gmail.com
Also-by: Christian Schneider <>
Also-by: René Stakemeier <>
Also-by: Christoph Weitkamp <>


This is the upgraded version of Kostal Inverter extended with
functionality for the Inverter type of Second generation PIKO 10-20
[kostalinverter] regarded oH3
[WIP]

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20200924 by Örjan Backsell

Signed-off-by: basse04 orjan.backsell@gmail.com
Also-by: Christian Schneider <>
Also-by: René Stakemeier <>
Also-by: Christoph Weitkamp <>

Changes made in
org.openhab.binding.internal.kostal.inverter.secondgeneration.SecondGenerationHandler.java
found by Travis tests.

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20201007 by Örjan Backsell

Signed-off-by: basse04 orjan.backsell@gmail.com
Also-by: Christian Schneider <>
Also-by: René Stakemeier <>
Also-by: Christoph Weitkamp <>

Done changes in:
Channels.xml
PIKO1020.xml
README.md
SecondGeneration.xml
SecondGenerationChannelConfiguration.java

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20201008 by Örjan Backsell

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20201012 by Örjan Backsell, regarded to @fwolter
requested changes

Signed-off-by: basse04 orjan.backsell@gmail.com
Also-by: Christian Schneider <>
Also-by: René Stakemeier <>
Also-by: Christoph Weitkamp <>
Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20201028 by Örjan Backsell, regarded to @cpmeister
requested changes.

Signed-off-by: basse04 orjan.backsell@gmail.com
Also-by: Christian Schneider <>
Also-by: René Stakemeier <>
Also-by: Christoph Weitkamp <>
Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20201105 by Örjan Backsell

Signed-off-by: basse04 orjan.backsell@gmail.com
Also-by: Christian Schneider <>
Also-by: René Stakemeier <>
Also-by: Christoph Weitkamp <>
Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20200923 by Örjan Backsell

'
Signed-off-by: basse04 orjan.backsell@gmail.com
Also-by: Christian Schneider <>
Also-by: René Stakemeier <>
Also-by: Christoph Weitkamp <>
'
Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20201111 by Örjan Backsell

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20201117 by Örjan Backsell

'
Signed-off-by: basse04 orjan.backsell@gmail.com
Also-by: Christian Schneider <>
Also-by: René Stakemeier <>
Also-by: Christoph Weitkamp <>


This is the upgraded version of Kostal Inverter extended with
functionality for the Inverter type of Second generation PIKO 10-20
[kostalinverter]
[WIP]
'

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20201119 by Örjan Backsell

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20201125 by Örjan Backsell

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20201130 by Örjan Backsell

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20201130, 1630 by Örjan Backsell

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20201202 by Örjan Backsell

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20201204 by Örjan Backsell

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Redesigned 20201204 by Örjan Backsell

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20201010 by Örjan Backsell

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20210112 by Örjan Backsell

'
Signed-off-by: basse04 orjan.backsell@gmail.com
Also-by: Christian Schneider <>
Also-by: René Stakemeier <>
Also-by: Christoph Weitkamp <>

This is the upgraded version of Kostal Inverter extended with
functionality for the Inverter type of Second generation PIKO 10-20
[kostalinverter]
'

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20210114 by Örjan Backsell

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20210119 by Örjan Backsell

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding (KostalInverterFactory.java)redesigned 20210119 by Örjan
Backsell

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20210125 by Örjan Backsell

* Binding redesigned 20200923 by Örjan Backsell

(KostalInverterFactory.java)

Signed-off-by: basse04 <orjan.backsell@gmail.com>

* Binding redesigned 20210125 by Örjan Backsell

Signed-off-by: basse04 <orjan.backsell@gmail.com>
This commit is contained in:
basse04
2021-02-04 23:17:04 +01:00
committed by GitHub
parent 6878384df9
commit 9498590edb
13 changed files with 1693 additions and 4 deletions

View File

@@ -21,6 +21,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.binding.kostalinverter.internal.firstgeneration.WebscrapeHandler;
import org.openhab.binding.kostalinverter.internal.secondgeneration.SecondGenerationHandler;
import org.openhab.binding.kostalinverter.internal.thirdgeneration.ThirdGenerationHandler;
import org.openhab.binding.kostalinverter.internal.thirdgeneration.ThirdGenerationInverterTypes;
import org.openhab.core.io.net.http.HttpClientFactory;
@@ -36,6 +37,7 @@ import org.osgi.service.component.annotations.Reference;
/**
* @author Christian Schneider - Initial contribution (as WebscrapeHandlerFactory.java)
* @author René Stakemeier - extension for the third generation of KOSTAL inverters
* @author Örjan Backsell - extension for the second generation of KOSTAL inverters
*/
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.kostalinverter")
@NonNullByDefault
@@ -72,6 +74,8 @@ public class KostalInverterFactory extends BaseThingHandlerFactory {
public static final ThingTypeUID FIRST_GENERATION_INVERTER = new ThingTypeUID("kostalinverter", "kostalinverter");
public static final ThingTypeUID SECOND_GENERATION_INVERTER = new ThingTypeUID("kostalinverter", "piko1020");
private final HttpClient httpClient;
@Activate
@@ -81,7 +85,7 @@ public class KostalInverterFactory extends BaseThingHandlerFactory {
@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return thingTypeUID.equals(FIRST_GENERATION_INVERTER)
return thingTypeUID.equals(FIRST_GENERATION_INVERTER) || thingTypeUID.equals(SECOND_GENERATION_INVERTER)
|| SUPPORTED_THIRD_GENERATION_THING_TYPES_UIDS.keySet().contains(thingTypeUID);
}
@@ -91,6 +95,10 @@ public class KostalInverterFactory extends BaseThingHandlerFactory {
if (FIRST_GENERATION_INVERTER.equals(thing.getThingTypeUID())) {
return new WebscrapeHandler(thing);
}
// second generation
if (SECOND_GENERATION_INVERTER.equals(thing.getThingTypeUID())) {
return new SecondGenerationHandler(thing, httpClient);
}
// third generation
ThirdGenerationInverterTypes inverterType = SUPPORTED_THIRD_GENERATION_THING_TYPES_UIDS
.get(thing.getThingTypeUID());

View File

@@ -0,0 +1,100 @@
/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.kostalinverter.internal.secondgeneration;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.ThingTypeUID;
/**
* The {@link SecondGenerationBindingConstants} class defines channel constants, which are
* used in the second generation part of the binding.
*
* @author Örjan Backsell - Initial contribution Piko1020, Piko New Generation
*/
@NonNullByDefault
public class SecondGenerationBindingConstants {
private static final String BINDING_ID = "kostalinverter";
// List of all Thing Type UIDs
public static final ThingTypeUID SECOND_GENERATION_INVERTER = new ThingTypeUID(BINDING_ID, "piko1020");
// List of all Channel ids
public static final String CHANNEL_GRIDOUTPUTPOWER = "gridOutputPower";
public static final String CHANNEL_YIELD_DAY_SECOND_GEN = "yieldDaySecondGen";
public static final String CHANNEL_YIELD_TOTAL_SECOND_GEN = "yieldTotalSecondGen";
public static final String CHANNEL_OPERATING_STATUS = "operatingStatus";
public static final String CHANNEL_GRIDVOLTAGEL1 = "gridVoltageL1";
public static final String CHANNEL_GRIDCURRENTL1 = "gridCurrentL1";
public static final String CHANNEL_GRIDPOWERL1 = "gridPowerL1";
public static final String CHANNEL_GRIDVOLTAGEL2 = "gridVoltageL2";
public static final String CHANNEL_GRIDCURRENTL2 = "gridCurrentL2";
public static final String CHANNEL_GRIDPOWERL2 = "gridPowerL2";
public static final String CHANNEL_GRIDVOLTAGEL3 = "gridVoltageL3";
public static final String CHANNEL_GRIDCURRENTL3 = "gridCurrentL3";
public static final String CHANNEL_GRIDPOWERL3 = "gridPowerL3";
public static final String CHANNEL_DCPOWERPV = "dcPowerPV";
public static final String CHANNEL_DC1VOLTAGE = "dc1Voltage";
public static final String CHANNEL_DC1CURRENT = "dc1Current";
public static final String CHANNEL_DC1POWER = "dc1Power";
public static final String CHANNEL_DC2VOLTAGE = "dc2Voltage";
public static final String CHANNEL_DC2CURRENT = "dc2Current";
public static final String CHANNEL_DC2POWER = "dc2Power";
public static final String CHANNEL_DC3VOLTAGE = "dc3Voltage";
public static final String CHANNEL_DC3CURRENT = "dc3Current";
public static final String CHANNEL_DC3POWER = "dc3Power";
public static final String CHANNEL_AKTHOMECONSUMTIONSOLAR = "aktHomeConsumptionSolar";
public static final String CHANNEL_AKTHOMECONSUMPTIONBAT = "aktHomeConsumptionBat";
public static final String CHANNEL_AKTHOMECONSUMPTIONGRID = "aktHomeConsumptionGrid";
public static final String CHANNEL_PHASESELHOMECONSUMPL1 = "phaseSelHomeConsumpL1";
public static final String CHANNEL_PHASESELHOMECONSUMPL2 = "phaseSelHomeConsumpL2";
public static final String CHANNEL_PHASESELHOMECONSUMPL3 = "phaseSelHomeConsumpL3";
public static final String CHANNEL_GRIDFREQ = "gridFreq";
public static final String CHANNEL_GRIDCOSPHI = "gridCosPhi";
public static final String CHANNEL_HOMECONSUMPTION_DAY = "homeConsumptionDay";
public static final String CHANNEL_OWNCONSUMPTION_DAY = "ownConsumptionDay";
public static final String CHANNEL_OWNCONSRATE_DAY = "ownConsRateDay";
public static final String CHANNEL_AUTONOMYDEGREE_DAY = "autonomyDegreeDay";
public static final String CHANNEL_HOMECONSUMPTION_TOTAL = "homeConsumptionTotal";
public static final String CHANNEL_OWNCONSUMPTION_TOTAL = "ownConsumptionTotal";
public static final String CHANNEL_OPERATINGTIME_TOTAL = "operatingTimeTotal";
public static final String CHANNEL_CURRENT = "current";
public static final String CHANNEL_CURRENTDIR = "currentDir";
public static final String CHANNEL_CHARGECYCLES = "chargeCycles";
public static final String CHANNEL_BATTERYTEMPERATURE = "batteryTemperature";
public static final String CHANNEL_LOGINTERVAL = "loginterval";
public static final String CHANNEL_S0INPULSECNT = "s0InPulseCnt";
public static final String CHANNEL_OWNCONSRATE_TOTAL = "ownConsRateTotal";
public static final String CHANNEL_AUTONOMYDEGREE_TOTAL = "autonomyDegreeTotal";
public static final String CHANNEL_BATTERYVOLTAGE = "batteryVoltage";
public static final String CHANNEL_BATSTATEOFCHARGE = "batStateOfCharge";
public static final String CHANNEL_SELFCONSUMPTION = "selfConsumption";
public static final String CHANNEL_BATTERYUSAGECONSUMPTION = "batteryUsageConsumption";
public static final String CHANNEL_SMARTBATTERYCONTROL = "smartBatteryControl";
public static final String CHANNEL_MAXDEPTHOFDISCHARGE = "maxDepthOfDischarge";
public static final String CHANNEL_SHADOWMANAGEMENT = "shadowManagement";
public static final String CHANNEL_EXTERNALMODULECONTROL = "externalModuleControl";
public static final String CHANNEL_BATTERYUSAGECONSUMPTIONSET = "batteryUsageConsumptionSet";
public static final String CHANNEL_BATTERYUSAGESTRATEGYSET = "batteryUsageStrategySet";
public static final String CHANNEL_SMARTBATTERYCONTROLSET = "smartBatteryControlSet";
public static final String CHANNEL_BATTERYCHARGETIMEFROMSET = "batteryChargeTimeFromSet";
public static final String CHANNEL_BATTERYCHARGETIMETOSET = "batteryChargeTimeToSet";
public static final String CHANNEL_MAXDEPTHOFDISCHARGESET = "maxDepthOfDischargeSet";
public static final String CHANNEL_SHADOWMANAGEMENTSET = "shadowManagementSet";
public static final String CHANNEL_EXTERNALMODULECONTROLSET = "externalModuleControlSet";
}

View File

@@ -0,0 +1,185 @@
/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.kostalinverter.internal.secondgeneration;
import java.util.ArrayList;
import java.util.List;
import javax.measure.Unit;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.library.unit.SIUnits;
import org.openhab.core.library.unit.Units;
/**
* The {@link SecondGenerationChannelConfiguration} class defines methods, which set up channel configuration,
* used in the second generation part of the binding.
*
*
* @author Christian Schneider - Initial contribution
* @author Christoph Weitkamp - Incorporated new QuantityType (Units of Measurement)
* @author Örjan Backsell - Added channels for (Piko1020, Piko New Generation)
*/
@NonNullByDefault
public class SecondGenerationChannelConfiguration {
public String id;
public String tag;
public int num;
public Unit<?> unit;
public String dxsEntries;
public SecondGenerationChannelConfiguration(String id, String tag, int num, Unit<?> unit, String dxsEntries) {
this.id = id;
this.tag = tag;
this.num = num;
this.unit = unit;
this.dxsEntries = dxsEntries;
}
public static List<SecondGenerationChannelConfiguration> getChannelConfiguration() {
final List<SecondGenerationChannelConfiguration> channelConfiguration = new ArrayList<>();
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_GRIDOUTPUTPOWER, "td", 4, Units.WATT, "67109120"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_YIELD_DAY_SECOND_GEN, "td", 7, Units.WATT_HOUR, "251658754"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_YIELD_TOTAL_SECOND_GEN, "td", 10, Units.KILOWATT_HOUR,
"251658753"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_OPERATING_STATUS, "td", 13, Units.ONE, "16780032"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_GRIDVOLTAGEL1, "td", 16, Units.VOLT, "67109378"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_GRIDCURRENTL1, "td", 19, Units.AMPERE, "67109377"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_GRIDPOWERL1, "td", 22, Units.WATT, "67109379"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_GRIDVOLTAGEL2, "td", 25, Units.VOLT, "67109634"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_GRIDCURRENTL2, "td", 28, Units.AMPERE, "67109633"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_GRIDPOWERL2, "td", 31, Units.WATT, "67109635"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_GRIDVOLTAGEL3, "td", 34, Units.VOLT, "67109890"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_GRIDCURRENTL3, "td", 37, Units.AMPERE, "67109889"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_GRIDPOWERL3, "td", 40, Units.WATT, "67109891"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_DCPOWERPV, "td", 43, Units.WATT, "33556736"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_DC1VOLTAGE, "td", 46, Units.VOLT, "33555202"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_DC1CURRENT, "td", 49, Units.AMPERE, "33555201"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_DC1POWER, "td", 52, Units.WATT, "33555203"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_DC2VOLTAGE, "td", 55, Units.VOLT, "33555458"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_DC2CURRENT, "td", 58, Units.AMPERE, "33555457"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_DC2POWER, "td", 61, Units.WATT, "33555459"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_DC3VOLTAGE, "td", 64, Units.VOLT, "33555714"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_DC3CURRENT, "td", 67, Units.AMPERE, "33555713"));
channelConfiguration.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_DC3POWER, "td", 70, Units.WATT, "33555715"));
return channelConfiguration;
}
public static List<SecondGenerationChannelConfiguration> getChannelConfigurationExt() {
final List<SecondGenerationChannelConfiguration> channelConfigurationExt = new ArrayList<>();
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_AKTHOMECONSUMTIONSOLAR, "td", 73, Units.WATT, "83886336"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_AKTHOMECONSUMPTIONBAT, "td", 76, Units.WATT, "83886592"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_AKTHOMECONSUMPTIONGRID, "td", 79, Units.WATT, "83886848"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_PHASESELHOMECONSUMPL1, "td", 82, Units.WATT, "83887106"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_PHASESELHOMECONSUMPL2, "td", 85, Units.WATT, "83887362"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_PHASESELHOMECONSUMPL3, "td", 88, Units.WATT, "83887618"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_GRIDFREQ, "td", 91, Units.HERTZ, "67110400"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_GRIDCOSPHI, "td", 94, Units.DEGREE_ANGLE, "67110656"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_HOMECONSUMPTION_DAY, "td", 97, Units.WATT_HOUR, "251659010"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_OWNCONSUMPTION_DAY, "td", 100, Units.WATT_HOUR, "251659266"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_OWNCONSRATE_DAY, "td", 103, Units.PERCENT, "251659278"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_AUTONOMYDEGREE_DAY, "td", 106, Units.PERCENT, "251659279"));
channelConfigurationExt.add(
new SecondGenerationChannelConfiguration(SecondGenerationBindingConstants.CHANNEL_HOMECONSUMPTION_TOTAL,
"td", 109, Units.WATT_HOUR, "251659009"));
channelConfigurationExt.add(
new SecondGenerationChannelConfiguration(SecondGenerationBindingConstants.CHANNEL_OWNCONSUMPTION_TOTAL,
"td", 112, Units.WATT_HOUR, "251659265"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_OPERATINGTIME_TOTAL, "td", 115, Units.HOUR, "251658496"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_CURRENT, "td", 118, Units.AMPERE, "33556238"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_CURRENTDIR, "td", 121, Units.ONE, "33556230"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_CHARGECYCLES, "td", 124, Units.ONE, "33556228"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_BATTERYTEMPERATURE, "td", 127, SIUnits.CELSIUS, "33556227"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_LOGINTERVAL, "td", 130, Units.MINUTE, "150995968"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_S0INPULSECNT, "td", 133, Units.ONE, "184549632"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_OWNCONSRATE_TOTAL, "td", 136, Units.PERCENT, "251659280"));
channelConfigurationExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_AUTONOMYDEGREE_TOTAL, "td", 139, Units.PERCENT, "251659281"));
return channelConfigurationExt;
}
public static List<SecondGenerationChannelConfiguration> getChannelConfigurationExtExt() {
final List<SecondGenerationChannelConfiguration> channelConfigurationExtExt = new ArrayList<>();
channelConfigurationExtExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_BATTERYVOLTAGE, "td", 142, Units.VOLT, "33556226"));
channelConfigurationExtExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_BATSTATEOFCHARGE, "td", 145, Units.PERCENT, "33556229"));
channelConfigurationExtExt.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_SELFCONSUMPTION, "td", 148, Units.WATT, "83888128"));
return channelConfigurationExtExt;
}
public static List<SecondGenerationChannelConfiguration> getChannelConfigurationConfigurable() {
final List<SecondGenerationChannelConfiguration> channelConfigurationConfigurable = new ArrayList<>();
channelConfigurationConfigurable.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_BATTERYUSAGECONSUMPTION, "td", 151, Units.WATT, "33556249"));
channelConfigurationConfigurable.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_SMARTBATTERYCONTROL, "td", 154, Units.ONE, "33556484"));
channelConfigurationConfigurable.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_MAXDEPTHOFDISCHARGE, "td", 157, Units.ONE, "33556247"));
channelConfigurationConfigurable.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_SHADOWMANAGEMENT, "td", 160, Units.ONE, "33556483"));
channelConfigurationConfigurable.add(new SecondGenerationChannelConfiguration(
SecondGenerationBindingConstants.CHANNEL_EXTERNALMODULECONTROL, "td", 163, Units.ONE, "33556482"));
return channelConfigurationConfigurable;
}
}

View File

@@ -0,0 +1,161 @@
/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.kostalinverter.internal.secondgeneration;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.util.StringContentProvider;
import org.eclipse.jetty.http.HttpHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.JsonArray;
import com.google.gson.JsonIOException;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
* The {@link SecondGenerationConfigurationHandler} is responsible for configuration changes,
* regarded to second generation part of the binding.
*
* @author Örjan Backsell - Initial contribution Piko1020, Piko New Generation
*/
@NonNullByDefault
public class SecondGenerationConfigurationHandler {
public static void executeConfigurationChanges(HttpClient httpClient, String url, String username, String password,
String dxsId, String value)
throws InterruptedException, ExecutionException, TimeoutException, NoSuchAlgorithmException {
String urlLogin = url + "/api/login.json?";
String salt = "";
String sessionId = "";
Logger logger = LoggerFactory.getLogger(SecondGenerationConfigurationHandler.class);
String getAuthenticateResponse = httpClient.GET(urlLogin).getContentAsString();
try {
JsonObject getAuthenticateResponseJsonObject = (JsonObject) new JsonParser()
.parse(transformJsonResponse(getAuthenticateResponse));
sessionId = extractSessionId(getAuthenticateResponseJsonObject);
JsonObject authenticateJsonObject = new JsonParser().parse(getAuthenticateResponse.toString())
.getAsJsonObject();
salt = authenticateJsonObject.get("salt").getAsString();
String saltedPassword = new StringBuilder(password).append(salt).toString();
MessageDigest mDigest = MessageDigest.getInstance("SHA1");
byte[] mDigestedPassword = mDigest.digest(saltedPassword.getBytes(StandardCharsets.UTF_8));
StringBuilder loginPostStringBuilder = new StringBuilder();
for (int i = 0; i < mDigestedPassword.length; i++) {
loginPostStringBuilder.append(Integer.toString((mDigestedPassword[i] & 0xff) + 0x100, 16).substring(1));
}
String saltedmDigestedPwd = Base64.getEncoder().encodeToString(mDigest.digest(saltedPassword.getBytes()));
String loginPostJsonData = "{\"mode\":1,\"userId\":\"" + username + "\",\"pwh\":\"" + saltedmDigestedPwd
+ "\"}";
Request loginPostJsonResponse = httpClient.POST(urlLogin + "?sessionId=" + sessionId);
loginPostJsonResponse.header(HttpHeader.CONTENT_TYPE, "application/json");
loginPostJsonResponse.content(new StringContentProvider(loginPostJsonData));
ContentResponse loginPostJsonDataContentResponse = loginPostJsonResponse.send();
String loginPostResponse = new String(loginPostJsonDataContentResponse.getContent(),
StandardCharsets.UTF_8);
JsonObject loginPostJsonObject = (JsonObject) new JsonParser()
.parse(transformJsonResponse(loginPostResponse));
sessionId = extractSessionId(loginPostJsonObject);
// Part for sending data to Inverter
String postJsonData = "{\"dxsEntries\":[{\"dxsId\":" + dxsId + ",\"value\":" + value + "}]}";
Request postJsonDataRequest = httpClient.POST(url + "/api/dxs.json?sessionId=" + sessionId);
postJsonDataRequest.header(HttpHeader.CONTENT_TYPE, "application/json");
postJsonDataRequest.content(new StringContentProvider(postJsonData));
postJsonDataRequest.send();
} catch (JsonIOException getAuthenticateResponseException) {
logger.debug("Could not read the response: {}", getAuthenticateResponseException.getMessage());
}
}
static String transformJsonResponse(String jsonResponse) {
// Method transformJsonResponse converts response,due to missing [] in ContentResponse
// postJsonDataContentResponse.
int sessionStartPosition = jsonResponse.indexOf("session");
int statusStartPosition = jsonResponse.indexOf("status");
StringBuilder transformStringBuilder = new StringBuilder();
transformStringBuilder.append(jsonResponse);
transformStringBuilder.insert(sessionStartPosition + 9, '[');
int roleIdStartPosition = jsonResponse.indexOf("roleId");
transformStringBuilder.insert(roleIdStartPosition + 11, ']');
transformStringBuilder.insert(statusStartPosition + 10, '[');
int codeStartPosition = jsonResponse.indexOf("code");
transformStringBuilder.insert(codeStartPosition + 11, ']');
String transformJsonObject = transformStringBuilder.toString();
return transformJsonObject;
}
// Method extractSessionId extracts sessionId from JsonObject
static String extractSessionId(JsonObject extractJsonObjectSessionId) {
Logger sessionIdLogger = LoggerFactory.getLogger(SecondGenerationConfigurationHandler.class);
String extractSessionId = "";
JsonArray extractJsonArraySessionId = extractJsonObjectSessionId.getAsJsonArray("session");
int size = extractJsonArraySessionId.size();
if (size > 0) {
extractSessionId = extractJsonArraySessionId.get(size - 1).getAsJsonObject().get("sessionId").getAsString();
}
if (extractSessionId == "0") {
sessionIdLogger.debug(" Login Post Json Reponse not OK! , inverter answered with sessionId like: {}",
extractSessionId);
}
return extractSessionId;
}
// Method extractCode extracts code from JsonObject
static String extractCode(JsonObject extractJsonObjectCode) {
Logger codeLogger = LoggerFactory.getLogger(SecondGenerationConfigurationHandler.class);
String extractCode = "";
JsonArray extractJsonArrayCode = extractJsonObjectCode.getAsJsonArray("status");
int size = extractJsonArrayCode.size();
if (size > 0) {
extractCode = extractJsonArrayCode.get(size - 1).getAsJsonObject().get("code").getAsString();
}
if (extractCode != "0") {
codeLogger.debug(" Login Post Json Reponse not OK! , inverter answered with status code like: {}",
extractCode);
}
return extractCode;
}
}

View File

@@ -0,0 +1,35 @@
/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.kostalinverter.internal.secondgeneration;
import org.eclipse.jdt.annotation.NonNullByDefault;
/**
* The {@link SecondGenerationDxsEntries} class defines methods, which are
* used in the second generation part of the binding.
*
* @author Örjan Backsell - Initial contribution Piko1020, Piko New Generation
*/
@NonNullByDefault
public class SecondGenerationDxsEntries {
private String dxsId = "";
private String value = "";
public String getId() {
return dxsId;
}
public String getName() {
return value;
}
}

View File

@@ -0,0 +1,26 @@
/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.kostalinverter.internal.secondgeneration;
import java.util.List;
/**
* The {@link SecondGenerationDxsEntriesContainer} class defines an Container, which is
* used in the second generation part of the binding.
*
* @author Örjan Backsell - Initial contribution Piko1020, Piko New Generation
*/
public class SecondGenerationDxsEntriesContainerDTO {
public List<SecondGenerationDxsEntries> dxsEntries;
}

View File

@@ -0,0 +1,401 @@
/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.kostalinverter.internal.secondgeneration;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import javax.measure.Unit;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.types.StringType;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingStatusDetail;
import org.openhab.core.thing.binding.BaseThingHandler;
import org.openhab.core.types.Command;
import org.openhab.core.types.State;
import org.openhab.core.types.UnDefType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
/**
* The {@link SecondGenerationHandler} is responsible for handling commands, which are
* sent to one of the channels, and initiation and refreshing regarded to second generation part of the binding.
*
*
* @author Christian Schneider - Initial contribution
* @author Christoph Weitkamp - Incorporated new QuantityType (Units of Measurement)
* @author Örjan Backsell - Redesigned regarding Piko1020, Piko New Generation
*/
@NonNullByDefault
public class SecondGenerationHandler extends BaseThingHandler {
private final Logger logger = LoggerFactory.getLogger(SecondGenerationHandler.class);
private @Nullable ScheduledFuture<?> secondGenerationPoller;
private final HttpClient httpClient;
private List<SecondGenerationChannelConfiguration> channelConfigs = new ArrayList<>();
private List<SecondGenerationChannelConfiguration> channelConfigsExt = new ArrayList<>();
private List<SecondGenerationChannelConfiguration> channelConfigsExtExt = new ArrayList<>();
private List<SecondGenerationChannelConfiguration> channelConfigsConfigurable = new ArrayList<>();
private List<SecondGenerationChannelConfiguration> channelConfigsAll = new ArrayList<>();
private List<String> channelPostsTemp = new ArrayList<>();
private List<String> channelPostsTempExt = new ArrayList<>();
private List<String> channelPostsTempExtExt = new ArrayList<>();
private List<String> channelPostsTempAll = new ArrayList<>();
private SecondGenerationInverterConfig inverterConfig = new SecondGenerationInverterConfig();
private Gson gson = new GsonBuilder().setPrettyPrinting().create();
public SecondGenerationHandler(Thing thing, HttpClient httpClient) {
super(thing);
this.httpClient = httpClient;
}
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
String url = inverterConfig.url;
String username = inverterConfig.username;
String password = inverterConfig.password;
String valueConfiguration = "";
String dxsEntriesConf = "";
if (inverterConfig.hasBattery) {
switch (channelUID.getId()) {
case SecondGenerationBindingConstants.CHANNEL_BATTERYUSAGECONSUMPTIONSET:
valueConfiguration = command.toString();
dxsEntriesConf = "33556249";
preSetExecuteConfigurationChanges(httpClient, url, username, password, dxsEntriesConf,
valueConfiguration);
break;
case SecondGenerationBindingConstants.CHANNEL_BATTERYUSAGESTRATEGYSET:
valueConfiguration = command.toString();
dxsEntriesConf = "83888896";
preSetExecuteConfigurationChanges(httpClient, url, username, password, dxsEntriesConf,
valueConfiguration);
break;
case SecondGenerationBindingConstants.CHANNEL_SMARTBATTERYCONTROLSET:
if (command.toString().equals("ON")) {
valueConfiguration = "true";
}
if (command.toString().equals("OFF")) {
valueConfiguration = "false";
}
dxsEntriesConf = "33556484";
preSetExecuteConfigurationChanges(httpClient, url, username, password, dxsEntriesConf,
valueConfiguration);
break;
case SecondGenerationBindingConstants.CHANNEL_BATTERYCHARGETIMEFROMSET:
valueConfiguration = command.toString();
String valueConfigurationFromTransformed = String.valueOf(stringToSeconds(valueConfiguration));
dxsEntriesConf = "33556239";
preSetExecuteConfigurationChanges(httpClient, url, username, password, dxsEntriesConf,
valueConfigurationFromTransformed);
break;
case SecondGenerationBindingConstants.CHANNEL_BATTERYCHARGETIMETOSET:
valueConfiguration = command.toString();
String valueConfigurationToTransformed = String.valueOf(stringToSeconds(valueConfiguration));
dxsEntriesConf = "33556240";
preSetExecuteConfigurationChanges(httpClient, url, username, password, dxsEntriesConf,
valueConfigurationToTransformed);
break;
case SecondGenerationBindingConstants.CHANNEL_MAXDEPTHOFDISCHARGESET:
valueConfiguration = command.toString();
dxsEntriesConf = "33556247";
preSetExecuteConfigurationChanges(httpClient, url, username, password, dxsEntriesConf,
valueConfiguration);
break;
case SecondGenerationBindingConstants.CHANNEL_SHADOWMANAGEMENTSET:
valueConfiguration = command.toString();
dxsEntriesConf = "33556483";
preSetExecuteConfigurationChanges(httpClient, url, username, password, dxsEntriesConf,
valueConfiguration);
break;
case SecondGenerationBindingConstants.CHANNEL_EXTERNALMODULECONTROLSET:
valueConfiguration = command.toString();
dxsEntriesConf = "33556482";
preSetExecuteConfigurationChanges(httpClient, url, username, password, dxsEntriesConf,
valueConfiguration);
break;
}
}
}
@Override
public void initialize() {
// Set channel configuration parameters
channelConfigs = SecondGenerationChannelConfiguration.getChannelConfiguration();
channelConfigsExt = SecondGenerationChannelConfiguration.getChannelConfigurationExt();
channelConfigsExtExt = SecondGenerationChannelConfiguration.getChannelConfigurationExtExt();
channelConfigsConfigurable = SecondGenerationChannelConfiguration.getChannelConfigurationConfigurable();
// Set inverter configuration parameters
final SecondGenerationInverterConfig inverterConfig = getConfigAs(SecondGenerationInverterConfig.class);
this.inverterConfig = inverterConfig;
// Temporary value during initializing
updateStatus(ThingStatus.UNKNOWN);
// Start update as configured
secondGenerationPoller = scheduler.scheduleWithFixedDelay(() -> {
try {
refresh();
updateStatus(ThingStatus.ONLINE);
} catch (RuntimeException scheduleWithFixedDelayException) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
scheduleWithFixedDelayException.getClass().getName() + ":"
+ scheduleWithFixedDelayException.getMessage());
} catch (InterruptedException interruptedException) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
interruptedException.getClass().getName() + ":" + interruptedException.getMessage());
} catch (ExecutionException executionException) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
executionException.getClass().getName() + ":" + executionException.getMessage());
} catch (TimeoutException timeoutException) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
timeoutException.getClass().getName() + ":" + timeoutException.getMessage());
}
}, 0, SecondGenerationInverterConfig.REFRESHINTERVAL_SEC, TimeUnit.SECONDS);
}
@Override
public void dispose() {
final ScheduledFuture<?> secondGenerationLocalPoller = secondGenerationPoller;
if (secondGenerationLocalPoller != null) {
secondGenerationLocalPoller.cancel(true);
secondGenerationPoller = null;
}
}
private void refresh() throws InterruptedException, ExecutionException, TimeoutException {
// Build posts for dxsEntries part
String dxsEntriesCall = inverterConfig.url + "/api/dxs.json?dxsEntries=" + channelConfigs.get(0).dxsEntries;
for (int i = 1; i < channelConfigs.size(); i++) {
dxsEntriesCall += ("&dxsEntries=" + channelConfigs.get(i).dxsEntries);
}
String jsonDxsEntriesResponse = callURL(dxsEntriesCall);
SecondGenerationDxsEntriesContainerDTO dxsEntriesContainer = gson.fromJson(jsonDxsEntriesResponse,
SecondGenerationDxsEntriesContainerDTO.class);
String[] channelPosts = new String[23];
int channelPostsCounter = 0;
for (SecondGenerationDxsEntries dxsentries : dxsEntriesContainer.dxsEntries) {
channelPosts[channelPostsCounter] = dxsentries.getName();
channelPostsCounter++;
}
channelPostsTemp = List.of(channelPosts);
// Build posts for dxsEntriesExt part
String dxsEntriesCallExt = inverterConfig.url + "/api/dxs.json?dxsEntries="
+ channelConfigsExt.get(0).dxsEntries;
for (int i = 1; i < channelConfigs.size(); i++) {
dxsEntriesCallExt += ("&dxsEntries=" + channelConfigsExt.get(i).dxsEntries);
}
String jsonDxsEntriesResponseExt = callURL(dxsEntriesCallExt);
SecondGenerationDxsEntriesContainerDTO dxsEntriesContainerExt = gson.fromJson(jsonDxsEntriesResponseExt,
SecondGenerationDxsEntriesContainerDTO.class);
String[] channelPostsExt = new String[23];
int channelPostsCounterExt = 0;
for (SecondGenerationDxsEntries dxsentriesExt : dxsEntriesContainerExt.dxsEntries) {
channelPostsExt[channelPostsCounterExt] = dxsentriesExt.getName();
channelPostsCounterExt++;
}
channelPostsTempExt = List.of(channelPostsExt);
// Build posts for dxsEntriesExtExt part
String dxsEntriesCallExtExt = inverterConfig.url + "/api/dxs.json?dxsEntries="
+ channelConfigsExtExt.get(0).dxsEntries;
for (int i = 1; i < channelConfigsExtExt.size(); i++) {
dxsEntriesCallExtExt += ("&dxsEntries=" + channelConfigsExtExt.get(i).dxsEntries);
}
String jsonDxsEntriesResponseExtExt = callURL(dxsEntriesCallExtExt);
SecondGenerationDxsEntriesContainerDTO dxsEntriesContainerExtExt = gson.fromJson(jsonDxsEntriesResponseExtExt,
SecondGenerationDxsEntriesContainerDTO.class);
String[] channelPostsExtExt = new String[3];
int channelPostsCounterExtExt = 0;
for (SecondGenerationDxsEntries dxsentriesExtExt : dxsEntriesContainerExtExt.dxsEntries) {
channelPostsExtExt[channelPostsCounterExtExt] = dxsentriesExtExt.getName();
channelPostsCounterExtExt++;
}
channelPostsTempExtExt = List.of(channelPostsExtExt);
// Concatenate posts for all parts except configurable channels
channelPostsTempAll = combinePostsLists(channelPostsTemp, channelPostsTempExt, channelPostsTempExtExt);
String[] channelPostsTempAll1 = channelPostsTempAll.toArray(new String[0]);
// Build posts for dxsEntriesConfigureable part
String dxsEntriesCallConfigurable = inverterConfig.url + "/api/dxs.json?dxsEntries="
+ channelConfigsConfigurable.get(0).dxsEntries;
for (int i = 1; i < channelConfigsConfigurable.size(); i++) {
dxsEntriesCallConfigurable += ("&dxsEntries=" + channelConfigsConfigurable.get(i).dxsEntries);
}
String jsonDxsEntriesResponseConfigurable = callURL(dxsEntriesCallConfigurable);
SecondGenerationDxsEntriesContainerDTO dxsEntriesContainerConfigurable = gson
.fromJson(jsonDxsEntriesResponseConfigurable, SecondGenerationDxsEntriesContainerDTO.class);
String[] channelPostsConfigurable = new String[5];
int channelPostsCounterConfigurable = 0;
for (SecondGenerationDxsEntries dxsentriesConfigurable : dxsEntriesContainerConfigurable.dxsEntries) {
channelPostsConfigurable[channelPostsCounterConfigurable] = dxsentriesConfigurable.getName();
channelPostsCounterConfigurable++;
}
// Create and update actual values for non-configurable channels
if (!inverterConfig.hasBattery) {
channelConfigsAll = combineChannelConfigLists(channelConfigs, channelConfigsExt, channelConfigsExtExt);
int channelValuesCounterAll = 0;
for (SecondGenerationChannelConfiguration cConfig : channelConfigsAll) {
String channel = cConfig.id;
updateState(channel, getState(channelPostsTempAll1[channelValuesCounterAll], cConfig.unit));
channelValuesCounterAll++;
}
}
// Create and update actual values for all channels
if (inverterConfig.hasBattery) {
// Part for updating non-configurable channels
channelConfigsAll = combineChannelConfigLists(channelConfigs, channelConfigsExt, channelConfigsExtExt);
// Update the non-configurable channels
int channelValuesCounterAll = 0;
for (SecondGenerationChannelConfiguration cConfig : channelConfigsAll) {
String channel = cConfig.id;
updateState(channel, getState(channelPostsTempAll1[channelValuesCounterAll], cConfig.unit));
channelValuesCounterAll++;
}
// Part for updating configurable channels
int channelValuesCounterConfigurable = 0;
for (SecondGenerationChannelConfiguration cConfig : channelConfigsConfigurable) {
String channel = cConfig.id;
String value = channelPostsConfigurable[channelValuesCounterConfigurable];
int dxsEntriesCheckCounter = 3;
if (cConfig.dxsEntries.equals("33556484")) {
dxsEntriesCheckCounter = 1;
}
if (cConfig.dxsEntries.equals("33556482")) {
dxsEntriesCheckCounter = 2;
}
switch (dxsEntriesCheckCounter) {
case 1:
if (value.equals("false")) {
updateState(channel, OnOffType.OFF);
}
if (value.equals("true")) {
updateState(channel, OnOffType.ON);
}
channelValuesCounterConfigurable++;
break;
case 2:
if (value.equals("false")) {
State stateFalse = new StringType("0");
updateState(channel, stateFalse);
}
if (value.equals("true")) {
State stateTrue = new StringType("1");
updateState(channel, stateTrue);
}
channelValuesCounterConfigurable++;
break;
case 3:
State stateOther = getState(channelPostsConfigurable[channelValuesCounterConfigurable],
cConfig.unit);
updateState(channel, stateOther);
channelValuesCounterConfigurable++;
break;
}
}
}
}
// Help method of handleCommand to with SecondGenerationConfigurationHandler.executeConfigurationChanges method send
// configuration changes.
private final void preSetExecuteConfigurationChanges(HttpClient httpClient, String url, String username,
String password, String dxsEntriesConf, String valueConfiguration) {
try {
SecondGenerationConfigurationHandler.executeConfigurationChanges(httpClient, url, username, password,
dxsEntriesConf, valueConfiguration);
} catch (Exception handleCommandException) {
logger.debug("Handle command for {} on channel {}: {}: {}: {}: {}", thing.getUID(), httpClient, url,
dxsEntriesConf, valueConfiguration, handleCommandException.getMessage());
}
}
// Method callURL connect to inverter for value scraping
private final String callURL(String dxsEntriesCall)
throws InterruptedException, ExecutionException, TimeoutException {
String jsonDxsResponse = httpClient.GET(dxsEntriesCall).getContentAsString();
return jsonDxsResponse;
}
// Method getState is used for non-configurable values
private State getState(String value, @Nullable Unit<?> unit) {
if (unit == null) {
return new StringType(value);
} else {
try {
return new QuantityType<>(new BigDecimal(value), unit);
} catch (NumberFormatException getStateException) {
logger.debug("Error parsing value '{}: {}'", value, getStateException.getMessage());
return UnDefType.UNDEF;
}
}
}
// Method stringToSeconds transform given time in 00:16 syntax to seconds syntax
private static long stringToSeconds(String stringTime) {
long secondsMin = Long.parseLong(stringTime.substring(3, 5)) * 60;
long secondsHrs = Long.parseLong(stringTime.substring(0, 2)) * 3600;
return secondsMin + secondsHrs;
}
// Method to concatenate channelConfigs Lists to one List
@SafeVarargs
private final List<SecondGenerationChannelConfiguration> combineChannelConfigLists(
List<SecondGenerationChannelConfiguration>... args) {
List<SecondGenerationChannelConfiguration> combinedChannelConfigLists = new ArrayList<>();
for (List<SecondGenerationChannelConfiguration> list : args) {
for (SecondGenerationChannelConfiguration i : list) {
combinedChannelConfigLists.add(i);
}
}
return combinedChannelConfigLists;
}
// Method to concatenate channelPosts Lists to one List
@SafeVarargs
private final List<String> combinePostsLists(List<String>... args) {
List<String> combinedPostsLists = new ArrayList<>();
for (List<String> list : args) {
for (String i : list) {
combinedPostsLists.add(i);
}
}
return combinedPostsLists;
}
}

View File

@@ -0,0 +1,36 @@
/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.kostalinverter.internal.secondgeneration;
import org.eclipse.jdt.annotation.NonNullByDefault;
/**
* The {@link SecondGenerationInverterConfig} class defines constants, which are
* used in the second generation part of the binding.
*
* @author Christian Schneider - Initial contribution
* @author Örjan Backsell - Added parameters for configuration options Piko1020, Piko New Generation
*
*/
@NonNullByDefault
public class SecondGenerationInverterConfig {
public static final long REFRESHINTERVAL_SEC = 60;
public String url = "";
public String username = "";
public String password = "";
public String dxsIdConf = "";
public String valueConf = "";
public boolean hasBattery;
}

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<config-description:config-descriptions
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:config-description="https://openhab.org/schemas/config-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/config-description/v1.0.0 https://openhab.org/schemas/config-description-1.0.0.xsd">
<config-description uri="thing-type:kostalpiko1020_config">
<parameter name="url" type="text" required="true">
<label>IP Address</label>
<description>IP address of the inverter.</description>
<context>url</context>
</parameter>
<parameter name="username" type="text" required="true">
<label>Username</label>
<description>The username to the inverter.</description>
</parameter>
<parameter name="password" type="text" required="true">
<label>Password</label>
<description>The password to the inverter.</description>
<context>password</context>
</parameter>
<parameter name="refreshInterval" type="integer" min="1" unit="s" required="true">
<label>Refresh Interval</label>
<description>Refresh Interval in seconds.</description>
<default>60</default>
</parameter>
<parameter name="hasBattery" type="boolean" required="true">
<label>Inverter Type</label>
<description>Type of inverter, with/without battery.</description>
</parameter>
</config-description>
</config-description:config-descriptions>

View File

@@ -32,7 +32,7 @@
<channel-type id="device-local-ownconsumption">
<item-type>Number:Power</item-type>
<label>Own Consumption</label>
<description>Current own comsumption</description>
<description>Current own consumption</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
@@ -46,7 +46,7 @@
<channel-type id="device-local-homeconsumption-total">
<item-type>Number:Power</item-type>
<label>Home Consumption</label>
<description>Current total homeconsumption</description>
<description>Current total home consumption</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
@@ -484,4 +484,438 @@
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-grid-output-power">
<item-type>Number:Power</item-type>
<label>Grid Output Power</label>
<description>Current output power to the grid</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="statistic-yield-day-second-gen">
<item-type>Number:Energy</item-type>
<label>Yield Day</label>
<description>Total produced power day</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="statistic-yield-total-second-gen">
<item-type>Number:Energy</item-type>
<label>Yield Total</label>
<description>Total produced power</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-operating-status">
<item-type>Number:Dimensionless</item-type>
<label>Operating Status</label>
<description>Operating status</description>
<category>Energy</category>
<state readOnly="true" pattern="%d"/>
</channel-type>
<channel-type id="device-local-grid-voltage-l1">
<item-type>Number:ElectricPotential</item-type>
<label>Grid Voltage L1</label>
<description>Current output voltage to the grid, L1</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-grid-current-l1">
<item-type>Number:ElectricCurrent</item-type>
<label>Grid Amperage L1</label>
<description>Current output amperage to the grid, L1</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-grid-power-l1">
<item-type>Number:Power</item-type>
<label>Grid Power L1</label>
<description>Current output power to the grid, L1</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-grid-voltage-l2">
<item-type>Number:ElectricPotential</item-type>
<label>Grid Voltage L2</label>
<description>Current output voltage to the grid, L2</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-grid-current-l2">
<item-type>Number:ElectricCurrent</item-type>
<label>Grid Amperage L2</label>
<description>Current output amperage to the grid, L2</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-grid-power-l2">
<item-type>Number:Power</item-type>
<label>Grid Power L2</label>
<description>Current output power to the grid, L2</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-grid-voltage-l3">
<item-type>Number:ElectricPotential</item-type>
<label>Grid Voltage L3</label>
<description>Current output voltage to the grid, L3</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-grid-current-l3">
<item-type>Number:ElectricCurrent</item-type>
<label>Grid Amperage L3</label>
<description>Current output amperage to the grid, L3</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-grid-power-l3">
<item-type>Number:Power</item-type>
<label>Grid Power L3</label>
<description>Current output power to the grid, L3</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-dc-power-pv">
<item-type>Number:Power</item-type>
<label>DC Power PV</label>
<description>Current power from solar panels</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-dc1-voltage">
<item-type>Number:ElectricPotential</item-type>
<label>DC1 Voltage</label>
<description>Current voltage from solar panels, DC1</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-dc1-current">
<item-type>Number:ElectricCurrent</item-type>
<label>DC1 Amperage</label>
<description>Current amperage from solar panels, DC1</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-dc1-power">
<item-type>Number:Power</item-type>
<label>DC1 Power</label>
<description>Current power from solar panels, DC1</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-dc2-voltage">
<item-type>Number:ElectricPotential</item-type>
<label>DC2 Voltage</label>
<description>Current voltage from solar panels, DC2</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-dc2-current">
<item-type>Number:ElectricCurrent</item-type>
<label>DC2 Amperage</label>
<description>Current amperage from solar panels, DC2</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-dc2-power">
<item-type>Number:Power</item-type>
<label>DC2 Power</label>
<description>Current power from solar panels, DC2</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-dc3-voltage">
<item-type>Number:ElectricPotential</item-type>
<label>DC3 Voltage</label>
<description>Current voltage from solar panels, DC3</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-dc3-current">
<item-type>Number:ElectricCurrent</item-type>
<label>DC3 Amperage</label>
<description>Current amperage from solar panels, DC3</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-dc3-power">
<item-type>Number:Power</item-type>
<label>DC3 Power</label>
<description>Current power from solar panels, DC3</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-akt-home-consumption-solar">
<item-type>Number:Power</item-type>
<label>Home Consumption PV</label>
<description>Current consumption from solar panels</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-akt-home-consumption-bat">
<item-type>Number:Power</item-type>
<label>Home Consumption Bat</label>
<description>Current consumption from battery</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-akt-home-consumption-grid">
<item-type>Number:Power</item-type>
<label>Home Consumption Grid</label>
<description>Current consumption from grid</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-phase-sel-home-consump-l1">
<item-type>Number:Power</item-type>
<label>Home Consumption L1</label>
<description>Current home consumption, L1</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-phase-sel-home-consump-l2">
<item-type>Number:Power</item-type>
<label>Home Consumption L2</label>
<description>Current home consumption, L2</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-phase-sel-home-consump-l3">
<item-type>Number:Power</item-type>
<label>Home Consumption L3</label>
<description>Current home consumption, L3</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-grid-freq">
<item-type>Number:Frequency</item-type>
<label>Grid Freq</label>
<description>Current frequency on grid</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-grid-cos-phi">
<item-type>Number:Angle</item-type>
<label>Grid Cos Phi</label>
<description>Current power factor on grid</description>
<category>Energy</category>
<state readOnly="true" pattern="%.0f %unit%"/>
</channel-type>
<channel-type id="statistic-home-consumption-day">
<item-type>Number:Energy</item-type>
<label>Home Consumption Day</label>
<description>Total home consumption day</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="statistic-own-consumption-day">
<item-type>Number:Energy</item-type>
<label>Own Consumption Day</label>
<description>Total own consumption day</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="statistic-own-cons-rate-day">
<item-type>Number:Dimensionless</item-type>
<label>Own Cons Rate Day</label>
<description>Total own consumption rate day</description>
<category>Energy</category>
<state readOnly="true" pattern="%.0f %unit%"/>
</channel-type>
<channel-type id="statistic-autonomy-degree-day">
<item-type>Number:Dimensionless</item-type>
<label>Autonomy Degree Day</label>
<description>Total autonomy degree day</description>
<category>Energy</category>
<state readOnly="true" pattern="%.0f %unit%"/>
</channel-type>
<channel-type id="statistic-home-consumption-total">
<item-type>Number:Energy</item-type>
<label>Home Consumption Total</label>
<description>Total home consumption</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="statistic-own-consumption-total">
<item-type>Number:Energy</item-type>
<label>Own Consumption Total</label>
<description>Total own consumptionl</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="statistic-operating-time-total">
<item-type>Number:Time</item-type>
<label>Operating Time Total</label>
<description>Total operating time</description>
<category>Energy</category>
<state readOnly="true" pattern="%d %unit%"/>
</channel-type>
<channel-type id="device-local-current">
<item-type>Number:ElectricCurrent</item-type>
<label>Current</label>
<description>Current</description>
<category>Energy</category>
<state readOnly="true" pattern="%.0f %unit%"/>
</channel-type>
<channel-type id="device-local-current-dir">
<item-type>Number:Dimensionless</item-type>
<label>Current Dir</label>
<description>Current direction</description>
<category>Energy</category>
<state readOnly="true" pattern="%d"/>
</channel-type>
<channel-type id="device-local-charge-cycles">
<item-type>Number:Dimensionless</item-type>
<label>Charge Cycles</label>
<description>Total number of charge cycles</description>
<category>Energy</category>
<state readOnly="true" pattern="%d"/>
</channel-type>
<channel-type id="device-local-battery-temperature">
<item-type>Number:Temperature</item-type>
<label>Battery Temperature</label>
<description>Current battery temperature</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-loginterval">
<item-type>Number:Time</item-type>
<label>Loginterval</label>
<description>Value for log interval</description>
<category>Energy</category>
<state readOnly="true" pattern="%d %unit%"/>
</channel-type>
<channel-type id="device-local-s0-inpulse-cnt">
<item-type>Number:Dimensionless</item-type>
<label>S0 Inpulse Cnt</label>
<description>S0-pulse counter</description>
<category>Energy</category>
<state readOnly="true" pattern="%d"/>
</channel-type>
<channel-type id="statistic-own-cons-rate-total">
<item-type>Number:Dimensionless</item-type>
<label>Own Cons Rate Total</label>
<description>Total own consumption rate</description>
<category>Energy</category>
<state readOnly="true" pattern="%.0f %unit%"/>
</channel-type>
<channel-type id="statistic-autonomy-degree-total">
<item-type>Number:Dimensionless</item-type>
<label>Autonomy Degree Total</label>
<description>Total autonomy degree</description>
<category>Energy</category>
<state readOnly="true" pattern="%.0f %unit%"/>
</channel-type>
<channel-type id="device-local-battery-voltage">
<item-type>Number:ElectricalPotential</item-type>
<label>Battery Voltage</label>
<description>Current battery voltage</description>
<category>Energy</category>
<state readOnly="true" pattern="%.0f %unit%"/>
</channel-type>
<channel-type id="device-local-bat-state-of-charge">
<item-type>Number:Dimensionless</item-type>
<label>Bat State of Charge</label>
<description>Current battery charge state</description>
<category>Energy</category>
<state readOnly="true" pattern="%.0f %unit%"/>
</channel-type>
<channel-type id="device-local-self-consumption">
<item-type>Number:Power</item-type>
<label>Self Consumption</label>
<description>Current self consumption</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-battery-usage-consumption">
<item-type>Number:Power</item-type>
<label>Battery Usage Consumption</label>
<description>Battery usage consumption</description>
<category>Energy</category>
<state readOnly="true" pattern="%.2f %unit%"/>
</channel-type>
<channel-type id="device-local-smart-battery-control">
<item-type>Switch</item-type>
<label>Smart Battery Control</label>
<description>Smart battery control</description>
<category>Energy</category>
<state readOnly="true"/>
</channel-type>
<channel-type id="device-local-max-depth-of-discharge">
<item-type>Number:Dimensionless</item-type>
<label>Max Depth of Discharge</label>
<description>Max depth of discharge</description>
<category>Energy</category>
<state readOnly="true" pattern="%d"/>
</channel-type>
<channel-type id="device-local-shadow-management">
<item-type>Number:Dimensionless</item-type>
<label>Shadow Management</label>
<description>Shadow management</description>
<category>Energy</category>
<state readOnly="true" pattern="%d"/>
</channel-type>
<channel-type id="device-local-external-module-control">
<item-type>Number:Dimensionless</item-type>
<label>External Module Control</label>
<description>External Module Control</description>
<category>Energy</category>
<state readOnly="true" pattern="%d"/>
</channel-type>
<channel-type id="device-local-battery-usage-consumption-set">
<item-type>String</item-type>
<label>Battery Usage Consumption Set</label>
<description>Set battery usage consumption</description>
<category>Energy</category>
<state readOnly="false"/>
</channel-type>
<channel-type id="device-local-battery-usage-strategy-set">
<item-type>String</item-type>
<label>Battery Usage Strategy Set</label>
<description>Set battery usage strategy</description>
<category>Energy</category>
<state readOnly="false"/>
</channel-type>
<channel-type id="device-local-smart-battery-control-set">
<item-type>Switch</item-type>
<label>Smart Battery Control Set</label>
<description>Set smart battery control</description>
<category>Energy</category>
<state readOnly="false"/>
</channel-type>
<channel-type id="device-local-battery-charge-time-from-set">
<item-type>String</item-type>
<label>Battery Charge Time from Set</label>
<description>Set battery charge time from</description>
<category>Energy</category>
<state readOnly="false"/>
</channel-type>
<channel-type id="device-local-battery-charge-time-to-set">
<item-type>String</item-type>
<label>Battery Charge Time to Set</label>
<description>Set battery charge time to</description>
<category>Energy</category>
<state readOnly="false"/>
</channel-type>
<channel-type id="device-local-max-depth-of-discharge-set">
<item-type>String</item-type>
<label>Max Depth of Discharge Set</label>
<description>Set max depth of discharge</description>
<category>Energy</category>
<state readOnly="false"/>
</channel-type>
<channel-type id="device-local-shadow-management-set">
<item-type>String</item-type>
<label>Shadow Management Set</label>
<description>Set shadow management</description>
<category>Energy</category>
<state readOnly="false"/>
</channel-type>
<channel-type id="device-local-external-module-control-set">
<item-type>String</item-type>
<label>External Module Control Set</label>
<description>Set External Module Control</description>
<category>Energy</category>
<state readOnly="false"/>
</channel-type>
</thing:thing-descriptions>

View File

@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="kostalinverter"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
<thing-type id="piko1020">
<label>KOSTAL PIKO 10-20</label>
<description>Bindings for the KOSTAL PIKO 10-20</description>
<category>Inverter</category>
<channels>
<channel typeId="device-local-grid-output-power" id="gridOutputPower"/>
<channel typeId="statistic-yield-day-second-gen" id="yieldDaySecondGen"/>
<channel typeId="statistic-yield-total-second-gen" id="yieldTotalSecondGen"/>
<channel typeId="device-local-operating-status" id="operatingStatus"/>
<channel typeId="device-local-grid-voltage-l1" id="gridVoltageL1"/>
<channel typeId="device-local-grid-current-l1" id="gridCurrentL1"/>
<channel typeId="device-local-grid-power-l1" id="gridPowerL1"/>
<channel typeId="device-local-grid-voltage-l2" id="gridVoltageL2"/>
<channel typeId="device-local-grid-current-l2" id="gridCurrentL2"/>
<channel typeId="device-local-grid-power-l2" id="gridPowerL2"/>
<channel typeId="device-local-grid-voltage-l3" id="gridVoltageL3"/>
<channel typeId="device-local-grid-current-l3" id="gridCurrentL3"/>
<channel typeId="device-local-grid-power-l3" id="gridPowerL3"/>
<channel typeId="device-local-dc-power-pv" id="dcPowerPV"/>
<channel typeId="device-local-dc1-voltage" id="dc1Voltage"/>
<channel typeId="device-local-dc1-current" id="dc1Current"/>
<channel typeId="device-local-dc1-power" id="dc1Power"/>
<channel typeId="device-local-dc2-voltage" id="dc2Voltage"/>
<channel typeId="device-local-dc2-current" id="dc2Current"/>
<channel typeId="device-local-dc2-power" id="dc2Power"/>
<channel typeId="device-local-dc3-voltage" id="dc3Voltage"/>
<channel typeId="device-local-dc3-current" id="dc3Current"/>
<channel typeId="device-local-dc3-power" id="dc3Power"/>
<channel typeId="device-local-akt-home-consumption-solar" id="aktHomeConsumptionSolar"/>
<channel typeId="device-local-akt-home-consumption-bat" id="aktHomeConsumptionBat"/>
<channel typeId="device-local-akt-home-consumption-grid" id="aktHomeConsumptionGrid"/>
<channel typeId="device-local-phase-sel-home-consump-l1" id="phaseSelHomeConsumpL1"/>
<channel typeId="device-local-phase-sel-home-consump-l2" id="phaseSelHomeConsumpL2"/>
<channel typeId="device-local-phase-sel-home-consump-l3" id="phaseSelHomeConsumpL3"/>
<channel typeId="device-local-grid-freq" id="gridFreq"/>
<channel typeId="device-local-grid-cos-phi" id="gridCosPhi"/>
<channel typeId="statistic-home-consumption-day" id="homeConsumptionDay"/>
<channel typeId="statistic-own-consumption-day" id="ownConsumptionDay"/>
<channel typeId="statistic-own-cons-rate-day" id="ownConsRateDay"/>
<channel typeId="statistic-autonomy-degree-day" id="autonomyDegreeDay"/>
<channel typeId="statistic-home-consumption-total" id="homeConsumptionTotal"/>
<channel typeId="statistic-own-consumption-total" id="ownConsumptionTotal"/>
<channel typeId="statistic-operating-time-total" id="operatingTimeTotal"/>
<channel typeId="device-local-current" id="current"/>
<channel typeId="device-local-current-dir" id="currentDir"/>
<channel typeId="device-local-charge-cycles" id="chargeCycles"/>
<channel typeId="device-local-battery-temperature" id="batteryTemperature"/>
<channel typeId="device-local-loginterval" id="loginterval"/>
<channel typeId="device-local-s0-inpulse-cnt" id="s0InPulseCnt"/>
<channel typeId="statistic-own-cons-rate-total" id="ownConsRateTotal"/>
<channel typeId="statistic-autonomy-degree-total" id="autonomyDegreeTotal"/>
<channel typeId="device-local-battery-voltage" id="batteryVoltage"/>
<channel typeId="device-local-bat-state-of-charge" id="batStateOfCharge"/>
<channel typeId="device-local-self-consumption" id="selfConsumption"/>
<channel typeId="device-local-battery-usage-consumption" id="batteryUsageConsumption"/>
<channel typeId="device-local-smart-battery-control" id="smartBatteryControl"/>
<channel typeId="device-local-max-depth-of-discharge" id="maxDepthOfDischarge"/>
<channel typeId="device-local-shadow-management" id="shadowManagement"/>
<channel typeId="device-local-external-module-control" id="externalModuleControl"/>
<channel typeId="device-local-battery-usage-consumption-set" id="batteryUsageConsumptionSet"/>
<channel typeId="device-local-battery-usage-strategy-set" id="batteryUsageStrategySet"/>
<channel typeId="device-local-smart-battery-control-set" id="smartBatteryControlSet"/>
<channel typeId="device-local-battery-charge-time-from-set" id="batteryChargeTimeFromSet"/>
<channel typeId="device-local-battery-charge-time-to-set" id="batteryChargeTimeToSet"/>
<channel typeId="device-local-max-depth-of-discharge-set" id="maxDepthOfDischargeSet"/>
<channel typeId="device-local-shadow-management-set" id="shadowManagementSet"/>
<channel typeId="device-local-external-module-control-set" id="externalModuleControlSet"/>
</channels>
<properties>
<property name="vendor">KOSTAL Solar Electric GmbH</property>
</properties>
<config-description-ref uri="thing-type:kostalpiko1020_config"/>
</thing-type>
</thing:thing-descriptions>