mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-25 14:55:55 +01:00
[SenecHome] Add writeable Charging Modes (#17474)
* [senechome] Now accepts commands for active charging Signed-off-by: Lukas Pindl <lukas.pindl@gmx.net> * [senechome] Manual update for charging modes Signed-off-by: Lukas Pindl <lukas.pindl@gmx.net> * [senechome] docu and spotless Signed-off-by: Lukas Pindl <lukas.pindl@gmx.net> * [Senechome] Charge Modes combined into a single channel Signed-off-by: Lukas Pindl <lukas.pindl@gmx.net> * [senechome] Apply suggestions from code review Co-authored-by: lsiepel <leosiepel@gmail.com> Signed-off-by: Lukas Pindl <36566235+BigFood2307@users.noreply.github.com> * [senechome] additional review fixes Signed-off-by: Lukas Pindl <lukas.pindl@gmx.net> --------- Signed-off-by: Lukas Pindl <lukas.pindl@gmx.net> Signed-off-by: Lukas Pindl <36566235+BigFood2307@users.noreply.github.com> Co-authored-by: lsiepel <leosiepel@gmail.com>
This commit is contained in:
parent
e655ddb65d
commit
5c99a6c19c
@ -7,6 +7,8 @@ In addition you can switch off devices if the power consumption is getting highe
|
|||||||
|
|
||||||
Examples: Lights, pool filters, wash machines, ...
|
Examples: Lights, pool filters, wash machines, ...
|
||||||
|
|
||||||
|
Also allows for turning the battery into safe charging mode or storage mode.
|
||||||
|
|
||||||
## Supported Things
|
## Supported Things
|
||||||
|
|
||||||
| Thing type id | Name |
|
| Thing type id | Name |
|
||||||
@ -19,6 +21,7 @@ Examples: Lights, pool filters, wash machines, ...
|
|||||||
- not equipped battery packs will return 0 for all ...Pack channels
|
- not equipped battery packs will return 0 for all ...Pack channels
|
||||||
- currently channels for the first wallbox are implemented (senec could handle 4 wallboxes)
|
- currently channels for the first wallbox are implemented (senec could handle 4 wallboxes)
|
||||||
- Senec disables http access at ~30.08.2023
|
- Senec disables http access at ~30.08.2023
|
||||||
|
- The chargeMode `STORAGE` also known as Lithium Storage Mode is intended (according to the manual) for disassembly and transport. It is untested if it has any side effects.
|
||||||
|
|
||||||
## Thing Configuration
|
## Thing Configuration
|
||||||
|
|
||||||
@ -57,6 +60,8 @@ The property `limitationTresholdValue` is used as threshold for channel `powerLi
|
|||||||
| batteryFuelCharge | percent | Fuel charge of your battery (0 - 100%) |
|
| batteryFuelCharge | percent | Fuel charge of your battery (0 - 100%) |
|
||||||
| systemState | | Text describing current action of the senec home system (e.g. CHARGE) |
|
| systemState | | Text describing current action of the senec home system (e.g. CHARGE) |
|
||||||
| systemStateValue | | Value describing current action of the senec home system (e.g. 14) |
|
| systemStateValue | | Value describing current action of the senec home system (e.g. 14) |
|
||||||
|
| chargeMode | OFF/CHARGE/ | In `CHARGE` mode, the battery will try to fill as quickly as possible |
|
||||||
|
| | STORAGE | in `STORAGE` mode, the battery will try to reach 25% SOC |
|
||||||
| gridPower | watt | Grid power level, negative for supply, positive values for drawing power |
|
| gridPower | watt | Grid power level, negative for supply, positive values for drawing power |
|
||||||
| gridPowerDraw | watt | Absolute power level of power draw, zero while supplying |
|
| gridPowerDraw | watt | Absolute power level of power draw, zero while supplying |
|
||||||
| gridPowerSupply | watt | Absolute power level of power supply, zero while drawing |
|
| gridPowerSupply | watt | Absolute power level of power supply, zero while drawing |
|
||||||
@ -135,6 +140,7 @@ Number SenecGridVoltagePh2 "Voltage Level on Phase 2 [%d V]" <e
|
|||||||
Number SenecGridVoltagePh3 "Voltage Level on Phase 3 [%d V]" <energy> { channel="senechome:senechome:pvbattery:gridVoltagePhase3" }
|
Number SenecGridVoltagePh3 "Voltage Level on Phase 3 [%d V]" <energy> { channel="senechome:senechome:pvbattery:gridVoltagePhase3" }
|
||||||
Number SenecGridFrequency "Grid Frequency [%.2f Hz]" <energy> { channel="senechome:senechome:pvbattery:gridFrequency" }
|
Number SenecGridFrequency "Grid Frequency [%.2f Hz]" <energy> { channel="senechome:senechome:pvbattery:gridFrequency" }
|
||||||
Number SenecBatteryVoltage "Battery Voltage [%.1f V]" <energy> { channel="senechome:senechome:pvbattery:batteryVoltage" }
|
Number SenecBatteryVoltage "Battery Voltage [%.1f V]" <energy> { channel="senechome:senechome:pvbattery:batteryVoltage" }
|
||||||
|
String SenecBatteryChargeMode "Battery Charge Mode [%s]" { channel="senechome:senechome:pvbattery:chargeMode" }
|
||||||
```
|
```
|
||||||
|
|
||||||
## Sitemap
|
## Sitemap
|
||||||
@ -166,6 +172,7 @@ Text label="Power Grid"{
|
|||||||
Default item=SenecGridVoltagePh3
|
Default item=SenecGridVoltagePh3
|
||||||
Default item=SenecGridFrequency
|
Default item=SenecGridFrequency
|
||||||
Default item=SenecBatteryVoltage
|
Default item=SenecBatteryVoltage
|
||||||
|
Default item=SenecBatteryChargeMode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -40,6 +40,7 @@ import com.google.gson.JsonSyntaxException;
|
|||||||
*
|
*
|
||||||
* @author Steven Schwarznau - Initial contribution
|
* @author Steven Schwarznau - Initial contribution
|
||||||
* @author Robert Delbrück - Update for Senec API changes
|
* @author Robert Delbrück - Update for Senec API changes
|
||||||
|
* @author Lukas Pindl - Update for writing to safeChargeMode
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@ -72,6 +73,38 @@ public class SenecHomeApi {
|
|||||||
*/
|
*/
|
||||||
public SenecHomeResponse getStatistics()
|
public SenecHomeResponse getStatistics()
|
||||||
throws TimeoutException, ExecutionException, IOException, InterruptedException, JsonSyntaxException {
|
throws TimeoutException, ExecutionException, IOException, InterruptedException, JsonSyntaxException {
|
||||||
|
|
||||||
|
String dataToSend = gson.toJson(new SenecHomeResponse());
|
||||||
|
ContentResponse response = postRequest(dataToSend);
|
||||||
|
return Objects.requireNonNull(gson.fromJson(response.getContentAsString(), SenecHomeResponse.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST json, to lala.cgi of Senec webinterface to set a given parameter
|
||||||
|
*
|
||||||
|
* @return boolean, wether or not the request was successful
|
||||||
|
*/
|
||||||
|
public boolean setValue(String section, String id, String value) {
|
||||||
|
String dataToSend = "{\"" + section + "\":{\"" + id + "\":\"" + value + "\"}}";
|
||||||
|
try {
|
||||||
|
postRequest(dataToSend);
|
||||||
|
return true;
|
||||||
|
} catch (TimeoutException | ExecutionException | IOException | InterruptedException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* helper function to handle the actual POST request to the webinterface
|
||||||
|
*
|
||||||
|
* @return object of type ContentResponse, the response received to the POST request
|
||||||
|
* @throws TimeoutException Communication failed (Timeout)
|
||||||
|
* @throws ExecutionException Communication failed
|
||||||
|
* @throws IOException Communication failed
|
||||||
|
* @throws InterruptedException Communication failed (Interrupted)
|
||||||
|
*/
|
||||||
|
private ContentResponse postRequest(String dataToSend)
|
||||||
|
throws TimeoutException, ExecutionException, IOException, InterruptedException {
|
||||||
String location = hostname + "/lala.cgi";
|
String location = hostname + "/lala.cgi";
|
||||||
logger.trace("sending request to: {}", location);
|
logger.trace("sending request to: {}", location);
|
||||||
|
|
||||||
@ -80,13 +113,11 @@ public class SenecHomeApi {
|
|||||||
request.header(HttpHeader.CONTENT_TYPE, MimeTypes.Type.APPLICATION_JSON.asString());
|
request.header(HttpHeader.CONTENT_TYPE, MimeTypes.Type.APPLICATION_JSON.asString());
|
||||||
ContentResponse response = null;
|
ContentResponse response = null;
|
||||||
try {
|
try {
|
||||||
String dataToSend = gson.toJson(new SenecHomeResponse());
|
|
||||||
logger.trace("data to send: {}", dataToSend);
|
logger.trace("data to send: {}", dataToSend);
|
||||||
response = request.method(HttpMethod.POST).content(new StringContentProvider(dataToSend))
|
response = request.method(HttpMethod.POST).content(new StringContentProvider(dataToSend))
|
||||||
.timeout(15, TimeUnit.SECONDS).send();
|
.timeout(15, TimeUnit.SECONDS).send();
|
||||||
if (response.getStatus() == HttpStatus.OK_200) {
|
if (response.getStatus() == HttpStatus.OK_200) {
|
||||||
String responseString = response.getContentAsString();
|
return response;
|
||||||
return Objects.requireNonNull(gson.fromJson(responseString, SenecHomeResponse.class));
|
|
||||||
} else {
|
} else {
|
||||||
logger.trace("Got unexpected response code {}", response.getStatus());
|
logger.trace("Got unexpected response code {}", response.getStatus());
|
||||||
throw new IOException("Got unexpected response code " + response.getStatus());
|
throw new IOException("Got unexpected response code " + response.getStatus());
|
||||||
|
@ -20,6 +20,7 @@ import org.openhab.core.thing.ThingTypeUID;
|
|||||||
* used across the whole binding.
|
* used across the whole binding.
|
||||||
*
|
*
|
||||||
* @author Steven Schwarznau - Initial contribution
|
* @author Steven Schwarznau - Initial contribution
|
||||||
|
* @author Lukas Pindl - Update for writing to chargeMode
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class SenecHomeBindingConstants {
|
public class SenecHomeBindingConstants {
|
||||||
@ -49,6 +50,7 @@ public class SenecHomeBindingConstants {
|
|||||||
public static final String CHANNEL_SENEC_BATTERY_FUEL_CHARGE = "batteryFuelCharge";
|
public static final String CHANNEL_SENEC_BATTERY_FUEL_CHARGE = "batteryFuelCharge";
|
||||||
public static final String CHANNEL_SENEC_BATTERY_VOLTAGE = "batteryVoltage";
|
public static final String CHANNEL_SENEC_BATTERY_VOLTAGE = "batteryVoltage";
|
||||||
public static final String CHANNEL_SENEC_BATTERY_CURRENT = "batteryCurrent";
|
public static final String CHANNEL_SENEC_BATTERY_CURRENT = "batteryCurrent";
|
||||||
|
public static final String CHANNEL_SENEC_CHARGE_MODE = "chargeMode";
|
||||||
|
|
||||||
// SenecHomeGrid
|
// SenecHomeGrid
|
||||||
public static final String CHANNEL_SENEC_GRID_POWER = "gridPower";
|
public static final String CHANNEL_SENEC_GRID_POWER = "gridPower";
|
||||||
@ -107,4 +109,9 @@ public class SenecHomeBindingConstants {
|
|||||||
public static final String CHANNEL_SENEC_WALLBOX1_CHARGING_CURRENT_PH2 = "wallbox1ChargingCurrentPhase2";
|
public static final String CHANNEL_SENEC_WALLBOX1_CHARGING_CURRENT_PH2 = "wallbox1ChargingCurrentPhase2";
|
||||||
public static final String CHANNEL_SENEC_WALLBOX1_CHARGING_CURRENT_PH3 = "wallbox1ChargingCurrentPhase3";
|
public static final String CHANNEL_SENEC_WALLBOX1_CHARGING_CURRENT_PH3 = "wallbox1ChargingCurrentPhase3";
|
||||||
public static final String CHANNEL_SENEC_WALLBOX1_CHARGING_POWER = "wallbox1ChargingPower";
|
public static final String CHANNEL_SENEC_WALLBOX1_CHARGING_POWER = "wallbox1ChargingPower";
|
||||||
|
|
||||||
|
// Charge Mode Definitions
|
||||||
|
public static final String STATE_SENEC_CHARGE_MODE_OFF = "OFF";
|
||||||
|
public static final String STATE_SENEC_CHARGE_MODE_CHARGE = "CHARGE";
|
||||||
|
public static final String STATE_SENEC_CHARGE_MODE_STORAGE = "STORAGE";
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ import com.google.gson.JsonParseException;
|
|||||||
*
|
*
|
||||||
* @author Steven Schwarznau - Initial contribution
|
* @author Steven Schwarznau - Initial contribution
|
||||||
* @author Erwin Guib - added more channels, added some convenience methods to reduce code duplication
|
* @author Erwin Guib - added more channels, added some convenience methods to reduce code duplication
|
||||||
|
* @author Lukas Pindl - Update for writing to chargeMode
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class SenecHomeHandler extends BaseThingHandler {
|
public class SenecHomeHandler extends BaseThingHandler {
|
||||||
@ -101,7 +102,32 @@ public class SenecHomeHandler extends BaseThingHandler {
|
|||||||
logger.debug("Refreshing {}", channelUID);
|
logger.debug("Refreshing {}", channelUID);
|
||||||
refresh();
|
refresh();
|
||||||
} else {
|
} else {
|
||||||
logger.trace("The SenecHome-Binding is a read-only binding and can not handle commands");
|
String channelID = channelUID.getId();
|
||||||
|
|
||||||
|
logger.trace("Channel: {}", channelID);
|
||||||
|
switch (channelID) {
|
||||||
|
case CHANNEL_SENEC_CHARGE_MODE: {
|
||||||
|
if (command instanceof StringType stringCommand) {
|
||||||
|
logger.trace("Command: {} ", stringCommand.toString());
|
||||||
|
if (stringCommand.toString().equals(STATE_SENEC_CHARGE_MODE_OFF)) {
|
||||||
|
senecHomeApi.setValue("ENERGY", "SAFE_CHARGE_PROHIBIT", "u8_01");
|
||||||
|
senecHomeApi.setValue("ENERGY", "LI_STORAGE_MODE_STOP", "u8_01");
|
||||||
|
} else if (stringCommand.toString().equals(STATE_SENEC_CHARGE_MODE_CHARGE)) {
|
||||||
|
senecHomeApi.setValue("ENERGY", "SAFE_CHARGE_FORCE", "u8_01");
|
||||||
|
senecHomeApi.setValue("ENERGY", "LI_STORAGE_MODE_STOP", "u8_01");
|
||||||
|
} else if (stringCommand.toString().equals(STATE_SENEC_CHARGE_MODE_STORAGE)) {
|
||||||
|
senecHomeApi.setValue("ENERGY", "SAFE_CHARGE_PROHIBIT", "u8_01");
|
||||||
|
senecHomeApi.setValue("ENERGY", "LI_STORAGE_MODE_START", "u8_01");
|
||||||
|
}
|
||||||
|
updateState(channelUID, stringCommand);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
logger.warn("Received command on unexpected channel: {}", channelID);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,6 +212,9 @@ public class SenecHomeHandler extends BaseThingHandler {
|
|||||||
updateQtyState(CHANNEL_SENEC_BATTERY_POWER, response.energy.batteryPower, 2, Units.WATT);
|
updateQtyState(CHANNEL_SENEC_BATTERY_POWER, response.energy.batteryPower, 2, Units.WATT);
|
||||||
updateQtyState(CHANNEL_SENEC_BATTERY_CURRENT, response.energy.batteryCurrent, 2, Units.AMPERE);
|
updateQtyState(CHANNEL_SENEC_BATTERY_CURRENT, response.energy.batteryCurrent, 2, Units.AMPERE);
|
||||||
updateQtyState(CHANNEL_SENEC_BATTERY_VOLTAGE, response.energy.batteryVoltage, 2, Units.VOLT);
|
updateQtyState(CHANNEL_SENEC_BATTERY_VOLTAGE, response.energy.batteryVoltage, 2, Units.VOLT);
|
||||||
|
|
||||||
|
updateChargeState(CHANNEL_SENEC_CHARGE_MODE, response.energy.safeChargeMode, response.energy.liStorageMode);
|
||||||
|
|
||||||
updateStringStateFromInt(CHANNEL_SENEC_SYSTEM_STATE, response.energy.systemState,
|
updateStringStateFromInt(CHANNEL_SENEC_SYSTEM_STATE, response.energy.systemState,
|
||||||
SenecSystemStatus::descriptionFromCode);
|
SenecSystemStatus::descriptionFromCode);
|
||||||
updateDecimalState(CHANNEL_SENEC_SYSTEM_STATE_VALUE, response.energy.systemState);
|
updateDecimalState(CHANNEL_SENEC_SYSTEM_STATE_VALUE, response.energy.systemState);
|
||||||
@ -314,6 +343,21 @@ public class SenecHomeHandler extends BaseThingHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void updateChargeState(String channelName, String senecValueCharge, String senecValueStorage) {
|
||||||
|
Channel channel = getThing().getChannel(channelName);
|
||||||
|
if (channel != null) {
|
||||||
|
BigDecimal valueCharge = getSenecValue(senecValueCharge);
|
||||||
|
BigDecimal valueStorage = getSenecValue(senecValueStorage);
|
||||||
|
if (valueStorage.intValue() == 1) {
|
||||||
|
updateState(channel.getUID(), new StringType(STATE_SENEC_CHARGE_MODE_STORAGE));
|
||||||
|
} else if (valueCharge.intValue() == 1) {
|
||||||
|
updateState(channel.getUID(), new StringType(STATE_SENEC_CHARGE_MODE_CHARGE));
|
||||||
|
} else {
|
||||||
|
updateState(channel.getUID(), new StringType(STATE_SENEC_CHARGE_MODE_OFF));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void updateDecimalState(String channelName, String senecValue) {
|
protected void updateDecimalState(String channelName, String senecValue) {
|
||||||
Channel channel = getThing().getChannel(channelName);
|
Channel channel = getThing().getChannel(channelName);
|
||||||
if (channel != null) {
|
if (channel != null) {
|
||||||
@ -322,6 +366,14 @@ public class SenecHomeHandler extends BaseThingHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void updateSwitchState(String channelName, String senecValue) {
|
||||||
|
Channel channel = getThing().getChannel(channelName);
|
||||||
|
if (channel != null) {
|
||||||
|
BigDecimal value = getSenecValue(senecValue);
|
||||||
|
updateState(channel.getUID(), OnOffType.from(value.intValue() == 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected <Q extends Quantity<Q>> void updateQtyState(String channelName, String senecValue, int scale,
|
protected <Q extends Quantity<Q>> void updateQtyState(String channelName, String senecValue, int scale,
|
||||||
Unit<Q> unit) {
|
Unit<Q> unit) {
|
||||||
updateQtyState(channelName, senecValue, scale, unit, null);
|
updateQtyState(channelName, senecValue, scale, unit, null);
|
||||||
|
@ -23,6 +23,7 @@ import com.google.gson.annotations.SerializedName;
|
|||||||
* Section is "ENERGY"
|
* Section is "ENERGY"
|
||||||
*
|
*
|
||||||
* @author Steven Schwarznau - Initial Contribution
|
* @author Steven Schwarznau - Initial Contribution
|
||||||
|
* @author Lukas Pindl - Update for writing to safeChargeMode
|
||||||
*/
|
*/
|
||||||
public class SenecHomeEnergy implements Serializable {
|
public class SenecHomeEnergy implements Serializable {
|
||||||
|
|
||||||
@ -64,11 +65,21 @@ public class SenecHomeEnergy implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public @SerializedName("STAT_STATE") String systemState;
|
public @SerializedName("STAT_STATE") String systemState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Safe Charge Mode Running.
|
||||||
|
*/
|
||||||
|
public @SerializedName("SAFE_CHARGE_RUNNING") String safeChargeMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lithium Storage Mode Running.
|
||||||
|
*/
|
||||||
|
public @SerializedName("LI_STORAGE_MODE_RUNNING") String liStorageMode;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "SenecHomeEnergy [housePowerConsumption=" + housePowerConsumption + ", inverterPowerGeneration="
|
return "SenecHomeEnergy [housePowerConsumption=" + housePowerConsumption + ", inverterPowerGeneration="
|
||||||
+ inverterPowerGeneration + ", batteryPower=" + batteryPower + ", batteryVoltage=" + batteryVoltage
|
+ inverterPowerGeneration + ", batteryPower=" + batteryPower + ", batteryVoltage=" + batteryVoltage
|
||||||
+ ", batteryCurrent=" + batteryCurrent + ", batteryFuelCharge=" + batteryFuelCharge + ", systemState="
|
+ ", batteryCurrent=" + batteryCurrent + ", batteryFuelCharge=" + batteryFuelCharge + ", systemState="
|
||||||
+ systemState + "]";
|
+ systemState + ", safeChargeMode=" + safeChargeMode + ", liStorageMode=" + liStorageMode + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,10 @@ channel-type.senechome.batteryPower.label = Battery Power
|
|||||||
channel-type.senechome.batteryTemperature.label = Battery Temperature
|
channel-type.senechome.batteryTemperature.label = Battery Temperature
|
||||||
channel-type.senechome.batteryVoltage.label = Battery Voltage
|
channel-type.senechome.batteryVoltage.label = Battery Voltage
|
||||||
channel-type.senechome.caseTemperature.label = Case Temperature
|
channel-type.senechome.caseTemperature.label = Case Temperature
|
||||||
|
channel-type.senechome.chargeMode.label = Safe Charge Mode
|
||||||
|
channel-type.senechome.chargeMode.state.option.OFF = Off
|
||||||
|
channel-type.senechome.chargeMode.state.option.CHARGE = Safe Charge
|
||||||
|
channel-type.senechome.chargeMode.state.option.STORAGE = Lithium Storage
|
||||||
channel-type.senechome.chargedEnergyPack1.label = Total charged energy battery pack 1
|
channel-type.senechome.chargedEnergyPack1.label = Total charged energy battery pack 1
|
||||||
channel-type.senechome.chargedEnergyPack2.label = Total charged energy battery pack 2
|
channel-type.senechome.chargedEnergyPack2.label = Total charged energy battery pack 2
|
||||||
channel-type.senechome.chargedEnergyPack3.label = Total charged energy battery pack 3
|
channel-type.senechome.chargedEnergyPack3.label = Total charged energy battery pack 3
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
<channel id="batteryFuelCharge" typeId="batteryFuelCharge"/>
|
<channel id="batteryFuelCharge" typeId="batteryFuelCharge"/>
|
||||||
<channel id="systemState" typeId="systemState"/>
|
<channel id="systemState" typeId="systemState"/>
|
||||||
<channel id="systemStateValue" typeId="systemStateValue"/>
|
<channel id="systemStateValue" typeId="systemStateValue"/>
|
||||||
|
<channel id="chargeMode" typeId="chargeMode"/>
|
||||||
|
|
||||||
<!-- SenecHomeGrid -->
|
<!-- SenecHomeGrid -->
|
||||||
<channel id="gridPower" typeId="gridPower"/>
|
<channel id="gridPower" typeId="gridPower"/>
|
||||||
@ -242,6 +243,18 @@
|
|||||||
<category>Number</category>
|
<category>Number</category>
|
||||||
<state readOnly="true" pattern="%d"/>
|
<state readOnly="true" pattern="%d"/>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
<channel-type id="chargeMode">
|
||||||
|
<item-type>String</item-type>
|
||||||
|
<label>Safe Charge Mode</label>
|
||||||
|
<category>Text</category>
|
||||||
|
<state readOnly="false" pattern="%s">
|
||||||
|
<options>
|
||||||
|
<option value="OFF">Off</option>
|
||||||
|
<option value="CHARGE">Safe Charge</option>
|
||||||
|
<option value="STORAGE">Lithium Storage</option>
|
||||||
|
</options>
|
||||||
|
</state>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
|
||||||
<channel-type id="gridPower">
|
<channel-type id="gridPower">
|
||||||
|
Loading…
Reference in New Issue
Block a user