[hdpowerview] Battery channels visible only when required (#13324)

* [hdpowerview] add batteryKind field
* [hdpowerview] battery channels visible depending on batteryKind

Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
This commit is contained in:
Andrew Fiddian-Green 2022-08-28 12:55:18 +01:00 committed by GitHub
parent c825171caf
commit f7295bd00f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 96 additions and 7 deletions

View File

@ -96,14 +96,16 @@ All of these channels appear in the binding, but only those which have a physica
| vane | Dimmer | The degree of opening of the slats or vanes (if any). On some shade types, setting this to a non-zero value might first move the shade `position` fully down, since the slats or vanes can only have a defined state if the shade is in its down position. See [Interdependency between Channel positions](#Interdependency-between-Channel-positions). |
| command | String | Send a command to the shade. Valid values are: `CALIBRATE`, `IDENTIFY` |
| lowBattery | Switch | Indicates ON when the battery level of the shade is low, as determined by the hub's internal rules. |
| batteryLevel | Number | Battery level (10% = low, 50% = medium, 100% = high)
| batteryVoltage | Number:ElectricPotential | Battery voltage reported by the shade. |
| batteryLevel | Number | Battery level (10% = low, 50% = medium, 100% = high) |
| batteryVoltage | Number:ElectricPotential | Battery (resp. mains power supply) voltage reported by the shade. |
| signalStrength | Number | Signal strength (0 for no or unknown signal, 1 for weak, 2 for average, 3 for good or 4 for excellent) |
| hubRssi | Number:Power | Received Signal Strength Indicator for Hub |
| repeaterRssi | Number:Power | Received Signal Strength Indicator for Repeater |
Notes:
- The channels `position`, `secondary` and `vane` only exist if the shade physically supports such channels.
- The channels `position`, `secondary` and `vane` exist if the shade physically supports such channels.
- The shade's Power Option is set via the PowerView app with possible values 'Battery Wand', 'Rechargeable Battery Wand' or 'Hardwired Power Supply'.
The channels `lowBattery` and `batteryLevel` exist if you have _not_ selected 'Hardwired Power Supply' in the app.
- The RSSI values will only be updated upon manual request by a `REFRESH` command (e.g. in a rule).
### Channels for Repeaters (Thing type `repeater`)

View File

@ -0,0 +1,57 @@
/**
* Copyright (c) 2010-2022 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.hdpowerview.internal.api;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
/**
* An enum for the type of power supply in a shade.
*
* @author Andrew Fiddian-Green - Initial contribution
*/
@NonNullByDefault
public enum BatteryKind {
ERROR_UNKNOWN(-1),
HARDWIRED_POWER_SUPPLY(1),
BATTERY_WAND(2),
RECHARGEABLE_BATTERY_WAND(3);
private int batteryKind;
private BatteryKind(int i) {
this.batteryKind = i;
}
/**
* Determine the BatteryKind by parsing the given string value.
*
* @param value the string to parse, or null.
* @return the BatteryKind or ERROR_UNKNOWN in case of error.
*/
public static BatteryKind fromString(@Nullable String value) {
if (value != null) {
try {
int intValue = Integer.parseInt(value);
for (BatteryKind e : values()) {
if (e.batteryKind == intValue) {
return e;
}
}
} catch (NumberFormatException e) {
// fall through
}
}
return ERROR_UNKNOWN;
}
}

View File

@ -17,6 +17,7 @@ import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.hdpowerview.internal.api.BatteryKind;
import org.openhab.binding.hdpowerview.internal.api.Firmware;
import org.openhab.binding.hdpowerview.internal.api.ShadePosition;
@ -55,9 +56,15 @@ public class Shades {
public @Nullable Integer capabilities;
public @Nullable Firmware firmware;
public @Nullable Firmware motor;
// note: in old JSON batteryKind was a string but now it's a number; fortunately GSON string accepts either
public @Nullable String batteryKind;
public String getName() {
return new String(Base64.getDecoder().decode(name));
}
public BatteryKind getBatteryKind() {
return BatteryKind.fromString(batteryKind);
}
}
}

View File

@ -29,6 +29,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants;
import org.openhab.binding.hdpowerview.internal.HDPowerViewWebTargets;
import org.openhab.binding.hdpowerview.internal.api.BatteryKind;
import org.openhab.binding.hdpowerview.internal.api.CoordinateSystem;
import org.openhab.binding.hdpowerview.internal.api.Firmware;
import org.openhab.binding.hdpowerview.internal.api.ShadePosition;
@ -274,7 +275,7 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
logger.debug("Caching capabilities {} for shade {}", capabilities.getValue(), shade.id);
this.capabilities = capabilities;
updateDynamicChannels(capabilities);
updateDynamicChannels(capabilities, shade);
}
private Capabilities getCapabilitiesOrDefault() {
@ -618,9 +619,12 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
}
/**
* Remove previously statically created channels if the shade does not support them.
* Remove previously statically created channels if the shade does not support them or they are not relevant.
*
* @param capabilities the capabilities of the shade.
* @param shade the shade data.
*/
private void updateDynamicChannels(Capabilities capabilities) {
private void updateDynamicChannels(Capabilities capabilities, ShadeData shade) {
List<Channel> removeList = new ArrayList<>();
removeListProcessChannel(removeList, CHANNEL_SHADE_POSITION, capabilities.supportsPrimary());
@ -631,6 +635,10 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
removeListProcessChannel(removeList, CHANNEL_SHADE_VANE,
capabilities.supportsTiltAnywhere() || capabilities.supportsTiltOnClosed());
boolean batteryChannelsRequired = shade.getBatteryKind() != BatteryKind.HARDWIRED_POWER_SUPPLY;
removeListProcessChannel(removeList, CHANNEL_SHADE_BATTERY_LEVEL, batteryChannelsRequired);
removeListProcessChannel(removeList, CHANNEL_SHADE_LOW_BATTERY, batteryChannelsRequired);
if (!removeList.isEmpty()) {
if (logger.isDebugEnabled()) {
StringJoiner joiner = new StringJoiner(", ");

View File

@ -23,6 +23,7 @@ import java.util.Objects;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.Test;
import org.openhab.binding.hdpowerview.internal.api.BatteryKind;
import org.openhab.binding.hdpowerview.internal.api.ShadePosition;
import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections;
import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections.SceneCollection;
@ -76,6 +77,20 @@ public class HDPowerViewJUnitTests {
assertEquals("Shade 2", shade.getName());
}
/**
* Test the BatteryKind decoding.
*/
@Test
public void testBatteryKind() throws IOException {
Shades shades = getObjectFromJson("shades.json", Shades.class);
List<ShadeData> shadeData = shades.shadeData;
assertNotNull(shadeData);
ShadeData shade = shadeData.get(0);
assertEquals(BatteryKind.HARDWIRED_POWER_SUPPLY, shade.getBatteryKind());
shade = shadeData.get(1);
assertEquals(BatteryKind.ERROR_UNKNOWN, shade.getBatteryKind());
}
/**
* Test generic JSON scene response.
*/

View File

@ -26,7 +26,7 @@
"aid": 2,
"signalStrength": 4,
"capabilities": 0,
"batteryKind": "unassigned",
"batteryKind": 1,
"positions": {
"posKind1": 3,
"position1": 32579