diff --git a/bundles/org.openhab.binding.homewizard/README.md b/bundles/org.openhab.binding.homewizard/README.md
index d835c2aed32d7..eaa1da8cfd862 100644
--- a/bundles/org.openhab.binding.homewizard/README.md
+++ b/bundles/org.openhab.binding.homewizard/README.md
@@ -6,18 +6,11 @@ The HomeWizard binding provides access to several HomeWizard devices by using th
There are two important points of attention:
-1. For API v1, the local API of each device must be enabled and a fixed address must be configured for the devices.
-1. For API v2, a bearer token needs to be obtained from the device. See for instructions how to obtain a token.
+1. For API v1, the local API of each device must be enabled.
+1. For API v2, a bearer token needs to be obtained from the device.
-### Local API v1
+See for a more detailed description of the API and for instructions how to enable/use the API versions.
-The local API of a device can be enabled from the HomeWizard app.
-Go to Settings in the app, then Meters and select the device you want to enable.
-On this page enable the local API.
-
-### Local API v2
-
-This version is still in beta. Currently hwe-p1 and hwe-bat are supported.
### Fixed Address
@@ -52,7 +45,7 @@ All devices can be configured through the web interface.
|--------------|----------|---------|---------------------------------------------------------------------------------------------------|
| ipAddress | * | | This specifies the IP address (or host name) where the meter can be found. |
| refreshDelay | | 5 | This specifies the interval in seconds used by the binding to read updated values from the meter. |
-| apiVersion | * | v1 | The API version to be used. v2 is still in beta but is already supported in this binding. |
+| apiVersion | * | v1 | The API version to be used. |
| bearerToken | | | The bearer token to be used when using API v2. |
Note that update rate of the P1 Meter itself depends on the frequency of the telegrams it receives from the Smart Meter.
@@ -60,41 +53,46 @@ For DSMR5 meters this is generally once per second, for older versions the frequ
## Channels
-| Channel ID | Item Type | Description | Available |
-|------------------------|---------------------------|--------------------------------------------------------------------------------------------|-----------------------------------|
-| power | Number:Power | This channel provides the active usage in Watt. | hwe-p1, hwe-skt, hwe-kwh, hwe-bat |
-| power_l1 | Number:Power | This channel provides the active usage for phase 1 in Watt. | hwe-p1, hwe-kwh |
-| power_l2 | Number:Power | This channel provides the active usage for phase 2 in Watt. | hwe-p1, hwe-kwh |
-| power_l3 | Number:Power | This channel provides the active usage for phase 3 in Watt. | hwe-p1, hwe-kwh |
-| voltage | Number:ElectricPotential | This channel provides the active voltage in Volt. | hwe-skt |
-| voltage_l1 | Number:ElectricPotential | This channel provides the active usage for phase 1 in Watt. | hwe-p1, hwe-kwh, hwe-bat |
-| voltage_l2 | Number:ElectricPotential | This channel provides the active usage for phase 2 in Watt. | hwe-p1, hwe-kwh |
-| voltage_l3 | Number:ElectricPotential | This channel provides the active usage for phase 3 in Watt. | hwe-p1, hwe-kwh |
-| current | Number:ElectricCurrent | This channel provides the active current in Ampere. | hwe-skt, hwe-kwh, hwe-bat |
-| current_l1 | Number:ElectricCurrent | This channel provides the active current for phase 1 in Ampere. | hwe-p1, hwe-kwh |
-| current_l2 | Number:ElectricCurrent | This channel provides the active current for phase 2 in Ampere. | hwe-p1, hwe-kwh |
-| current_l3 | Number:ElectricCurrent | This channel provides the active current for phase 3 in Ampere. | hwe-p1, hwe-kwh |
-| energy_import | Number:Energy | This channel provides the total energy usage meter reading in kWh. | hwe-p1, hwe-skt, hwe-kwh, hwe-bat |
-| energy_import_t1 | Number:Energy | This channel provides the energy usage meter reading for tariff 1 in kWh. | hwe-p1 |
-| energy_import_t2 | Number:Energy | This channel provides the energy usage meter reading for tariff 2 in kWh. | hwe-p1 |
-| energy_export | Number:Energy | This channel provides the total energy feed-in meter reading in kWh. | hwe-p1, hwe-skt, hwe-kwh, hwe-bat |
-| energy_export_t1 | Number:Energy | This channel provides the energy feed-in meter reading for tarff 1 in kWh. | hwe-p1 |
-| energy_export_t2 | Number:Energy | This channel provides the energy feed-in meter reading for tarff 2 in kWh. | hwe-p1 |
-| reactive_power | Number | This channel provides the active reactive power in Volt-Ampere reactive. | hwe-p1, hwe-skt, hwe-kwh |
-| apparent_power | Number | This channel provides the active apparent power in Volt-Ampere. | hwe-p1, hwe-skt, hwe-kwh |
-| power_factor | Number:Dimensionless | This channel provides the active power factor. | hwe-p1, hwe-skt, hwe-kwh |
-| frequency | Number:Frequency | This channel provides the active frequency in Hertz. | hwe-p1, hwe-skt, hwe-kwh, hwe-bat |
-| total_gas | Number:Volume | This channel provides the most recently reported total imported gas in m^3. | hwe-p1 |
-| gas_timestamp | DateTime | This channel provides the time stamp of the total_gas measurement. | hwe-p1 |
-| power_failures | Number | This channel provides the number of power failures detected by meter. | hwe-p1 |
-| long_power_failures | Number | This channel provides the number of 'long' power failures detected by meter. | hwe-p1 |
-| power_switch | Switch | This channel provides access to the power switch of the Energy Socket. | hwe-skt |
-| power_lock | Switch | This channel provides access to the power lock of the Energy Socket. | hwe-skt |
-| ring_brightness | Number:Dimensionless | This channel provides access to the brightness of the ring of the Energy Socket. | hwe-skt |
-| total_liter | Number:Volume | This channel provides total water usage in cubic meters. | hwe-wtr |
-| active_liter | Number:VolumetricFlowRate | This channel provides the active water usage in liters per minute. | hwe-wtr |
-| state_of_charge | Number:Dimensionless | This channel provides access to the current state of charge in percent. | hwe-bat |
-| cycles | Number:Dimensionless | This channel provides access to the number of battery cycles. | hwe-bat |
+| Channel ID | Item Type | Description | Available |
+|---------------------------|---------------------------|--------------------------------------------------------------------------------------------------------------|-----------------------------------|
+| power | Number:Power | This channel provides the active usage in Watt. | hwe-p1, hwe-skt, hwe-kwh, hwe-bat |
+| power_l1 | Number:Power | This channel provides the active usage for phase 1 in Watt. | hwe-p1, hwe-kwh |
+| power_l2 | Number:Power | This channel provides the active usage for phase 2 in Watt. | hwe-p1, hwe-kwh |
+| power_l3 | Number:Power | This channel provides the active usage for phase 3 in Watt. | hwe-p1, hwe-kwh |
+| voltage | Number:ElectricPotential | This channel provides the active voltage in Volt. | hwe-skt |
+| voltage_l1 | Number:ElectricPotential | This channel provides the active usage for phase 1 in Watt. | hwe-p1, hwe-kwh, hwe-bat |
+| voltage_l2 | Number:ElectricPotential | This channel provides the active usage for phase 2 in Watt. | hwe-p1, hwe-kwh |
+| voltage_l3 | Number:ElectricPotential | This channel provides the active usage for phase 3 in Watt. | hwe-p1, hwe-kwh |
+| current | Number:ElectricCurrent | This channel provides the active current in Ampere. | hwe-skt, hwe-kwh, hwe-bat |
+| current_l1 | Number:ElectricCurrent | This channel provides the active current for phase 1 in Ampere. | hwe-p1, hwe-kwh |
+| current_l2 | Number:ElectricCurrent | This channel provides the active current for phase 2 in Ampere. | hwe-p1, hwe-kwh |
+| current_l3 | Number:ElectricCurrent | This channel provides the active current for phase 3 in Ampere. | hwe-p1, hwe-kwh |
+| energy_import | Number:Energy | This channel provides the total energy usage meter reading in kWh. | hwe-p1, hwe-skt, hwe-kwh, hwe-bat |
+| energy_import_t1 | Number:Energy | This channel provides the energy usage meter reading for tariff 1 in kWh. | hwe-p1 |
+| energy_import_t2 | Number:Energy | This channel provides the energy usage meter reading for tariff 2 in kWh. | hwe-p1 |
+| energy_export | Number:Energy | This channel provides the total energy feed-in meter reading in kWh. | hwe-p1, hwe-skt, hwe-kwh, hwe-bat |
+| energy_export_t1 | Number:Energy | This channel provides the energy feed-in meter reading for tarff 1 in kWh. | hwe-p1 |
+| energy_export_t2 | Number:Energy | This channel provides the energy feed-in meter reading for tarff 2 in kWh. | hwe-p1 |
+| reactive_power | Number | This channel provides the active reactive power in Volt-Ampere reactive. | hwe-p1, hwe-skt, hwe-kwh |
+| apparent_power | Number | This channel provides the active apparent power in Volt-Ampere. | hwe-p1, hwe-skt, hwe-kwh |
+| power_factor | Number:Dimensionless | This channel provides the active power factor. | hwe-p1, hwe-skt, hwe-kwh |
+| frequency | Number:Frequency | This channel provides the active frequency in Hertz. | hwe-p1, hwe-skt, hwe-kwh, hwe-bat |
+| total_gas | Number:Volume | This channel provides the most recently reported total imported gas in m^3. | hwe-p1 |
+| gas_timestamp | DateTime | This channel provides the time stamp of the total_gas measurement. | hwe-p1 |
+| power_failures | Number | This channel provides the number of power failures detected by meter. | hwe-p1 |
+| long_power_failures | Number | This channel provides the number of 'long' power failures detected by meter. | hwe-p1 |
+| power_switch | Switch | This channel provides access to the power switch of the Energy Socket. | hwe-skt |
+| power_lock | Switch | This channel provides access to the power lock of the Energy Socket. | hwe-skt |
+| ring_brightness | Number:Dimensionless | This channel provides access to the brightness of the ring of the Energy Socket. | hwe-skt |
+| total_liter | Number:Volume | This channel provides total water usage in cubic meters. | hwe-wtr |
+| active_liter | Number:VolumetricFlowRate | This channel provides the active water usage in liters per minute. | hwe-wtr |
+| state_of_charge | Number:Dimensionless | This channel provides access to the current state of charge in percent. | hwe-bat |
+| cycles | Number:Dimensionless | This channel provides access to the number of battery cycles. | hwe-bat |
+| batteries_mode | String | This channel provides the control mode of the Plug-In Battery. | hwe-p1 |
+| batteries_power | Number:Power | This channel provides the current combined power consumption/production of the controlled Plug-In Batteries. | hwe-p1 |
+| batteries_target_power | Number:Power | This channel provides the target power consumption/production of the controlled Plug-In Batteries. | hwe-p1 |
+| batteries_max_consumption | Number:Power | This channel provides the maximum allowed consumption power of the controlled Plug-In Batteries. | hwe-p1 |
+| batteries_max_production | Number:Power | This channel provides the maximum allowed production power of the controlled Plug-In Batteries. | hwe-p1 |
## Full Example
diff --git a/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/HomeWizardBindingConstants.java b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/HomeWizardBindingConstants.java
index ce48d58098e9b..8938e4f9a7ed2 100644
--- a/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/HomeWizardBindingConstants.java
+++ b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/HomeWizardBindingConstants.java
@@ -52,6 +52,7 @@ public class HomeWizardBindingConstants {
// Channel Groups
public static final String CHANNEL_GROUP_ENERGY = "energy";
+ public static final String CHANNEL_GROUP_P1_BATTERIES = "batteries";
public static final String CHANNEL_GROUP_WATER = "water";
public static final String CHANNEL_GROUP_SKT_CONTROL = "control";
@@ -104,6 +105,12 @@ public class HomeWizardBindingConstants {
public static final String CHANNEL_GAS_TIMESTAMP = "gas_timestamp";
public static final String CHANNEL_GAS_TOTAL = "total_gas";
+ public static final String CHANNEL_BATTERIES_MODE = "batteries_mode";
+ public static final String CHANNEL_BATTERIES_POWER = "batteries_power";
+ public static final String CHANNEL_BATTERIES_TARGET_POWER = "batteries_target_power";
+ public static final String CHANNEL_BATTERIES_MAX_CONSUMPTION = "batteries_max_consumption";
+ public static final String CHANNEL_BATTERIES_MAX_PRODUCTION = "batteries_max_production";
+
// Energy Socket And kWh Meter Channels
public static final String CHANNEL_REACTIVE_POWER = "reactive_power";
public static final String CHANNEL_APPARENT_POWER = "apparent_power";
diff --git a/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/HomeWizardDeviceHandler.java b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/HomeWizardDeviceHandler.java
index f854612a02f96..d05ce2f8bb0cf 100644
--- a/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/HomeWizardDeviceHandler.java
+++ b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/HomeWizardDeviceHandler.java
@@ -27,13 +27,19 @@
import org.eclipse.jdt.annotation.Nullable;
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.util.ssl.SslContextFactory;
import org.openhab.binding.homewizard.internal.HomeWizardConfiguration;
+import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingStatusDetail;
import org.openhab.core.thing.binding.BaseThingHandler;
+import org.openhab.core.types.Command;
import org.openhab.core.types.State;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -116,7 +122,7 @@ public void initialize() {
if (configure() && processDeviceInformation()) {
updateStatus(ThingStatus.UNKNOWN);
- pollingJob = executorService.scheduleWithFixedDelay(this::pollingCode, 0, config.refreshDelay,
+ pollingJob = executorService.scheduleWithFixedDelay(this::retrieveData, 0, config.refreshDelay,
TimeUnit.SECONDS);
}
}
@@ -155,6 +161,20 @@ private boolean configure() {
return true;
}
+ /**
+ * Not listening to any commands.
+ */
+ @Override
+ public void handleCommand(ChannelUID channelUID, Command command) {
+ }
+
+ /**
+ * The actual polling loop
+ */
+ protected void retrieveData() {
+ retrieveMeasurementData();
+ }
+
private boolean processDeviceInformation() {
String deviceInformation = "";
@@ -226,19 +246,29 @@ protected void updateState(String groupID, String channelID, State state) {
}
/**
- * Device specific handling of the returned data.
+ * Device specific handling of the returned measurement data.
*
* @param payload The data obtained form the API call
*/
- protected abstract void handleDataPayload(String data);
+ protected abstract void handleMeasurementData(String data);
+
+ protected ContentResponse putDataTo(String url, String data)
+ throws InterruptedException, TimeoutException, ExecutionException {
+ var request = httpClient.newRequest(url).method(HttpMethod.PUT).content(new StringContentProvider(data));
+
+ return sendRequest(request);
+ }
protected ContentResponse getResponseFrom(String url)
throws InterruptedException, TimeoutException, ExecutionException {
- var request = httpClient.newRequest(url);
+ return sendRequest(httpClient.newRequest(url));
+ }
+ private ContentResponse sendRequest(Request request)
+ throws InterruptedException, TimeoutException, ExecutionException {
if (config.apiVersion > 1) {
- request = request.header(HttpHeader.AUTHORIZATION, BEARER + " " + config.bearerToken);
- request = request.header(API_VERSION_HEADER, "" + config.apiVersion);
+ request.header(HttpHeader.AUTHORIZATION, BEARER + " " + config.bearerToken);
+ request.header(API_VERSION_HEADER, "" + config.apiVersion);
}
return request.timeout(20, TimeUnit.SECONDS).send();
}
@@ -250,7 +280,7 @@ protected ContentResponse getResponseFrom(String url)
public String getDeviceInformationData()
throws InterruptedException, TimeoutException, ExecutionException, SecurityException {
var response = getResponseFrom(apiURL);
- if (response.getStatus() == 401) {
+ if (response.getStatus() == HttpStatus.UNAUTHORIZED_401) {
throw new SecurityException("Bearer token is invalid.");
}
return response.getContentAsString();
@@ -267,13 +297,11 @@ public String getMeasurementData() throws InterruptedException, TimeoutException
} else {
url += "measurement";
}
-
return getResponseFrom(url).getContentAsString();
}
- protected void pollData() {
+ protected void retrieveMeasurementData() {
final String measurementData;
-
try {
measurementData = getMeasurementData();
} catch (Exception e) {
@@ -281,15 +309,7 @@ protected void pollData() {
String.format("Device is offline or doesn't support the API version"));
return;
}
-
updateStatus(ThingStatus.ONLINE);
- handleDataPayload(measurementData);
- }
-
- /**
- * The actual polling loop
- */
- protected void pollingCode() {
- pollData();
+ handleMeasurementData(measurementData);
}
}
diff --git a/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/HomeWizardEnergyMeterHandler.java b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/HomeWizardEnergyMeterHandler.java
index a81db947c5c3b..050a24ce94c91 100644
--- a/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/HomeWizardEnergyMeterHandler.java
+++ b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/HomeWizardEnergyMeterHandler.java
@@ -16,9 +16,7 @@
import org.openhab.binding.homewizard.internal.HomeWizardBindingConstants;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.unit.Units;
-import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
-import org.openhab.core.types.Command;
/**
* The {@link HomeWizardEnergyMeterHandler} implements functionality generic to several energy meters.
@@ -38,20 +36,13 @@ public HomeWizardEnergyMeterHandler(Thing thing) {
super(thing);
}
- /**
- * Not listening to any commands.
- */
- @Override
- public void handleCommand(ChannelUID channelUID, Command command) {
- }
-
/**
* Device specific handling of the returned data.
*
* @param data The data obtained form the API call
*/
@Override
- protected void handleDataPayload(String data) {
+ protected void handleMeasurementData(String data) {
var payload = gson.fromJson(data, HomeWizardEnergyMeterMeasurementPayload.class);
if (payload != null) {
if (!thing.getThingTypeUID().equals(HomeWizardBindingConstants.THING_TYPE_P1_METER)
diff --git a/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/energy_socket/HomeWizardEnergySocketHandler.java b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/energy_socket/HomeWizardEnergySocketHandler.java
index dbdbedddb81e3..99fd637737ce1 100644
--- a/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/energy_socket/HomeWizardEnergySocketHandler.java
+++ b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/energy_socket/HomeWizardEnergySocketHandler.java
@@ -130,8 +130,8 @@ public void handleCommand(ChannelUID channelUID, Command command) {
* @param data The data obtained from the API call
*/
@Override
- protected void handleDataPayload(String data) {
- super.handleDataPayload(data);
+ protected void handleMeasurementData(String data) {
+ super.handleMeasurementData(data);
var payload = gson.fromJson(data, HomeWizardEnergySocketMeasurementPayload.class);
if (payload != null) {
diff --git a/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/energy_socket/HomeWizardEnergySocketStateHandler.java b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/energy_socket/HomeWizardEnergySocketStateHandler.java
index 80bc35cb0523d..dc337ccfdf03b 100644
--- a/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/energy_socket/HomeWizardEnergySocketStateHandler.java
+++ b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/energy_socket/HomeWizardEnergySocketStateHandler.java
@@ -12,20 +12,13 @@
*/
package org.openhab.binding.homewizard.internal.devices.energy_socket;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.homewizard.internal.devices.HomeWizardEnergyMeterHandler;
-import org.openhab.core.io.net.http.HttpUtil;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingStatusDetail;
-import com.google.gson.JsonSyntaxException;
-
/**
* The {@link HomeWizardEnergySocketStateHandler} extends the base class
* to provide support for devices that also have a 'state' interface.
@@ -38,6 +31,8 @@
@NonNullByDefault
public abstract class HomeWizardEnergySocketStateHandler extends HomeWizardEnergyMeterHandler {
+ private final String STATE_URL = "v1/state";
+
/**
* Constructor
*
@@ -57,10 +52,10 @@ public HomeWizardEnergySocketStateHandler(Thing thing) {
/**
* @return json response from the state api
- * @throws IOException
+ * @throws Exception
*/
public String getStateData() throws Exception {
- return getResponseFrom(apiURL + "v1/state").getContentAsString();
+ return getResponseFrom(apiURL + STATE_URL).getContentAsString();
}
protected void pollState() {
@@ -96,21 +91,22 @@ protected void pollState() {
* @param command The command to send.
*/
protected @Nullable HomeWizardEnergySocketStatePayload sendStateCommand(String command) {
- try (InputStream is = new ByteArrayInputStream(command.getBytes())) {
- String updatedState = HttpUtil.executeUrl("PUT", apiURL + "v1/state", is, "application/json", 30000);
- return gson.fromJson(updatedState, HomeWizardEnergySocketStatePayload.class);
- } catch (IOException | JsonSyntaxException e) {
- logger.warn("Failed to send command {} to {}", command, apiURL + "state");
- return null;
+ String updatedState = "";
+ try {
+ updatedState = putDataTo(apiURL + STATE_URL, command).getContentAsString();
+ } catch (Exception ex) {
+ logger.warn("Failed to send command {} to {}", command, apiURL + STATE_URL);
}
+
+ return gson.fromJson(updatedState, HomeWizardEnergySocketStatePayload.class);
}
/*
* This overrides the original polling loop by including a request for the current state..
*/
@Override
- protected void pollingCode() {
- pollData();
+ protected void retrieveData() {
+ retrieveMeasurementData();
pollState();
}
}
diff --git a/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/kwh_meter/HomeWizardKwhMeterHandler.java b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/kwh_meter/HomeWizardKwhMeterHandler.java
index 2e643b22e4c97..a28a9c7f116e7 100644
--- a/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/kwh_meter/HomeWizardKwhMeterHandler.java
+++ b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/kwh_meter/HomeWizardKwhMeterHandler.java
@@ -50,8 +50,8 @@ public HomeWizardKwhMeterHandler(Thing thing) {
* @param payload The data obtained form the API call
*/
@Override
- protected void handleDataPayload(String data) {
- super.handleDataPayload(data);
+ protected void handleMeasurementData(String data) {
+ super.handleMeasurementData(data);
var payload = gson.fromJson(data, HomeWizardEnergySocketMeasurementPayload.class);
if (payload != null) {
diff --git a/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/p1_meter/HomeWizardP1MeterBatteriesPayload.java b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/p1_meter/HomeWizardP1MeterBatteriesPayload.java
new file mode 100644
index 0000000000000..dd73474521042
--- /dev/null
+++ b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/p1_meter/HomeWizardP1MeterBatteriesPayload.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2010-2025 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.homewizard.internal.devices.p1_meter;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * Class that provides storage for the json objects obtained from HomeWizard devices.
+ *
+ * @author Gearrel Welvaart - Initial contribution
+ *
+ *
+ */
+@NonNullByDefault
+public class HomeWizardP1MeterBatteriesPayload {
+
+ private String mode = "";
+
+ @SerializedName("power_w")
+ private Double power = 0.0;
+
+ @SerializedName("target_power_w")
+ private Double targetPower = 0.0;
+
+ @SerializedName("max_consumption_w")
+ private Double maxConsumption = 0.0;
+
+ @SerializedName("max_production_w")
+ private Double maxProduction = 0.0;
+
+ /**
+ * Getter for the mode
+ *
+ * @return mode
+ */
+ public String getMode() {
+ return mode;
+ }
+
+ /**
+ * Getter for the power in watt
+ *
+ * @return power
+ */
+ public int getPower() {
+ return power.intValue();
+ }
+
+ /**
+ * Getter for the target power in watt
+ *
+ * @return target power
+ */
+ public int getTargetPower() {
+ return targetPower.intValue();
+ }
+
+ /**
+ * Getter for the max consumption in watt
+ *
+ * @return max consumption
+ */
+ public int getMaxConsumption() {
+ return maxConsumption.intValue();
+ }
+
+ /**
+ * Getter for the max production in watt
+ *
+ * @return max production
+ */
+ public int getMaxProduction() {
+ return maxProduction.intValue();
+ }
+
+ @Override
+ public String toString() {
+ return String.format("""
+ Data [mode: %s power: %f targetPower: %f
+ maxConsumption: %f maxProduction: %f
+
+ """, mode, power, targetPower, maxConsumption, maxProduction);
+ }
+}
diff --git a/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/p1_meter/HomeWizardP1MeterHandler.java b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/p1_meter/HomeWizardP1MeterHandler.java
index 3534a78d51327..c8db0a450476f 100644
--- a/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/p1_meter/HomeWizardP1MeterHandler.java
+++ b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/p1_meter/HomeWizardP1MeterHandler.java
@@ -14,18 +14,28 @@
import java.time.DateTimeException;
import java.time.ZonedDateTime;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jetty.http.HttpStatus;
import org.openhab.binding.homewizard.internal.HomeWizardBindingConstants;
import org.openhab.binding.homewizard.internal.devices.HomeWizardEnergyMeterHandler;
import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.types.StringType;
import org.openhab.core.library.unit.SIUnits;
+import org.openhab.core.library.unit.Units;
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.types.Command;
+import org.openhab.core.types.RefreshType;
+
+import com.google.gson.JsonSyntaxException;
/**
* The {@link HomeWizardP1MeterHandler} implements functionality to handle a HomeWizard P1 Meter.
@@ -36,6 +46,8 @@
@NonNullByDefault
public class HomeWizardP1MeterHandler extends HomeWizardEnergyMeterHandler {
+ private final String BATTERIES_URL = "batteries";
+
private String meterModel = "";
private int meterVersion = 0;
private TimeZoneProvider timeZoneProvider;
@@ -52,21 +64,47 @@ public HomeWizardP1MeterHandler(Thing thing, TimeZoneProvider timeZoneProvider)
supportedTypes.add(HomeWizardBindingConstants.HWE_P1);
}
- /**
- * Not listening to any commands.
- */
+ @Override
+ protected void retrieveData() {
+ super.retrieveData();
+ if (config.apiVersion == 2) {
+ retrieveBatteriesData();
+ }
+ }
+
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
+ if (command instanceof RefreshType) {
+ retrieveBatteriesData();
+ return;
+ }
+
+ if (channelUID.getIdWithoutGroup().equals(HomeWizardBindingConstants.CHANNEL_BATTERIES_MODE)) {
+ var cmd = String.format("{\"mode\": \"%s\"}", command.toFullString());
+
+ try {
+ var response = putDataTo(apiURL + BATTERIES_URL, cmd);
+ if (response.getStatus() == HttpStatus.OK_200) {
+ handleBatteriesData(response.getContentAsString());
+ } else {
+ logger.warn("Failed to send command {} to {}", command, apiURL + BATTERIES_URL);
+ }
+ } catch (Exception ex) {
+ logger.warn("Failed to send command {} to {}", command, apiURL + BATTERIES_URL);
+ }
+ } else {
+ logger.warn("Should handle {} {}", channelUID.getIdWithoutGroup(), command);
+ }
}
/**
- * Device specific handling of the returned data.
+ * Device specific handling of the returned measurement data.
*
- * @param payload The data obtained form the API call
+ * @param data The data obtained form the API call
*/
@Override
- protected void handleDataPayload(String data) {
- super.handleDataPayload(data);
+ protected void handleMeasurementData(String data) {
+ super.handleMeasurementData(data);
var payload = gson.fromJson(data, HomeWizardP1MeterMeasurementPayload.class);
if (payload != null) {
@@ -135,4 +173,62 @@ protected void handleDataPayload(String data) {
}
}
}
+
+ /**
+ * Device specific handling of the returned batteries data.
+ *
+ * @param data The data obtained form the API call
+ */
+ protected void handleBatteriesData(String data) {
+ HomeWizardP1MeterBatteriesPayload payload = null;
+ try {
+ payload = gson.fromJson(data, HomeWizardP1MeterBatteriesPayload.class);
+ } catch (JsonSyntaxException ex) {
+ logger.warn("No Batteries data available");
+ }
+ if (payload != null) {
+ updateState(HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
+ HomeWizardBindingConstants.CHANNEL_BATTERIES_MODE, new StringType(payload.getMode()));
+ updateState(HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
+ HomeWizardBindingConstants.CHANNEL_BATTERIES_POWER,
+ new QuantityType<>(payload.getPower(), Units.WATT));
+ updateState(HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
+ HomeWizardBindingConstants.CHANNEL_BATTERIES_TARGET_POWER,
+ new QuantityType<>(payload.getTargetPower(), Units.WATT));
+ updateState(HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
+ HomeWizardBindingConstants.CHANNEL_BATTERIES_MAX_CONSUMPTION,
+ new QuantityType<>(payload.getMaxConsumption(), Units.WATT));
+ updateState(HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
+ HomeWizardBindingConstants.CHANNEL_BATTERIES_MAX_PRODUCTION,
+ new QuantityType<>(payload.getMaxProduction(), Units.WATT));
+ }
+ }
+
+ protected void retrieveBatteriesData() {
+ final String batteriesData;
+
+ try {
+ batteriesData = getBatteriesData();
+ } catch (Exception e) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
+ String.format("Device is offline or doesn't support the API version"));
+ return;
+ }
+
+ handleBatteriesData(batteriesData);
+ }
+
+ /**
+ * @return json response from the batteries api
+ * @throws InterruptedException, TimeoutException, ExecutionException
+ */
+ public String getBatteriesData() throws InterruptedException, TimeoutException, ExecutionException {
+ var response = getResponseFrom(apiURL + BATTERIES_URL);
+ if (response.getStatus() == HttpStatus.OK_200) {
+ return response.getContentAsString();
+ } else {
+ logger.warn("No Batteries data available");
+ return "";
+ }
+ }
}
diff --git a/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/plug_in_battery/HomeWizardPlugInBatteryHandler.java b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/plug_in_battery/HomeWizardPlugInBatteryHandler.java
index 671bd433dbd6f..376b74b154d11 100644
--- a/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/plug_in_battery/HomeWizardPlugInBatteryHandler.java
+++ b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/plug_in_battery/HomeWizardPlugInBatteryHandler.java
@@ -16,9 +16,7 @@
import org.openhab.binding.homewizard.internal.HomeWizardBindingConstants;
import org.openhab.binding.homewizard.internal.devices.HomeWizardEnergyMeterHandler;
import org.openhab.core.library.types.DecimalType;
-import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
-import org.openhab.core.types.Command;
/**
* The {@link HomeWizardPlugInBatteryHandler} implements functionality to handle a HomeWizard P1 Meter.
@@ -40,21 +38,14 @@ public HomeWizardPlugInBatteryHandler(Thing thing) {
supportedTypes.add(HomeWizardBindingConstants.HWE_BAT);
}
- /**
- * Not listening to any commands.
- */
- @Override
- public void handleCommand(ChannelUID channelUID, Command command) {
- }
-
/**
* Device specific handling of the returned data.
*
* @param payload The data obtained form the API call
*/
@Override
- protected void handleDataPayload(String data) {
- super.handleDataPayload(data);
+ protected void handleMeasurementData(String data) {
+ super.handleMeasurementData(data);
var payload = gson.fromJson(data, HomeWizardPlugInBatteryMeasurementPayload.class);
if (payload != null) {
diff --git a/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/water_meter/HomeWizardWaterMeterHandler.java b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/water_meter/HomeWizardWaterMeterHandler.java
index 73e695ea30cc0..ef9e58304d720 100644
--- a/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/water_meter/HomeWizardWaterMeterHandler.java
+++ b/bundles/org.openhab.binding.homewizard/src/main/java/org/openhab/binding/homewizard/internal/devices/water_meter/HomeWizardWaterMeterHandler.java
@@ -18,9 +18,7 @@
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.unit.SIUnits;
import org.openhab.core.library.unit.Units;
-import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
-import org.openhab.core.types.Command;
/**
* The {@link HomeWizardWaterMeterHandler} implements functionality to handle a HomeWizard Watermeter.
@@ -43,20 +41,13 @@ public HomeWizardWaterMeterHandler(Thing thing) {
supportedTypes.add(HomeWizardBindingConstants.HWE_WTR);
}
- /**
- * Not listening to any commands.
- */
- @Override
- public void handleCommand(ChannelUID channelUID, Command command) {
- }
-
/**
* Device specific handling of the returned data.
*
* @param payload The data obtained form the API call
*/
@Override
- protected void handleDataPayload(String data) {
+ protected void handleMeasurementData(String data) {
var payload = gson.fromJson(data, HomeWizardWaterMeterMeasurementPayload.class);
if (payload != null) {
if (!thing.getThingTypeUID().equals(HomeWizardBindingConstants.THING_TYPE_WATERMETER)) {
diff --git a/bundles/org.openhab.binding.homewizard/src/main/resources/OH-INF/i18n/homewizard.properties b/bundles/org.openhab.binding.homewizard/src/main/resources/OH-INF/i18n/homewizard.properties
index be80878a5e5e4..add88ee1dbec3 100644
--- a/bundles/org.openhab.binding.homewizard/src/main/resources/OH-INF/i18n/homewizard.properties
+++ b/bundles/org.openhab.binding.homewizard/src/main/resources/OH-INF/i18n/homewizard.properties
@@ -5,12 +5,12 @@ addon.homewizard.description = This binding provides access to the data provided
# thing types
-thing-type.homewizard.hwe-kwh.label = HomeWizard kWh Meter
-thing-type.homewizard.hwe-kwh.description = This thing provides the measurement data that is available through the API of a HomeWizard kWh Meter.
thing-type.homewizard.energy_socket.label = HomeWizard Energysocket
thing-type.homewizard.energy_socket.description = This thing provides the measurement data that is available through the http interface of a HomeWizard Energysocket.
thing-type.homewizard.hwe-bat.label = HomeWizard Plug-In Battery
thing-type.homewizard.hwe-bat.description = This thing provides the measurement data that is available through the API of a HomeWizard Plug-In Battery.
+thing-type.homewizard.hwe-kwh.label = HomeWizard kWh Meter
+thing-type.homewizard.hwe-kwh.description = This thing provides the measurement data that is available through the API of a HomeWizard kWh Meter.
thing-type.homewizard.hwe-p1.label = HomeWizard P1 Meter
thing-type.homewizard.hwe-p1.description = This thing provides the measurement data that is available through the API of a HomeWizard P1 Meter.
thing-type.homewizard.hwe-skt.label = HomeWizard Energy Socket
@@ -81,6 +81,15 @@ channel-group-type.homewizard.kwh-energy-group.channel.voltage_l2.label = Active
channel-group-type.homewizard.kwh-energy-group.channel.voltage_l2.description = This channel provides the active voltage for phase 2 in Volt.
channel-group-type.homewizard.kwh-energy-group.channel.voltage_l3.label = Active Voltage L3
channel-group-type.homewizard.kwh-energy-group.channel.voltage_l3.description = This channel provides the active voltage for phase 3 in Volt.
+channel-group-type.homewizard.p1-batteries-group.label = Batteries
+channel-group-type.homewizard.p1-batteries-group.channel.batteries_max_consumption.label = Maximum Consumption
+channel-group-type.homewizard.p1-batteries-group.channel.batteries_max_consumption.description = This channel provides the maximum allowed consumption power of the controlled Plug-In Batteries.
+channel-group-type.homewizard.p1-batteries-group.channel.batteries_max_production.label = Maximum Production
+channel-group-type.homewizard.p1-batteries-group.channel.batteries_max_production.description = This channel provides the maximum allowed production power of the controlled Plug-In Batteries.
+channel-group-type.homewizard.p1-batteries-group.channel.batteries_power.label = Power
+channel-group-type.homewizard.p1-batteries-group.channel.batteries_power.description = This channel provides the current combined power consumption/production of the controlled Plug-In Batteries.
+channel-group-type.homewizard.p1-batteries-group.channel.batteries_target_power.label = Target Power
+channel-group-type.homewizard.p1-batteries-group.channel.batteries_target_power.description = This channel provides the target power consumption/production of the controlled Plug-In Batteries.
channel-group-type.homewizard.p1-energy-group.label = Recent Measurements
channel-group-type.homewizard.p1-energy-group.channel.current_l1.label = Active Current L1
channel-group-type.homewizard.p1-energy-group.channel.current_l1.description = This channel provides the active current for phase 1 in Ampere.
@@ -165,6 +174,11 @@ channel-type.homewizard.hw-voltage-advanced.label = Active Voltage
channel-type.homewizard.hw-voltage-advanced.description = This channel provides the active voltage in Volt.
channel-type.homewizard.hw-voltage.label = Active Voltage
channel-type.homewizard.hw-voltage.description = This channel provides the active voltage in Volt.
+channel-type.homewizard.p1-batteries-mode.label = Battery Control Mode
+channel-type.homewizard.p1-batteries-mode.description = This channel provides the control mode of the Plug-In Battery.
+channel-type.homewizard.p1-batteries-mode.command.option.zero = Maintain net-zero balance
+channel-type.homewizard.p1-batteries-mode.command.option.to_full = Charge to 100%
+channel-type.homewizard.p1-batteries-mode.command.option.standby = Stand-by mode
channel-type.homewizard.p1-gas-timestamp.label = Gas Update Time Stamp
channel-type.homewizard.p1-gas-timestamp.description = This channel provides the time stamp of the total_gas measurement.
channel-type.homewizard.p1-power-failures.label = Power Failures
diff --git a/bundles/org.openhab.binding.homewizard/src/main/resources/OH-INF/thing/channels.xml b/bundles/org.openhab.binding.homewizard/src/main/resources/OH-INF/thing/channels.xml
index 30a028a5d7edf..ab4aa3cc75bfb 100644
--- a/bundles/org.openhab.binding.homewizard/src/main/resources/OH-INF/thing/channels.xml
+++ b/bundles/org.openhab.binding.homewizard/src/main/resources/OH-INF/thing/channels.xml
@@ -24,6 +24,10 @@
This channel provides the active usage in Watt.
Energy
+
+ Measurement
+ Power
+
@@ -46,6 +50,10 @@
This channel provides the active voltage in Volt.
Energy
+
+ Measurement
+ Voltage
+
@@ -69,6 +77,10 @@
This channel provides the active current in Ampere.
Energy
+
+ Measurement
+ Current
+
@@ -92,6 +104,10 @@
This channel provides the total energy usage meter reading in kWh.
Energy
+
+ Measurement
+ Energy
+
@@ -114,6 +130,10 @@
This channel provides the total energy feed-in meter reading in kWh.
Energy
+
+ Measurement
+ Energy
+
diff --git a/bundles/org.openhab.binding.homewizard/src/main/resources/OH-INF/thing/hwe-p1.xml b/bundles/org.openhab.binding.homewizard/src/main/resources/OH-INF/thing/hwe-p1.xml
index 1ab8fe59d45aa..c1966934b8863 100644
--- a/bundles/org.openhab.binding.homewizard/src/main/resources/OH-INF/thing/hwe-p1.xml
+++ b/bundles/org.openhab.binding.homewizard/src/main/resources/OH-INF/thing/hwe-p1.xml
@@ -11,9 +11,10 @@
ElectricMeter
+
- 1
+ 2
@@ -122,6 +123,40 @@
+
+
+
+
+
+
+
+
+ This channel provides the current combined power consumption/production of the controlled Plug-In
+ Batteries.
+
+
+
+
+
+ This channel provides the target power consumption/production of the controlled Plug-In Batteries.
+
+
+
+
+
+ This channel provides the maximum allowed consumption power of the controlled Plug-In Batteries.
+
+
+
+
+
+ This channel provides the maximum allowed production power of the controlled Plug-In Batteries.
+
+
+
+
+
+
Number
@@ -150,5 +185,24 @@
+
+ String
+
+
+ This channel provides the control mode of the Plug-In Battery.
+
+
+ Setpoint
+ Mode
+
+
+
+
+
+
+
+
+
+
diff --git a/bundles/org.openhab.binding.homewizard/src/main/resources/OH-INF/update/update-hwe-p1.xml b/bundles/org.openhab.binding.homewizard/src/main/resources/OH-INF/update/update-hwe-p1.xml
new file mode 100644
index 0000000000000..ba08c0d95f457
--- /dev/null
+++ b/bundles/org.openhab.binding.homewizard/src/main/resources/OH-INF/update/update-hwe-p1.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+ homewizard:p1-batteries-mode
+
+
+ homewizard:hw-power-advanced
+
+
+ This channel provides the current combined power consumption/production of the controlled Plug-In
+ Batteries.
+
+
+
+ homewizard:hw-power-advanced
+
+
+ This channel provides the target power consumption/production of the controlled Plug-In Batteries.
+
+
+
+ homewizard:hw-power-advanced
+
+
+ This channel provides the maximum allowed consumption power of the controlled Plug-In Batteries.
+
+
+
+ homewizard:hw-power-advanced
+
+
+ This channel provides the maximum allowed production power of the controlled Plug-In Batteries.
+
+
+
+
+
+
+
+
diff --git a/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/HomeWizardHandlerTest.java b/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/HomeWizardHandlerTest.java
index f2f6826a8690d..6db184d8b7b89 100644
--- a/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/HomeWizardHandlerTest.java
+++ b/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/HomeWizardHandlerTest.java
@@ -23,6 +23,7 @@
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.types.StringType;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
@@ -38,11 +39,14 @@
@NonNullByDefault
public class HomeWizardHandlerTest {
- protected static final Configuration CONFIG = createConfig();
+ protected static final Configuration CONFIG_V1 = createConfig(1);
+ protected static final Configuration CONFIG_V2 = createConfig(2);
- protected static Configuration createConfig() {
+ protected static Configuration createConfig(int apiVersion) {
final Configuration config = new Configuration();
config.put("ipAddress", "192.168.1.1");
+ config.put("apiVersion", apiVersion);
+ config.put("bearerToken", "token");
return config;
}
@@ -66,6 +70,10 @@ protected static State getState(final int input, Unit> unit) {
return new QuantityType<>(input, unit);
}
+ protected static State getState(final String input) {
+ return new StringType(input);
+ }
+
protected static State getState(final double input) {
return new DecimalType(input);
}
@@ -81,4 +89,8 @@ protected static State getState(final double input, Unit> unit) {
protected static ChannelUID getEnergyChannelUid(Thing thing, String channelId) {
return new ChannelUID(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY + "#" + channelId);
}
+
+ protected static ChannelUID getBatteriesChannelUid(Thing thing, String channelId) {
+ return new ChannelUID(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES + "#" + channelId);
+ }
}
diff --git a/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/energy_socket/HomeWizardEnergySocketHandlerTest.java b/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/energy_socket/HomeWizardEnergySocketHandlerTest.java
index ebd0ae757ded7..e4758d51de54e 100644
--- a/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/energy_socket/HomeWizardEnergySocketHandlerTest.java
+++ b/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/energy_socket/HomeWizardEnergySocketHandlerTest.java
@@ -53,7 +53,7 @@ private static Thing mockThing(boolean legacy) {
new ThingUID(HomeWizardBindingConstants.THING_TYPE_HWE_SKT, "homewizard-test-thing-skt"));
when(thing.getThingTypeUID()).thenReturn(HomeWizardBindingConstants.THING_TYPE_HWE_SKT);
}
- when(thing.getConfiguration()).thenReturn(CONFIG);
+ when(thing.getConfiguration()).thenReturn(CONFIG_V1);
final List channelList = Arrays.asList(
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
diff --git a/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/kwh_meter/HomeWizardKwhMeterHandlerTest.java b/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/kwh_meter/HomeWizardKwhMeterHandlerTest.java
index ff7f87cb9292c..0e63cb4968369 100644
--- a/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/kwh_meter/HomeWizardKwhMeterHandlerTest.java
+++ b/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/kwh_meter/HomeWizardKwhMeterHandlerTest.java
@@ -45,7 +45,7 @@ private static Thing mockThing(boolean legacy) {
when(thing.getUID())
.thenReturn(new ThingUID(HomeWizardBindingConstants.THING_TYPE_HWE_SKT, "homewizard-test-thing-skt"));
when(thing.getThingTypeUID()).thenReturn(HomeWizardBindingConstants.THING_TYPE_HWE_KWH);
- when(thing.getConfiguration()).thenReturn(CONFIG);
+ when(thing.getConfiguration()).thenReturn(CONFIG_V1);
final List channelList = Arrays.asList(
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
diff --git a/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/p1_meter/HomeWizardP1MeterBatteriesPayloadTest.java b/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/p1_meter/HomeWizardP1MeterBatteriesPayloadTest.java
new file mode 100644
index 0000000000000..96242fb33fc6a
--- /dev/null
+++ b/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/p1_meter/HomeWizardP1MeterBatteriesPayloadTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010-2025 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.homewizard.internal.devices.p1_meter;
+
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+import java.io.IOException;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.junit.jupiter.api.Test;
+import org.openhab.binding.homewizard.internal.dto.DataUtil;
+
+/**
+ * Tests deserialization of HomeWizard API responses from JSON.
+ *
+ * @author Gearrel Welvaart - Initial contribution
+ *
+ *
+ */
+@NonNullByDefault
+public class HomeWizardP1MeterBatteriesPayloadTest {
+
+ private static final DataUtil DATA_UTIL = new DataUtil();
+
+ @Test
+ public void deserializeResponse() throws IOException {
+ HomeWizardP1MeterBatteriesPayload key = DATA_UTIL.fromJson("response-batteries-p1-meter.json",
+ HomeWizardP1MeterBatteriesPayload.class);
+ assertThat(key, is(notNullValue()));
+
+ assertThat(key.getMode(), is("to_full"));
+ assertThat(key.getPower(), is(1599));
+ assertThat(key.getTargetPower(), is(1600));
+ assertThat(key.getMaxConsumption(), is(1600));
+ assertThat(key.getMaxProduction(), is(800));
+ }
+
+ @Test
+ public void deserializeResponseEmpty() throws IOException {
+ HomeWizardP1MeterBatteriesPayload key = DATA_UTIL.fromJson("response-empty.json",
+ HomeWizardP1MeterBatteriesPayload.class);
+ assertThat(key, is(notNullValue()));
+
+ assertThat(key.getMode(), is(""));
+ assertThat(key.getPower(), is(0));
+ assertThat(key.getTargetPower(), is(0));
+ assertThat(key.getMaxConsumption(), is(0));
+ assertThat(key.getMaxProduction(), is(0));
+ }
+}
diff --git a/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/p1_meter/HomeWizardP1MeterHandlerTest.java b/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/p1_meter/HomeWizardP1MeterHandlerTest.java
index 114403cce572f..05f7017c27074 100644
--- a/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/p1_meter/HomeWizardP1MeterHandlerTest.java
+++ b/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/p1_meter/HomeWizardP1MeterHandlerTest.java
@@ -46,7 +46,7 @@
@NonNullByDefault
public class HomeWizardP1MeterHandlerTest extends HomeWizardHandlerTest {
- private static Thing mockThing(boolean legacy) {
+ private static Thing mockThing(int apiVersion, boolean legacy) {
final Thing thing = mock(Thing.class);
if (legacy) {
when(thing.getUID()).thenReturn(
@@ -57,7 +57,11 @@ private static Thing mockThing(boolean legacy) {
.thenReturn(new ThingUID(HomeWizardBindingConstants.THING_TYPE_HWE_P1, "homewizard-test-thing-p1"));
when(thing.getThingTypeUID()).thenReturn(HomeWizardBindingConstants.THING_TYPE_HWE_P1);
}
- when(thing.getConfiguration()).thenReturn(CONFIG);
+ if (apiVersion == 1) {
+ when(thing.getConfiguration()).thenReturn(CONFIG_V1);
+ } else {
+ when(thing.getConfiguration()).thenReturn(CONFIG_V2);
+ }
final List channelList = Arrays.asList(
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
@@ -97,7 +101,17 @@ private static Thing mockThing(boolean legacy) {
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
HomeWizardBindingConstants.CHANNEL_GAS_TIMESTAMP), //
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
- HomeWizardBindingConstants.CHANNEL_GAS_TOTAL));
+ HomeWizardBindingConstants.CHANNEL_GAS_TOTAL),
+ mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
+ HomeWizardBindingConstants.CHANNEL_BATTERIES_MODE), //
+ mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
+ HomeWizardBindingConstants.CHANNEL_BATTERIES_POWER), //
+ mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
+ HomeWizardBindingConstants.CHANNEL_BATTERIES_TARGET_POWER), //
+ mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
+ HomeWizardBindingConstants.CHANNEL_BATTERIES_MAX_CONSUMPTION), //
+ mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
+ HomeWizardBindingConstants.CHANNEL_BATTERIES_MAX_PRODUCTION));
when(thing.getChannels()).thenReturn(channelList);
return thing;
@@ -113,6 +127,7 @@ private static HomeWizardP1MeterHandlerMock createAndInitHandler(final ThingHand
doReturn(DataUtil.fromFile("response-device-information-p1-meter.json")).when(handler)
.getDeviceInformationData();
doReturn(DataUtil.fromFile("response-measurement-p1-meter.json")).when(handler).getMeasurementData();
+ doReturn(DataUtil.fromFile("response-batteries-p1-meter.json")).when(handler).getBatteriesData();
} catch (Exception e) {
assertFalse(true);
}
@@ -124,7 +139,7 @@ private static HomeWizardP1MeterHandlerMock createAndInitHandler(final ThingHand
@Test
public void testUpdateChannels() {
- final Thing thing = mockThing(false);
+ final Thing thing = mockThing(1, false);
final ThingHandlerCallback callback = mock(ThingHandlerCallback.class);
final HomeWizardP1MeterHandlerMock handler = createAndInitHandler(callback, thing);
@@ -181,9 +196,40 @@ public void testUpdateChannels() {
}
}
+ @Test
+ public void testUpdateBatteriesChannels() {
+ final Thing thing = mockThing(2, false);
+ final ThingHandlerCallback callback = mock(ThingHandlerCallback.class);
+ final HomeWizardP1MeterHandlerMock handler = createAndInitHandler(callback, thing);
+
+ try {
+ verify(callback).statusUpdated(eq(thing), argThat(arg -> arg.getStatus().equals(ThingStatus.UNKNOWN)));
+ verify(callback).statusUpdated(eq(thing), argThat(arg -> arg.getStatus().equals(ThingStatus.ONLINE)));
+
+ verify(callback).stateUpdated(
+ getBatteriesChannelUid(thing, HomeWizardBindingConstants.CHANNEL_BATTERIES_MODE),
+ getState("to_full"));
+ verify(callback).stateUpdated(
+ getBatteriesChannelUid(thing, HomeWizardBindingConstants.CHANNEL_BATTERIES_POWER),
+ getState(1599, Units.WATT));
+ verify(callback).stateUpdated(
+ getBatteriesChannelUid(thing, HomeWizardBindingConstants.CHANNEL_BATTERIES_TARGET_POWER),
+ getState(1600, Units.WATT));
+ verify(callback).stateUpdated(
+ getBatteriesChannelUid(thing, HomeWizardBindingConstants.CHANNEL_BATTERIES_MAX_CONSUMPTION),
+ getState(1600, Units.WATT));
+ verify(callback).stateUpdated(
+ getBatteriesChannelUid(thing, HomeWizardBindingConstants.CHANNEL_BATTERIES_MAX_PRODUCTION),
+ getState(800, Units.WATT));
+
+ } finally {
+ handler.dispose();
+ }
+ }
+
@Test
public void testUpdateLegacyChannels() {
- final Thing thing = mockThing(true);
+ final Thing thing = mockThing(1, true);
final ThingHandlerCallback callback = mock(ThingHandlerCallback.class);
final HomeWizardP1MeterHandlerMock handler = createAndInitHandler(callback, thing);
diff --git a/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/plug_in_battery/HomeWizardPlugInBatteryMeterHandlerTest.java b/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/plug_in_battery/HomeWizardPlugInBatteryMeterHandlerTest.java
index 1d9fc3fd83caa..07360f6d30e1f 100644
--- a/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/plug_in_battery/HomeWizardPlugInBatteryMeterHandlerTest.java
+++ b/bundles/org.openhab.binding.homewizard/src/test/java/org/openhab/binding/homewizard/internal/devices/plug_in_battery/HomeWizardPlugInBatteryMeterHandlerTest.java
@@ -46,7 +46,7 @@ private static Thing mockThing() {
.thenReturn(new ThingUID(HomeWizardBindingConstants.THING_TYPE_HWE_P1, "homewizard-test-thing-bat"));
when(thing.getThingTypeUID()).thenReturn(HomeWizardBindingConstants.THING_TYPE_HWE_BAT);
- when(thing.getConfiguration()).thenReturn(CONFIG);
+ when(thing.getConfiguration()).thenReturn(CONFIG_V2);
final List channelList = Arrays.asList(
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
diff --git a/bundles/org.openhab.binding.homewizard/src/test/resources/org/openhab/binding/homewizard/internal/dto/response-batteries-p1-meter.json b/bundles/org.openhab.binding.homewizard/src/test/resources/org/openhab/binding/homewizard/internal/dto/response-batteries-p1-meter.json
new file mode 100644
index 0000000000000..65e1d0f6a3001
--- /dev/null
+++ b/bundles/org.openhab.binding.homewizard/src/test/resources/org/openhab/binding/homewizard/internal/dto/response-batteries-p1-meter.json
@@ -0,0 +1,8 @@
+{
+ "mode": "to_full",
+ "power_w": 1599,
+ "target_power_w": 1600,
+ "max_consumption_w": 1600,
+ "max_production_w": 800
+}
+