added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
32
bundles/org.openhab.binding.senechome/.classpath
Normal file
32
bundles/org.openhab.binding.senechome/.classpath
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
23
bundles/org.openhab.binding.senechome/.project
Normal file
23
bundles/org.openhab.binding.senechome/.project
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.openhab.binding.senechome</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
13
bundles/org.openhab.binding.senechome/NOTICE
Normal file
13
bundles/org.openhab.binding.senechome/NOTICE
Normal file
@@ -0,0 +1,13 @@
|
||||
This content is produced and maintained by the openHAB project.
|
||||
|
||||
* Project home: https://www.openhab.org
|
||||
|
||||
== Declared Project Licenses
|
||||
|
||||
This program and the accompanying materials are made available under the terms
|
||||
of the Eclipse Public License 2.0 which is available at
|
||||
https://www.eclipse.org/legal/epl-2.0/.
|
||||
|
||||
== Source Code
|
||||
|
||||
https://github.com/openhab/openhab-addons
|
||||
82
bundles/org.openhab.binding.senechome/README.md
Normal file
82
bundles/org.openhab.binding.senechome/README.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Senec Home Binding
|
||||
|
||||
Binding to request status information from Senec Home Batteries to allow home automation decisions based on your current energy management.
|
||||
|
||||
If your power feed is limited by regulations for example, you can switch on devices if a limited rate was applied by your Senec Home device.
|
||||
In addition you can switch off devices if the power consumption is getting higher.
|
||||
|
||||
Examples: Lights, pool filters, wash machines, ...
|
||||
|
||||
## Supported Things
|
||||
|
||||
| Thing type id | Name |
|
||||
|----------------------|-----------------------------------------------|
|
||||
| senechome | Senec Home Lithium Battery, V2.0, V2.1 and V3 |
|
||||
|
||||
|
||||
## Thing Configuration
|
||||
|
||||
demo.things
|
||||
|
||||
```
|
||||
Thing senechome:senechome:pvbattery [ hostname="192.168.0.128", refreshInterval=60, limitationTresholdValue=70, limitationDuration=60 ]
|
||||
```
|
||||
|
||||
If the thing goes online then the connection to the web interface is successful.
|
||||
In case it is offline you should see an error message.
|
||||
The refresh interval is 15 seconds by default, but you can optionally provide your own value adding the `refreshInterval` key.
|
||||
|
||||
The property `limitationTresholdValue` is used as threshold for channel `powerLimitationState`. It is combined with property `limitationDuration` (seconds) to define a stable status for power limitation. Therefor use `powerLimitationState` to trigger Events (switches) based on your current power limitation.
|
||||
|
||||
## Channels
|
||||
|
||||
| Channel | Type | Description |
|
||||
|----------------------|---------|--------------------------------------------------------------------------|
|
||||
| powerLimitation | percent | How much is your pv generator limited (0% if not limited anyway) |
|
||||
| powerLimitationState | ON/OFF | Power limitation active (based on configuration) |
|
||||
| houseConsumption | watt | Current power consumption of your house/living |
|
||||
| energyProduction | watt | Energy generated by your pv / inverter |
|
||||
| batteryPower | watt | Energy processed by batterie itself, for example while charging |
|
||||
| batteryFuelCharge | percent | Fuel charge of your battery (0 - 100%) |
|
||||
| batteryState | | text describing current action of battery (e.g. CHARGING) |
|
||||
| gridPower | watt | Grid power level, negative for supply, positive values for drawing power |
|
||||
| gridPowerDraw | watt | absolute power level of power draw, zero while supplying |
|
||||
| gridPowerSupply | watt | absolute power level of power supply, zero while drawing |
|
||||
|
||||
## Items
|
||||
|
||||
Sample:
|
||||
|
||||
```
|
||||
Number SenecPowerLimitation "pv generator limit [%d %%]" <heating> { channel="senechome:senechome:pvbattery:powerLimitation" }
|
||||
Switch SenecPowerLimitationState "Power limitation active" <switch> { channel="senechome:senechome:pvbattery:powerLimitationState" }
|
||||
Number SenecHouseConsumption "Current power consumption [%d W]" <energy> { channel="senechome:senechome:pvbattery:houseConsumption" }
|
||||
Number SenecEnergyProduction "Energy generated by pv [%d W]" <energy> { channel="senechome:senechome:pvbattery:energyProduction" }
|
||||
Number SenecBatteryPower "Energy processed by battery [%d W]" <energy> { channel="senechome:senechome:pvbattery:batteryPower" }
|
||||
Number SenecBatteryFuelCharge "State of Charge [%d %%]" <batterylevel> { channel="senechome:senechome:pvbattery:batteryFuelCharge" }
|
||||
String SenecBatteryState "Current action [%s]" <text> { channel="senechome:senechome:pvbattery:batteryState" }
|
||||
Number SenecGridPower "Grid power level [%d W]" <energy> { channel="senechome:senechome:pvbattery:gridPower" }
|
||||
Number SenecGridPowerDraw "Power draw from grid [%d W]" <energy> { channel="senechome:senechome:pvbattery:gridPowerDraw" }
|
||||
Number SenecGridPowerSupply "Power supply to grid [%d W]" <energy> { channel="senechome:senechome:pvbattery:gridPowerSupply" }
|
||||
```
|
||||
|
||||
## Sitemap
|
||||
|
||||
Sample:
|
||||
|
||||
```
|
||||
Text label="Power Grid"{
|
||||
Frame label="Photovoltaik" {
|
||||
Default item=SenecPowerLimitation
|
||||
Default item=SenecPowerLimitationState
|
||||
Default item=SenecHouseConsumption
|
||||
Default item=SenecEnergyProduction
|
||||
Default item=SenecBatteryPower
|
||||
Default item=SenecBatteryFuelCharge
|
||||
Default item=SenecBatteryState
|
||||
Default item=SenecGridPower
|
||||
Default item=SenecGridPowerDraw
|
||||
Default item=SenecGridPowerSupply
|
||||
}
|
||||
}
|
||||
```
|
||||
17
bundles/org.openhab.binding.senechome/pom.xml
Normal file
17
bundles/org.openhab.binding.senechome/pom.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.binding.senechome</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Bundles :: SenecHome Binding</name>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.senechome-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||
|
||||
<feature name="openhab-binding-senechome" description="SenecHome Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.senechome/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.senechome.internal;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* The {@link PowerLimitationStatusDTO} class is used as a POJO to
|
||||
* in-memory persist the last limitation state change.
|
||||
*
|
||||
* @author Steven Schwarznau - Initial contribution
|
||||
*
|
||||
*/
|
||||
public class PowerLimitationStatusDTO {
|
||||
|
||||
public boolean state = false;
|
||||
|
||||
public long time = new Date().getTime();
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.senechome.internal;
|
||||
|
||||
/**
|
||||
* The {@link SenecBatteryStatus} class defines available Senec specific
|
||||
* battery states.
|
||||
*
|
||||
* @author Steven Schwarznau - Initial contribution
|
||||
*
|
||||
*/
|
||||
public enum SenecBatteryStatus {
|
||||
|
||||
INITIALSTATE(0, "INITIAL STATE"),
|
||||
ERROR_INVERTER_COMMUNICATION(1, "ERROR INVERTER COMMUNICATION"),
|
||||
ERROR_ELECTRICY_METER(2, "ERROR ELECTRICY METER"),
|
||||
RIPPLE_CONTROL_RECEIVER(3, "RIPPLE CONTROL RECEIVER"),
|
||||
INITIAL_CHARGE(4, "INITIAL CHARGE"),
|
||||
MAINTENANCE_CHARGE(5, "MAINTENANCE CHARGE"),
|
||||
MAINTENANCE_READY(6, "MAINTENANCE READY"),
|
||||
MAINTENANCE_REQUIRED(7, "MAINTENANCE REQUIRED"),
|
||||
MAN_SAFETY_CHARGE(8, "MAN. SAFETY CHARGE"),
|
||||
SAFETY_CHARGE_READY(9, "SAFETY CHARGE READY"),
|
||||
FULL_CHARGE(10, "FULL CHARGE"),
|
||||
EQUALIZATION_CHARGE(11, "EQUALIZATION: CHARGE"),
|
||||
DESULFATATION_CHARGE(12, "DESULFATATION: CHARGE"),
|
||||
BATTERY_FULL(13, "BATTERY FULL"),
|
||||
CHARGE(14, "CHARGE"),
|
||||
BATTERY_EMPTY(15, "BATTERY EMPTY"),
|
||||
DISCHARGE(16, "DISCHARGE"),
|
||||
PV_AND_DISCHARGE(17, "PV + DISCHARGE"),
|
||||
GRID_AND_DISCHARGE(18, "GRID + DISCHARGE"),
|
||||
PASSIVE(19, "PASSIVE"),
|
||||
OFF(20, "OFF"),
|
||||
OWN_CONSUMPTION(21, "OWN CONSUMPTION"),
|
||||
RESTART(22, "RESTART"),
|
||||
MAN_EQUALIZATION_CHARGE(23, "MAN. EQUALIZATION: CHARGE"),
|
||||
MAN_DESULFATATION_CHARGE(24, "MAN. DESULFATATION: CHARGE"),
|
||||
SAFETY_CHARGE(25, "SAFETY CHARGE"),
|
||||
BATTERY_PROTECTION_MODE(26, "BATTERY PROTECTION MODE"),
|
||||
EG_ERROR(27, "EG ERROR"),
|
||||
EG_CHARGE(28, "EG CHARGE"),
|
||||
EG_DISCHARGE(29, "EG DISCHARGE"),
|
||||
EG_PASSIVE(30, "EG PASSIVE"),
|
||||
EG_PROHIBIT_CHARGE(31, "EG PROHIBIT CHARGE"),
|
||||
EG_PROHIBIT_DISCHARGE(32, "EG PROHIBIT DISCHARGE"),
|
||||
EMERGANCY_CHARGE(33, "EMERGANCY CHARGE"),
|
||||
SOFTWARE_UPDATE(34, "SOFTWARE UPDATE"),
|
||||
NSP_ERROR(35, "NSP ERROR"),
|
||||
NSP_ERROR_GRID(36, "NSP ERROR: GRID"),
|
||||
NSP_ERROR_HARDWRE(37, "NSP ERROR: HARDWRE"),
|
||||
NO_SERVER_CONNECTION(38, "NO SERVER CONNECTION"),
|
||||
BMS_ERROR(39, "BMS ERROR"),
|
||||
MAINTENANCE_FILTER(40, "MAINTENANCE: FILTER"),
|
||||
SLEEPING_MODE(41, "SLEEPING MODE"),
|
||||
WAITING_EXCESS(42, "WAITING EXCESS"),
|
||||
CAPACITY_TEST_CHARGE(43, "CAPACITY TEST: CHARGE"),
|
||||
CAPACITY_TEST_DISCHARGE(44, "CAPACITY TEST: DISCHARGE"),
|
||||
MAN_DESULFATATION_WAIT(45, "MAN. DESULFATATION: WAIT"),
|
||||
MAN_DESULFATATION_READY(46, "MAN. DESULFATATION: READY"),
|
||||
MAN_DESULFATATION_ERROR(47, "MAN. DESULFATATION: ERROR"),
|
||||
EQUALIZATION_WAIT(48, "EQUALIZATION: WAIT"),
|
||||
EMERGANCY_CHARGE_ERROR(49, "EMERGANCY CHARGE: ERROR"),
|
||||
MAN_EQUALIZATION_WAIT(50, "MAN. EQUALIZATION: WAIT"),
|
||||
MAN_EQUALIZATION_ERROR(51, "MAN. EQUALIZATION: ERROR"),
|
||||
MAN_EQUALIZATION_READY(52, "MAN: EQUALIZATION: READY"),
|
||||
AUTO_DESULFATATION_WAIT(53, "AUTO. DESULFATATION: WAIT"),
|
||||
ABSORPTION_PHASE(54, "ABSORPTION PHASE"),
|
||||
DCSWITCH_OFF(55, "DC-SWITCH OFF"),
|
||||
PEAKSHAVING_WAIT(56, "PEAK-SHAVING: WAIT"),
|
||||
ERROR_BATTERY_INVERTER(57, "ERROR BATTERY INVERTER"),
|
||||
NPUERROR(58, "NPU-ERROR"),
|
||||
BMS_OFFLINE(59, "BMS OFFLINE"),
|
||||
MAINTENANCE_CHARGE_ERROR(60, "MAINTENANCE CHARGE ERROR"),
|
||||
MAN_SAFETY_CHARGE_ERROR(61, "MAN. SAFETY CHARGE ERROR"),
|
||||
SAFETY_CHARGE_ERROR(62, "SAFETY CHARGE ERROR"),
|
||||
NO_CONNECTION_TO_MASTER(63, "NO CONNECTION TO MASTER"),
|
||||
LITHIUM_SAFE_MODE_ACTIVE(64, "LITHIUM SAFE MODE ACTIVE"),
|
||||
LITHIUM_SAFE_MODE_DONE(65, "LITHIUM SAFE MODE DONE"),
|
||||
BATTERY_VOLTAGE_ERROR(66, "BATTERY VOLTAGE ERROR"),
|
||||
BMS_DC_SWITCHED_OFF(67, "BMS DC SWITCHED OFF"),
|
||||
GRID_INITIALIZATION(68, "GRID INITIALIZATION"),
|
||||
GRID_STABILIZATION(69, "GRID STABILIZATION"),
|
||||
REMOTE_SHUTDOWN(70, "REMOTE SHUTDOWN"),
|
||||
OFFPEAKCHARGE(71, "OFFPEAK-CHARGE"),
|
||||
ERROR_HALFBRIDGE(72, "ERROR HALFBRIDGE"),
|
||||
BMS_ERROR_OPERATING_TEMPERATURE(73, "BMS: ERROR OPERATING TEMPERATURE"),
|
||||
FACOTRY_SETTINGS_NOT_FOUND(74, "FACOTRY SETTINGS NOT FOUND"),
|
||||
BACKUP_POWER_MODE_ACTIVE(75, "BACKUP POWER MODE - ACTIVE"),
|
||||
BACKUP_POWER_MODE_BATTERY_EMPTY(76, "BACKUP POWER MODE - BATTERY EMPTY"),
|
||||
BACKUP_POWER_MODE_ERROR(77, "BACKUP POWER MODE ERROR"),
|
||||
INITIALISING(78, "INITIALISING"),
|
||||
INSTALLATION_MODE(79, "INSTALLATION MODE"),
|
||||
GRID_OFFLINE(80, "GRID OFFLINE"),
|
||||
BMS_UPDATE_NEEDED(81, "BMS UPDATE NEEDED"),
|
||||
BMS_CONFIGURATION_NEEDED(82, "BMS CONFIGURATION NEEDED"),
|
||||
INSULATION_TEST(83, "INSULATION TEST"),
|
||||
SELFTEST(84, "SELFTEST"),
|
||||
EXTERNAL_CONTROL(85, "EXTERNAL CONTROL"),
|
||||
ERROR_TEMPERATURESENSOR(86, "ERROR: TEMPERATURESENSOR"),
|
||||
GRID_OPERATOR_CHARGE_PROHIBITED(87, "GRID OPERATOR: CHARGE PROHIBITED"),
|
||||
GRID_OPERATOR_DISCHARGE_PROHIBITED(88, "GRID OPERATOR: DISCHARGE PROHIBITED"),
|
||||
SPARE_CAPACITY(89, "SPARE CAPACITY"),
|
||||
SELFTEST_ERROR(90, "SELFTEST ERROR"),
|
||||
EARTH_FAULT(91, "EARTH FAULT"),
|
||||
UNKNOWN(-1, "UNKNOWN");
|
||||
|
||||
private int code;
|
||||
private String description;
|
||||
|
||||
SenecBatteryStatus(int index, String description) {
|
||||
this.code = index;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public static SenecBatteryStatus fromCode(int code) {
|
||||
for (SenecBatteryStatus state : SenecBatteryStatus.values()) {
|
||||
if (state.code == code) {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
return SenecBatteryStatus.UNKNOWN;
|
||||
}
|
||||
|
||||
public static String descriptionFromCode(int code) {
|
||||
for (SenecBatteryStatus state : SenecBatteryStatus.values()) {
|
||||
if (state.code == code) {
|
||||
return state.description;
|
||||
}
|
||||
}
|
||||
return SenecBatteryStatus.UNKNOWN.description;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.senechome.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
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.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.http.MimeTypes;
|
||||
import org.openhab.binding.senechome.internal.json.SenecHomeResponse;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
/**
|
||||
* The {@link SenecHomeApi} class configures http client and
|
||||
* performs status requests
|
||||
*
|
||||
* @author Steven Schwarznau - Initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SenecHomeApi {
|
||||
private static final String HTTP_PROTO_PREFIX = "http://";
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(SenecHomeApi.class);
|
||||
private final HttpClient httpClient;
|
||||
private final Gson gson = new Gson();
|
||||
private String hostname = "";
|
||||
|
||||
public SenecHomeApi(HttpClient httpClient) {
|
||||
this.httpClient = httpClient;
|
||||
}
|
||||
|
||||
public void setHostname(String hostname) {
|
||||
this.hostname = hostname;
|
||||
}
|
||||
|
||||
/**
|
||||
* POST json with empty, but expected fields, to lala.cgi of Senec webinterface
|
||||
* the response will contain the same fields, but with the corresponding values
|
||||
*
|
||||
* To receive new values, just modify the Json objects and add them to the thing channels
|
||||
*
|
||||
* @param hostname Hostname or ip address of senec battery
|
||||
* @return Instance of SenecHomeResponse
|
||||
* @throws MalformedURLException Configuration/URL is wrong
|
||||
* @throws IOException Communication failed
|
||||
*/
|
||||
public SenecHomeResponse getStatistics()
|
||||
throws InterruptedException, TimeoutException, ExecutionException, IOException {
|
||||
String location = HTTP_PROTO_PREFIX + hostname;
|
||||
|
||||
Request request = httpClient.newRequest(location);
|
||||
request.header(HttpHeader.ACCEPT, MimeTypes.Type.APPLICATION_JSON.asString());
|
||||
request.header(HttpHeader.CONTENT_TYPE, MimeTypes.Type.FORM_ENCODED.asString());
|
||||
ContentResponse response = request.method(HttpMethod.POST)
|
||||
.content(new StringContentProvider(gson.toJson(new SenecHomeResponse()))).send();
|
||||
|
||||
if (response.getStatus() == HttpStatus.OK_200) {
|
||||
return gson.fromJson(response.getContentAsString(), SenecHomeResponse.class);
|
||||
} else {
|
||||
logger.trace("Got unexpected response code {}", response.getStatus());
|
||||
throw new IOException("Got unexpected response code " + response.getStatus());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.senechome.internal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link SenecHomeBindingConstants} class defines common constants, which are
|
||||
* used across the whole binding.
|
||||
*
|
||||
* @author Steven Schwarznau - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SenecHomeBindingConstants {
|
||||
private static final String BINDING_ID = "senechome";
|
||||
private static final String THING_BASE_ID = "senechome";
|
||||
public static final ThingTypeUID THING_TYPE_SENEC_HOME_BATTERY = new ThingTypeUID(BINDING_ID, THING_BASE_ID);
|
||||
|
||||
public static final String CHANNEL_SENEC_POWER_LIMITATION = "powerLimitation";
|
||||
public static final String CHANNEL_SENEC_POWER_LIMITATION_STATE = "powerLimitationState";
|
||||
public static final String CHANNEL_SENEC_BATTERY_STATE = "batteryState";
|
||||
public static final String CHANNEL_SENEC_POWER_CONSUMPTION = "houseConsumption";
|
||||
public static final String CHANNEL_SENEC_ENERGY_PRODUCTION = "energyProduction";
|
||||
public static final String CHANNEL_SENEC_BATTERY_POWER = "batteryPower";
|
||||
public static final String CHANNEL_SENEC_BATTERY_FUEL_CHARGE = "batteryFuelCharge";
|
||||
public static final String CHANNEL_SENEC_GRID_POWER = "gridPower";
|
||||
public static final String CHANNEL_SENEC_GRID_POWER_SUPPLY = "gridPowerSupply";
|
||||
public static final String CHANNEL_SENEC_GRID_POWER_DRAW = "gridPowerDraw";
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.senechome.internal;
|
||||
|
||||
/**
|
||||
* The {@link SenecHomeConfigurationDTO} class contains fields mapping thing configuration parameters.
|
||||
*
|
||||
* @author Steven Schwarznau - Initial contribution
|
||||
*/
|
||||
public class SenecHomeConfigurationDTO {
|
||||
public String hostname;
|
||||
public int refreshInterval = 15;
|
||||
public int limitationTresholdValue = 95;
|
||||
public int limitationDuration = 120;
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.senechome.internal;
|
||||
|
||||
import static org.openhab.core.types.RefreshType.REFRESH;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.Duration;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import javax.measure.quantity.Dimensionless;
|
||||
import javax.measure.quantity.Power;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.binding.senechome.internal.json.SenecHomeResponse;
|
||||
import org.openhab.core.cache.ExpiringCache;
|
||||
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.library.unit.SmartHomeUnits;
|
||||
import org.openhab.core.thing.Channel;
|
||||
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.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link SenecHomeHandler} is responsible for handling commands, which are
|
||||
* sent to one of the channels.
|
||||
*
|
||||
* @author Steven Schwarznau - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SenecHomeHandler extends BaseThingHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(SenecHomeHandler.class);
|
||||
private final static String VALUE_TYPE_INT = "u3";
|
||||
private final static String VALUE_TYPE_UNSIGNED_INT = "u8";
|
||||
private final static String VALUE_TYPE_FLOAT = "fl";
|
||||
|
||||
private @Nullable ScheduledFuture<?> refreshJob;
|
||||
private @Nullable PowerLimitationStatusDTO limitationStatus = null;
|
||||
private final @Nullable SenecHomeApi senecHomeApi;
|
||||
private SenecHomeConfigurationDTO config = new SenecHomeConfigurationDTO();
|
||||
private final ExpiringCache<Boolean> refreshCache = new ExpiringCache<>(Duration.ofSeconds(5), this::refreshState);
|
||||
|
||||
public SenecHomeHandler(Thing thing, HttpClient httpClient) {
|
||||
super(thing);
|
||||
this.senecHomeApi = new SenecHomeApi(httpClient);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleRemoval() {
|
||||
stopJobIfRunning();
|
||||
super.handleRemoval();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (command == REFRESH) {
|
||||
logger.debug("Refreshing {}", channelUID);
|
||||
refresh();
|
||||
} else {
|
||||
logger.trace("The SenecHome-Binding is a read-only binding and can not handle commands");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
stopJobIfRunning();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
protected void stopJobIfRunning() {
|
||||
final ScheduledFuture<?> refreshJob = this.refreshJob;
|
||||
if (refreshJob != null && !refreshJob.isCancelled()) {
|
||||
refreshJob.cancel(true);
|
||||
this.refreshJob = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
config = getConfigAs(SenecHomeConfigurationDTO.class);
|
||||
senecHomeApi.setHostname(config.hostname);
|
||||
refreshJob = scheduler.scheduleWithFixedDelay(this::refresh, 0, config.refreshInterval, TimeUnit.SECONDS);
|
||||
limitationStatus = null;
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
refreshCache.getValue();
|
||||
}
|
||||
|
||||
public @Nullable Boolean refreshState() {
|
||||
try {
|
||||
SenecHomeResponse response = senecHomeApi.getStatistics();
|
||||
logger.trace("received {}", response);
|
||||
|
||||
BigDecimal pvLimitation = new BigDecimal(100).subtract(getSenecValue(response.limitation.powerLimitation))
|
||||
.setScale(0, RoundingMode.HALF_UP);
|
||||
|
||||
updateState(SenecHomeBindingConstants.CHANNEL_SENEC_POWER_LIMITATION,
|
||||
new QuantityType<Dimensionless>(pvLimitation, SmartHomeUnits.PERCENT));
|
||||
|
||||
Channel channelLimitationState = getThing()
|
||||
.getChannel(SenecHomeBindingConstants.CHANNEL_SENEC_POWER_LIMITATION_STATE);
|
||||
updatePowerLimitationStatus(channelLimitationState,
|
||||
(100 - pvLimitation.intValue()) <= config.limitationTresholdValue, config.limitationDuration);
|
||||
|
||||
Channel channelConsumption = getThing()
|
||||
.getChannel(SenecHomeBindingConstants.CHANNEL_SENEC_POWER_CONSUMPTION);
|
||||
updateState(channelConsumption.getUID(),
|
||||
new QuantityType<Power>(
|
||||
getSenecValue(response.energy.homePowerConsumption).setScale(2, RoundingMode.HALF_UP),
|
||||
SmartHomeUnits.WATT));
|
||||
|
||||
Channel channelEnergyProduction = getThing()
|
||||
.getChannel(SenecHomeBindingConstants.CHANNEL_SENEC_ENERGY_PRODUCTION);
|
||||
updateState(channelEnergyProduction.getUID(),
|
||||
new QuantityType<Power>(
|
||||
getSenecValue(response.energy.inverterPowerGeneration).setScale(0, RoundingMode.HALF_UP),
|
||||
SmartHomeUnits.WATT));
|
||||
|
||||
Channel channelBatteryPower = getThing().getChannel(SenecHomeBindingConstants.CHANNEL_SENEC_BATTERY_POWER);
|
||||
updateState(channelBatteryPower.getUID(),
|
||||
new QuantityType<Power>(
|
||||
getSenecValue(response.energy.batteryPower).setScale(2, RoundingMode.HALF_UP),
|
||||
SmartHomeUnits.WATT));
|
||||
|
||||
Channel channelBatteryFuelCharge = getThing()
|
||||
.getChannel(SenecHomeBindingConstants.CHANNEL_SENEC_BATTERY_FUEL_CHARGE);
|
||||
updateState(channelBatteryFuelCharge.getUID(),
|
||||
new QuantityType<Dimensionless>(
|
||||
getSenecValue(response.energy.batteryFuelCharge).setScale(0, RoundingMode.HALF_UP),
|
||||
SmartHomeUnits.PERCENT));
|
||||
|
||||
Channel channelBatteryState = getThing().getChannel(SenecHomeBindingConstants.CHANNEL_SENEC_BATTERY_STATE);
|
||||
updateBatteryState(channelBatteryState, getSenecValue(response.energy.batteryState).intValue());
|
||||
|
||||
updateGridPowerValues(getSenecValue(response.grid.currentGridValue));
|
||||
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
} catch (IOException | InterruptedException | TimeoutException | ExecutionException e) {
|
||||
logger.warn("Error refreshing source '{}'", getThing().getUID(), e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Could not connect to Senec web interface:" + e.getMessage());
|
||||
}
|
||||
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
protected BigDecimal getSenecValue(String value) {
|
||||
String[] type = value.split("_");
|
||||
|
||||
if (VALUE_TYPE_INT.equalsIgnoreCase(type[0])) {
|
||||
return new BigDecimal(Integer.valueOf(type[1], 16));
|
||||
} else if (VALUE_TYPE_UNSIGNED_INT.equalsIgnoreCase(type[0])) {
|
||||
return new BigDecimal(Integer.valueOf(type[1], 16));
|
||||
} else if (VALUE_TYPE_FLOAT.equalsIgnoreCase(type[0])) {
|
||||
return parseFloatValue(type[1]);
|
||||
} else {
|
||||
logger.warn("Unknown value type [{}]", type[0]);
|
||||
}
|
||||
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the hex coded float value of Senec device and return as BigDecimal
|
||||
*
|
||||
* @param value String with hex float
|
||||
* @return BigDecimal with float value
|
||||
*/
|
||||
private static BigDecimal parseFloatValue(String value) {
|
||||
// sample: value = 43E26188
|
||||
|
||||
float f = Float.intBitsToFloat(Integer.parseUnsignedInt(value, 16));
|
||||
return new BigDecimal(f);
|
||||
}
|
||||
|
||||
protected void updatePowerLimitationStatus(Channel channel, boolean status, int duration) {
|
||||
if (this.limitationStatus != null) {
|
||||
if (this.limitationStatus.state == status) {
|
||||
long stateSince = new Date().getTime() - this.limitationStatus.time;
|
||||
|
||||
if (((int) (stateSince / 1000)) < duration) {
|
||||
// skip updating state (possible flapping state)
|
||||
return;
|
||||
} else {
|
||||
logger.debug("{} longer than required duration {}", status, duration);
|
||||
}
|
||||
} else {
|
||||
this.limitationStatus.state = status;
|
||||
this.limitationStatus.time = new Date().getTime();
|
||||
|
||||
// skip updating state (state changed, possible flapping state)
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
this.limitationStatus = new PowerLimitationStatusDTO();
|
||||
this.limitationStatus.state = status;
|
||||
}
|
||||
|
||||
logger.debug("Updating power limitation state {}", status);
|
||||
updateState(channel.getUID(), status ? OnOffType.ON : OnOffType.OFF);
|
||||
}
|
||||
|
||||
protected void updateBatteryState(Channel channel, int code) {
|
||||
updateState(channel.getUID(), new StringType(SenecBatteryStatus.descriptionFromCode(code)));
|
||||
}
|
||||
|
||||
protected void updateGridPowerValues(BigDecimal gridTotalValue) {
|
||||
BigDecimal gridTotal = gridTotalValue.setScale(2, RoundingMode.HALF_UP);
|
||||
|
||||
Channel channelGridPower = getThing().getChannel(SenecHomeBindingConstants.CHANNEL_SENEC_GRID_POWER);
|
||||
if (channelGridPower != null) {
|
||||
updateState(channelGridPower.getUID(), new QuantityType<Power>(gridTotal, SmartHomeUnits.WATT));
|
||||
}
|
||||
|
||||
Channel channelGridPowerSupply = getThing()
|
||||
.getChannel(SenecHomeBindingConstants.CHANNEL_SENEC_GRID_POWER_SUPPLY);
|
||||
if (channelGridPowerSupply != null) {
|
||||
BigDecimal gridSupply = gridTotal.compareTo(BigDecimal.ZERO) < 0 ? gridTotal.abs() : BigDecimal.ZERO;
|
||||
updateState(channelGridPowerSupply.getUID(), new QuantityType<Power>(gridSupply, SmartHomeUnits.WATT));
|
||||
}
|
||||
|
||||
Channel channelGridPowerDraw = getThing().getChannel(SenecHomeBindingConstants.CHANNEL_SENEC_GRID_POWER_DRAW);
|
||||
if (channelGridPowerDraw != null) {
|
||||
BigDecimal gridDraw = gridTotal.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : gridTotal.abs();
|
||||
updateState(channelGridPowerDraw.getUID(), new QuantityType<Power>(gridDraw, SmartHomeUnits.WATT));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.senechome.internal;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
* The {@link SenecHomeHandlerFactory} is responsible for creating things and thing
|
||||
* handlers.
|
||||
*
|
||||
* @author Steven Schwarznau - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(configurationPid = "binding.senechome", service = ThingHandlerFactory.class)
|
||||
public class SenecHomeHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections
|
||||
.singleton(SenecHomeBindingConstants.THING_TYPE_SENEC_HOME_BATTERY);
|
||||
|
||||
private HttpClient httpClient;
|
||||
|
||||
@Activate
|
||||
public SenecHomeHandlerFactory(@Reference HttpClientFactory httpClientFactory) {
|
||||
this.httpClient = httpClientFactory.getCommonHttpClient();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
if (SenecHomeBindingConstants.THING_TYPE_SENEC_HOME_BATTERY.equals(thingTypeUID)) {
|
||||
return new SenecHomeHandler(thing, httpClient);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.senechome.internal.json;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* Json model of senec home devices: This sub model contains values of current workload, i. e. current consumption and
|
||||
* battery charge.
|
||||
*
|
||||
* @author Steven Schwarznau - Initial Contribution
|
||||
*/
|
||||
public class SenecHomeEnergy implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -6171687327416551070L;
|
||||
|
||||
public @SerializedName("GUI_HOUSE_POW") String homePowerConsumption;
|
||||
public @SerializedName("GUI_INVERTER_POWER") String inverterPowerGeneration;
|
||||
public @SerializedName("GUI_BAT_DATA_POWER") String batteryPower;
|
||||
public @SerializedName("GUI_BAT_DATA_FUEL_CHARGE") String batteryFuelCharge;
|
||||
public @SerializedName("STAT_STATE") String batteryState;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SenecHomeEnergy [homePowerConsumption=" + homePowerConsumption + ", inverterPowerGeneration="
|
||||
+ inverterPowerGeneration + ", batteryPower=" + batteryPower + ", batteryFuelCharge="
|
||||
+ batteryFuelCharge + ", batteryState=" + batteryState + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.senechome.internal.json;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* Json model of senec home devices: This sub model provides the current power limitation by the inverter.
|
||||
*
|
||||
* @author Steven Schwarznau - Initial Contribution
|
||||
*/
|
||||
public class SenecHomeGrid implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -7479338321370375451L;
|
||||
|
||||
/**
|
||||
* grid value indicating the current power draw (for values larger zero) or supply (for negative values)
|
||||
*/
|
||||
public @SerializedName("P_TOTAL") String currentGridValue;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SenecHomeGrid [currentGridValue=" + currentGridValue + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.senechome.internal.json;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* Json model of senec home devices: This sub model contains grid related power values.
|
||||
*
|
||||
* @author Steven Schwarznau - Initial Contribution
|
||||
*/
|
||||
public class SenecHomeLimitation implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -8990871346958824085L;
|
||||
|
||||
public @SerializedName("POWER_RATIO") String powerLimitation;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SenecHomePower [powerLimitation=" + powerLimitation + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.senechome.internal.json;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* Json model of senec home devices rebuilt by analyzing the api.
|
||||
*
|
||||
* @author Steven Schwarznau - Initial Contribution
|
||||
*/
|
||||
public class SenecHomeResponse implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 5302080655053778494L;
|
||||
|
||||
public @SerializedName("PV1") SenecHomeLimitation limitation = new SenecHomeLimitation();
|
||||
public @SerializedName("ENERGY") SenecHomeEnergy energy = new SenecHomeEnergy();
|
||||
public @SerializedName("PM1OBJ1") SenecHomeGrid grid = new SenecHomeGrid();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SenecHomeResponse [limitation=" + limitation + ", energy=" + energy + ", grid=" + grid + "]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding id="senechome" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
|
||||
|
||||
<name>SenecHome Binding</name>
|
||||
<description>This is the binding for SenecHome.</description>
|
||||
<author>Steven Schwarznau and Korbinian Probst</author>
|
||||
|
||||
</binding:binding>
|
||||
@@ -0,0 +1,113 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="senechome"
|
||||
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">
|
||||
|
||||
<!-- Sample Thing Type -->
|
||||
<thing-type id="senechome">
|
||||
<label>Senec Home</label>
|
||||
<description>Senec Home</description>
|
||||
|
||||
<channels>
|
||||
<channel id="powerLimitation" typeId="powerLimitation"/>
|
||||
<channel id="powerLimitationState" typeId="powerLimitationState"/>
|
||||
<channel id="houseConsumption" typeId="houseConsumption"/>
|
||||
<channel id="energyProduction" typeId="energyProduction"/>
|
||||
<channel id="batteryPower" typeId="batteryPower"/>
|
||||
<channel id="batteryFuelCharge" typeId="batteryFuelCharge"/>
|
||||
<channel id="batteryState" typeId="system.battery-level"/>
|
||||
<channel id="gridPower" typeId="gridPower"/>
|
||||
<channel id="gridPowerSupply" typeId="gridPowerSupply"/>
|
||||
<channel id="gridPowerDraw" typeId="gridPowerDraw"/>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
<parameter name="hostname" type="text" required="true">
|
||||
<label>Hostname/IP Address</label>
|
||||
<description>Enter the hostname or ip address of your Senec Home device</description>
|
||||
<context>network-address</context>
|
||||
</parameter>
|
||||
<parameter name="refreshInterval" type="integer" min="1" unit="s">
|
||||
<label>Refresh Interval</label>
|
||||
<description>Rate of refreshing details (in s)</description>
|
||||
<default>15</default>
|
||||
</parameter>
|
||||
<parameter name="limitationTresholdValue" type="integer" min="0" max="100" unit="%">
|
||||
<label>Limitation Treshold</label>
|
||||
<description>Treshold in percent, defines when limitation state is enabled</description>
|
||||
<default>95</default>
|
||||
</parameter>
|
||||
<parameter name="limitationDuration" type="integer" unit="s" min="1" max="1200">
|
||||
<label>Limitation Duration</label>
|
||||
<description>Duration of stable values until state is changed, defined in seconds</description>
|
||||
<default>120</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</thing-type>
|
||||
|
||||
<channel-type id="powerLimitation">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Power Limitation</label>
|
||||
<category>Energy</category>
|
||||
<state readOnly="true" pattern="%.0f %unit%"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="powerLimitationState">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Limitation State</label>
|
||||
<category>Energy</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="houseConsumption">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Home Power Consumption</label>
|
||||
<category>Energy</category>
|
||||
<state readOnly="true" pattern="%.2f %unit%"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="batteryPower">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Battery Power</label>
|
||||
<category>Energy</category>
|
||||
<state readOnly="true" pattern="%.2f %unit%"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="batteryFuelCharge">
|
||||
<item-type>Number:Dimensionless</item-type>
|
||||
<label>Battery Fuel</label>
|
||||
<category>Battery</category>
|
||||
<state readOnly="true" pattern="%.0f %unit%"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="energyProduction">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Solar Production</label>
|
||||
<category>Energy</category>
|
||||
<state readOnly="true" pattern="%.0f %unit%"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="gridPower">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Grid Power</label>
|
||||
<category>Energy</category>
|
||||
<state readOnly="true" pattern="%.2f %unit%"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="gridPowerSupply">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Grid Supply</label>
|
||||
<category>Energy</category>
|
||||
<state readOnly="true" pattern="%.2f %unit%"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="gridPowerDraw">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Grid Draw</label>
|
||||
<category>Energy</category>
|
||||
<state readOnly="true" pattern="%.2f %unit%"/>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
Reference in New Issue
Block a user