mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-25 14:55:55 +01:00
[Senec] Fix for Senec firmware update (#15535)
* Fix for Senec update Signed-off-by: querdenker2k <querdenker2k@gmx.de>
This commit is contained in:
parent
6176b080c4
commit
1eacf67f34
@ -18,13 +18,14 @@ Examples: Lights, pool filters, wash machines, ...
|
||||
- only V3, V3duo have a power generator and thus MPPs (V3 has 2 MPP, V3duo has 3 MPP)
|
||||
- not equipped battery packs will return 0 for all ...Pack channels
|
||||
- currently channels for the first wallbox are implemented (senec could handle 4 wallboxes)
|
||||
- Senec disables http access at ~30.08.2023
|
||||
|
||||
## Thing Configuration
|
||||
|
||||
demo.things
|
||||
|
||||
```java
|
||||
Thing senechome:senechome:pvbattery [ hostname="192.168.0.128", refreshInterval=60, limitationTresholdValue=70, limitationDuration=60 ]
|
||||
Thing senechome:senechome:pvbattery [ hostname="192.168.0.128", refreshInterval=60, limitationTresholdValue=70, limitationDuration=60, useHttp=false ]
|
||||
```
|
||||
|
||||
If the thing goes online then the connection to the web interface is successful.
|
||||
@ -69,13 +70,6 @@ The property `limitationTresholdValue` is used as threshold for channel `powerLi
|
||||
| gridVoltagePhase2 | volt | Grid voltage on Phase 2 |
|
||||
| gridVoltagePhase3 | volt | Grid voltage on Phase 3 |
|
||||
| gridFrequency | hertz | Grid frequency |
|
||||
| liveBatCharge | kilo watt hour | Live Total Bat Charge |
|
||||
| liveBatDischarge | kilo watt hour | Live Total Bat Discharge |
|
||||
| liveGridImport | kilo watt hour | Live Total Grid Import |
|
||||
| liveGridExport | kilo watt hour | Live Total Grid Export |
|
||||
| liveHouseConsumption | kilo watt hour | Live Total House Consumption (without WB) |
|
||||
| livePowerGenerator | kilo watt hour | Live Total PV generator generated energy |
|
||||
| liveEnergyWallbox1 | kilo watt hour | Live Total Wallbox 1 charged energy |
|
||||
| chargedEnergyPack1 | kilo watt hour | total charged energy battery pack 1 |
|
||||
| chargedEnergyPack2 | kilo watt hour | total charged energy battery pack 2 |
|
||||
| chargedEnergyPack3 | kilo watt hour | total charged energy battery pack 3 |
|
||||
@ -141,10 +135,6 @@ 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 SenecGridFrequency "Grid Frequency [%.2f Hz]" <energy> { channel="senechome:senechome:pvbattery:gridFrequency" }
|
||||
Number SenecBatteryVoltage "Battery Voltage [%.1f V]" <energy> { channel="senechome:senechome:pvbattery:batteryVoltage" }
|
||||
Number SenecLiveBatCharge "Live Bat Charge [%d kWh]" <energy> { channel="senechome:senechome:pvbattery:liveBatCharge" }
|
||||
Number SenecLiveBatDischarge "Live Bat Discharge [%d kWh]" <energy> { channel="senechome:senechome:pvbattery:liveBatDischarge" }
|
||||
Number SenecLiveGridImport "Live Grid Import [%d kWh]" <energy> { channel="senechome:senechome:pvbattery:liveGridImport" }
|
||||
Number SenecLiveGridExport "Live Grid Export [%d kWh]" <energy> { channel="senechome:senechome:pvbattery:liveGridExport" }
|
||||
```
|
||||
|
||||
## Sitemap
|
||||
@ -176,10 +166,6 @@ Text label="Power Grid"{
|
||||
Default item=SenecGridVoltagePh3
|
||||
Default item=SenecGridFrequency
|
||||
Default item=SenecBatteryVoltage
|
||||
Default item=SenecLiveBatCharge
|
||||
Default item=SenecLiveBatDischarge
|
||||
Default item=SenecLiveGridImport
|
||||
Default item=SenecLiveGridExport
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -13,7 +13,6 @@
|
||||
package org.openhab.binding.senechome.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
@ -33,19 +32,17 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.stream.MalformedJsonException;
|
||||
|
||||
/**
|
||||
* The {@link SenecHomeApi} class configures http client and
|
||||
* performs status requests
|
||||
*
|
||||
* @author Steven Schwarznau - Initial contribution
|
||||
* @author Robert Delbrück - Update for Senec API changes
|
||||
*
|
||||
*/
|
||||
@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();
|
||||
@ -66,28 +63,33 @@ public class SenecHomeApi {
|
||||
* To receive new values, just modify the Json objects and add them to the thing channels
|
||||
*
|
||||
* @return Instance of SenecHomeResponse
|
||||
* @throws MalformedURLException Configuration/URL is wrong
|
||||
* @throws TimeoutException Communication failed (Timeout)
|
||||
* @throws ExecutionException Communication failed
|
||||
* @throws IOException Communication failed
|
||||
* @throws InterruptedException Communication failed (Interrupted)
|
||||
* @throws JsonSyntaxException Received response has an invalid json syntax
|
||||
*/
|
||||
public SenecHomeResponse getStatistics()
|
||||
throws InterruptedException, TimeoutException, ExecutionException, IOException {
|
||||
String location = HTTP_PROTO_PREFIX + hostname;
|
||||
throws TimeoutException, ExecutionException, IOException, InterruptedException, JsonSyntaxException {
|
||||
String location = hostname + "/lala.cgi";
|
||||
logger.trace("sending request to: {}", location);
|
||||
|
||||
Request request = httpClient.newRequest(location);
|
||||
request.header(HttpHeader.ACCEPT, MimeTypes.Type.APPLICATION_JSON.asString());
|
||||
request.header(HttpHeader.CONTENT_TYPE, MimeTypes.Type.FORM_ENCODED.asString());
|
||||
request.header(HttpHeader.CONTENT_TYPE, MimeTypes.Type.APPLICATION_JSON.asString());
|
||||
ContentResponse response = null;
|
||||
try {
|
||||
response = request.method(HttpMethod.POST)
|
||||
.content(new StringContentProvider(gson.toJson(new SenecHomeResponse()))).send();
|
||||
String dataToSend = gson.toJson(new SenecHomeResponse());
|
||||
logger.trace("data to send: {}", dataToSend);
|
||||
response = request.method(HttpMethod.POST).content(new StringContentProvider(dataToSend)).send();
|
||||
if (response.getStatus() == HttpStatus.OK_200) {
|
||||
return Objects.requireNonNull(gson.fromJson(response.getContentAsString(), SenecHomeResponse.class));
|
||||
String responseString = response.getContentAsString();
|
||||
return Objects.requireNonNull(gson.fromJson(responseString, SenecHomeResponse.class));
|
||||
} else {
|
||||
logger.trace("Got unexpected response code {}", response.getStatus());
|
||||
throw new IOException("Got unexpected response code " + response.getStatus());
|
||||
}
|
||||
} catch (MalformedJsonException | JsonSyntaxException | InterruptedException | TimeoutException
|
||||
| ExecutionException e) {
|
||||
} catch (JsonSyntaxException | InterruptedException | TimeoutException | ExecutionException e) {
|
||||
String errorMessage = "\nlocation: " + location;
|
||||
errorMessage += "\nrequest: " + request.toString();
|
||||
errorMessage += "\nrequest.getHeaders: " + request.getHeaders();
|
||||
|
@ -23,7 +23,7 @@ import org.openhab.core.thing.ThingTypeUID;
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SenecHomeBindingConstants {
|
||||
private static final String BINDING_ID = "senechome";
|
||||
protected 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);
|
||||
|
||||
@ -65,15 +65,6 @@ public class SenecHomeBindingConstants {
|
||||
public static final String CHANNEL_SENEC_GRID_VOLTAGE_PH3 = "gridVoltagePhase3";
|
||||
public static final String CHANNEL_SENEC_GRID_FREQUENCY = "gridFrequency";
|
||||
|
||||
// SenecHomeStatistics
|
||||
public static final String CHANNEL_SENEC_LIVE_BAT_CHARGE = "liveBatCharge";
|
||||
public static final String CHANNEL_SENEC_LIVE_BAT_DISCHARGE = "liveBatDischarge";
|
||||
public static final String CHANNEL_SENEC_LIVE_GRID_IMPORT = "liveGridImport";
|
||||
public static final String CHANNEL_SENEC_LIVE_GRID_EXPORT = "liveGridExport";
|
||||
public static final String CHANNEL_SENEC_LIVE_HOUSE_CONSUMPTION = "liveHouseConsumption";
|
||||
public static final String CHANNEL_SENEC_LIVE_POWER_GENERATOR = "livePowerGenerator";
|
||||
public static final String CHANNEL_SENEC_LIVE_ENERGY_WALLBOX1 = "liveEnergyWallbox1";
|
||||
|
||||
// SenecHomeBattery
|
||||
public static final String CHANNEL_SENEC_CHARGED_ENERGY_PACK1 = "chargedEnergyPack1";
|
||||
public static final String CHANNEL_SENEC_CHARGED_ENERGY_PACK2 = "chargedEnergyPack2";
|
||||
|
@ -16,10 +16,12 @@ package org.openhab.binding.senechome.internal;
|
||||
* The {@link SenecHomeConfigurationDTO} class contains fields mapping thing configuration parameters.
|
||||
*
|
||||
* @author Steven Schwarznau - Initial contribution
|
||||
* @author Robert Delbrück - Add useHttp
|
||||
*/
|
||||
public class SenecHomeConfigurationDTO {
|
||||
public String hostname;
|
||||
public int refreshInterval = 15;
|
||||
public int limitationTresholdValue = 95;
|
||||
public int limitationDuration = 120;
|
||||
public boolean useHttp = false;
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ public class SenecHomeHandler extends BaseThingHandler {
|
||||
@Override
|
||||
public void initialize() {
|
||||
config = getConfigAs(SenecHomeConfigurationDTO.class);
|
||||
senecHomeApi.setHostname(config.hostname);
|
||||
senecHomeApi.setHostname("%s://%s".formatted(config.useHttp ? "http" : "https", config.hostname));
|
||||
refreshJob = scheduler.scheduleWithFixedDelay(this::refresh, 0, config.refreshInterval, TimeUnit.SECONDS);
|
||||
limitationStatus = null;
|
||||
}
|
||||
@ -197,20 +197,6 @@ public class SenecHomeHandler extends BaseThingHandler {
|
||||
updateQtyState(CHANNEL_SENEC_GRID_VOLTAGE_PH3, response.grid.currentGridVoltagePerPhase[2], 2, Units.VOLT);
|
||||
updateQtyState(CHANNEL_SENEC_GRID_FREQUENCY, response.grid.currentGridFrequency, 2, Units.HERTZ);
|
||||
|
||||
updateQtyState(CHANNEL_SENEC_LIVE_BAT_CHARGE, response.statistics.liveBatCharge, 2, Units.KILOWATT_HOUR);
|
||||
updateQtyState(CHANNEL_SENEC_LIVE_BAT_DISCHARGE, response.statistics.liveBatDischarge, 2,
|
||||
Units.KILOWATT_HOUR);
|
||||
updateQtyState(CHANNEL_SENEC_LIVE_GRID_IMPORT, response.statistics.liveGridImport, 2, Units.KILOWATT_HOUR);
|
||||
updateQtyState(CHANNEL_SENEC_LIVE_GRID_EXPORT, response.statistics.liveGridExport, 2, Units.KILOWATT_HOUR);
|
||||
updateQtyState(CHANNEL_SENEC_LIVE_HOUSE_CONSUMPTION, response.statistics.liveHouseConsumption, 2,
|
||||
Units.KILOWATT_HOUR);
|
||||
updateQtyState(CHANNEL_SENEC_LIVE_POWER_GENERATOR, response.statistics.livePowerGenerator, 2,
|
||||
Units.KILOWATT_HOUR);
|
||||
if (response.statistics.liveWallboxEnergy != null) {
|
||||
updateQtyState(CHANNEL_SENEC_LIVE_ENERGY_WALLBOX1, response.statistics.liveWallboxEnergy[0], 2,
|
||||
Units.KILOWATT_HOUR, DIVISOR_ISO_TO_KILO);
|
||||
}
|
||||
|
||||
if (response.battery.chargedEnergy != null) {
|
||||
updateQtyState(CHANNEL_SENEC_CHARGED_ENERGY_PACK1, response.battery.chargedEnergy[0], 2,
|
||||
Units.KILOWATT_HOUR, DIVISOR_MILLI_TO_KILO);
|
||||
|
@ -17,15 +17,19 @@ import java.util.Set;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
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.ComponentContext;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link SenecHomeHandlerFactory} is responsible for creating things and thing
|
||||
@ -36,15 +40,17 @@ import org.osgi.service.component.annotations.Reference;
|
||||
@NonNullByDefault
|
||||
@Component(configurationPid = "binding.senechome", service = ThingHandlerFactory.class)
|
||||
public class SenecHomeHandlerFactory extends BaseThingHandlerFactory {
|
||||
private final Logger logger = LoggerFactory.getLogger(SenecHomeHandlerFactory.class);
|
||||
|
||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set
|
||||
.of(SenecHomeBindingConstants.THING_TYPE_SENEC_HOME_BATTERY);
|
||||
|
||||
private HttpClient httpClient;
|
||||
private final HttpClient httpClient;
|
||||
|
||||
@Activate
|
||||
public SenecHomeHandlerFactory(@Reference HttpClientFactory httpClientFactory) {
|
||||
this.httpClient = httpClientFactory.getCommonHttpClient();
|
||||
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client(true); // Accept all certificates
|
||||
this.httpClient = httpClientFactory.createHttpClient(SenecHomeBindingConstants.BINDING_ID, sslContextFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -62,4 +68,26 @@ public class SenecHomeHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void activate(ComponentContext componentContext) {
|
||||
super.activate(componentContext);
|
||||
|
||||
try {
|
||||
httpClient.start();
|
||||
} catch (Exception e) {
|
||||
logger.warn("cannot start Jetty-Http-Client", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deactivate(ComponentContext componentContext) {
|
||||
super.deactivate(componentContext);
|
||||
|
||||
try {
|
||||
httpClient.stop();
|
||||
} catch (Exception e) {
|
||||
logger.warn("cannot stop Jetty-Http-Client", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,14 +28,13 @@ public class SenecHomeResponse implements Serializable {
|
||||
public @SerializedName("PV1") SenecHomePower power = new SenecHomePower();
|
||||
public @SerializedName("ENERGY") SenecHomeEnergy energy = new SenecHomeEnergy();
|
||||
public @SerializedName("PM1OBJ1") SenecHomeGrid grid = new SenecHomeGrid();
|
||||
public @SerializedName("STATISTIC") SenecHomeStatistics statistics = new SenecHomeStatistics();
|
||||
public @SerializedName("BMS") SenecHomeBattery battery = new SenecHomeBattery();
|
||||
public @SerializedName("TEMPMEASURE") SenecHomeTemperature temperature = new SenecHomeTemperature();
|
||||
public @SerializedName("WALLBOX") SenecHomeWallbox wallbox = new SenecHomeWallbox();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SenecHomeResponse [power=" + power + ", energy=" + energy + ", grid=" + grid + ", statistics="
|
||||
+ statistics + "battery" + battery + "temperature" + temperature + "wallbox" + wallbox + "]";
|
||||
return "SenecHomeResponse [power=" + power + ", energy=" + energy + ", grid=" + grid + ", battery" + battery
|
||||
+ "temperature" + temperature + "wallbox" + wallbox + "]";
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ thing-type.config.senechome.senechome.limitationTresholdValue.label = Limitation
|
||||
thing-type.config.senechome.senechome.limitationTresholdValue.description = Treshold in percent, defines when limitation state is enabled
|
||||
thing-type.config.senechome.senechome.refreshInterval.label = Refresh Interval
|
||||
thing-type.config.senechome.senechome.refreshInterval.description = Rate of refreshing details (in s)
|
||||
thing-type.config.senechome.senechome.useHttp.label = Use HTTP
|
||||
thing-type.config.senechome.senechome.useHttp.description = Use legacy http access instead of https
|
||||
|
||||
# channel types
|
||||
|
||||
|
@ -48,15 +48,6 @@
|
||||
<channel id="gridVoltagePhase3" typeId="gridVoltagePhase3"/>
|
||||
<channel id="gridFrequency" typeId="gridFrequency"/>
|
||||
|
||||
<!-- SenecHomeStatistics -->
|
||||
<channel id="liveBatCharge" typeId="liveBatCharge"/>
|
||||
<channel id="liveBatDischarge" typeId="liveBatDischarge"/>
|
||||
<channel id="liveGridImport" typeId="liveGridImport"/>
|
||||
<channel id="liveGridExport" typeId="liveGridExport"/>
|
||||
<channel id="liveHouseConsumption" typeId="liveHouseConsumption"/>
|
||||
<channel id="livePowerGenerator" typeId="livePowerGenerator"/>
|
||||
<channel id="liveEnergyWallbox1" typeId="liveEnergyWallbox1"/>
|
||||
|
||||
<!-- SenecHomeBattery -->
|
||||
<channel id="chargedEnergyPack1" typeId="chargedEnergyPack1"/>
|
||||
<channel id="chargedEnergyPack2" typeId="chargedEnergyPack2"/>
|
||||
@ -101,6 +92,10 @@
|
||||
<channel id="wallbox1ChargingPower" typeId="wallbox1ChargingPower"/>
|
||||
</channels>
|
||||
|
||||
<properties>
|
||||
<property name="thingTypeVersion">1</property>
|
||||
</properties>
|
||||
|
||||
<config-description>
|
||||
<parameter name="hostname" type="text" required="true">
|
||||
<label>Hostname/IP Address</label>
|
||||
@ -122,6 +117,11 @@
|
||||
<description>Duration of stable values until state is changed, defined in seconds</description>
|
||||
<default>120</default>
|
||||
</parameter>
|
||||
<parameter name="useHttp" type="boolean" required="false">
|
||||
<label>Use HTTP</label>
|
||||
<description>Use legacy http access instead of https</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</thing-type>
|
||||
|
@ -0,0 +1,20 @@
|
||||
<?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="senechome:senechome">
|
||||
|
||||
<instruction-set targetVersion="1">
|
||||
<remove-channel id="liveBatCharge"/>
|
||||
<remove-channel id="liveBatDischarge"/>
|
||||
<remove-channel id="liveGridImport"/>
|
||||
<remove-channel id="liveGridExport"/>
|
||||
<remove-channel id="liveHouseConsumption"/>
|
||||
<remove-channel id="livePowerGenerator"/>
|
||||
<remove-channel id="liveEnergyWallbox1"/>
|
||||
</instruction-set>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</update:update-descriptions>
|
Loading…
Reference in New Issue
Block a user