mirror of
https://github.com/danieldemus/openhab-addons
synced 2026-07-29 12:34:21 +02:00
[homewizard] Add support for the system API (#19967)
* Added support for the system API. This API is available for all devices; only a subset of the channels is available for the v1 devices. In addition, the code was refactored to make is more simple and consistent. Signed-off-by: Gearrel Welvaart <gearrel.welvaart@gmail.com>
This commit is contained in:
@@ -26,7 +26,7 @@ The binding offers Things, providing access to all the supported HomeWizard devi
|
||||
| hwe-p1 | P1 Meter | Reads total and current energy usage and total gas usage (v1 and v2). |
|
||||
| hwe-skt | Energy Socket | Reads total and current energy usage. Controls power switch, lock, and ring brightness (v1). |
|
||||
| hwe-wtr | Watermeter | Reads total and current water usage (v1). |
|
||||
| hwe-kwh | kWh Meter | Reads total and current energy usage (v1). |
|
||||
| hwe-kwh | kWh Meter | Reads total and current energy usage (v1 and v2). |
|
||||
| hwe-bat | Plug-In Battery | Reads total and current energy usage and the current charge (v2). |
|
||||
| p1_wifi_meter | Wi-Fi P1 Meter | [Deprecated] Reads total and current energy usage and total gas usage. |
|
||||
| energy_socket | Wi-Fi Energy Socket | [Deprecated] Reads total and current energy usage. Controls power switch, lock, and ring brightness.|
|
||||
@@ -87,6 +87,11 @@ For DSMR5 meters this is generally once per second, for older versions the frequ
|
||||
| batteries_target_power | Number:Power | The target power consumption/production of the controlled Plug-In Batteries. | v1, 2.1.0 |
|
||||
| batteries_max_consumption | Number:Power | The maximum allowed consumption power of the controlled Plug-In Batteries. | v1, 2.1.0 |
|
||||
| batteries_max_production | Number:Power | The maximum allowed production power of the controlled Plug-In Batteries. | v1, 2.1.0 |
|
||||
| wifi_ssid | String | The SSID of the Wi-Fi network. | v1, 2.0.0 |
|
||||
| wifi_rssi | Number:Dimensionless | The signal strength of the Wi-Fi network. | v1, 2.0.0 |
|
||||
| uptime | Number:Time | The uptime of the device in seconds. | v1, 2.0.0 |
|
||||
| cloud_enabled | Switch | The state of the cloud communication. | v1, 2.0.0 |
|
||||
| status_led_brightness | Number:Dimensionless | The brightness of the status LED in percent. | v1, 2.0.0 |
|
||||
|
||||
### HWE-KWH
|
||||
|
||||
@@ -115,6 +120,11 @@ For DSMR5 meters this is generally once per second, for older versions the frequ
|
||||
| batteries_target_power | Number:Power | The target power consumption/production of the controlled Plug-In Batteries. | v1, 2.1.0 |
|
||||
| batteries_max_consumption | Number:Power | The maximum allowed consumption power of the controlled Plug-In Batteries. | v1, 2.1.0 |
|
||||
| batteries_max_production | Number:Power | The maximum allowed production power of the controlled Plug-In Batteries. | v1, 2.1.0 |
|
||||
| wifi_ssid | String | The SSID of the Wi-Fi network. | v1, 2.0.0 |
|
||||
| wifi_rssi | Number:Dimensionless | The signal strength of the Wi-Fi network. | v1, 2.0.0 |
|
||||
| uptime | Number:Time | The uptime of the device in seconds. | v1, 2.0.0 |
|
||||
| cloud_enabled | Switch | The state of the cloud communication. | v1, 2.0.0 |
|
||||
| status_led_brightness | Number:Dimensionless | The brightness of the status LED in percent. | v1, 2.0.0 |
|
||||
|
||||
### HWE-SKT
|
||||
|
||||
@@ -132,6 +142,9 @@ For DSMR5 meters this is generally once per second, for older versions the frequ
|
||||
| power_switch | Switch | Access to the power switch of the Energy Socket. | v1 |
|
||||
| power_lock | Switch | Access to the power lock of the Energy Socket. | v1 |
|
||||
| ring_brightness | Number:Dimensionless | Access to the brightness of the ring of the Energy Socket. | v1 |
|
||||
| wifi_ssid | String | The SSID of the Wi-Fi network. | v1 |
|
||||
| wifi_rssi | Number:Dimensionless | The signal strength of the Wi-Fi network. | v1 |
|
||||
| cloud_enabled | Switch | The state of the cloud communication. | v1 |
|
||||
|
||||
### HWE-BAT
|
||||
|
||||
@@ -145,6 +158,11 @@ For DSMR5 meters this is generally once per second, for older versions the frequ
|
||||
| frequency | Number:Frequency | The active frequency in Hertz. | 2.0.0 |
|
||||
| state_of_charge | Number:Dimensionless | Access to the current state of charge in percent. | 2.0.0 |
|
||||
| cycles | Number:Dimensionless | Access to the number of battery cycles. | 2.0.0 |
|
||||
| wifi_ssid | String | The SSID of the Wi-Fi network. | 2.0.0 |
|
||||
| wifi_rssi | Number:Dimensionless | The signal strength of the Wi-Fi network. | 2.0.0 |
|
||||
| uptime | Number:Time | The uptime of the device in seconds. | 2.0.0 |
|
||||
| cloud_enabled | Switch | The state of the cloud communication. | 2.0.0 |
|
||||
| status_led_brightness | Number:Dimensionless | The brightness of the status LED in percent. | 2.0.0 |
|
||||
|
||||
### HWE-WTR
|
||||
|
||||
@@ -152,6 +170,9 @@ For DSMR5 meters this is generally once per second, for older versions the frequ
|
||||
|---------------------------|---------------------------|----------------------------------------------------------------------------------------|--------------|
|
||||
| total_liter | Number:Volume | Total water usage in cubic meters. | v1 |
|
||||
| active_liter | Number:VolumetricFlowRate | The active water usage in liters per minute. | v1 |
|
||||
| wifi_ssid | String | The SSID of the Wi-Fi network. | v1 |
|
||||
| wifi_rssi | Number:Dimensionless | The signal strength of the Wi-Fi network. | v1 |
|
||||
| cloud_enabled | Switch | The state of the cloud communication. | v1 |
|
||||
|
||||
## Full Example
|
||||
|
||||
|
||||
+11
-3
@@ -52,7 +52,8 @@ 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_BATTERIES = "batteries";
|
||||
public static final String CHANNEL_GROUP_SYSTEM = "system";
|
||||
public static final String CHANNEL_GROUP_WATER = "water";
|
||||
public static final String CHANNEL_GROUP_SKT_CONTROL = "control";
|
||||
|
||||
@@ -107,14 +108,21 @@ public class HomeWizardBindingConstants {
|
||||
public static final String CHANNEL_GAS_TIMESTAMP = "gas_timestamp";
|
||||
public static final String CHANNEL_GAS_TOTAL = "total_gas";
|
||||
|
||||
// System
|
||||
public static final String CHANNEL_SYSTEM_WIFI_SSID = "wifi_ssid";
|
||||
public static final String CHANNEL_SYSTEM_WIFI_RSSI = "wifi_rssi";
|
||||
public static final String CHANNEL_SYSTEM_CLOUD_ENABLED = "cloud_enabled";
|
||||
public static final String CHANNEL_SYSTEM_UPTIME = "uptime";
|
||||
public static final String CHANNEL_SYSTEM_STATUS_LED_BRIGHTNESS = "status_led_brightness";
|
||||
|
||||
// Batteries
|
||||
public static final String CHANNEL_BATTERIES_MODE = "batteries_mode";
|
||||
public static final String CHANNEL_BATTERIES_COUNT = "batteries_count";
|
||||
public static final String CHANNEL_BATTERIES_COUNT = "batteries_battery_count";
|
||||
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";
|
||||
|
||||
// Batteries
|
||||
public static final String BATTERIES_MODE_STANDBY = "standby";
|
||||
public static final String BATTERIES_MODE_ZERO = "zero";
|
||||
public static final String BATTERIES_MODE_TO_FULL = "to_full";
|
||||
|
||||
+15
-64
@@ -12,11 +12,7 @@
|
||||
*/
|
||||
package org.openhab.binding.homewizard.internal.devices;
|
||||
|
||||
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.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
@@ -39,24 +35,11 @@ import com.google.gson.JsonSyntaxException;
|
||||
@NonNullByDefault
|
||||
public class HomeWizardBatteriesSubHandler {
|
||||
|
||||
private final String BATTERIES_URL = "batteries";
|
||||
protected final static Logger logger = LoggerFactory.getLogger(HomeWizardBatteriesSubHandler.class);
|
||||
private final static Gson gson = new GsonBuilder()
|
||||
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
|
||||
|
||||
protected final Logger logger = LoggerFactory.getLogger(HomeWizardBatteriesSubHandler.class);
|
||||
private final Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
|
||||
.create();
|
||||
|
||||
private HomeWizardDeviceHandler handler;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param handler The device handler used to communicate with the HomeWizard device
|
||||
*/
|
||||
public HomeWizardBatteriesSubHandler(HomeWizardDeviceHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
public void handleCommand(Command command) {
|
||||
public static void handleCommand(Command command, HomeWizardDeviceHandler handler) {
|
||||
var mode = "";
|
||||
var permissions = "";
|
||||
|
||||
@@ -96,30 +79,19 @@ public class HomeWizardBatteriesSubHandler {
|
||||
}
|
||||
var cmd = String.format("{%s\"mode\": \"%s\"}", permissions, mode);
|
||||
|
||||
try {
|
||||
var response = handler.putDataTo(handler.apiURL + BATTERIES_URL, cmd);
|
||||
if (response.getStatus() == HttpStatus.OK_200) {
|
||||
handleBatteriesData(response.getContentAsString());
|
||||
} else {
|
||||
logger.warn("Failed to send command {} to {}", command, handler.apiURL + BATTERIES_URL);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
logger.warn("Failed to send command {} to {}", command, handler.apiURL + BATTERIES_URL);
|
||||
}
|
||||
handler.sendBatteriesCommand(cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Device specific handling of the returned batteries data.
|
||||
*
|
||||
* @param data The data obtained from the API call
|
||||
* @throws JsonSyntaxException when the data cannot be parsed to the expected format
|
||||
*/
|
||||
public void handleBatteriesData(String data) {
|
||||
public static void handleBatteriesData(String data, HomeWizardDeviceHandler handler) throws JsonSyntaxException {
|
||||
HomeWizardBatteriesPayload payload = null;
|
||||
try {
|
||||
payload = gson.fromJson(data, HomeWizardBatteriesPayload.class);
|
||||
} catch (JsonSyntaxException ex) {
|
||||
logger.warn("No Batteries data available");
|
||||
}
|
||||
payload = gson.fromJson(data, HomeWizardBatteriesPayload.class);
|
||||
|
||||
if (payload != null) {
|
||||
var mode = payload.getMode();
|
||||
if (mode.equals(HomeWizardBindingConstants.BATTERIES_MODE_ZERO)) {
|
||||
@@ -133,43 +105,22 @@ public class HomeWizardBatteriesSubHandler {
|
||||
mode = HomeWizardBindingConstants.BATTERIES_MODE_STANDBY;
|
||||
}
|
||||
}
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_BATTERIES,
|
||||
HomeWizardBindingConstants.CHANNEL_BATTERIES_MODE, new StringType(mode));
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_BATTERIES,
|
||||
HomeWizardBindingConstants.CHANNEL_BATTERIES_COUNT, new DecimalType(payload.getBatteryCount()));
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_BATTERIES,
|
||||
HomeWizardBindingConstants.CHANNEL_BATTERIES_POWER,
|
||||
new QuantityType<>(payload.getPower(), Units.WATT));
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_BATTERIES,
|
||||
HomeWizardBindingConstants.CHANNEL_BATTERIES_TARGET_POWER,
|
||||
new QuantityType<>(payload.getTargetPower(), Units.WATT));
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_BATTERIES,
|
||||
HomeWizardBindingConstants.CHANNEL_BATTERIES_MAX_CONSUMPTION,
|
||||
new QuantityType<>(payload.getMaxConsumption(), Units.WATT));
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_BATTERIES,
|
||||
HomeWizardBindingConstants.CHANNEL_BATTERIES_MAX_PRODUCTION,
|
||||
new QuantityType<>(payload.getMaxProduction(), Units.WATT));
|
||||
}
|
||||
}
|
||||
|
||||
public void retrieveBatteriesData() throws InterruptedException, TimeoutException, ExecutionException {
|
||||
final String batteriesData;
|
||||
|
||||
batteriesData = getBatteriesData();
|
||||
handleBatteriesData(batteriesData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return json response from the batteries api
|
||||
* @throws InterruptedException, TimeoutException, ExecutionException
|
||||
*/
|
||||
public String getBatteriesData() throws InterruptedException, TimeoutException, ExecutionException {
|
||||
var response = handler.getResponseFrom(handler.apiURL + BATTERIES_URL);
|
||||
if (response.getStatus() == HttpStatus.OK_200) {
|
||||
return response.getContentAsString();
|
||||
} else {
|
||||
logger.warn("No Batteries data available");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+202
-40
@@ -12,7 +12,11 @@
|
||||
*/
|
||||
package org.openhab.binding.homewizard.internal.devices;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -34,13 +38,21 @@ 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.HomeWizardBindingConstants;
|
||||
import org.openhab.binding.homewizard.internal.HomeWizardConfiguration;
|
||||
import org.openhab.binding.homewizard.internal.devices.water_meter.HomeWizardWaterMeterMeasurementPayload;
|
||||
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.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.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -48,6 +60,7 @@ import org.slf4j.LoggerFactory;
|
||||
import com.google.gson.FieldNamingPolicy;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
/**
|
||||
* The {@link HomeWizardDeviceHandler} is a base class for all
|
||||
@@ -61,6 +74,9 @@ import com.google.gson.GsonBuilder;
|
||||
@NonNullByDefault
|
||||
public abstract class HomeWizardDeviceHandler extends BaseThingHandler {
|
||||
|
||||
private final String SYSTEM_URL = "system";
|
||||
private final String BATTERIES_URL = "batteries";
|
||||
|
||||
private static final String BEARER = "Bearer";
|
||||
private static final String API_VERSION_HEADER = "X-Api-Version";
|
||||
private static final String CERTIFICATE_ALIAS = "caCert";
|
||||
@@ -84,7 +100,7 @@ public abstract class HomeWizardDeviceHandler extends BaseThingHandler {
|
||||
|
||||
protected List<String> supportedTypes = new ArrayList<String>();
|
||||
protected List<Integer> supportedApiVersions = Arrays.asList(API_V1);
|
||||
public String apiURL = "";
|
||||
private String apiURL = "";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -114,7 +130,7 @@ public abstract class HomeWizardDeviceHandler extends BaseThingHandler {
|
||||
keyStore.load(null, null);
|
||||
keyStore.setCertificateEntry(CERTIFICATE_ALIAS, CertificateFactory.getInstance(CERTIFICATE_TYPE)
|
||||
.generateCertificate(classloader.getResourceAsStream(caCertPath)));
|
||||
} catch (Exception ex) {
|
||||
} catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException ex) {
|
||||
}
|
||||
|
||||
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
|
||||
@@ -163,7 +179,7 @@ public abstract class HomeWizardDeviceHandler extends BaseThingHandler {
|
||||
try {
|
||||
httpClient.setConnectTimeout(30000);
|
||||
httpClient.start();
|
||||
} catch (Exception ex) {
|
||||
} catch (Exception ex) { // No specific exception is thrown by the start method
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"@text/offline.comm-error-device-offline");
|
||||
logger.debug("Unable to reach device", ex);
|
||||
@@ -174,17 +190,57 @@ public abstract class HomeWizardDeviceHandler extends BaseThingHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Not listening to any commands.
|
||||
* Listening to commands for the system api.
|
||||
*/
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (command instanceof RefreshType) {
|
||||
return;
|
||||
}
|
||||
|
||||
var cmd = "";
|
||||
|
||||
switch (channelUID.getIdWithoutGroup()) {
|
||||
case HomeWizardBindingConstants.CHANNEL_SYSTEM_CLOUD_ENABLED: {
|
||||
boolean onOff = command.equals(OnOffType.ON);
|
||||
cmd = String.format("{\"cloud_enabled\": %b}", onOff);
|
||||
break;
|
||||
}
|
||||
case HomeWizardBindingConstants.CHANNEL_SYSTEM_STATUS_LED_BRIGHTNESS: {
|
||||
cmd = String.format("{\"status_led_brightness_pct\": %s}", command.toFullString());
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
logger.warn("Unhandled command for channel: {} command: {}", channelUID.getIdWithoutGroup(), command);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sendSystemCommand(cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual polling loop
|
||||
*/
|
||||
protected void retrieveData() {
|
||||
retrieveMeasurementData();
|
||||
try {
|
||||
handleSystemData(getSystemData());
|
||||
handleMeasurementData(getMeasurementData());
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
} catch (JsonSyntaxException ex) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"@text/offline.comm-error-device-offline");
|
||||
logger.debug("Unable to get data from the API", ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
protected String getApiUrl() {
|
||||
if (config.isUsingApiVersion2()) {
|
||||
return apiURL;
|
||||
} else {
|
||||
return apiURL + "v1/";
|
||||
}
|
||||
}
|
||||
|
||||
private boolean processDeviceInformation() {
|
||||
@@ -192,7 +248,7 @@ public abstract class HomeWizardDeviceHandler extends BaseThingHandler {
|
||||
|
||||
try {
|
||||
deviceInformation = getDeviceInformationData();
|
||||
} catch (Exception ex) {
|
||||
} catch (SecurityException ex) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"@text/offline.comm-error-device-offline");
|
||||
logger.debug("Unable to get device information", ex);
|
||||
@@ -243,7 +299,7 @@ public abstract class HomeWizardDeviceHandler extends BaseThingHandler {
|
||||
pollingJob = null;
|
||||
try {
|
||||
httpClient.stop();
|
||||
} catch (Exception ex) {
|
||||
} catch (Exception ex) { // No specific exception is thrown by the stop method
|
||||
logger.debug("Error stopping the http client: {}", ex.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -256,76 +312,182 @@ public abstract class HomeWizardDeviceHandler extends BaseThingHandler {
|
||||
* @param channelID id of the channel, which was updated
|
||||
* @param state new state
|
||||
*/
|
||||
protected void updateState(String groupID, String channelID, State state) {
|
||||
updateState(groupID + "#" + channelID, state);
|
||||
public void updateState(String groupID, String channelID, State state) {
|
||||
if (!groupID.isEmpty()) {
|
||||
updateState(groupID + "#" + channelID, state);
|
||||
} else {
|
||||
updateState(channelID, state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Device specific handling of the returned measurement data.
|
||||
*
|
||||
* @param payload The data obtained form the API call
|
||||
* @param payload The data obtained from the API call
|
||||
* @throws JsonSyntaxException when the returned data cannot be parsed
|
||||
*/
|
||||
protected abstract void handleMeasurementData(String data);
|
||||
protected void handleMeasurementData(String data) throws JsonSyntaxException {
|
||||
if (!config.isUsingApiVersion2()) {
|
||||
// We're only interested in the Wi-Fi data and the water meter payload processes these data.
|
||||
HomeWizardWaterMeterMeasurementPayload payload = null;
|
||||
payload = gson.fromJson(data, HomeWizardWaterMeterMeasurementPayload.class);
|
||||
|
||||
protected ContentResponse putDataTo(String url, String data)
|
||||
throws InterruptedException, TimeoutException, ExecutionException {
|
||||
if (payload != null) {
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_SYSTEM,
|
||||
HomeWizardBindingConstants.CHANNEL_SYSTEM_WIFI_SSID, new StringType(payload.getWifiSsid()));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_SYSTEM,
|
||||
HomeWizardBindingConstants.CHANNEL_SYSTEM_WIFI_RSSI, new DecimalType(payload.getWifiRssi()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Device specific handling of the returned batteries data.
|
||||
*
|
||||
* @param data The data obtained from the API call
|
||||
*/
|
||||
protected void handleBatteriesData(String data) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Device specific handling of the returned system data.
|
||||
*
|
||||
* @param data The data obtained from the API call
|
||||
* @throws JsonSyntaxException when the returned data cannot be parsed
|
||||
*/
|
||||
protected void handleSystemData(String data) throws JsonSyntaxException {
|
||||
HomeWizardSystemPayload payload = null;
|
||||
payload = gson.fromJson(data, HomeWizardSystemPayload.class);
|
||||
if (payload != null) {
|
||||
if (config.isUsingApiVersion2()) {
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_SYSTEM,
|
||||
HomeWizardBindingConstants.CHANNEL_SYSTEM_WIFI_SSID, new StringType(payload.getWifiSsid()));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_SYSTEM,
|
||||
HomeWizardBindingConstants.CHANNEL_SYSTEM_WIFI_RSSI, new DecimalType(payload.getWifiRssi()));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_SYSTEM,
|
||||
HomeWizardBindingConstants.CHANNEL_SYSTEM_UPTIME,
|
||||
new QuantityType<>(payload.getUptime(), Units.SECOND));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_SYSTEM,
|
||||
HomeWizardBindingConstants.CHANNEL_SYSTEM_STATUS_LED_BRIGHTNESS,
|
||||
new DecimalType(payload.getStatusLedBrightness()));
|
||||
}
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_SYSTEM,
|
||||
HomeWizardBindingConstants.CHANNEL_SYSTEM_CLOUD_ENABLED, OnOffType.from(payload.isCloudEnabled()));
|
||||
}
|
||||
}
|
||||
|
||||
protected @Nullable ContentResponse putDataTo(String url, String data) {
|
||||
var request = httpClient.newRequest(url).method(HttpMethod.PUT).content(new StringContentProvider(data));
|
||||
|
||||
return sendRequest(request);
|
||||
}
|
||||
|
||||
protected ContentResponse getResponseFrom(String url)
|
||||
throws InterruptedException, TimeoutException, ExecutionException {
|
||||
public @Nullable ContentResponse getResponseFrom(String url) {
|
||||
return sendRequest(httpClient.newRequest(url));
|
||||
}
|
||||
|
||||
private ContentResponse sendRequest(Request request)
|
||||
throws InterruptedException, TimeoutException, ExecutionException {
|
||||
private @Nullable ContentResponse sendRequest(Request request) {
|
||||
if (config.isUsingApiVersion2()) {
|
||||
request.header(HttpHeader.AUTHORIZATION, BEARER + " " + config.bearerToken);
|
||||
request.header(API_VERSION_HEADER, "2");
|
||||
}
|
||||
return request.timeout(20, TimeUnit.SECONDS).send();
|
||||
try {
|
||||
return request.timeout(20, TimeUnit.SECONDS).send();
|
||||
} catch (InterruptedException ex) {
|
||||
Thread.currentThread().interrupt(); // restore interrupt status
|
||||
return null;
|
||||
} catch (TimeoutException | ExecutionException ex) {
|
||||
logger.debug("Error sending request", ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return json response from the device information api
|
||||
* @throws InterruptedException, TimeoutException, ExecutionException, SecurityException
|
||||
* @return json response from the device information api or an empty string if no data is available
|
||||
* @throws SecurityException
|
||||
*/
|
||||
public String getDeviceInformationData()
|
||||
throws InterruptedException, TimeoutException, ExecutionException, SecurityException {
|
||||
public String getDeviceInformationData() throws SecurityException {
|
||||
var response = getResponseFrom(apiURL);
|
||||
if (response == null) {
|
||||
logger.warn("No Device Information data available");
|
||||
return "";
|
||||
}
|
||||
if (response.getStatus() == HttpStatus.UNAUTHORIZED_401) {
|
||||
throw new SecurityException("Bearer token is invalid.");
|
||||
}
|
||||
return response.getContentAsString();
|
||||
if (response.getStatus() == HttpStatus.OK_200) {
|
||||
return response.getContentAsString();
|
||||
} else {
|
||||
logger.warn("No Device Information data available");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return json response from the measurement api
|
||||
* @throws InterruptedException, TimeoutException, ExecutionException
|
||||
* @return json response from the system api or an empty string if no data is available
|
||||
*
|
||||
*/
|
||||
public String getMeasurementData() throws InterruptedException, TimeoutException, ExecutionException {
|
||||
var url = apiURL;
|
||||
public String getSystemData() {
|
||||
var response = getResponseFrom(getApiUrl() + SYSTEM_URL);
|
||||
if (response != null && response.getStatus() == HttpStatus.OK_200) {
|
||||
return response.getContentAsString();
|
||||
} else {
|
||||
logger.warn("No System data available");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public void sendSystemCommand(String command) {
|
||||
var url = getApiUrl() + SYSTEM_URL;
|
||||
var response = putDataTo(url, command);
|
||||
if (response != null && response.getStatus() == HttpStatus.OK_200) {
|
||||
handleSystemData(response.getContentAsString());
|
||||
} else {
|
||||
logger.warn("Failed to send command {} to {}", command, url);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return json response from the measurement api or an empty string if no data is available
|
||||
*
|
||||
*/
|
||||
public String getMeasurementData() {
|
||||
var url = getApiUrl();
|
||||
if (config.isUsingApiVersion2()) {
|
||||
url += "measurement";
|
||||
} else {
|
||||
url += "v1/data";
|
||||
url += "data";
|
||||
}
|
||||
var response = getResponseFrom(url);
|
||||
if (response != null && response.getStatus() == HttpStatus.OK_200) {
|
||||
return response.getContentAsString();
|
||||
} else {
|
||||
logger.warn("No Measurements data available");
|
||||
return "";
|
||||
}
|
||||
return getResponseFrom(url).getContentAsString();
|
||||
}
|
||||
|
||||
protected void retrieveMeasurementData() {
|
||||
final String measurementData;
|
||||
try {
|
||||
measurementData = getMeasurementData();
|
||||
} catch (Exception ex) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"@text/offline.comm-error-device-offline");
|
||||
logger.debug("Unable to get measurement data", ex);
|
||||
return;
|
||||
/**
|
||||
* @return json response from the batteries api or an empty string if no data is available
|
||||
*
|
||||
*/
|
||||
public String getBatteriesData() {
|
||||
var response = getResponseFrom(getApiUrl() + BATTERIES_URL);
|
||||
if (response != null && response.getStatus() == HttpStatus.OK_200) {
|
||||
return response.getContentAsString();
|
||||
} else {
|
||||
logger.warn("No Batteries data available");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
protected void sendBatteriesCommand(String command) {
|
||||
var url = getApiUrl() + BATTERIES_URL;
|
||||
var response = putDataTo(url, command);
|
||||
if (response != null && response.getStatus() == HttpStatus.OK_200) {
|
||||
handleBatteriesData(response.getContentAsString());
|
||||
} else {
|
||||
logger.warn("Failed to send command {} to {}", command, url);
|
||||
}
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
handleMeasurementData(measurementData);
|
||||
}
|
||||
}
|
||||
|
||||
+53
-53
@@ -16,131 +16,131 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
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.Thing;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.FieldNamingPolicy;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
/**
|
||||
* The {@link HomeWizardEnergyMeterHandler} implements functionality generic to several energy meters.
|
||||
* The {@link HomeWizardEnergyMeterSubHandler} implements functionality generic to several energy meters.
|
||||
*
|
||||
* @author Gearrel Welvaart - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HomeWizardEnergyMeterHandler extends HomeWizardDeviceHandler {
|
||||
public class HomeWizardEnergyMeterSubHandler {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param thing The thing to handle
|
||||
* @param timeZoneProvider The TimeZoneProvider
|
||||
*/
|
||||
public HomeWizardEnergyMeterHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
protected final Logger logger = LoggerFactory.getLogger(HomeWizardEnergyMeterSubHandler.class);
|
||||
private final static Gson gson = new GsonBuilder()
|
||||
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
|
||||
|
||||
/**
|
||||
* Device specific handling of the returned data.
|
||||
*
|
||||
* @param data The data obtained form the API call
|
||||
* @param data The data obtained from the API call
|
||||
*/
|
||||
@Override
|
||||
protected void handleMeasurementData(String data) {
|
||||
public static void handleMeasurementData(String data, HomeWizardDeviceHandler handler) {
|
||||
var payload = gson.fromJson(data, HomeWizardEnergyMeterMeasurementPayload.class);
|
||||
if (payload != null) {
|
||||
if (!thing.getThingTypeUID().equals(HomeWizardBindingConstants.THING_TYPE_P1_METER)
|
||||
&& !thing.getThingTypeUID().equals(HomeWizardBindingConstants.THING_TYPE_ENERGY_SOCKET)) {
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
if (!handler.getThing().getThingTypeUID().equals(HomeWizardBindingConstants.THING_TYPE_P1_METER) && !handler
|
||||
.getThing().getThingTypeUID().equals(HomeWizardBindingConstants.THING_TYPE_ENERGY_SOCKET)) {
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_ENERGY_IMPORT,
|
||||
new QuantityType<>(payload.getEnergyImport(), Units.KILOWATT_HOUR));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_ENERGY_IMPORT_T1,
|
||||
new QuantityType<>(payload.getEnergyImportT1(), Units.KILOWATT_HOUR));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_ENERGY_IMPORT_T2,
|
||||
new QuantityType<>(payload.getEnergyImportT2(), Units.KILOWATT_HOUR));
|
||||
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_ENERGY_EXPORT,
|
||||
new QuantityType<>(payload.getEnergyExport(), Units.KILOWATT_HOUR));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_ENERGY_EXPORT_T1,
|
||||
new QuantityType<>(payload.getEnergyExportT1(), Units.KILOWATT_HOUR));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_ENERGY_EXPORT_T2,
|
||||
new QuantityType<>(payload.getEnergyExportT2(), Units.KILOWATT_HOUR));
|
||||
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY, HomeWizardBindingConstants.CHANNEL_POWER,
|
||||
new QuantityType<>(payload.getPower(), Units.WATT));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_POWER, new QuantityType<>(payload.getPower(), Units.WATT));
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_POWER_L1,
|
||||
new QuantityType<>(payload.getPowerL1(), Units.WATT));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_POWER_L2,
|
||||
new QuantityType<>(payload.getPowerL2(), Units.WATT));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_POWER_L3,
|
||||
new QuantityType<>(payload.getPowerL3(), Units.WATT));
|
||||
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY, HomeWizardBindingConstants.CHANNEL_CURRENT,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_CURRENT,
|
||||
new QuantityType<>(payload.getCurrent(), Units.AMPERE));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_CURRENT_L1,
|
||||
new QuantityType<>(payload.getCurrentL1(), Units.AMPERE));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_CURRENT_L2,
|
||||
new QuantityType<>(payload.getCurrentL2(), Units.AMPERE));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_CURRENT_L3,
|
||||
new QuantityType<>(payload.getCurrentL3(), Units.AMPERE));
|
||||
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY, HomeWizardBindingConstants.CHANNEL_VOLTAGE,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_VOLTAGE,
|
||||
new QuantityType<>(payload.getVoltage(), Units.VOLT));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_VOLTAGE_L1,
|
||||
new QuantityType<>(payload.getVoltageL1(), Units.VOLT));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_VOLTAGE_L2,
|
||||
new QuantityType<>(payload.getVoltageL2(), Units.VOLT));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_VOLTAGE_L3,
|
||||
new QuantityType<>(payload.getVoltageL3(), Units.VOLT));
|
||||
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
handler.updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_FREQUENCY,
|
||||
new QuantityType<>(payload.getFrequency(), Units.HERTZ));
|
||||
} else {
|
||||
updateState(HomeWizardBindingConstants.LEGACY_CHANNEL_ENERGY_IMPORT_T1,
|
||||
handler.updateState("", HomeWizardBindingConstants.LEGACY_CHANNEL_ENERGY_IMPORT_T1,
|
||||
new QuantityType<>(payload.getEnergyImportT1(), Units.KILOWATT_HOUR));
|
||||
updateState(HomeWizardBindingConstants.LEGACY_CHANNEL_ENERGY_IMPORT_T2,
|
||||
handler.updateState("", HomeWizardBindingConstants.LEGACY_CHANNEL_ENERGY_IMPORT_T2,
|
||||
new QuantityType<>(payload.getEnergyImportT2(), Units.KILOWATT_HOUR));
|
||||
updateState(HomeWizardBindingConstants.LEGACY_CHANNEL_ENERGY_EXPORT_T1,
|
||||
handler.updateState("", HomeWizardBindingConstants.LEGACY_CHANNEL_ENERGY_EXPORT_T1,
|
||||
new QuantityType<>(payload.getEnergyExportT1(), Units.KILOWATT_HOUR));
|
||||
updateState(HomeWizardBindingConstants.LEGACY_CHANNEL_ENERGY_EXPORT_T2,
|
||||
handler.updateState("", HomeWizardBindingConstants.LEGACY_CHANNEL_ENERGY_EXPORT_T2,
|
||||
new QuantityType<>(payload.getEnergyExportT2(), Units.KILOWATT_HOUR));
|
||||
|
||||
updateState(HomeWizardBindingConstants.LEGACY_CHANNEL_POWER,
|
||||
handler.updateState("", HomeWizardBindingConstants.LEGACY_CHANNEL_POWER,
|
||||
new QuantityType<>(payload.getPower(), Units.WATT));
|
||||
updateState(HomeWizardBindingConstants.LEGACY_CHANNEL_POWER_L1,
|
||||
handler.updateState("", HomeWizardBindingConstants.LEGACY_CHANNEL_POWER_L1,
|
||||
new QuantityType<>(payload.getPowerL1(), Units.WATT));
|
||||
updateState(HomeWizardBindingConstants.LEGACY_CHANNEL_POWER_L2,
|
||||
handler.updateState("", HomeWizardBindingConstants.LEGACY_CHANNEL_POWER_L2,
|
||||
new QuantityType<>(payload.getPowerL2(), Units.WATT));
|
||||
updateState(HomeWizardBindingConstants.LEGACY_CHANNEL_POWER_L3,
|
||||
handler.updateState("", HomeWizardBindingConstants.LEGACY_CHANNEL_POWER_L3,
|
||||
new QuantityType<>(payload.getPowerL3(), Units.WATT));
|
||||
|
||||
updateState(HomeWizardBindingConstants.LEGACY_CHANNEL_VOLTAGE,
|
||||
handler.updateState("", HomeWizardBindingConstants.LEGACY_CHANNEL_VOLTAGE,
|
||||
new QuantityType<>(payload.getVoltage(), Units.VOLT));
|
||||
updateState(HomeWizardBindingConstants.LEGACY_CHANNEL_VOLTAGE_L1,
|
||||
handler.updateState("", HomeWizardBindingConstants.LEGACY_CHANNEL_VOLTAGE_L1,
|
||||
new QuantityType<>(payload.getVoltageL1(), Units.VOLT));
|
||||
updateState(HomeWizardBindingConstants.LEGACY_CHANNEL_VOLTAGE_L2,
|
||||
handler.updateState("", HomeWizardBindingConstants.LEGACY_CHANNEL_VOLTAGE_L2,
|
||||
new QuantityType<>(payload.getVoltageL2(), Units.VOLT));
|
||||
updateState(HomeWizardBindingConstants.LEGACY_CHANNEL_VOLTAGE_L3,
|
||||
handler.updateState("", HomeWizardBindingConstants.LEGACY_CHANNEL_VOLTAGE_L3,
|
||||
new QuantityType<>(payload.getVoltageL3(), Units.VOLT));
|
||||
|
||||
updateState(HomeWizardBindingConstants.LEGACY_CHANNEL_CURRENT,
|
||||
handler.updateState("", HomeWizardBindingConstants.LEGACY_CHANNEL_CURRENT,
|
||||
new QuantityType<>(payload.getCurrent(), Units.AMPERE));
|
||||
updateState(HomeWizardBindingConstants.LEGACY_CHANNEL_CURRENT_L1,
|
||||
handler.updateState("", HomeWizardBindingConstants.LEGACY_CHANNEL_CURRENT_L1,
|
||||
new QuantityType<>(payload.getCurrentL1(), Units.AMPERE));
|
||||
updateState(HomeWizardBindingConstants.LEGACY_CHANNEL_CURRENT_L2,
|
||||
handler.updateState("", HomeWizardBindingConstants.LEGACY_CHANNEL_CURRENT_L2,
|
||||
new QuantityType<>(payload.getCurrentL2(), Units.AMPERE));
|
||||
updateState(HomeWizardBindingConstants.LEGACY_CHANNEL_CURRENT_L3,
|
||||
handler.updateState("", HomeWizardBindingConstants.LEGACY_CHANNEL_CURRENT_L3,
|
||||
new QuantityType<>(payload.getCurrentL3(), Units.AMPERE));
|
||||
}
|
||||
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2026 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;
|
||||
|
||||
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 HomeWizardSystemPayload {
|
||||
|
||||
@SerializedName("wifi_ssid")
|
||||
private String wifiSsid = "";
|
||||
|
||||
@SerializedName("wifi_rssi_db")
|
||||
private int wifiRssi = 0;
|
||||
|
||||
@SerializedName("cloud_enabled")
|
||||
private Boolean cloudEnabled = false;
|
||||
|
||||
@SerializedName("uptime_s")
|
||||
private int uptime = 0;
|
||||
|
||||
@SerializedName("status_led_brightness_pct")
|
||||
private int ledBrightness = 0;
|
||||
|
||||
/**
|
||||
* Getter for the wifi ssid
|
||||
*
|
||||
* @return wifiSsid
|
||||
*/
|
||||
public String getWifiSsid() {
|
||||
return wifiSsid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the wifi rssi
|
||||
*
|
||||
* @return wifiRssi
|
||||
*/
|
||||
public int getWifiRssi() {
|
||||
return wifiRssi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for cloud enabled
|
||||
*
|
||||
* @return cloudEnabled
|
||||
*/
|
||||
public Boolean isCloudEnabled() {
|
||||
return cloudEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the uptime
|
||||
*
|
||||
* @return uptime
|
||||
*/
|
||||
public int getUptime() {
|
||||
return uptime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the status led brightness
|
||||
*
|
||||
* @return ledBrightness
|
||||
*/
|
||||
public int getStatusLedBrightness() {
|
||||
return ledBrightness;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("""
|
||||
Data [wifiSsid: %s wifiRssi: %d cloudEnable: %B uptime: %d ledBrightness: %d]
|
||||
|
||||
""", wifiSsid, wifiRssi, cloudEnabled, uptime, ledBrightness);
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -20,10 +20,11 @@ import com.google.gson.annotations.SerializedName;
|
||||
* Class that provides storage for the json object obtained from the HomeWizard Energy Socket State API
|
||||
*
|
||||
* @author Daniël van Os - Initial contribution
|
||||
* @author Gearrel Welvaart - Renamed class
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HomeWizardEnergySocketStatePayload {
|
||||
public class HomeWizardDeviceStatePayload {
|
||||
@SerializedName("power_on")
|
||||
private boolean powerOn;
|
||||
@SerializedName("switch_lock")
|
||||
+107
-45
@@ -13,16 +13,24 @@
|
||||
package org.openhab.binding.homewizard.internal.devices.energy_socket;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.openhab.binding.homewizard.internal.HomeWizardBindingConstants;
|
||||
import org.openhab.binding.homewizard.internal.devices.HomeWizardDeviceHandler;
|
||||
import org.openhab.binding.homewizard.internal.devices.HomeWizardEnergyMeterSubHandler;
|
||||
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.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 HomeWizardEnergySocketHandler} implements functionality to handle a HomeWizard EnergySocket.
|
||||
*
|
||||
@@ -31,7 +39,8 @@ import org.openhab.core.types.RefreshType;
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HomeWizardEnergySocketHandler extends HomeWizardEnergySocketStateHandler {
|
||||
public class HomeWizardEnergySocketHandler extends HomeWizardDeviceHandler {
|
||||
private final String STATE_URL = "state";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -44,28 +53,16 @@ public class HomeWizardEnergySocketHandler extends HomeWizardEnergySocketStateHa
|
||||
supportedTypes.add(HomeWizardBindingConstants.HWE_SKT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a brightness value (0..255) to a percentage.
|
||||
*
|
||||
* @param brightness The brightness to convert.
|
||||
* @return brightness percentage
|
||||
*/
|
||||
private double brightnessToPercentage(int brightness) {
|
||||
return (100.0 * (brightness / 255.0));
|
||||
}
|
||||
@Override
|
||||
protected void retrieveData() {
|
||||
super.retrieveData();
|
||||
|
||||
/**
|
||||
* Converts a percentage to a brightness value (0..255)
|
||||
*
|
||||
* @param percentage The percentage to convert.
|
||||
* @return brightness value
|
||||
*/
|
||||
private int percentageToBrightness(String percentage) {
|
||||
try {
|
||||
return (int) (Double.valueOf(percentage.replaceAll("[^\\d.]", "")) * 255.0 / 100.0);
|
||||
} catch (NumberFormatException ex) {
|
||||
logger.warn("Recevied invalid brightness percentage from socket");
|
||||
return 0;
|
||||
handleStateData(getStateData());
|
||||
} catch (JsonSyntaxException ex) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"@text/offline.comm-error-device-offline");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,17 +74,10 @@ public class HomeWizardEnergySocketHandler extends HomeWizardEnergySocketStateHa
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (command instanceof RefreshType) {
|
||||
// For now I prefer not updating immediately above firing a full update request for each channel
|
||||
return;
|
||||
}
|
||||
|
||||
HomeWizardEnergySocketStatePayload result = null;
|
||||
|
||||
/*
|
||||
* The returned payloads below only contain the modified value, so each has it's own
|
||||
* call to updateState instead of just calling handleStatePayload() with the returned
|
||||
* payload.
|
||||
*/
|
||||
HomeWizardDeviceStatePayload result = null;
|
||||
|
||||
switch (channelUID.getIdWithoutGroup()) {
|
||||
case HomeWizardBindingConstants.CHANNEL_RING_BRIGHTNESS: {
|
||||
@@ -119,7 +109,7 @@ public class HomeWizardEnergySocketHandler extends HomeWizardEnergySocketStateHa
|
||||
break;
|
||||
}
|
||||
default:
|
||||
logger.warn("Unhandled command for channel: {} command: {}", channelUID.getIdWithoutGroup(), command);
|
||||
super.handleCommand(channelUID, command);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -131,7 +121,7 @@ public class HomeWizardEnergySocketHandler extends HomeWizardEnergySocketStateHa
|
||||
*/
|
||||
@Override
|
||||
protected void handleMeasurementData(String data) {
|
||||
super.handleMeasurementData(data);
|
||||
HomeWizardEnergyMeterSubHandler.handleMeasurementData(data, this);
|
||||
|
||||
var payload = gson.fromJson(data, HomeWizardEnergySocketMeasurementPayload.class);
|
||||
if (payload != null) {
|
||||
@@ -144,23 +134,95 @@ public class HomeWizardEnergySocketHandler extends HomeWizardEnergySocketStateHa
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_POWER_FACTOR, new DecimalType(payload.getPowerFactor()));
|
||||
}
|
||||
super.handleMeasurementData(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleStatePayload(HomeWizardEnergySocketStatePayload payload) {
|
||||
if (!thing.getThingTypeUID().equals(HomeWizardBindingConstants.THING_TYPE_ENERGY_SOCKET)) {
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_SKT_CONTROL,
|
||||
HomeWizardBindingConstants.CHANNEL_POWER_SWITCH, OnOffType.from(payload.getPowerOn()));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_SKT_CONTROL,
|
||||
HomeWizardBindingConstants.CHANNEL_POWER_LOCK, OnOffType.from(payload.getSwitchLock()));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_SKT_CONTROL,
|
||||
HomeWizardBindingConstants.CHANNEL_RING_BRIGHTNESS,
|
||||
new DecimalType(brightnessToPercentage(payload.getBrightness())));
|
||||
/**
|
||||
* Device specific handling of the returned state data.
|
||||
*
|
||||
* @param data The data obtained from the API call
|
||||
*/
|
||||
public void handleStateData(String data) {
|
||||
HomeWizardDeviceStatePayload payload = null;
|
||||
try {
|
||||
payload = gson.fromJson(data, HomeWizardDeviceStatePayload.class);
|
||||
} catch (JsonSyntaxException ex) {
|
||||
logger.warn("No State data available");
|
||||
}
|
||||
if (payload != null) {
|
||||
if (!thing.getThingTypeUID().equals(HomeWizardBindingConstants.THING_TYPE_ENERGY_SOCKET)) {
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_SKT_CONTROL,
|
||||
HomeWizardBindingConstants.CHANNEL_POWER_SWITCH, OnOffType.from(payload.getPowerOn()));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_SKT_CONTROL,
|
||||
HomeWizardBindingConstants.CHANNEL_POWER_LOCK, OnOffType.from(payload.getSwitchLock()));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_SKT_CONTROL,
|
||||
HomeWizardBindingConstants.CHANNEL_RING_BRIGHTNESS,
|
||||
new DecimalType(brightnessToPercentage(payload.getBrightness())));
|
||||
} else {
|
||||
updateState("", HomeWizardBindingConstants.CHANNEL_POWER_SWITCH, OnOffType.from(payload.getPowerOn()));
|
||||
updateState("", HomeWizardBindingConstants.CHANNEL_POWER_LOCK, OnOffType.from(payload.getSwitchLock()));
|
||||
updateState("", HomeWizardBindingConstants.CHANNEL_RING_BRIGHTNESS,
|
||||
new DecimalType(brightnessToPercentage(payload.getBrightness())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return json response from the state api
|
||||
*
|
||||
*/
|
||||
public String getStateData() {
|
||||
var response = getResponseFrom(getApiUrl() + STATE_URL);
|
||||
if (response != null && response.getStatus() == HttpStatus.OK_200) {
|
||||
return response.getContentAsString();
|
||||
} else {
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_POWER_SWITCH, OnOffType.from(payload.getPowerOn()));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_POWER_LOCK, OnOffType.from(payload.getSwitchLock()));
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_RING_BRIGHTNESS,
|
||||
new DecimalType(brightnessToPercentage(payload.getBrightness())));
|
||||
logger.warn("No State data available");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a command to the state interface of the device.
|
||||
*
|
||||
* @param command The command to send.
|
||||
*/
|
||||
private @Nullable HomeWizardDeviceStatePayload sendStateCommand(String command) {
|
||||
var url = getApiUrl() + STATE_URL;
|
||||
var response = putDataTo(url, command);
|
||||
if (response == null) {
|
||||
logger.warn("Failed to send command {} to {}", command, url);
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return gson.fromJson(response.getContentAsString(), HomeWizardDeviceStatePayload.class);
|
||||
} catch (JsonSyntaxException ex) {
|
||||
logger.warn("Failed to parse response for command {} to {}", command, url);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a brightness value (0..255) to a percentage.
|
||||
*
|
||||
* @param brightness The brightness to convert.
|
||||
* @return brightness percentage
|
||||
*/
|
||||
private static double brightnessToPercentage(int brightness) {
|
||||
return (100.0 * (brightness / 255.0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a percentage to a brightness value (0..255)
|
||||
*
|
||||
* @param percentage The percentage to convert.
|
||||
* @return brightness value
|
||||
*/
|
||||
private int percentageToBrightness(String percentage) {
|
||||
try {
|
||||
return (int) (Double.valueOf(percentage.replaceAll("[^\\d.]", "")) * 255.0 / 100.0);
|
||||
} catch (NumberFormatException ex) {
|
||||
logger.warn("Received invalid brightness percentage from socket");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-112
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2026 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.energy_socket;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.homewizard.internal.devices.HomeWizardEnergyMeterHandler;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
|
||||
/**
|
||||
* The {@link HomeWizardEnergySocketStateHandler} extends the base class
|
||||
* to provide support for devices that also have a 'state' interface.
|
||||
* This interface can be used to query and control the state of a device.
|
||||
*
|
||||
* @author Daniël van Os - Initial contribution
|
||||
* @author Gearrel Welvaart - Several minor tweaks
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public abstract class HomeWizardEnergySocketStateHandler extends HomeWizardEnergyMeterHandler {
|
||||
|
||||
private final String STATE_URL = "v1/state";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param thing The thing to handle
|
||||
*
|
||||
*/
|
||||
public HomeWizardEnergySocketStateHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Device specific handling of the returned state payload.
|
||||
*
|
||||
* @param payload The data parsed from the state Json file
|
||||
*/
|
||||
protected abstract void handleStatePayload(HomeWizardEnergySocketStatePayload payload);
|
||||
|
||||
/**
|
||||
* @return json response from the state api
|
||||
* @throws Exception
|
||||
*/
|
||||
public String getStateData() throws Exception {
|
||||
return getResponseFrom(apiURL + STATE_URL).getContentAsString();
|
||||
}
|
||||
|
||||
protected void pollState() {
|
||||
final String stateResult;
|
||||
|
||||
try {
|
||||
stateResult = getStateData();
|
||||
} catch (Exception ex) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
String.format("Unable to query device state: %s", ex.getMessage()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (stateResult.isBlank()) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Device returned empty state");
|
||||
return;
|
||||
}
|
||||
|
||||
HomeWizardEnergySocketStatePayload statePayload = gson.fromJson(stateResult,
|
||||
HomeWizardEnergySocketStatePayload.class);
|
||||
if (statePayload == null) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Unable to parse state response from device");
|
||||
return;
|
||||
}
|
||||
|
||||
handleStatePayload(statePayload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a command to the state interface of the device.
|
||||
*
|
||||
* @param command The command to send.
|
||||
*/
|
||||
protected @Nullable HomeWizardEnergySocketStatePayload sendStateCommand(String command) {
|
||||
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 retrieveData() {
|
||||
retrieveMeasurementData();
|
||||
pollState();
|
||||
}
|
||||
}
|
||||
+35
-22
@@ -17,7 +17,8 @@ import java.util.Arrays;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.homewizard.internal.HomeWizardBindingConstants;
|
||||
import org.openhab.binding.homewizard.internal.devices.HomeWizardBatteriesSubHandler;
|
||||
import org.openhab.binding.homewizard.internal.devices.HomeWizardEnergyMeterHandler;
|
||||
import org.openhab.binding.homewizard.internal.devices.HomeWizardDeviceHandler;
|
||||
import org.openhab.binding.homewizard.internal.devices.HomeWizardEnergyMeterSubHandler;
|
||||
import org.openhab.binding.homewizard.internal.devices.energy_socket.HomeWizardEnergySocketMeasurementPayload;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
@@ -29,6 +30,8 @@ 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 HomeWizardKwhMeterHandler} implements functionality to handle a HomeWizard kWh Meter.
|
||||
*
|
||||
@@ -36,9 +39,7 @@ import org.openhab.core.types.RefreshType;
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HomeWizardKwhMeterHandler extends HomeWizardEnergyMeterHandler {
|
||||
|
||||
protected HomeWizardBatteriesSubHandler batteriesHandler;
|
||||
public class HomeWizardKwhMeterHandler extends HomeWizardDeviceHandler {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -53,8 +54,22 @@ public class HomeWizardKwhMeterHandler extends HomeWizardEnergyMeterHandler {
|
||||
supportedTypes.add(HomeWizardBindingConstants.HWE_KWH3);
|
||||
supportedTypes.add(HomeWizardBindingConstants.SDM630_WIFI);
|
||||
supportedApiVersions = Arrays.asList(API_V1, API_V2);
|
||||
}
|
||||
|
||||
batteriesHandler = new HomeWizardBatteriesSubHandler(this);
|
||||
@Override
|
||||
protected void retrieveData() {
|
||||
super.retrieveData();
|
||||
|
||||
try {
|
||||
if (config.isUsingApiVersion2()) {
|
||||
handleBatteriesData(getBatteriesData());
|
||||
}
|
||||
} catch (JsonSyntaxException ex) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"@text/offline.comm-error-device-offline");
|
||||
logger.debug("Unable to get data from the API", ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,23 +80,9 @@ public class HomeWizardKwhMeterHandler extends HomeWizardEnergyMeterHandler {
|
||||
}
|
||||
|
||||
if (channelUID.getIdWithoutGroup().equals(HomeWizardBindingConstants.CHANNEL_BATTERIES_MODE)) {
|
||||
batteriesHandler.handleCommand(command);
|
||||
HomeWizardBatteriesSubHandler.handleCommand(command, this);
|
||||
} else {
|
||||
logger.warn("Unhandled command for channel: {} command: {}", channelUID.getIdWithoutGroup(), command);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void retrieveData() {
|
||||
super.retrieveData();
|
||||
if (config.isUsingApiVersion2()) {
|
||||
try {
|
||||
batteriesHandler.retrieveBatteriesData();
|
||||
} catch (Exception e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"@text/offline.comm-error-device-offline");
|
||||
return;
|
||||
}
|
||||
super.handleCommand(channelUID, command);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +93,7 @@ public class HomeWizardKwhMeterHandler extends HomeWizardEnergyMeterHandler {
|
||||
*/
|
||||
@Override
|
||||
protected void handleMeasurementData(String data) {
|
||||
super.handleMeasurementData(data);
|
||||
HomeWizardEnergyMeterSubHandler.handleMeasurementData(data, this);
|
||||
|
||||
var payload = gson.fromJson(data, HomeWizardEnergySocketMeasurementPayload.class);
|
||||
if (payload != null) {
|
||||
@@ -105,5 +106,17 @@ public class HomeWizardKwhMeterHandler extends HomeWizardEnergyMeterHandler {
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_POWER_FACTOR, new DecimalType(payload.getPowerFactor()));
|
||||
}
|
||||
super.handleMeasurementData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Device specific handling of the returned batteries data.
|
||||
*
|
||||
* @param data The data obtained from the API call
|
||||
* @throws JsonSyntaxException when the data cannot be parsed to the expected format
|
||||
*/
|
||||
@Override
|
||||
protected void handleBatteriesData(String data) throws JsonSyntaxException {
|
||||
HomeWizardBatteriesSubHandler.handleBatteriesData(data, this);
|
||||
}
|
||||
}
|
||||
|
||||
+28
-16
@@ -19,7 +19,8 @@ import java.util.Arrays;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.homewizard.internal.HomeWizardBindingConstants;
|
||||
import org.openhab.binding.homewizard.internal.devices.HomeWizardBatteriesSubHandler;
|
||||
import org.openhab.binding.homewizard.internal.devices.HomeWizardEnergyMeterHandler;
|
||||
import org.openhab.binding.homewizard.internal.devices.HomeWizardDeviceHandler;
|
||||
import org.openhab.binding.homewizard.internal.devices.HomeWizardEnergyMeterSubHandler;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
@@ -32,6 +33,8 @@ 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.
|
||||
*
|
||||
@@ -39,9 +42,7 @@ import org.openhab.core.types.RefreshType;
|
||||
* @author Gearrel Welvaart - Adapted to new structure
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HomeWizardP1MeterHandler extends HomeWizardEnergyMeterHandler {
|
||||
protected HomeWizardBatteriesSubHandler batteriesHandler;
|
||||
|
||||
public class HomeWizardP1MeterHandler extends HomeWizardDeviceHandler {
|
||||
private String meterModel = "";
|
||||
private int meterVersion = 0;
|
||||
private TimeZoneProvider timeZoneProvider;
|
||||
@@ -57,21 +58,21 @@ public class HomeWizardP1MeterHandler extends HomeWizardEnergyMeterHandler {
|
||||
this.timeZoneProvider = timeZoneProvider;
|
||||
supportedTypes.add(HomeWizardBindingConstants.HWE_P1);
|
||||
supportedApiVersions = Arrays.asList(API_V1, API_V2);
|
||||
|
||||
batteriesHandler = new HomeWizardBatteriesSubHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void retrieveData() {
|
||||
super.retrieveData();
|
||||
if (config.isUsingApiVersion2()) {
|
||||
try {
|
||||
batteriesHandler.retrieveBatteriesData();
|
||||
} catch (Exception e) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"@text/offline.comm-error-device-offline");
|
||||
return;
|
||||
|
||||
try {
|
||||
if (config.isUsingApiVersion2()) {
|
||||
handleBatteriesData(getBatteriesData());
|
||||
}
|
||||
} catch (JsonSyntaxException ex) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"@text/offline.comm-error-device-offline");
|
||||
logger.debug("Unable to get data from the API", ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,9 +84,9 @@ public class HomeWizardP1MeterHandler extends HomeWizardEnergyMeterHandler {
|
||||
}
|
||||
|
||||
if (channelUID.getIdWithoutGroup().equals(HomeWizardBindingConstants.CHANNEL_BATTERIES_MODE)) {
|
||||
batteriesHandler.handleCommand(command);
|
||||
HomeWizardBatteriesSubHandler.handleCommand(command, this);
|
||||
} else {
|
||||
logger.warn("Unhandled command for channel: {} command: {}", channelUID.getIdWithoutGroup(), command);
|
||||
super.handleCommand(channelUID, command);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +97,7 @@ public class HomeWizardP1MeterHandler extends HomeWizardEnergyMeterHandler {
|
||||
*/
|
||||
@Override
|
||||
protected void handleMeasurementData(String data) {
|
||||
super.handleMeasurementData(data);
|
||||
HomeWizardEnergyMeterSubHandler.handleMeasurementData(data, this);
|
||||
|
||||
var payload = gson.fromJson(data, HomeWizardP1MeterMeasurementPayload.class);
|
||||
if (payload != null) {
|
||||
@@ -167,5 +168,16 @@ public class HomeWizardP1MeterHandler extends HomeWizardEnergyMeterHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
super.handleMeasurementData(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Device specific handling of the returned batteries data.
|
||||
*
|
||||
* @param data The data obtained from the API call
|
||||
*/
|
||||
@Override
|
||||
protected void handleBatteriesData(String data) {
|
||||
HomeWizardBatteriesSubHandler.handleBatteriesData(data, this);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-4
@@ -17,7 +17,9 @@ import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
@@ -110,7 +112,7 @@ public class HomeWizardP1MeterMeasurementPayload extends HomeWizardEnergyMeterMe
|
||||
var gas = external.stream().filter(e -> e.getType().equals(EXTERNAL_GAS_METER)).findFirst();
|
||||
try {
|
||||
return Double.parseDouble(gas.get().getValue());
|
||||
} catch (Exception e) {
|
||||
} catch (NumberFormatException | NoSuchElementException ex) {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
@@ -153,15 +155,15 @@ public class HomeWizardP1MeterMeasurementPayload extends HomeWizardEnergyMeterMe
|
||||
|
||||
try {
|
||||
zonedDateTime = ZonedDateTime.of(year, month, day, hours, minutes, seconds, 0, timeZoneId);
|
||||
} catch (Exception ex) {
|
||||
} catch (DateTimeException ex) {
|
||||
return null;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (NumberFormatException | NoSuchElementException ex) {
|
||||
try {
|
||||
zonedDateTime = ZonedDateTime.of(
|
||||
LocalDateTime.parse(gas.get().getTimestamp(), DateTimeFormatter.ISO_LOCAL_DATE_TIME),
|
||||
timeZoneId);
|
||||
} catch (Exception ex) {
|
||||
} catch (DateTimeParseException | NoSuchElementException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-4
@@ -16,7 +16,8 @@ import java.util.Arrays;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.homewizard.internal.HomeWizardBindingConstants;
|
||||
import org.openhab.binding.homewizard.internal.devices.HomeWizardEnergyMeterHandler;
|
||||
import org.openhab.binding.homewizard.internal.devices.HomeWizardDeviceHandler;
|
||||
import org.openhab.binding.homewizard.internal.devices.HomeWizardEnergyMeterSubHandler;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.thing.Thing;
|
||||
|
||||
@@ -27,8 +28,7 @@ import org.openhab.core.thing.Thing;
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class HomeWizardPlugInBatteryHandler extends HomeWizardEnergyMeterHandler {
|
||||
|
||||
public class HomeWizardPlugInBatteryHandler extends HomeWizardDeviceHandler {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -48,7 +48,7 @@ public class HomeWizardPlugInBatteryHandler extends HomeWizardEnergyMeterHandler
|
||||
*/
|
||||
@Override
|
||||
protected void handleMeasurementData(String data) {
|
||||
super.handleMeasurementData(data);
|
||||
HomeWizardEnergyMeterSubHandler.handleMeasurementData(data, this);
|
||||
|
||||
var payload = gson.fromJson(data, HomeWizardPlugInBatteryMeasurementPayload.class);
|
||||
if (payload != null) {
|
||||
@@ -57,5 +57,6 @@ public class HomeWizardPlugInBatteryHandler extends HomeWizardEnergyMeterHandler
|
||||
updateState(HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY, HomeWizardBindingConstants.CHANNEL_CYCLES,
|
||||
new DecimalType(payload.getCycles()));
|
||||
}
|
||||
super.handleMeasurementData(data);
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -64,5 +64,6 @@ public class HomeWizardWaterMeterHandler extends HomeWizardDeviceHandler {
|
||||
new QuantityType<>(payload.getTotalLiter(), SIUnits.CUBIC_METRE));
|
||||
}
|
||||
}
|
||||
super.handleMeasurementData(data);
|
||||
}
|
||||
}
|
||||
|
||||
+26
-2
@@ -26,12 +26,36 @@ import com.google.gson.annotations.SerializedName;
|
||||
@NonNullByDefault
|
||||
public class HomeWizardWaterMeterMeasurementPayload {
|
||||
|
||||
@SerializedName("wifi_ssid")
|
||||
private String wifiSsid = "";
|
||||
|
||||
@SerializedName("wifi_strength")
|
||||
private int wifiRssi = 0;
|
||||
|
||||
@SerializedName("active_liter_lpm")
|
||||
private double activeLiter;
|
||||
|
||||
@SerializedName("total_liter_m3")
|
||||
private double totalLiter;
|
||||
|
||||
/**
|
||||
* Getter for the wifi ssid
|
||||
*
|
||||
* @return wifiSsid
|
||||
*/
|
||||
public String getWifiSsid() {
|
||||
return wifiSsid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the wifi rssi. The value is converted from percentage to dB.
|
||||
*
|
||||
* @return wifiRssi
|
||||
*/
|
||||
public int getWifiRssi() {
|
||||
return (wifiRssi / 2) - 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the active liter per minute
|
||||
*
|
||||
@@ -53,7 +77,7 @@ public class HomeWizardWaterMeterMeasurementPayload {
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("""
|
||||
Water Meter Data [activeLiter: %f totalLiter: %f"]
|
||||
""", activeLiter, totalLiter);
|
||||
Water Meter Data [wifiSsid: %s wifiRssi: %d activeLiter: %f totalLiter: %f"]
|
||||
""", wifiSsid, wifiRssi, activeLiter, totalLiter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
<type>binding</type>
|
||||
<name>HomeWizard Binding</name>
|
||||
<description>This binding provides access to the data provided by the API of HomeWizard devices. API version 1 is
|
||||
supported, API version 2 (still in beta) is not yet supported.</description>
|
||||
<description>This binding provides access to the data provided by the API of HomeWizard devices. API versions 1 and 2
|
||||
are supported.</description>
|
||||
<connection>local</connection>
|
||||
|
||||
</addon:addon>
|
||||
|
||||
+22
-10
@@ -1,7 +1,7 @@
|
||||
# add-on
|
||||
|
||||
addon.homewizard.name = HomeWizard Binding
|
||||
addon.homewizard.description = This binding provides access to the data provided by the API of HomeWizard devices. API version 1 is supported, API version 2 (still in beta) is not yet supported.
|
||||
addon.homewizard.description = This binding provides access to the data provided by the API of HomeWizard devices. API versions 1 and 2 are supported.
|
||||
|
||||
# thing types
|
||||
|
||||
@@ -33,15 +33,6 @@ thing-type.homewizard.p1_wifi_meter.channel.long_power_failures.description = Th
|
||||
thing-type.homewizard.watermeter.label = HomeWizard Wi-Fi Watermeter
|
||||
thing-type.homewizard.watermeter.description = This thing provides the measurement data that is available through the http interface of a HomeWizard Watermeter.
|
||||
|
||||
# thing status descriptions
|
||||
|
||||
offline.config-error-missing-host = Missing ipAddress/host configuration
|
||||
offline.config-error-invalid-api-version = The selected API version is not supported
|
||||
offline.config-error-missing-bearer-token = Missing bearer token
|
||||
offline.comm-error-no-data = The device returned empty data
|
||||
offline.comm-error-device-offline = The device is offline or doesn't support the API version
|
||||
offline.comm-error-device-not-compatible = The device is not compatible with this thing type
|
||||
|
||||
# thing types config
|
||||
|
||||
thing-type.config.homewizard.device.apiVersion.label = API Version
|
||||
@@ -80,6 +71,8 @@ channel-group-type.homewizard.hw-batteries-group.channel.batteries_power.label =
|
||||
channel-group-type.homewizard.hw-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.hw-batteries-group.channel.batteries_target_power.label = Target Power
|
||||
channel-group-type.homewizard.hw-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.hw-system-group.label = System
|
||||
channel-group-type.homewizard.hw-v1-system-group.label = System
|
||||
channel-group-type.homewizard.kwh-energy-group.label = Recent Measurements
|
||||
channel-group-type.homewizard.kwh-energy-group.channel.current_l1.label = Active Current L1
|
||||
channel-group-type.homewizard.kwh-energy-group.channel.current_l1.description = This channel provides the active current for phase 1 in Ampere.
|
||||
@@ -166,6 +159,8 @@ channel-type.homewizard.hw-batteries-mode.command.option.zero_charge_only = Main
|
||||
channel-type.homewizard.hw-batteries-mode.command.option.zero_discharge_only = Maintain net-zero balance, discharge only
|
||||
channel-type.homewizard.hw-batteries-mode.command.option.to_full = Charge to 100%
|
||||
channel-type.homewizard.hw-batteries-mode.command.option.standby = Stand-by mode
|
||||
channel-type.homewizard.hw-cloud-enabled.label = Cloud Enabled
|
||||
channel-type.homewizard.hw-cloud-enabled.description = This channel provides the state of the cloud communication.
|
||||
channel-type.homewizard.hw-current-advanced.label = Active Current
|
||||
channel-type.homewizard.hw-current-advanced.description = This channel provides the active current in Ampere.
|
||||
channel-type.homewizard.hw-current.label = Active Current
|
||||
@@ -188,10 +183,18 @@ channel-type.homewizard.hw-power.label = Active Power
|
||||
channel-type.homewizard.hw-power.description = This channel provides the active usage in Watt.
|
||||
channel-type.homewizard.hw-reactive-power.label = Reactive Power
|
||||
channel-type.homewizard.hw-reactive-power.description = This channel provides the active reactive power in Volt-Ampere reactive.
|
||||
channel-type.homewizard.hw-status-led-brightness.label = Status LED Brightness
|
||||
channel-type.homewizard.hw-status-led-brightness.description = This channel provides the brightness of the status LED in percent.
|
||||
channel-type.homewizard.hw-uptime.label = Uptime
|
||||
channel-type.homewizard.hw-uptime.description = This channel provides the uptime of the device in seconds.
|
||||
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.hw-wifi-rssi.label = Wi-Fi RSSI
|
||||
channel-type.homewizard.hw-wifi-rssi.description = This channel provides the signal strength of the Wi-Fi network.
|
||||
channel-type.homewizard.hw-wifi-ssid.label = Wi-Fi SSID
|
||||
channel-type.homewizard.hw-wifi-ssid.description = This channel provides the SSID of the Wi-Fi network.
|
||||
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
|
||||
@@ -226,3 +229,12 @@ channel-type.homewizard.total_gas.label = Total Imported Gas
|
||||
channel-type.homewizard.total_gas.description = This channel provides the most recently reported total imported gas in m^3. It does not get updated as frequently as the data in the other channels, the gas_timestamp channel provides the time stamp of the most recent update.
|
||||
channel-type.homewizard.total_water.label = Total Imported Water
|
||||
channel-type.homewizard.total_water.description = This channel provides the most recently reported total imported water in m^3.
|
||||
|
||||
# thing status descriptions
|
||||
|
||||
offline.config-error-missing-host = Missing ipAddress/host configuration
|
||||
offline.config-error-invalid-api-version = The selected API version is not supported
|
||||
offline.config-error-missing-bearer-token = Missing bearer token
|
||||
offline.comm-error-no-data = The device returned empty data
|
||||
offline.comm-error-device-offline = The device is offline or doesn't support the API version
|
||||
offline.comm-error-device-not-compatible = The device is not compatible with this thing type
|
||||
|
||||
@@ -4,6 +4,26 @@
|
||||
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">
|
||||
|
||||
<channel-group-type id="hw-v1-system-group">
|
||||
<label>System</label>
|
||||
<channels>
|
||||
<channel id="wifi_ssid" typeId="hw-wifi-ssid"/>
|
||||
<channel id="wifi_rssi" typeId="hw-wifi-rssi"/>
|
||||
<channel id="cloud_enabled" typeId="hw-cloud-enabled"/>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="hw-system-group">
|
||||
<label>System</label>
|
||||
<channels>
|
||||
<channel id="wifi_ssid" typeId="hw-wifi-ssid"/>
|
||||
<channel id="wifi_rssi" typeId="hw-wifi-rssi"/>
|
||||
<channel id="uptime" typeId="hw-uptime"/>
|
||||
<channel id="cloud_enabled" typeId="hw-cloud-enabled"/>
|
||||
<channel id="status_led_brightness" typeId="hw-status-led-brightness"/>
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-group-type id="hw-batteries-group">
|
||||
<label>Batteries</label>
|
||||
<channels>
|
||||
@@ -39,6 +59,64 @@
|
||||
</channels>
|
||||
</channel-group-type>
|
||||
|
||||
<channel-type id="hw-wifi-ssid">
|
||||
<item-type>String</item-type>
|
||||
<label>Wi-Fi SSID</label>
|
||||
<description>
|
||||
This channel provides the SSID of the Wi-Fi network.
|
||||
</description>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="hw-wifi-rssi" advanced="true">
|
||||
<item-type unitHint="dB">Number:Dimensionless</item-type>
|
||||
<label>Wi-Fi RSSI</label>
|
||||
<description>
|
||||
This channel provides the signal strength of the Wi-Fi network.
|
||||
</description>
|
||||
<category>QualityOfService</category>
|
||||
<tags>
|
||||
<tag>Measurement</tag>
|
||||
<tag>SignalStrength</tag>
|
||||
</tags>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="hw-uptime" advanced="true">
|
||||
<item-type>Number:Time</item-type>
|
||||
<label>Uptime</label>
|
||||
<description>
|
||||
This channel provides the uptime of the device in seconds.
|
||||
</description>
|
||||
<category>Duration</category>
|
||||
<tags>
|
||||
<tag>Calculation</tag>
|
||||
<tag>Duration</tag>
|
||||
</tags>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="hw-cloud-enabled">
|
||||
<item-type>Switch</item-type>
|
||||
<label>Cloud Enabled</label>
|
||||
<description>
|
||||
This channel provides the state of the cloud communication.
|
||||
</description>
|
||||
<tags>
|
||||
<tag>Status</tag>
|
||||
<tag>Enabled</tag>
|
||||
</tags>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="hw-status-led-brightness" advanced="true">
|
||||
<item-type unitHint="%">Number:Dimensionless</item-type>
|
||||
<label>Status LED Brightness</label>
|
||||
<description>
|
||||
This channel provides the brightness of the status LED in percent.
|
||||
</description>
|
||||
<tags>
|
||||
<tag>Control</tag>
|
||||
<tag>Brightness</tag>
|
||||
</tags>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="hw-power">
|
||||
<item-type>Number:Power</item-type>
|
||||
<label>Active Power</label>
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
<semantic-equipment-tag>Battery</semantic-equipment-tag>
|
||||
<channel-groups>
|
||||
<channel-group id="energy" typeId="bat-energy-group"/>
|
||||
<channel-group id="system" typeId="hw-system-group"/>
|
||||
</channel-groups>
|
||||
<properties>
|
||||
<property name="thingTypeVersion">2</property>
|
||||
<property name="thingTypeVersion">3</property>
|
||||
</properties>
|
||||
|
||||
<config-description-ref uri="thing-type:homewizard:device"/>
|
||||
|
||||
@@ -12,9 +12,10 @@
|
||||
<channel-groups>
|
||||
<channel-group id="energy" typeId="kwh-energy-group"/>
|
||||
<channel-group id="batteries" typeId="hw-batteries-group"/>
|
||||
<channel-group id="system" typeId="hw-system-group"/>
|
||||
</channel-groups>
|
||||
<properties>
|
||||
<property name="thingTypeVersion">2</property>
|
||||
<property name="thingTypeVersion">3</property>
|
||||
</properties>
|
||||
|
||||
<config-description-ref uri="thing-type:homewizard:device"/>
|
||||
|
||||
@@ -12,9 +12,10 @@
|
||||
<channel-groups>
|
||||
<channel-group id="energy" typeId="p1-energy-group"/>
|
||||
<channel-group id="batteries" typeId="hw-batteries-group"/>
|
||||
<channel-group id="system" typeId="hw-system-group"/>
|
||||
</channel-groups>
|
||||
<properties>
|
||||
<property name="thingTypeVersion">4</property>
|
||||
<property name="thingTypeVersion">5</property>
|
||||
</properties>
|
||||
|
||||
<config-description-ref uri="thing-type:homewizard:device"/>
|
||||
|
||||
@@ -12,9 +12,10 @@
|
||||
<channel-groups>
|
||||
<channel-group id="energy" typeId="skt-energy-group"/>
|
||||
<channel-group id="control" typeId="skt-control-group"/>
|
||||
<channel-group id="system" typeId="hw-v1-system-group"/>
|
||||
</channel-groups>
|
||||
<properties>
|
||||
<property name="thingTypeVersion">1</property>
|
||||
<property name="thingTypeVersion">2</property>
|
||||
</properties>
|
||||
|
||||
<config-description-ref uri="thing-type:homewizard:device"/>
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
<semantic-equipment-tag>WaterMeter</semantic-equipment-tag>
|
||||
<channel-groups>
|
||||
<channel-group id="water" typeId="es-water-group"/>
|
||||
<channel-group id="system" typeId="hw-v1-system-group"/>
|
||||
</channel-groups>
|
||||
<properties>
|
||||
<property name="thingTypeVersion">1</property>
|
||||
<property name="thingTypeVersion">2</property>
|
||||
</properties>
|
||||
|
||||
<config-description-ref uri="thing-type:homewizard:device"/>
|
||||
|
||||
+18
@@ -14,6 +14,24 @@
|
||||
</add-channel>
|
||||
|
||||
</instruction-set>
|
||||
|
||||
<instruction-set targetVersion="3">
|
||||
<add-channel id="wifi_ssid" groupIds="system">
|
||||
<type>homewizard:hw-wifi-ssid</type>
|
||||
</add-channel>
|
||||
<add-channel id="wifi_rssi" groupIds="system">
|
||||
<type>homewizard:hw-wifi-rssi</type>
|
||||
</add-channel>
|
||||
<add-channel id="uptime" groupIds="system">
|
||||
<type>homewizard:hw-uptime</type>
|
||||
</add-channel>
|
||||
<add-channel id="cloud_enabled" groupIds="system">
|
||||
<type>homewizard:hw-cloud-enabled</type>
|
||||
</add-channel>
|
||||
<add-channel id="status_led_brightness" groupIds="system">
|
||||
<type>homewizard:hw-status-led-brightness</type>
|
||||
</add-channel>
|
||||
</instruction-set>
|
||||
</thing-type>
|
||||
|
||||
</update:update-descriptions>
|
||||
|
||||
+18
@@ -44,6 +44,24 @@
|
||||
|
||||
</instruction-set>
|
||||
|
||||
<instruction-set targetVersion="3">
|
||||
<add-channel id="wifi_ssid" groupIds="system">
|
||||
<type>homewizard:hw-wifi-ssid</type>
|
||||
</add-channel>
|
||||
<add-channel id="wifi_rssi" groupIds="system">
|
||||
<type>homewizard:hw-wifi-rssi</type>
|
||||
</add-channel>
|
||||
<add-channel id="uptime" groupIds="system">
|
||||
<type>homewizard:hw-uptime</type>
|
||||
</add-channel>
|
||||
<add-channel id="cloud_enabled" groupIds="system">
|
||||
<type>homewizard:hw-cloud-enabled</type>
|
||||
</add-channel>
|
||||
<add-channel id="status_led_brightness" groupIds="system">
|
||||
<type>homewizard:hw-status-led-brightness</type>
|
||||
</add-channel>
|
||||
</instruction-set>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</update:update-descriptions>
|
||||
|
||||
+18
@@ -56,6 +56,24 @@
|
||||
</add-channel>
|
||||
</instruction-set>
|
||||
|
||||
<instruction-set targetVersion="5">
|
||||
<add-channel id="wifi_ssid" groupIds="system">
|
||||
<type>homewizard:hw-wifi-ssid</type>
|
||||
</add-channel>
|
||||
<add-channel id="wifi_rssi" groupIds="system">
|
||||
<type>homewizard:hw-wifi-rssi</type>
|
||||
</add-channel>
|
||||
<add-channel id="uptime" groupIds="system">
|
||||
<type>homewizard:hw-uptime</type>
|
||||
</add-channel>
|
||||
<add-channel id="cloud_enabled" groupIds="system">
|
||||
<type>homewizard:hw-cloud-enabled</type>
|
||||
</add-channel>
|
||||
<add-channel id="status_led_brightness" groupIds="system">
|
||||
<type>homewizard:hw-status-led-brightness</type>
|
||||
</add-channel>
|
||||
</instruction-set>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</update:update-descriptions>
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<?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="homewizard:hwe-skt">
|
||||
|
||||
<instruction-set targetVersion="2">
|
||||
<add-channel id="wifi_ssid" groupIds="system">
|
||||
<type>homewizard:hw-wifi-ssid</type>
|
||||
</add-channel>
|
||||
<add-channel id="wifi_rssi" groupIds="system">
|
||||
<type>homewizard:hw-wifi-rssi</type>
|
||||
</add-channel>
|
||||
<add-channel id="cloud_enabled" groupIds="system">
|
||||
<type>homewizard:hw-cloud-enabled</type>
|
||||
</add-channel>
|
||||
</instruction-set>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</update:update-descriptions>
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<?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="homewizard:hwe-wtr">
|
||||
|
||||
<instruction-set targetVersion="2">
|
||||
<add-channel id="wifi_ssid" groupIds="system">
|
||||
<type>homewizard:hw-wifi-ssid</type>
|
||||
</add-channel>
|
||||
<add-channel id="wifi_rssi" groupIds="system">
|
||||
<type>homewizard:hw-wifi-rssi</type>
|
||||
</add-channel>
|
||||
<add-channel id="cloud_enabled" groupIds="system">
|
||||
<type>homewizard:hw-cloud-enabled</type>
|
||||
</add-channel>
|
||||
</instruction-set>
|
||||
|
||||
</thing-type>
|
||||
|
||||
</update:update-descriptions>
|
||||
+5
-1
@@ -91,6 +91,10 @@ public class HomeWizardHandlerTest {
|
||||
}
|
||||
|
||||
protected static ChannelUID getBatteriesChannelUid(Thing thing, String channelId) {
|
||||
return new ChannelUID(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES + "#" + channelId);
|
||||
return new ChannelUID(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_BATTERIES + "#" + channelId);
|
||||
}
|
||||
|
||||
protected static ChannelUID getSystemChannelUid(Thing thing, String channelId) {
|
||||
return new ChannelUID(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_SYSTEM + "#" + channelId);
|
||||
}
|
||||
}
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2026 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;
|
||||
|
||||
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 HomeWizardSystemPayloadTest {
|
||||
|
||||
private static final DataUtil DATA_UTIL = new DataUtil();
|
||||
|
||||
@Test
|
||||
public void deserializeResponse() throws IOException {
|
||||
HomeWizardSystemPayload key = DATA_UTIL.fromJson("response-system.json", HomeWizardSystemPayload.class);
|
||||
assertThat(key, is(notNullValue()));
|
||||
|
||||
assertThat(key.getWifiSsid(), is("My Wi-Fi"));
|
||||
assertThat(key.getWifiRssi(), is(-77));
|
||||
assertThat(key.isCloudEnabled(), is(true));
|
||||
assertThat(key.getUptime(), is(356));
|
||||
assertThat(key.getStatusLedBrightness(), is(100));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deserializeResponseEmpty() throws IOException {
|
||||
HomeWizardSystemPayload key = DATA_UTIL.fromJson("response-empty.json", HomeWizardSystemPayload.class);
|
||||
assertThat(key, is(notNullValue()));
|
||||
|
||||
assertThat(key.getWifiSsid(), is(""));
|
||||
assertThat(key.getWifiRssi(), is(0));
|
||||
assertThat(key.isCloudEnabled(), is(false));
|
||||
assertThat(key.getUptime(), is(0));
|
||||
assertThat(key.getStatusLedBrightness(), is(0));
|
||||
}
|
||||
}
|
||||
+16
-1
@@ -16,6 +16,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -81,6 +82,11 @@ public class HomeWizardEnergySocketHandlerTest extends HomeWizardHandlerTest {
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_RING_BRIGHTNESS),
|
||||
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_SYSTEM,
|
||||
HomeWizardBindingConstants.CHANNEL_SYSTEM_WIFI_SSID),
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_SYSTEM,
|
||||
HomeWizardBindingConstants.CHANNEL_SYSTEM_CLOUD_ENABLED),
|
||||
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.LEGACY_CHANNEL_ENERGY_IMPORT_T1),
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.LEGACY_CHANNEL_ENERGY_EXPORT_T1),
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.LEGACY_CHANNEL_POWER),
|
||||
@@ -100,7 +106,8 @@ public class HomeWizardEnergySocketHandlerTest extends HomeWizardHandlerTest {
|
||||
.getDeviceInformationData();
|
||||
doReturn(DataUtil.fromFile("response-measurement-energy-socket.json")).when(handler).getMeasurementData();
|
||||
doReturn(DataUtil.fromFile("response-state-energy-socket.json")).when(handler).getStateData();
|
||||
} catch (Exception e) {
|
||||
doReturn(DataUtil.fromFile("response-system.json")).when(handler).getSystemData();
|
||||
} catch (IOException ex) {
|
||||
assertFalse(true);
|
||||
}
|
||||
|
||||
@@ -146,6 +153,14 @@ public class HomeWizardEnergySocketHandlerTest extends HomeWizardHandlerTest {
|
||||
verify(callback)
|
||||
.stateUpdated(new ChannelUID(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_SKT_CONTROL
|
||||
+ "#" + HomeWizardBindingConstants.CHANNEL_RING_BRIGHTNESS), getState(100.0));
|
||||
verify(callback).stateUpdated(
|
||||
getSystemChannelUid(thing, HomeWizardBindingConstants.CHANNEL_SYSTEM_WIFI_SSID),
|
||||
getState("My Wi-Fi"));
|
||||
verify(callback).stateUpdated(
|
||||
getSystemChannelUid(thing, HomeWizardBindingConstants.CHANNEL_SYSTEM_WIFI_RSSI), getState(-50));
|
||||
verify(callback).stateUpdated(
|
||||
getSystemChannelUid(thing, HomeWizardBindingConstants.CHANNEL_SYSTEM_CLOUD_ENABLED),
|
||||
getState(true));
|
||||
|
||||
} finally {
|
||||
handler.dispose();
|
||||
|
||||
+4
-4
@@ -34,8 +34,8 @@ public class HomeWizardEnergySocketStatePayloadTest {
|
||||
|
||||
@Test
|
||||
public void deserializeResponse() throws IOException {
|
||||
HomeWizardEnergySocketStatePayload key = DATA_UTIL.fromJson("response-state-energy-socket.json",
|
||||
HomeWizardEnergySocketStatePayload.class);
|
||||
HomeWizardDeviceStatePayload key = DATA_UTIL.fromJson("response-state-energy-socket.json",
|
||||
HomeWizardDeviceStatePayload.class);
|
||||
assertThat(key, is(notNullValue()));
|
||||
|
||||
assertThat(key.getPowerOn(), is(true));
|
||||
@@ -45,8 +45,8 @@ public class HomeWizardEnergySocketStatePayloadTest {
|
||||
|
||||
@Test
|
||||
public void deserializeResponseEmpty() throws IOException {
|
||||
HomeWizardEnergySocketStatePayload key = DATA_UTIL.fromJson("response-empty.json",
|
||||
HomeWizardEnergySocketStatePayload.class);
|
||||
HomeWizardDeviceStatePayload key = DATA_UTIL.fromJson("response-empty.json",
|
||||
HomeWizardDeviceStatePayload.class);
|
||||
assertThat(key, is(notNullValue()));
|
||||
|
||||
assertThat(key.getPowerOn(), is(false));
|
||||
|
||||
+10
-10
@@ -16,13 +16,13 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.homewizard.internal.HomeWizardBindingConstants;
|
||||
import org.openhab.binding.homewizard.internal.devices.HomeWizardBatteriesSubHandler;
|
||||
import org.openhab.binding.homewizard.internal.devices.HomeWizardHandlerTest;
|
||||
import org.openhab.binding.homewizard.internal.dto.DataUtil;
|
||||
import org.openhab.core.library.unit.Units;
|
||||
@@ -85,17 +85,17 @@ public class HomeWizardKwhMeterHandlerTest extends HomeWizardHandlerTest {
|
||||
HomeWizardBindingConstants.CHANNEL_APPARENT_POWER), //
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_FREQUENCY),
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_BATTERIES,
|
||||
HomeWizardBindingConstants.CHANNEL_BATTERIES_MODE), //
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_BATTERIES,
|
||||
HomeWizardBindingConstants.CHANNEL_BATTERIES_COUNT), //
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_BATTERIES,
|
||||
HomeWizardBindingConstants.CHANNEL_BATTERIES_POWER), //
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_BATTERIES,
|
||||
HomeWizardBindingConstants.CHANNEL_BATTERIES_TARGET_POWER), //
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_BATTERIES,
|
||||
HomeWizardBindingConstants.CHANNEL_BATTERIES_MAX_CONSUMPTION), //
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_BATTERIES,
|
||||
HomeWizardBindingConstants.CHANNEL_BATTERIES_MAX_PRODUCTION)
|
||||
|
||||
);
|
||||
@@ -107,14 +107,14 @@ public class HomeWizardKwhMeterHandlerTest extends HomeWizardHandlerTest {
|
||||
private static HomeWizardKwhMeterHandlerMock createAndInitHandler(final ThingHandlerCallback callback,
|
||||
final Thing thing) {
|
||||
final HomeWizardKwhMeterHandlerMock handler = spy(new HomeWizardKwhMeterHandlerMock(thing));
|
||||
handler.batteriesHandler = spy(new HomeWizardBatteriesSubHandler(handler));
|
||||
|
||||
try {
|
||||
doReturn(DataUtil.fromFile("response-device-information-kwh3-meter.json")).when(handler)
|
||||
.getDeviceInformationData();
|
||||
doReturn(DataUtil.fromFile("response-measurement-kwh-meter.json")).when(handler).getMeasurementData();
|
||||
doReturn(DataUtil.fromFile("response-batteries.json")).when(handler.batteriesHandler).getBatteriesData();
|
||||
} catch (Exception e) {
|
||||
doReturn(DataUtil.fromFile("response-batteries.json")).when(handler).getBatteriesData();
|
||||
doReturn(DataUtil.fromFile("response-system.json")).when(handler).getSystemData();
|
||||
} catch (IOException ex) {
|
||||
assertFalse(true);
|
||||
}
|
||||
|
||||
|
||||
+104
-16
@@ -16,6 +16,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Arrays;
|
||||
@@ -24,7 +25,6 @@ import java.util.List;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.homewizard.internal.HomeWizardBindingConstants;
|
||||
import org.openhab.binding.homewizard.internal.devices.HomeWizardBatteriesSubHandler;
|
||||
import org.openhab.binding.homewizard.internal.devices.HomeWizardHandlerTest;
|
||||
import org.openhab.binding.homewizard.internal.dto.DataUtil;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
@@ -105,17 +105,17 @@ public class HomeWizardP1MeterHandlerTest extends HomeWizardHandlerTest {
|
||||
HomeWizardBindingConstants.CHANNEL_GAS_TIMESTAMP), //
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_ENERGY,
|
||||
HomeWizardBindingConstants.CHANNEL_GAS_TOTAL),
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_BATTERIES,
|
||||
HomeWizardBindingConstants.CHANNEL_BATTERIES_MODE), //
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_BATTERIES,
|
||||
HomeWizardBindingConstants.CHANNEL_BATTERIES_COUNT), //
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_BATTERIES,
|
||||
HomeWizardBindingConstants.CHANNEL_BATTERIES_POWER), //
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_BATTERIES,
|
||||
HomeWizardBindingConstants.CHANNEL_BATTERIES_TARGET_POWER), //
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_BATTERIES,
|
||||
HomeWizardBindingConstants.CHANNEL_BATTERIES_MAX_CONSUMPTION), //
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_P1_BATTERIES,
|
||||
mockChannel(thing.getUID(), HomeWizardBindingConstants.CHANNEL_GROUP_BATTERIES,
|
||||
HomeWizardBindingConstants.CHANNEL_BATTERIES_MAX_PRODUCTION));
|
||||
|
||||
when(thing.getChannels()).thenReturn(channelList);
|
||||
@@ -123,18 +123,22 @@ public class HomeWizardP1MeterHandlerTest extends HomeWizardHandlerTest {
|
||||
}
|
||||
|
||||
private static HomeWizardP1MeterHandlerMock createAndInitHandler(final ThingHandlerCallback callback,
|
||||
final Thing thing) {
|
||||
final Thing thing, int apiVersion) {
|
||||
final TimeZoneProvider timeZoneProvider = mock(TimeZoneProvider.class);
|
||||
doReturn(ZoneId.systemDefault()).when(timeZoneProvider).getTimeZone();
|
||||
final HomeWizardP1MeterHandlerMock handler = spy(new HomeWizardP1MeterHandlerMock(thing, timeZoneProvider));
|
||||
handler.batteriesHandler = spy(new HomeWizardBatteriesSubHandler(handler));
|
||||
|
||||
try {
|
||||
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.json")).when(handler.batteriesHandler).getBatteriesData();
|
||||
} catch (Exception e) {
|
||||
if (apiVersion == 1) {
|
||||
doReturn(DataUtil.fromFile("v1-response-measurement-p1-meter.json")).when(handler).getMeasurementData();
|
||||
} else {
|
||||
doReturn(DataUtil.fromFile("response-measurement-p1-meter.json")).when(handler).getMeasurementData();
|
||||
}
|
||||
doReturn(DataUtil.fromFile("response-batteries.json")).when(handler).getBatteriesData();
|
||||
doReturn(DataUtil.fromFile("response-system.json")).when(handler).getSystemData();
|
||||
} catch (IOException ex) {
|
||||
assertFalse(true);
|
||||
}
|
||||
|
||||
@@ -144,10 +148,10 @@ public class HomeWizardP1MeterHandlerTest extends HomeWizardHandlerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateChannels() {
|
||||
public void testUpdateChannelsForApiV1() {
|
||||
final Thing thing = mockThing(1, false);
|
||||
final ThingHandlerCallback callback = mock(ThingHandlerCallback.class);
|
||||
final HomeWizardP1MeterHandlerMock handler = createAndInitHandler(callback, thing);
|
||||
final HomeWizardP1MeterHandlerMock handler = createAndInitHandler(callback, thing, 1);
|
||||
|
||||
try {
|
||||
verify(callback).statusUpdated(eq(thing), argThat(arg -> arg.getStatus().equals(ThingStatus.UNKNOWN)));
|
||||
@@ -199,6 +203,90 @@ public class HomeWizardP1MeterHandlerTest extends HomeWizardHandlerTest {
|
||||
new DateTimeType(ZonedDateTime.of(2021, 6, 06, 14, 0, 10, 0, ZoneId.systemDefault())));
|
||||
verify(callback).stateUpdated(getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_GAS_TOTAL),
|
||||
getState(2569.646, SIUnits.CUBIC_METRE));
|
||||
|
||||
verify(callback).stateUpdated(
|
||||
getSystemChannelUid(thing, HomeWizardBindingConstants.CHANNEL_SYSTEM_WIFI_SSID),
|
||||
getState("My Wi-Fi"));
|
||||
verify(callback).stateUpdated(
|
||||
getSystemChannelUid(thing, HomeWizardBindingConstants.CHANNEL_SYSTEM_WIFI_RSSI), getState(-58));
|
||||
verify(callback).stateUpdated(
|
||||
getSystemChannelUid(thing, HomeWizardBindingConstants.CHANNEL_SYSTEM_CLOUD_ENABLED),
|
||||
getState(true));
|
||||
} finally {
|
||||
handler.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateChannelsForApiV2() {
|
||||
final Thing thing = mockThing(2, false);
|
||||
final ThingHandlerCallback callback = mock(ThingHandlerCallback.class);
|
||||
final HomeWizardP1MeterHandlerMock handler = createAndInitHandler(callback, thing, 2);
|
||||
|
||||
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(getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_CURRENT_L1),
|
||||
getState(-4.0, Units.AMPERE));
|
||||
verify(callback).stateUpdated(getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_CURRENT_L2),
|
||||
getState(2.0, Units.AMPERE));
|
||||
verify(callback).stateUpdated(getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_CURRENT_L3),
|
||||
getState(333.0, Units.AMPERE));
|
||||
verify(callback).stateUpdated(getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_POWER),
|
||||
getState(-543, Units.WATT));
|
||||
verify(callback).stateUpdated(getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_TARIFF),
|
||||
getState(2));
|
||||
verify(callback).stateUpdated(getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_POWER_L1),
|
||||
getState(-676, Units.WATT));
|
||||
verify(callback).stateUpdated(getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_POWER_L2),
|
||||
getState(133, Units.WATT));
|
||||
verify(callback).stateUpdated(getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_POWER_L3),
|
||||
getState(18, Units.WATT));
|
||||
verify(callback).stateUpdated(getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_VOLTAGE_L1),
|
||||
getState(221, Units.VOLT));
|
||||
verify(callback).stateUpdated(getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_VOLTAGE_L2),
|
||||
getState(222, Units.VOLT));
|
||||
verify(callback).stateUpdated(getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_VOLTAGE_L3),
|
||||
getState(223, Units.VOLT));
|
||||
verify(callback).stateUpdated(getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_ENERGY_EXPORT),
|
||||
getState(8877.0, Units.KILOWATT_HOUR));
|
||||
verify(callback).stateUpdated(
|
||||
getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_ENERGY_EXPORT_T1),
|
||||
getState(8874, Units.KILOWATT_HOUR));
|
||||
verify(callback).stateUpdated(
|
||||
getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_ENERGY_EXPORT_T2),
|
||||
getState(7788, Units.KILOWATT_HOUR));
|
||||
verify(callback).stateUpdated(getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_ENERGY_IMPORT),
|
||||
getState(13779.338, Units.KILOWATT_HOUR));
|
||||
verify(callback).stateUpdated(
|
||||
getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_ENERGY_IMPORT_T1),
|
||||
getState(10830.511, Units.KILOWATT_HOUR));
|
||||
verify(callback).stateUpdated(
|
||||
getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_ENERGY_IMPORT_T2),
|
||||
getState(2948.827, Units.KILOWATT_HOUR));
|
||||
verify(callback).stateUpdated(getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_POWER_FAILURES),
|
||||
getState(7));
|
||||
verify(callback).stateUpdated(
|
||||
getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_LONG_POWER_FAILURES), getState(2));
|
||||
verify(callback).stateUpdated(getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_GAS_TIMESTAMP),
|
||||
new DateTimeType(ZonedDateTime.of(2021, 6, 06, 14, 0, 10, 0, ZoneId.systemDefault())));
|
||||
verify(callback).stateUpdated(getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_GAS_TOTAL),
|
||||
getState(2569.646, SIUnits.CUBIC_METRE));
|
||||
|
||||
verify(callback).stateUpdated(
|
||||
getSystemChannelUid(thing, HomeWizardBindingConstants.CHANNEL_SYSTEM_WIFI_SSID),
|
||||
getState("My Wi-Fi"));
|
||||
verify(callback).stateUpdated(
|
||||
getSystemChannelUid(thing, HomeWizardBindingConstants.CHANNEL_SYSTEM_WIFI_RSSI), getState(-77));
|
||||
verify(callback).stateUpdated(getSystemChannelUid(thing, HomeWizardBindingConstants.CHANNEL_SYSTEM_UPTIME),
|
||||
getState(356, Units.SECOND));
|
||||
verify(callback).stateUpdated(
|
||||
getSystemChannelUid(thing, HomeWizardBindingConstants.CHANNEL_SYSTEM_CLOUD_ENABLED),
|
||||
getState(true));
|
||||
verify(callback).stateUpdated(
|
||||
getSystemChannelUid(thing, HomeWizardBindingConstants.CHANNEL_SYSTEM_STATUS_LED_BRIGHTNESS),
|
||||
getState(100));
|
||||
} finally {
|
||||
handler.dispose();
|
||||
}
|
||||
@@ -208,7 +296,7 @@ public class HomeWizardP1MeterHandlerTest extends HomeWizardHandlerTest {
|
||||
public void testUpdateBatteriesChannels() {
|
||||
final Thing thing = mockThing(2, false);
|
||||
final ThingHandlerCallback callback = mock(ThingHandlerCallback.class);
|
||||
final HomeWizardP1MeterHandlerMock handler = createAndInitHandler(callback, thing);
|
||||
final HomeWizardP1MeterHandlerMock handler = createAndInitHandler(callback, thing, 2);
|
||||
|
||||
try {
|
||||
verify(callback).statusUpdated(eq(thing), argThat(arg -> arg.getStatus().equals(ThingStatus.UNKNOWN)));
|
||||
@@ -241,7 +329,7 @@ public class HomeWizardP1MeterHandlerTest extends HomeWizardHandlerTest {
|
||||
public void testUpdateLegacyChannels() {
|
||||
final Thing thing = mockThing(1, true);
|
||||
final ThingHandlerCallback callback = mock(ThingHandlerCallback.class);
|
||||
final HomeWizardP1MeterHandlerMock handler = createAndInitHandler(callback, thing);
|
||||
final HomeWizardP1MeterHandlerMock handler = createAndInitHandler(callback, thing, 1);
|
||||
|
||||
try {
|
||||
verify(callback).statusUpdated(eq(thing), argThat(arg -> arg.getStatus().equals(ThingStatus.UNKNOWN)));
|
||||
|
||||
+17
-1
@@ -16,6 +16,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -76,7 +77,8 @@ public class HomeWizardPlugInBatteryMeterHandlerTest extends HomeWizardHandlerTe
|
||||
doReturn(DataUtil.fromFile("response-device-information-plug-in-battery.json")).when(handler)
|
||||
.getDeviceInformationData();
|
||||
doReturn(DataUtil.fromFile("response-measurement-plug-in-battery.json")).when(handler).getMeasurementData();
|
||||
} catch (Exception e) {
|
||||
doReturn(DataUtil.fromFile("response-system.json")).when(handler).getSystemData();
|
||||
} catch (IOException ex) {
|
||||
assertFalse(true);
|
||||
}
|
||||
|
||||
@@ -109,6 +111,20 @@ public class HomeWizardPlugInBatteryMeterHandlerTest extends HomeWizardHandlerTe
|
||||
|
||||
verify(callback).stateUpdated(getEnergyChannelUid(thing, HomeWizardBindingConstants.CHANNEL_FREQUENCY),
|
||||
getState(50.0, Units.HERTZ));
|
||||
|
||||
verify(callback).stateUpdated(
|
||||
getSystemChannelUid(thing, HomeWizardBindingConstants.CHANNEL_SYSTEM_WIFI_SSID),
|
||||
getState("My Wi-Fi"));
|
||||
verify(callback).stateUpdated(
|
||||
getSystemChannelUid(thing, HomeWizardBindingConstants.CHANNEL_SYSTEM_WIFI_RSSI), getState(-77));
|
||||
verify(callback).stateUpdated(getSystemChannelUid(thing, HomeWizardBindingConstants.CHANNEL_SYSTEM_UPTIME),
|
||||
getState(356, Units.SECOND));
|
||||
verify(callback).stateUpdated(
|
||||
getSystemChannelUid(thing, HomeWizardBindingConstants.CHANNEL_SYSTEM_CLOUD_ENABLED),
|
||||
getState(true));
|
||||
verify(callback).stateUpdated(
|
||||
getSystemChannelUid(thing, HomeWizardBindingConstants.CHANNEL_SYSTEM_STATUS_LED_BRIGHTNESS),
|
||||
getState(100));
|
||||
} finally {
|
||||
handler.dispose();
|
||||
}
|
||||
|
||||
+12
-1
@@ -16,6 +16,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -81,7 +82,8 @@ public class HomeWizardWaterMeterHandlerTest extends HomeWizardHandlerTest {
|
||||
doReturn(DataUtil.fromFile("response-device-information-water-meter.json")).when(handler)
|
||||
.getDeviceInformationData();
|
||||
doReturn(DataUtil.fromFile("response-measurement-water-meter.json")).when(handler).getMeasurementData();
|
||||
} catch (Exception e) {
|
||||
doReturn(DataUtil.fromFile("response-system.json")).when(handler).getSystemData();
|
||||
} catch (IOException ex) {
|
||||
assertFalse(true);
|
||||
}
|
||||
|
||||
@@ -111,6 +113,15 @@ public class HomeWizardWaterMeterHandlerTest extends HomeWizardHandlerTest {
|
||||
+ HomeWizardBindingConstants.CHANNEL_TOTAL_LITER),
|
||||
getState(123.456, SIUnits.CUBIC_METRE));
|
||||
|
||||
verify(callback).stateUpdated(
|
||||
getSystemChannelUid(thing, HomeWizardBindingConstants.CHANNEL_SYSTEM_WIFI_SSID),
|
||||
getState("My Wi-Fi"));
|
||||
verify(callback).stateUpdated(
|
||||
getSystemChannelUid(thing, HomeWizardBindingConstants.CHANNEL_SYSTEM_WIFI_RSSI), getState(-58));
|
||||
verify(callback).stateUpdated(
|
||||
getSystemChannelUid(thing, HomeWizardBindingConstants.CHANNEL_SYSTEM_CLOUD_ENABLED),
|
||||
getState(true));
|
||||
|
||||
} finally {
|
||||
handler.dispose();
|
||||
}
|
||||
|
||||
+6
@@ -38,6 +38,9 @@ public class HomeWizardWaterMeterMeasurementPayloadTest {
|
||||
HomeWizardWaterMeterMeasurementPayload.class);
|
||||
assertThat(key, is(notNullValue()));
|
||||
|
||||
assertThat(key.getWifiSsid(), is("My Wi-Fi"));
|
||||
assertThat(key.getWifiRssi(), is(-58));
|
||||
|
||||
assertThat(key.getActiveLiter(), is(7.2));
|
||||
assertThat(key.getTotalLiter(), is(123.456));
|
||||
}
|
||||
@@ -48,6 +51,9 @@ public class HomeWizardWaterMeterMeasurementPayloadTest {
|
||||
HomeWizardWaterMeterMeasurementPayload.class);
|
||||
assertThat(key, is(notNullValue()));
|
||||
|
||||
assertThat(key.getWifiSsid(), is(""));
|
||||
assertThat(key.getWifiRssi(), is(-100));
|
||||
|
||||
assertThat(key.getActiveLiter(), is(0.0));
|
||||
assertThat(key.getTotalLiter(), is(0.0));
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"wifi_ssid": "My Wi-Fi",
|
||||
"wifi_strength": 100,
|
||||
"wifi_strength": 85,
|
||||
"total_liter_m3": 123.456,
|
||||
"active_liter_lpm": 7.2,
|
||||
"total_liter_offset_m3": 0
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"wifi_ssid": "My Wi-Fi",
|
||||
"wifi_rssi_db": -77,
|
||||
"cloud_enabled": true,
|
||||
"uptime_s": 356,
|
||||
"status_led_brightness_pct": 100,
|
||||
"api_v1_enabled": true
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"wifi_ssid": "My Wi-Fi",
|
||||
"wifi_strength": 100,
|
||||
"wifi_strength": 85,
|
||||
"smr_version": 50,
|
||||
"meter_model": "ISKRA 2M550T-101",
|
||||
"unique_id": "00112233445566778899AABBCCDDEEFF",
|
||||
|
||||
Reference in New Issue
Block a user