[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>
pull/12917/head
Andrew Fiddian-Green 2022-06-10 20:10:31 +02:00 committed by GitHub
parent 798d59b2c5
commit c806c76631
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 255 additions and 97 deletions

View File

@ -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");

View File

@ -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:

View File

@ -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!";

View File

@ -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)

View File

@ -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);

View File

@ -43,17 +43,18 @@ public class ShadePositionTest {
assertTrue(db.isCapabilitiesInDatabase(0));
assertTrue(db.getCapabilities(0).supportsPrimary());
assertTrue(db.getCapabilities(0).supportsTiltOnClosed());
assertTrue(db.getCapabilities(1).supportsTiltOnClosed());
assertTrue(db.getCapabilities(2).supportsTilt180());
assertTrue(db.getCapabilities(3).supportsTiltOnClosed());
assertTrue(db.getCapabilities(4).supportsTilt180());
assertTrue(db.getCapabilities(2).supportsTiltAnywhere());
assertTrue(db.getCapabilities(3).supportsTilt180());
assertTrue(db.getCapabilities(3).supportsTiltAnywhere());
assertTrue(db.getCapabilities(5).supportsTilt180());
assertFalse(db.getCapabilities(5).supportsPrimary());
assertTrue(db.getCapabilities(6).isPrimaryInverted());
assertTrue(db.getCapabilities(7).supportsSecondary());
assertTrue(db.getCapabilities(8).supportsSecondaryOverlapped());
assertTrue(db.getCapabilities(9).supportsSecondaryOverlapped());
assertTrue(db.getCapabilities(9).supportsTiltOnClosed());
assertEquals(db.getType(4).getCapabilities(), 0);
assertEquals(db.getType(-1).getCapabilities(), -1);
@ -82,57 +83,59 @@ public class ShadePositionTest {
}
/**
* Test parsing of ShadePosition (shade fully up).
* Test parsing of Capabilities 1 ShadePosition (shade fully up).
*
*/
@Test
public void testShadePositionParsingFullyUp() {
Capabilities capabilities = db.getCapabilities(0);
public void testCaps1ShadePositionParsingFullyUp() {
Capabilities capabilities = db.getCapabilities(1);
ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0);
assertNotNull(test);
State pos = test.getState(capabilities, PRIMARY_POSITION);
assertShadePosition(pos, 0);
pos = test.getState(capabilities, VANE_TILT_POSITION);
assertTrue(UnDefType.UNDEF.equals(pos));
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
}
/**
* Test parsing of ShadePosition (shade fully down (method 1)).
* Test parsing of Capabilities 1 ShadePosition (shade fully down (method 1)).
*
*/
@Test
public void testShadePositionParsingShadeFullyDown1() {
Capabilities capabilities = db.getCapabilities(0);
public void testCaps1ShadePositionParsingShadeFullyDown1() {
Capabilities capabilities = db.getCapabilities(1);
ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 100);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 0);
}
/**
* Test parsing of ShadePosition (shade fully down (method 2)).
* Test parsing of Capabilities 1 ShadePosition (shade fully down (method 2)).
*
*/
@Test
public void testShadePositionParsingShadeFullyDown2() {
Capabilities capabilities = db.getCapabilities(0);
public void testCaps1ShadePositionParsingShadeFullyDown2() {
Capabilities capabilities = db.getCapabilities(1);
ShadePosition test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 0);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 0);
}
/**
* Test parsing of ShadePosition (shade fully down (method 2) and vane fully open).
* Test parsing of Capabilities 1 ShadePosition (shade fully down (method 2) and vane fully open).
*
*/
@Test
public void testShadePositionParsingShadeFullyDownVaneOpen() {
Capabilities capabilities = db.getCapabilities(0);
ShadePosition test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 100);
public void testCaps1ShadePositionParsingShadeFullyDownVaneOpen() {
Capabilities capabilities = db.getCapabilities(1);
ShadePosition test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 88);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 88);
}
/**
@ -149,40 +152,47 @@ public class ShadePositionTest {
test.setPosition(capabilities, PRIMARY_POSITION, 100).setPosition(capabilities, SECONDARY_POSITION, 0);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
// ==== OK !! primary at middle, secondary at top ====
test.setPosition(capabilities, PRIMARY_POSITION, 50).setPosition(capabilities, SECONDARY_POSITION, 0);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 50);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
// ==== OK !! primary at middle, secondary at middle ====
test.setPosition(capabilities, PRIMARY_POSITION, 50).setPosition(capabilities, SECONDARY_POSITION, 50);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 50);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 50);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
// ==== IMPOSSIBLE !! secondary at middle, primary above => test the constraining code ====
test.setPosition(capabilities, SECONDARY_POSITION, 0).setPosition(capabilities, PRIMARY_POSITION, 100);
test.setPosition(capabilities, SECONDARY_POSITION, 40).setPosition(capabilities, PRIMARY_POSITION, 25);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 40);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 40);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
// ==== OK !! secondary at middle, primary below ====
test.setPosition(capabilities, SECONDARY_POSITION, 0).setPosition(capabilities, PRIMARY_POSITION, 100);
test.setPosition(capabilities, SECONDARY_POSITION, 50).setPosition(capabilities, PRIMARY_POSITION, 75);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 75);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 50);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
// ==== IMPOSSIBLE !! primary at middle, secondary below => test the constraining code ====
test.setPosition(capabilities, SECONDARY_POSITION, 0).setPosition(capabilities, PRIMARY_POSITION, 100);
test.setPosition(capabilities, PRIMARY_POSITION, 60).setPosition(capabilities, SECONDARY_POSITION, 75);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 60);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 60);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
// ==== OK !! primary at middle, secondary above ====
test.setPosition(capabilities, SECONDARY_POSITION, 0).setPosition(capabilities, PRIMARY_POSITION, 100);
test.setPosition(capabilities, PRIMARY_POSITION, 60).setPosition(capabilities, SECONDARY_POSITION, 25);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 60);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 25);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
}
/**
@ -200,40 +210,46 @@ public class ShadePositionTest {
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
// front shade 50% down
test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 50);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 50);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
// front shade 100% down, back shade 0% down
test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 100);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
// front shade 100% down, back shade 0% down (ALTERNATE)
test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 0);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
// front shade 100% down, back shade 50% down
test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 50);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 50);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
// front shade 100% down, back shade 100% down
test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 100);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
}
/**
* Test parsing of DuoLite shades having both a secondary blackout shade, and tilt anywhere functionality.
* Test parsing of DuoLite shades having both a secondary blackout shade, and tilt functionality.
*
*/
@Test
@ -242,51 +258,149 @@ public class ShadePositionTest {
Capabilities capabilities = db.getCapabilities(9);
ShadePosition test;
// both shades up, tilt 0%
test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0).setPosition(capabilities,
VANE_TILT_POSITION, 0);
// front shade up
test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
// front shade 50% down, tilt 30%
test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 50).setPosition(capabilities,
VANE_TILT_POSITION, 30);
// front shade 30% down
test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 30);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 50);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 30);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 30);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
// front shade 100% down, back shade 0% down, tilt 30%
test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 100).setPosition(capabilities,
VANE_TILT_POSITION, 30);
// front shade 100% down
test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 100);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 0);
// tilt 0%
test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 0);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 0);
// tilt 30%
test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 30);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 30);
// front shade 100% down, back shade 0% down, tilt 30% (ALTERNATE)
test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 0).setPosition(capabilities,
VANE_TILT_POSITION, 30);
// tilt 100%
test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 100);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 30);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100);
// front shade 100% down, back shade 50% down, tilt 30%
test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 50).setPosition(capabilities,
VANE_TILT_POSITION, 30);
// back shade 0% down
test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 0);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 50);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 30);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100);
// front shade 100% down, back shade 100% down, tilt 70%
test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 100).setPosition(capabilities,
VANE_TILT_POSITION, 70);
// back shade 30% down
test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 30);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 30);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100);
// back shade 100% down
test = new ShadePosition().setPosition(capabilities, SECONDARY_POSITION, 100);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 70);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100);
// test constraints on impossible values: primary 30% => tilt 30%
test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 30).setPosition(capabilities,
VANE_TILT_POSITION, 30);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 0);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 30);
// test constraints on impossible values: primary 30% => tilt 30% => back shade 30% down
test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 30)
.setPosition(capabilities, VANE_TILT_POSITION, 30).setPosition(capabilities, SECONDARY_POSITION, 30);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), 30);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 100);
}
/**
* Test parsing of Capabilities 0 ShadePosition (shade fully up).
*
*/
@Test
public void testCaps0ShadePositionParsingFullyUp() {
Capabilities capabilities = db.getCapabilities(0);
ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
}
/**
* Test parsing of Capabilities 0 ShadePosition (shade fully down).
*
*/
@Test
public void testCap0ShadePositionParsingShadeFullyDown() {
Capabilities capabilities = db.getCapabilities(0);
ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 100);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
}
/**
* Helper method; test if shade State is correct.
*
* @param actual the shade State
* @param target the test value to compare with
*/
private void assertShadePosition(State actual, State target) {
assertTrue(target.equals(actual));
}
/**
* Test parsing of Type 44 ShadePosition (shade fully up).
*
*/
@Test
public void testType44ShadePositionParsingFullyUp() {
Capabilities capabilities = db.getCapabilities(44, null);
ShadePosition test = new ShadePosition().setPosition(capabilities, PRIMARY_POSITION, 0);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 0);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), UnDefType.UNDEF);
}
/**
* Test parsing of Type 44 ShadePosition (shade fully down (method 2) and vane fully open).
*
*/
@Test
public void testType44ShadePositionParsingShadeFullyDownVaneOpen() {
Capabilities capabilities = db.getCapabilities(44, null);
ShadePosition test = new ShadePosition().setPosition(capabilities, VANE_TILT_POSITION, 88);
assertNotNull(test);
assertShadePosition(test.getState(capabilities, PRIMARY_POSITION), 100);
assertShadePosition(test.getState(capabilities, SECONDARY_POSITION), UnDefType.UNDEF);
assertShadePosition(test.getState(capabilities, VANE_TILT_POSITION), 88);
}
}