[sonnen] Update to API V2 of vendor and add PowerMeter (#14589)
* Implementing sonnen APi V2 * Fixed issues with powermeter and added two more channels from consumption. Signed-off-by: chingon007 <tron81@gmx.de>pull/15008/head
parent
6ab8111f9e
commit
4d811691e9
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
The binding for sonnen communicates with a sonnen battery.
|
The binding for sonnen communicates with a sonnen battery.
|
||||||
More information about the sonnen battery can be found [here](https://sonnen.de/).
|
More information about the sonnen battery can be found [here](https://sonnen.de/).
|
||||||
|
The binding supports the old deprecated V1 from sonnen as well as V2 which requires an authentication token.
|
||||||
|
More information about the V2 API can be found at `http://LOCAL-SONNENBATTERY-SYSTEM-IP/api/doc.html`
|
||||||
|
|
||||||
## Supported Things
|
## Supported Things
|
||||||
|
|
||||||
|
@ -12,6 +14,7 @@ More information about the sonnen battery can be found [here](https://sonnen.de/
|
||||||
## Thing Configuration
|
## Thing Configuration
|
||||||
|
|
||||||
Only the parameter `hostIP` is required; this is the IP address of the sonnen battery in your local network.
|
Only the parameter `hostIP` is required; this is the IP address of the sonnen battery in your local network.
|
||||||
|
If you want to use the V2 API, which supports more channels, you need to provide the `authToken`.
|
||||||
|
|
||||||
## Channels
|
## Channels
|
||||||
|
|
||||||
|
@ -35,7 +38,10 @@ The following channels are yet supported:
|
||||||
| flowConsumptionProductionState | Switch | read | Indicates if there is a current flow from Solar Production towards Consumption |
|
| flowConsumptionProductionState | Switch | read | Indicates if there is a current flow from Solar Production towards Consumption |
|
||||||
| flowGridBatteryState | Switch | read | Indicates if there is a current flow from Grid towards Battery |
|
| flowGridBatteryState | Switch | read | Indicates if there is a current flow from Grid towards Battery |
|
||||||
| flowProductionBatteryState | Switch | read | Indicates if there is a current flow from Production towards Battery |
|
| flowProductionBatteryState | Switch | read | Indicates if there is a current flow from Production towards Battery |
|
||||||
| flowProductionGridState | Switch | read | Indicates if there is a current flow from Production towards Grid |
|
| energyImportedStateProduction | Number:Energy | read | Indicates the imported kWh Production |
|
||||||
|
| energyExportedStateProduction | Number:Energy | read | Indicates the exported kWh Production |
|
||||||
|
| energyImportedStateConsumption | Number:Energy | read | Indicates the imported kWh Consumption |
|
||||||
|
| energyExportedStateConsumption | Number:Energy | read | Indicates the exported kWh Consumption |
|
||||||
|
|
||||||
## Full Example
|
## Full Example
|
||||||
|
|
||||||
|
|
|
@ -45,4 +45,10 @@ public class SonnenBindingConstants {
|
||||||
public static final String CHANNELFLOWGRIDBATTERYSTATE = "flowGridBatteryState";
|
public static final String CHANNELFLOWGRIDBATTERYSTATE = "flowGridBatteryState";
|
||||||
public static final String CHANNELFLOWPRODUCTIONBATTERYSTATE = "flowProductionBatteryState";
|
public static final String CHANNELFLOWPRODUCTIONBATTERYSTATE = "flowProductionBatteryState";
|
||||||
public static final String CHANNELFLOWPRODUCTIONGRIDSTATE = "flowProductionGridState";
|
public static final String CHANNELFLOWPRODUCTIONGRIDSTATE = "flowProductionGridState";
|
||||||
|
|
||||||
|
// List of new Channel ids for PowerMeter API
|
||||||
|
public static final String CHANNELENERGYIMPORTEDSTATEPRODUCTION = "energyImportedStateProduction";
|
||||||
|
public static final String CHANNELENERGYEXPORTEDSTATEPRODUCTION = "energyExportedStateProduction";
|
||||||
|
public static final String CHANNELENERGYIMPORTEDSTATECONSUMPTION = "energyImportedStateConsumption";
|
||||||
|
public static final String CHANNELENERGYEXPORTEDSTATECONSUMPTION = "energyExportedStateConsumption";
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,4 +25,5 @@ public class SonnenConfiguration {
|
||||||
|
|
||||||
public @Nullable String hostIP = null;
|
public @Nullable String hostIP = null;
|
||||||
public int refreshInterval = 30;
|
public int refreshInterval = 30;
|
||||||
|
public String authToken = "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,14 @@ import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.measure.quantity.Dimensionless;
|
import javax.measure.quantity.Dimensionless;
|
||||||
|
import javax.measure.quantity.Energy;
|
||||||
import javax.measure.quantity.Power;
|
import javax.measure.quantity.Power;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.binding.sonnen.internal.communication.SonnenJSONCommunication;
|
import org.openhab.binding.sonnen.internal.communication.SonnenJSONCommunication;
|
||||||
import org.openhab.binding.sonnen.internal.communication.SonnenJsonDataDTO;
|
import org.openhab.binding.sonnen.internal.communication.SonnenJsonDataDTO;
|
||||||
|
import org.openhab.binding.sonnen.internal.communication.SonnenJsonPowerMeterDataDTO;
|
||||||
import org.openhab.core.library.types.OnOffType;
|
import org.openhab.core.library.types.OnOffType;
|
||||||
import org.openhab.core.library.types.QuantityType;
|
import org.openhab.core.library.types.QuantityType;
|
||||||
import org.openhab.core.library.unit.Units;
|
import org.openhab.core.library.unit.Units;
|
||||||
|
@ -61,6 +63,10 @@ public class SonnenHandler extends BaseThingHandler {
|
||||||
|
|
||||||
private boolean automaticRefreshing = false;
|
private boolean automaticRefreshing = false;
|
||||||
|
|
||||||
|
private boolean sonnenAPIV2 = false;
|
||||||
|
|
||||||
|
private int disconnectionCounter = 0;
|
||||||
|
|
||||||
private Map<String, Boolean> linkedChannels = new HashMap<>();
|
private Map<String, Boolean> linkedChannels = new HashMap<>();
|
||||||
|
|
||||||
public SonnenHandler(Thing thing) {
|
public SonnenHandler(Thing thing) {
|
||||||
|
@ -82,6 +88,10 @@ public class SonnenHandler extends BaseThingHandler {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!config.authToken.isEmpty()) {
|
||||||
|
sonnenAPIV2 = true;
|
||||||
|
}
|
||||||
|
|
||||||
serviceCommunication.setConfig(config);
|
serviceCommunication.setConfig(config);
|
||||||
updateStatus(ThingStatus.UNKNOWN);
|
updateStatus(ThingStatus.UNKNOWN);
|
||||||
scheduler.submit(() -> {
|
scheduler.submit(() -> {
|
||||||
|
@ -101,13 +111,23 @@ public class SonnenHandler extends BaseThingHandler {
|
||||||
* @return true if the update succeeded, false otherwise
|
* @return true if the update succeeded, false otherwise
|
||||||
*/
|
*/
|
||||||
private boolean updateBatteryData() {
|
private boolean updateBatteryData() {
|
||||||
String error = serviceCommunication.refreshBatteryConnection();
|
String error = "";
|
||||||
|
if (sonnenAPIV2) {
|
||||||
|
error = serviceCommunication.refreshBatteryConnectionAPICALLV2(arePowerMeterChannelsLinked());
|
||||||
|
} else {
|
||||||
|
error = serviceCommunication.refreshBatteryConnectionAPICALLV1();
|
||||||
|
}
|
||||||
if (error.isEmpty()) {
|
if (error.isEmpty()) {
|
||||||
if (!ThingStatus.ONLINE.equals(getThing().getStatus())) {
|
if (!ThingStatus.ONLINE.equals(getThing().getStatus())) {
|
||||||
updateStatus(ThingStatus.ONLINE);
|
updateStatus(ThingStatus.ONLINE);
|
||||||
|
disconnectionCounter = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
disconnectionCounter++;
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, error);
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, error);
|
||||||
|
if (disconnectionCounter < 60) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return error.isEmpty();
|
return error.isEmpty();
|
||||||
}
|
}
|
||||||
|
@ -134,7 +154,7 @@ public class SonnenHandler extends BaseThingHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the job refreshing the oven status
|
* Start the job refreshing the battery status
|
||||||
*/
|
*/
|
||||||
private void startAutomaticRefresh() {
|
private void startAutomaticRefresh() {
|
||||||
ScheduledFuture<?> job = refreshJob;
|
ScheduledFuture<?> job = refreshJob;
|
||||||
|
@ -176,6 +196,35 @@ public class SonnenHandler extends BaseThingHandler {
|
||||||
if (isLinked(channelId)) {
|
if (isLinked(channelId)) {
|
||||||
State state = null;
|
State state = null;
|
||||||
SonnenJsonDataDTO data = serviceCommunication.getBatteryData();
|
SonnenJsonDataDTO data = serviceCommunication.getBatteryData();
|
||||||
|
// The sonnen API has two sub-channels, e.g. 4_1 and 4_2, one representing consumption and the
|
||||||
|
// other production. E.g. 4_1.kwh_imported represents the total production since the
|
||||||
|
// battery was installed.
|
||||||
|
SonnenJsonPowerMeterDataDTO[] dataPM = null;
|
||||||
|
if (arePowerMeterChannelsLinked()) {
|
||||||
|
dataPM = serviceCommunication.getPowerMeterData();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataPM != null && dataPM.length >= 2) {
|
||||||
|
switch (channelId) {
|
||||||
|
case CHANNELENERGYIMPORTEDSTATEPRODUCTION:
|
||||||
|
state = new QuantityType<Energy>(dataPM[0].getKwhImported(), Units.KILOWATT_HOUR);
|
||||||
|
update(state, channelId);
|
||||||
|
break;
|
||||||
|
case CHANNELENERGYEXPORTEDSTATEPRODUCTION:
|
||||||
|
state = new QuantityType<Energy>(dataPM[0].getKwhExported(), Units.KILOWATT_HOUR);
|
||||||
|
update(state, channelId);
|
||||||
|
break;
|
||||||
|
case CHANNELENERGYIMPORTEDSTATECONSUMPTION:
|
||||||
|
state = new QuantityType<Energy>(dataPM[1].getKwhImported(), Units.KILOWATT_HOUR);
|
||||||
|
update(state, channelId);
|
||||||
|
break;
|
||||||
|
case CHANNELENERGYEXPORTEDSTATECONSUMPTION:
|
||||||
|
state = new QuantityType<Energy>(dataPM[1].getKwhExported(), Units.KILOWATT_HOUR);
|
||||||
|
update(state, channelId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
switch (channelId) {
|
switch (channelId) {
|
||||||
case CHANNELBATTERYDISCHARGINGSTATE:
|
case CHANNELBATTERYDISCHARGINGSTATE:
|
||||||
|
@ -234,9 +283,23 @@ public class SonnenHandler extends BaseThingHandler {
|
||||||
update(OnOffType.from(data.isFlowProductionGrid()), channelId);
|
update(OnOffType.from(data.isFlowProductionGrid()), channelId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
update(null, channelId);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
update(null, channelId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean arePowerMeterChannelsLinked() {
|
||||||
|
if (isLinked(CHANNELENERGYIMPORTEDSTATEPRODUCTION)) {
|
||||||
|
return true;
|
||||||
|
} else if (isLinked(CHANNELENERGYEXPORTEDSTATEPRODUCTION)) {
|
||||||
|
return true;
|
||||||
|
} else if (isLinked(CHANNELENERGYIMPORTEDSTATECONSUMPTION)) {
|
||||||
|
return true;
|
||||||
|
} else if (isLinked(CHANNELENERGYEXPORTEDSTATECONSUMPTION)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
package org.openhab.binding.sonnen.internal.communication;
|
package org.openhab.binding.sonnen.internal.communication;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
@ -38,6 +39,7 @@ public class SonnenJSONCommunication {
|
||||||
|
|
||||||
private Gson gson;
|
private Gson gson;
|
||||||
private @Nullable SonnenJsonDataDTO batteryData;
|
private @Nullable SonnenJsonDataDTO batteryData;
|
||||||
|
private SonnenJsonPowerMeterDataDTO @Nullable [] powerMeterData;
|
||||||
|
|
||||||
public SonnenJSONCommunication() {
|
public SonnenJSONCommunication() {
|
||||||
gson = new Gson();
|
gson = new Gson();
|
||||||
|
@ -45,14 +47,56 @@ public class SonnenJSONCommunication {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refreshes the battery connection.
|
* Refreshes the battery connection with the new API Call V2.
|
||||||
*
|
*
|
||||||
* @return an empty string if no error occurred, the error message otherwise.
|
* @return an empty string if no error occurred, the error message otherwise.
|
||||||
*/
|
*/
|
||||||
public String refreshBatteryConnection() {
|
public String refreshBatteryConnectionAPICALLV2(boolean powerMeter) {
|
||||||
|
String result = "";
|
||||||
|
String urlStr = "http://" + config.hostIP + "/api/v2/status";
|
||||||
|
Properties httpHeader = new Properties();
|
||||||
|
httpHeader = createHeader(config.authToken);
|
||||||
|
try {
|
||||||
|
String response = HttpUtil.executeUrl("GET", urlStr, httpHeader, null, "application/json", 10000);
|
||||||
|
logger.debug("BatteryData = {}", response);
|
||||||
|
if (response == null) {
|
||||||
|
throw new IOException("HttpUtil.executeUrl returned null");
|
||||||
|
}
|
||||||
|
batteryData = gson.fromJson(response, SonnenJsonDataDTO.class);
|
||||||
|
|
||||||
|
if (powerMeter) {
|
||||||
|
response = HttpUtil.executeUrl("GET", "http://" + config.hostIP + "/api/v2/powermeter", httpHeader,
|
||||||
|
null, "application/json", 10000);
|
||||||
|
logger.debug("PowerMeterData = {}", response);
|
||||||
|
if (response == null) {
|
||||||
|
throw new IOException("HttpUtil.executeUrl returned null");
|
||||||
|
}
|
||||||
|
|
||||||
|
powerMeterData = gson.fromJson(response, SonnenJsonPowerMeterDataDTO[].class);
|
||||||
|
}
|
||||||
|
} catch (IOException | JsonSyntaxException e) {
|
||||||
|
logger.debug("Error processiong Get request {}: {}", urlStr, e.getMessage());
|
||||||
|
String message = e.getMessage();
|
||||||
|
if (message != null && message.contains("WWW-Authenticate header")) {
|
||||||
|
result = "Given token: " + config.authToken + " is not valid.";
|
||||||
|
} else {
|
||||||
|
result = "Cannot find service on given IP " + config.hostIP + ". Please verify the IP address!";
|
||||||
|
logger.debug("Error in establishing connection: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
batteryData = null;
|
||||||
|
powerMeterData = new SonnenJsonPowerMeterDataDTO[] {};
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refreshes the battery connection with the Old API Call.
|
||||||
|
*
|
||||||
|
* @return an empty string if no error occurred, the error message otherwise.
|
||||||
|
*/
|
||||||
|
public String refreshBatteryConnectionAPICALLV1() {
|
||||||
String result = "";
|
String result = "";
|
||||||
String urlStr = "http://" + config.hostIP + "/api/v1/status";
|
String urlStr = "http://" + config.hostIP + "/api/v1/status";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String response = HttpUtil.executeUrl("GET", urlStr, 10000);
|
String response = HttpUtil.executeUrl("GET", urlStr, 10000);
|
||||||
logger.debug("BatteryData = {}", response);
|
logger.debug("BatteryData = {}", response);
|
||||||
|
@ -85,4 +129,28 @@ public class SonnenJSONCommunication {
|
||||||
public @Nullable SonnenJsonDataDTO getBatteryData() {
|
public @Nullable SonnenJsonDataDTO getBatteryData() {
|
||||||
return this.batteryData;
|
return this.batteryData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the actual stored Power Meter Data Array
|
||||||
|
*
|
||||||
|
* @return JSON Data from the Power Meter or null if request failed
|
||||||
|
*/
|
||||||
|
public SonnenJsonPowerMeterDataDTO @Nullable [] getPowerMeterData() {
|
||||||
|
return this.powerMeterData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the header for the Get Request
|
||||||
|
*
|
||||||
|
* @return The created Header Properties
|
||||||
|
*/
|
||||||
|
private Properties createHeader(String authToken) {
|
||||||
|
Properties httpHeader = new Properties();
|
||||||
|
httpHeader.setProperty("Host", config.hostIP);
|
||||||
|
httpHeader.setProperty("Accept", "*/*");
|
||||||
|
httpHeader.setProperty("Proxy-Connection", "keep-alive");
|
||||||
|
httpHeader.setProperty("Auth-Token", authToken);
|
||||||
|
httpHeader.setProperty("Accept-Encoding", "gzip;q=1.0, compress;q=0.5");
|
||||||
|
return httpHeader;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link SonnenJsonDataDTO} is the Java class used to map the JSON
|
* The {@link SonnenJsonDataDTO} is the Java class used to map the JSON
|
||||||
* response to an Oven request.
|
* response to an Object.
|
||||||
*
|
*
|
||||||
* @author Christian Feininger - Initial contribution
|
* @author Christian Feininger - Initial contribution
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2010-2023 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.sonnen.internal.communication;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link SonnenJsonPowerMeterDataDTO} is the Java class used to map the JSON
|
||||||
|
* response from the API to a PowerMeter Object.
|
||||||
|
*
|
||||||
|
* @author Christian Feininger - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class SonnenJsonPowerMeterDataDTO {
|
||||||
|
|
||||||
|
@SerializedName("kwh_exported")
|
||||||
|
private float kwhExported;
|
||||||
|
@SerializedName("kwh_imported")
|
||||||
|
private float kwhImported;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the kwh_exported
|
||||||
|
*/
|
||||||
|
public float getKwhExported() {
|
||||||
|
return kwhExported;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the kwh_imported
|
||||||
|
*/
|
||||||
|
public float getKwhImported() {
|
||||||
|
return kwhImported;
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,6 +14,8 @@ thing-type.config.sonnen.sonnenbattery.hostIP.label = IP Address
|
||||||
thing-type.config.sonnen.sonnenbattery.hostIP.description = Please add the IP Address of your sonnen battery.
|
thing-type.config.sonnen.sonnenbattery.hostIP.description = Please add the IP Address of your sonnen battery.
|
||||||
thing-type.config.sonnen.sonnenbattery.refreshInterval.label = Refresh Interval
|
thing-type.config.sonnen.sonnenbattery.refreshInterval.label = Refresh Interval
|
||||||
thing-type.config.sonnen.sonnenbattery.refreshInterval.description = How often in seconds the sonnen battery should schedule a refresh after a channel is linked to an item. Valid input is 0 - 1000.
|
thing-type.config.sonnen.sonnenbattery.refreshInterval.description = How often in seconds the sonnen battery should schedule a refresh after a channel is linked to an item. Valid input is 0 - 1000.
|
||||||
|
thing-type.config.sonnen.sonnenbattery.authToken.label = Authentication Token
|
||||||
|
thing-type.config.sonnen.sonnenbattery.authToken.description = Authentication Token which can be found under "Software Integration" if you connect locally to your sonnen battery. If empty the old deprecated API will be used.
|
||||||
|
|
||||||
# channel types
|
# channel types
|
||||||
|
|
||||||
|
@ -45,3 +47,11 @@ channel-type.sonnen.gridFeedIn.label = Grid Feed In
|
||||||
channel-type.sonnen.gridFeedIn.description = Indicates the actual current feeding to the Grid. Otherwise 0.
|
channel-type.sonnen.gridFeedIn.description = Indicates the actual current feeding to the Grid. Otherwise 0.
|
||||||
channel-type.sonnen.solarProduction.label = Solar Production
|
channel-type.sonnen.solarProduction.label = Solar Production
|
||||||
channel-type.sonnen.solarProduction.description = Indicates the actual production of the Solar system.
|
channel-type.sonnen.solarProduction.description = Indicates the actual production of the Solar system.
|
||||||
|
channel-type.sonnen.energyImportedStateProduction.label = Imported kWh Production.
|
||||||
|
channel-type.sonnen.energyImportedStateProduction.description = Indicates the imported kWh Production
|
||||||
|
channel-type.sonnen.energyExportedStateProduction.label= Exported kWh Production.
|
||||||
|
channel-type.sonnen.energyExportedStateProduction.description = Indicates the exported kWh Production
|
||||||
|
channel-type.sonnen.energyImportedStateConsumption.label = Imported kWh Consumption.
|
||||||
|
channel-type.sonnen.energyImportedStateConsupmtion.description = Indicates the imported kWh Consumption
|
||||||
|
channel-type.sonnen.energyExportedStateConsumption.label= Exported kWh Consumption.
|
||||||
|
channel-type.sonnen.energyExportedStateConsumption.description = Indicates the exported kWh Consumption
|
||||||
|
|
|
@ -25,7 +25,15 @@
|
||||||
<channel id="flowGridBatteryState" typeId="flowGridBatteryState"/>
|
<channel id="flowGridBatteryState" typeId="flowGridBatteryState"/>
|
||||||
<channel id="flowProductionBatteryState" typeId="flowProductionBatteryState"/>
|
<channel id="flowProductionBatteryState" typeId="flowProductionBatteryState"/>
|
||||||
<channel id="flowProductionGridState" typeId="flowProductionGridState"/>
|
<channel id="flowProductionGridState" typeId="flowProductionGridState"/>
|
||||||
|
<channel id="energyImportedStateProduction" typeId="energyImportedStateProduction"/>
|
||||||
|
<channel id="energyExportedStateProduction" typeId="energyExportedStateProduction"/>
|
||||||
|
<channel id="energyImportedStateConsumption" typeId="energyImportedStateConsumption"/>
|
||||||
|
<channel id="energyExportedStateConsumption" typeId="energyExportedStateConsumption"/>
|
||||||
</channels>
|
</channels>
|
||||||
|
<properties>
|
||||||
|
<property name="vendor">sonnen</property>
|
||||||
|
<property name="thingTypeVersion">1</property>
|
||||||
|
</properties>
|
||||||
|
|
||||||
<config-description>
|
<config-description>
|
||||||
<parameter name="hostIP" type="text" required="true">
|
<parameter name="hostIP" type="text" required="true">
|
||||||
|
@ -33,6 +41,12 @@
|
||||||
<label>IP Address</label>
|
<label>IP Address</label>
|
||||||
<description>Please add the IP Address of your sonnen battery.</description>
|
<description>Please add the IP Address of your sonnen battery.</description>
|
||||||
</parameter>
|
</parameter>
|
||||||
|
<parameter name="authToken" type="text">
|
||||||
|
<context>service</context>
|
||||||
|
<label>sonnen Authentication Token</label>
|
||||||
|
<description>Authentication Token which can be found under "Software Integration" if you connect locally to your
|
||||||
|
sonnen battery. If empty the old deprecated API will be used.</description>
|
||||||
|
</parameter>
|
||||||
<parameter name="refreshInterval" type="integer" unit="s" min="0" max="1000">
|
<parameter name="refreshInterval" type="integer" unit="s" min="0" max="1000">
|
||||||
<label>Refresh Interval</label>
|
<label>Refresh Interval</label>
|
||||||
<description>How often in seconds the sonnen battery should schedule a refresh after a channel is linked to an item.
|
<description>How often in seconds the sonnen battery should schedule a refresh after a channel is linked to an item.
|
||||||
|
@ -128,4 +142,28 @@
|
||||||
<description>Indicates if there is a current flow from production towards grid.</description>
|
<description>Indicates if there is a current flow from production towards grid.</description>
|
||||||
<state readOnly="true"/>
|
<state readOnly="true"/>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
<channel-type id="energyImportedStateProduction">
|
||||||
|
<item-type>Number:Energy</item-type>
|
||||||
|
<label>kWh Imported Production</label>
|
||||||
|
<description>Indicates the imported kWh Production.</description>
|
||||||
|
<state readOnly="true" pattern="%.1f %unit%"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="energyExportedStateProduction">
|
||||||
|
<item-type>Number:Energy</item-type>
|
||||||
|
<label>kWh Exported Production</label>
|
||||||
|
<description>Indicates the exported kWh Production.</description>
|
||||||
|
<state readOnly="true" pattern="%.1f %unit%"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="energyImportedStateConsumption">
|
||||||
|
<item-type>Number:Energy</item-type>
|
||||||
|
<label>kWh Imported Consumption</label>
|
||||||
|
<description>Indicates the imported kWh Consumption.</description>
|
||||||
|
<state readOnly="true" pattern="%.1f %unit%"/>
|
||||||
|
</channel-type>
|
||||||
|
<channel-type id="energyExportedStateConsumption">
|
||||||
|
<item-type>Number:Energy</item-type>
|
||||||
|
<label>kWh Exported Consumption</label>
|
||||||
|
<description>Indicates the exported kWh Consumption.</description>
|
||||||
|
<state readOnly="true" pattern="%.1f %unit%"/>
|
||||||
|
</channel-type>
|
||||||
</thing:thing-descriptions>
|
</thing:thing-descriptions>
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||||
|
<update:update-descriptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:update="https://openhab.org/schemas/update-description/v1.0.0"
|
||||||
|
xsi:schemaLocation="https://openhab.org/schemas/update-description/v1.0.0 https://openhab.org/schemas/update-description-1.0.0.xsd">
|
||||||
|
|
||||||
|
<thing-type uid="sonnen:sonnenbattery">
|
||||||
|
|
||||||
|
<instruction-set targetVersion="1">
|
||||||
|
<add-channel id="energyImportedStateProduction">
|
||||||
|
<type>sonnen:energyImportedStateProduction</type>
|
||||||
|
</add-channel>
|
||||||
|
<add-channel id="energyExportedStateProduction">
|
||||||
|
<type>sonnen:energyExportedStateProduction</type>
|
||||||
|
</add-channel>
|
||||||
|
<add-channel id="energyImportedStateConsumption">
|
||||||
|
<type>sonnen:energyImportedStateConsumption</type>
|
||||||
|
</add-channel>
|
||||||
|
<add-channel id="energyExportedStateConsumption">
|
||||||
|
<type>sonnen:energyExportedStateConsumption</type>
|
||||||
|
</add-channel>
|
||||||
|
</instruction-set>
|
||||||
|
</thing-type>
|
||||||
|
</update:update-descriptions>
|
Loading…
Reference in New Issue