[hdpowerview] Corrections to shade database and capabilities (#12902)
* [hdpowerview] add type 66 shutters to database * [hdpowerview] shade database updates * [hdpowerview] shade database additions and corrections * [hdpowerview] enhance database features * [hdpowerview] fix capabilities 8, 9 functionality * [hdpowerview] adjust tests to match new capabilities * [hdpowerview] correct method visibility * [hdpowerview] test type 44 * [hdpowerview] remove comment * [hdpowerview] name change * [hdpowerview] remove comments attribute * [hdpowerview] refactor capabilities code * [hdpowerview] 'hard' properties now hidden * [hdpowerview] adopt reviewer suggestion * [hdpowerview] refactor constant names Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
This commit is contained in:
committed by
GitHub
parent
798d59b2c5
commit
c806c76631
@@ -67,8 +67,6 @@ public class HDPowerViewBindingConstants {
|
||||
// Shade properties
|
||||
public static final String PROPERTY_SHADE_TYPE = "type";
|
||||
public static final String PROPERTY_SHADE_CAPABILITIES = "capabilities";
|
||||
public static final String PROPERTY_SECONDARY_RAIL_DETECTED = "secondaryRailDetected";
|
||||
public static final String PROPERTY_TILT_ANYWHERE_DETECTED = "tiltAnywhereDetected";
|
||||
public static final String PROPERTY_MOTOR_FIRMWARE_VERSION = "motorFirmwareVersion";
|
||||
|
||||
public static final List<String> NETBIOS_NAMES = Arrays.asList("PDBU-Hub3.0", "PowerView-Hub");
|
||||
|
||||
@@ -158,7 +158,7 @@ public class ShadePosition {
|
||||
}
|
||||
return new PercentType((int) Math.round((double) position1 / MAX_SHADE * 100));
|
||||
}
|
||||
if (PRIMARY_POSITION.equals(posKind1) && shadeCapabilities.supportsSecondaryOverlapped()) {
|
||||
if (!SECONDARY_POSITION.equals(posKind1) && shadeCapabilities.supportsSecondaryOverlapped()) {
|
||||
return PercentType.ZERO;
|
||||
}
|
||||
break;
|
||||
@@ -182,6 +182,10 @@ public class ShadePosition {
|
||||
if (PRIMARY_POSITION.equals(posKind1) && shadeCapabilities.supportsTiltOnClosed()) {
|
||||
return position1 != 0 ? UnDefType.UNDEF : PercentType.ZERO;
|
||||
}
|
||||
if (SECONDARY_POSITION.equals(posKind1) && shadeCapabilities.supportsSecondaryOverlapped()
|
||||
&& shadeCapabilities.supportsTiltOnClosed()) {
|
||||
return PercentType.HUNDRED;
|
||||
}
|
||||
break;
|
||||
|
||||
case ERROR_UNKNOWN:
|
||||
|
||||
@@ -18,6 +18,7 @@ import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -40,16 +41,17 @@ public class ShadeCapabilitiesDatabase {
|
||||
*/
|
||||
private static final Map<Integer, Capabilities> CAPABILITIES_DATABASE = Arrays.asList(
|
||||
// @formatter:off
|
||||
new Capabilities(0).primary() .tiltOnClosed() .text("Bottom Up"),
|
||||
new Capabilities(0).primary() .text("Bottom Up"),
|
||||
new Capabilities(1).primary() .tiltOnClosed() .text("Bottom Up Tilt 90°"),
|
||||
new Capabilities(2).primary() .tiltAnywhere().tilt180() .text("Bottom Up Tilt 180°"),
|
||||
new Capabilities(3).primary() .tiltOnClosed() .text("Vertical"),
|
||||
new Capabilities(4).primary() .tiltAnywhere().tilt180() .text("Vertical Tilt 180°"),
|
||||
new Capabilities(3).primary() .tiltAnywhere().tilt180() .text("Vertical Tilt 180°"),
|
||||
new Capabilities(4).primary() .text("Vertical"),
|
||||
new Capabilities(5) .tiltAnywhere().tilt180() .text("Tilt Only 180°"),
|
||||
new Capabilities(6).primaryInverted() .text("Top Down"),
|
||||
new Capabilities(7).primary() .secondary() .text("Top Down Bottom Up"),
|
||||
new Capabilities(8).primary() .secondaryOverlapped().text("Dual Overlapped"),
|
||||
new Capabilities(9).primary() .tiltAnywhere() .secondaryOverlapped().text("Dual Overlapped Tilt 90°"),
|
||||
// note: for the following capabilities entry the 'tiltOnClosed()' applies to the primary shade
|
||||
new Capabilities(9).primary() .tiltOnClosed() .secondaryOverlapped().text("Dual Overlapped Tilt 90°"),
|
||||
// @formatter:on
|
||||
new Capabilities()).stream().collect(Collectors.toMap(Capabilities::getValue, Function.identity()));
|
||||
|
||||
@@ -58,18 +60,20 @@ public class ShadeCapabilitiesDatabase {
|
||||
*/
|
||||
private static final Map<Integer, Type> TYPE_DATABASE = Arrays.asList(
|
||||
// @formatter:off
|
||||
new Type( 1).capabilities(0).text("Roller / Solar"),
|
||||
new Type( 4).capabilities(0).text("Roman"),
|
||||
new Type( 5).capabilities(0).text("Bottom Up"),
|
||||
new Type( 6).capabilities(0).text("Duette"),
|
||||
new Type( 7).capabilities(6).text("Top Down"),
|
||||
new Type( 8).capabilities(7).text("Duette Top Down Bottom Up"),
|
||||
new Type( 9).capabilities(7).text("Duette DuoLite Top Down Bottom Up"),
|
||||
new Type(18).capabilities(1).text("Silhouette"),
|
||||
new Type(18).capabilities(1).text("Pirouette"),
|
||||
new Type(23).capabilities(1).text("Silhouette"),
|
||||
new Type(38).capabilities(9).text("Silhouette Duolite"),
|
||||
new Type(42).capabilities(0).text("M25T Roller Blind"),
|
||||
new Type(43).capabilities(1).text("Facette"),
|
||||
new Type(44).capabilities(0).text("Twist"),
|
||||
// note: the following shade type has the functionality of a capabilities 1 shade
|
||||
new Type(44).capabilities(0).text("Twist").capabilitiesOverride(1),
|
||||
new Type(47).capabilities(7).text("Pleated Top Down Bottom Up"),
|
||||
new Type(49).capabilities(0).text("AC Roller"),
|
||||
new Type(51).capabilities(2).text("Venetian"),
|
||||
@@ -79,9 +83,9 @@ public class ShadeCapabilitiesDatabase {
|
||||
new Type(62).capabilities(2).text("Venetian"),
|
||||
new Type(65).capabilities(8).text("Vignette Duolite"),
|
||||
new Type(66).capabilities(5).text("Shutter"),
|
||||
new Type(69).capabilities(3).text("Curtain Left Stack"),
|
||||
new Type(70).capabilities(3).text("Curtain Right Stack"),
|
||||
new Type(71).capabilities(3).text("Curtain Split Stack"),
|
||||
new Type(69).capabilities(4).text("Curtain Left Stack"),
|
||||
new Type(70).capabilities(4).text("Curtain Right Stack"),
|
||||
new Type(71).capabilities(4).text("Curtain Split Stack"),
|
||||
new Type(79).capabilities(8).text("Duolite Lift"),
|
||||
// @formatter:on
|
||||
new Type()).stream().collect(Collectors.toMap(Type::getValue, Function.identity()));
|
||||
@@ -112,6 +116,7 @@ public class ShadeCapabilitiesDatabase {
|
||||
*/
|
||||
public static class Type extends Base {
|
||||
private int capabilities = -1;
|
||||
private int capabilitiesOverride = -1;
|
||||
|
||||
protected Type() {
|
||||
}
|
||||
@@ -130,6 +135,11 @@ public class ShadeCapabilitiesDatabase {
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Type capabilitiesOverride(int capabilitiesOverride) {
|
||||
this.capabilitiesOverride = capabilitiesOverride;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shade types's 'capabilities'.
|
||||
*
|
||||
@@ -138,6 +148,15 @@ public class ShadeCapabilitiesDatabase {
|
||||
public int getCapabilities() {
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shade's type specific 'capabilities'.
|
||||
*
|
||||
* @return 'typeCapabilities'.
|
||||
*/
|
||||
public int getCapabilitiesOverride() {
|
||||
return capabilitiesOverride;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -301,13 +320,35 @@ public class ShadeCapabilitiesDatabase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Capabilities class instance that corresponds to the given 'capabilities' parameter.
|
||||
* Return a Capabilities class instance that corresponds to the given 'capabilitiesId' parameter. If the
|
||||
* 'capabilitiesId' parameter is for a valid capabilities entry in the database, then that respective Capabilities
|
||||
* class instance is returned. Otherwise a blank Capabilities class instance is returned.
|
||||
*
|
||||
* @param capabilities the shade 'capabilities' parameter.
|
||||
* @return corresponding instance of Capabilities class.
|
||||
* @param capabilitiesId the target capabilities Id.
|
||||
* @return corresponding Capabilities class instance.
|
||||
*/
|
||||
public Capabilities getCapabilities(int capabilities) {
|
||||
return CAPABILITIES_DATABASE.getOrDefault(capabilities, new Capabilities());
|
||||
public Capabilities getCapabilities(@Nullable Integer capabilitiesId) {
|
||||
return CAPABILITIES_DATABASE.getOrDefault(capabilitiesId != null ? capabilitiesId.intValue() : -1,
|
||||
new Capabilities());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Capabilities class instance that corresponds to the given 'typeId' parameter. If the 'typeId' parameter
|
||||
* is a valid type in the database, and it has a 'capabilitiesOverride' value, then an instance of the respective
|
||||
* overridden Capabilities class is returned. Otherwise if the 'capabilitiesId' parameter is for a valid
|
||||
* capabilities entry in the database, then that respective Capabilities class instance is returned. Otherwise a
|
||||
* blank Capabilities class instance is returned.
|
||||
*
|
||||
* @param typeId the target shade type Id (to check if it has a 'capabilitiesOverride' value).
|
||||
* @param capabilitiesId the target capabilities value (when type Id does not have a 'capabilitiesOverride').
|
||||
* @return corresponding Capabilities class instance.
|
||||
*/
|
||||
public Capabilities getCapabilities(int typeId, @Nullable Integer capabilitiesId) {
|
||||
int targetCapabilities = TYPE_DATABASE.getOrDefault(typeId, new Type()).getCapabilitiesOverride();
|
||||
if (targetCapabilities < 0) {
|
||||
targetCapabilities = capabilitiesId != null ? capabilitiesId.intValue() : -1;
|
||||
}
|
||||
return getCapabilities(targetCapabilities);
|
||||
}
|
||||
|
||||
private static final String REQUEST_DEVELOPERS_TO_UPDATE = " => Please request developers to update the database!";
|
||||
|
||||
@@ -115,8 +115,7 @@ public class HDPowerViewDeviceDiscoveryService extends AbstractDiscoveryService
|
||||
}
|
||||
String id = Integer.toString(shadeData.id);
|
||||
ThingUID thingUID = new ThingUID(HDPowerViewBindingConstants.THING_TYPE_SHADE, bridgeUid, id);
|
||||
Integer caps = shadeData.capabilities;
|
||||
Capabilities capabilities = db.getCapabilities((caps != null) ? caps.intValue() : -1);
|
||||
Capabilities capabilities = db.getCapabilities(shadeData.capabilities);
|
||||
|
||||
DiscoveryResultBuilder builder = DiscoveryResultBuilder.create(thingUID).withLabel(shadeData.getName())
|
||||
.withBridge(bridgeUid).withProperty(HDPowerViewShadeConfiguration.ID, id)
|
||||
|
||||
@@ -15,6 +15,7 @@ package org.openhab.binding.hdpowerview.internal.handler;
|
||||
import static org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants.*;
|
||||
import static org.openhab.binding.hdpowerview.internal.api.CoordinateSystem.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -75,6 +76,10 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
|
||||
private static final String COMMAND_CALIBRATE = "CALIBRATE";
|
||||
private static final String COMMAND_IDENTIFY = "IDENTIFY";
|
||||
|
||||
private static final String DETECTED_SECONDARY_RAIL = "secondaryRailDetected";
|
||||
private static final String DETECTED_TILT_ANYWHERE = "tiltAnywhereDetected";
|
||||
private final Map<String, String> detectedCapabilities = new HashMap<>();
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(HDPowerViewShadeHandler.class);
|
||||
private final ShadeCapabilitiesDatabase db = new ShadeCapabilitiesDatabase();
|
||||
|
||||
@@ -260,14 +265,13 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
|
||||
// Already cached.
|
||||
return;
|
||||
}
|
||||
Integer value = shade.capabilities;
|
||||
if (value != null) {
|
||||
int valueAsInt = value.intValue();
|
||||
logger.debug("Caching capabilities {} for shade {}", valueAsInt, shade.id);
|
||||
capabilities = db.getCapabilities(valueAsInt);
|
||||
} else {
|
||||
logger.debug("Capabilities not included in shade response");
|
||||
Capabilities capabilities = db.getCapabilities(shade.type, shade.capabilities);
|
||||
if (capabilities.getValue() < 0) {
|
||||
logger.debug("Unable to set capabilities for shade {}", shade.id);
|
||||
return;
|
||||
}
|
||||
logger.debug("Caching capabilities {} for shade {}", capabilities.getValue(), shade.id);
|
||||
this.capabilities = capabilities;
|
||||
}
|
||||
|
||||
private Capabilities getCapabilitiesOrDefault() {
|
||||
@@ -304,9 +308,8 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
|
||||
}
|
||||
|
||||
// update 'capabilities' property
|
||||
final Integer temp = shadeData.capabilities;
|
||||
final int capabilitiesVal = temp != null ? temp.intValue() : -1;
|
||||
Capabilities capabilities = db.getCapabilities(capabilitiesVal);
|
||||
Capabilities capabilities = db.getCapabilities(shadeData.capabilities);
|
||||
final int capabilitiesVal = capabilities.getValue();
|
||||
propKey = HDPowerViewBindingConstants.PROPERTY_SHADE_CAPABILITIES;
|
||||
propOldVal = properties.getOrDefault(propKey, "");
|
||||
propNewVal = capabilities.toString();
|
||||
@@ -338,7 +341,7 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* After a hard refresh, update the Thing's properties based on the contents of the provided ShadeData.
|
||||
* After a hard refresh, update the Thing's detected capabilities based on the contents of the provided ShadeData.
|
||||
*
|
||||
* Checks if the secondary support capabilities in the database of known Shade 'types' and 'capabilities' matches
|
||||
* that implied by the ShadeData and logs any incompatible values, so that developers can be kept updated about the
|
||||
@@ -346,35 +349,34 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
|
||||
*
|
||||
* @param shadeData
|
||||
*/
|
||||
private void updateHardProperties(ShadeData shadeData) {
|
||||
private void updateDetectedCapabilities(ShadeData shadeData) {
|
||||
final ShadePosition positions = shadeData.positions;
|
||||
if (positions == null) {
|
||||
return;
|
||||
}
|
||||
Capabilities capabilities = getCapabilitiesOrDefault();
|
||||
final Map<String, String> properties = getThing().getProperties();
|
||||
|
||||
// update 'secondary rail detected' property
|
||||
String propKey = HDPowerViewBindingConstants.PROPERTY_SECONDARY_RAIL_DETECTED;
|
||||
String propOldVal = properties.getOrDefault(propKey, "");
|
||||
boolean propNewBool = positions.secondaryRailDetected();
|
||||
String propNewVal = String.valueOf(propNewBool);
|
||||
if (!propNewVal.equals(propOldVal)) {
|
||||
getThing().setProperty(propKey, propNewVal);
|
||||
if (propNewBool != capabilities.supportsSecondary()) {
|
||||
db.logPropertyMismatch(propKey, shadeData.type, capabilities.getValue(), propNewBool);
|
||||
// update 'secondary rail' detected capability
|
||||
String capsKey = DETECTED_SECONDARY_RAIL;
|
||||
String capsOldVal = detectedCapabilities.getOrDefault(capsKey, "");
|
||||
boolean capsNewBool = positions.secondaryRailDetected();
|
||||
String capsNewVal = String.valueOf(capsNewBool);
|
||||
if (!capsNewVal.equals(capsOldVal)) {
|
||||
detectedCapabilities.put(capsKey, capsNewVal);
|
||||
if (capsNewBool != capabilities.supportsSecondary()) {
|
||||
db.logPropertyMismatch(capsKey, shadeData.type, capabilities.getValue(), capsNewBool);
|
||||
}
|
||||
}
|
||||
|
||||
// update 'tilt anywhere detected' property
|
||||
propKey = HDPowerViewBindingConstants.PROPERTY_TILT_ANYWHERE_DETECTED;
|
||||
propOldVal = properties.getOrDefault(propKey, "");
|
||||
propNewBool = positions.tiltAnywhereDetected();
|
||||
propNewVal = String.valueOf(propNewBool);
|
||||
if (!propNewVal.equals(propOldVal)) {
|
||||
getThing().setProperty(propKey, propNewVal);
|
||||
if (propNewBool != capabilities.supportsTiltAnywhere()) {
|
||||
db.logPropertyMismatch(propKey, shadeData.type, capabilities.getValue(), propNewBool);
|
||||
// update 'tilt anywhere' detected capability
|
||||
capsKey = DETECTED_TILT_ANYWHERE;
|
||||
capsOldVal = detectedCapabilities.getOrDefault(capsKey, "");
|
||||
capsNewBool = positions.tiltAnywhereDetected();
|
||||
capsNewVal = String.valueOf(capsNewBool);
|
||||
if (!capsNewVal.equals(capsOldVal)) {
|
||||
detectedCapabilities.put(capsKey, capsNewVal);
|
||||
if (capsNewBool != capabilities.supportsTiltAnywhere()) {
|
||||
db.logPropertyMismatch(capsKey, shadeData.type, capabilities.getValue(), capsNewBool);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -523,7 +525,7 @@ public class HDPowerViewShadeHandler extends AbstractHubbedThingHandler {
|
||||
case POSITION:
|
||||
shadeData = webTargets.refreshShadePosition(shadeId);
|
||||
updateShadePositions(shadeData);
|
||||
updateHardProperties(shadeData);
|
||||
updateDetectedCapabilities(shadeData);
|
||||
break;
|
||||
case SURVEY:
|
||||
Survey survey = webTargets.getShadeSurvey(shadeId);
|
||||
|
||||
Reference in New Issue
Block a user