public final class TraitConstraint
- Object
- TraitConstraint
What one particular accessory will actually accept for one particular
Trait: whether it can be read or written, the range it works over, the
step it moves in, and for an enum trait, which constants it can produce.
Trait documents the nominal range – brightness is a percentage, so it
is 0 to 100. This carries the real one, from HomeKit’s
HMCharacteristicMetadata or the Matter attribute’s own min and max
attributes. A dimmer whose floor is 10 percent and that steps in fives says
so here, and a slider built from these numbers will not offer the user a
value the accessory is going to reject.
Writes are refused, not clamped
A write outside getMinimum() to getMaximum() fails with
HomeError.VALUE_OUT_OF_RANGE. Clamping was the obvious alternative and it
is worse: an app that asked for 40 degrees and silently got 38 never learns
it was wrong, so the bug reaches the user as a thermostat that “does not go
high enough” rather than as a failure at the call site where it can be
fixed.
Methods
Inherited methods
Method details
of
public static TraitConstraint of(Trait trait, boolean readable, boolean writable, boolean notifies)Parameters
traitTrait- the trait this describes
readableboolean- whether the accessory will answer a read
writableboolean- whether the accessory will accept a write
notifiesboolean- whether the accessory pushes changes, so a subscription on it can do better than polling
Returns
Throws
IllegalArgumentException- when
traitisnull
ranged
public static TraitConstraint ranged(Trait trait, boolean readable, boolean writable, boolean notifies, double minimum, double maximum, double step)Parameters
traitTrait- the trait this describes
readableboolean- whether the accessory will answer a read
writableboolean- whether the accessory will accept a write
notifiesboolean- whether the accessory pushes changes
minimumdouble- the smallest accepted value, in
Trait.getUnit() maximumdouble- the largest accepted value, in
Trait.getUnit() stepdouble- the increment the accessory moves in, or zero when it did not say
Returns
Throws
IllegalArgumentException- when
traitisnull, ormaximumis belowminimum
choices
public static TraitConstraint choices(Trait trait, boolean readable, boolean writable, boolean notifies, int[] validOrdinals)Parameters
traitTrait- the trait this describes
readableboolean- whether the accessory will answer a read
writableboolean- whether the accessory will accept a write
notifiesboolean- whether the accessory pushes changes
validOrdinalsint[]- the ordinals of the constants this accessory can
produce or accept, in the domain enum for this trait;
nullor empty means it did not say, which is not the same as “none”
Returns
Throws
IllegalArgumentException- when
traitisnull
getTrait
public Trait getTrait()Returns
nullisReadable
public boolean isReadable()Returns
true when the trait is readable hereisWritable
public boolean isWritable()Whether this accessory will accept a write of this trait.
Narrower than Trait.isReadOnly(), which says whether writing the
trait could ever mean anything at all. A writable trait can still be
read-only on a particular accessory – a thermostat you have been given
view-only access to, a covering with its motor disabled.
Returns
true when the trait is writable herenotifiesOnChange
public boolean notifiesOnChange()Whether this accessory pushes changes to this trait.
Where this is false, a subscription still works but has nothing
better than polling behind it, so changes arrive late or only when you
call SmartHome.drainChanges(). Independent of
TraitSubscription.isPushDelivery(), which is about whether the
platform can deliver at all; this is about whether the accessory
bothers to say.
Returns
true when the accessory reports changes on its ownhasRange
public boolean hasRange()Returns
true when the accessory declared a rangegetMinimum
public double getMinimum()Trait.getUnit().Returns
hasRange() is falsegetMaximum
public double getMaximum()Trait.getUnit().Returns
hasRange() is falsegetStep
public double getStep()The increment this accessory moves in, in Trait.getUnit().
Zero means it did not say, which is not the same as continuous – treat it as unknown rather than as a step of nothing.
Returns
getValidOrdinals
public List<Integer> getValidOrdinals()The ordinals of the domain-enum constants this accessory can produce or accept.
An empty list means the accessory did not say, not that it accepts nothing. Most do not say.
Returns
accepts
public boolean accepts(TraitValue value)Whether a value falls inside what this accessory will accept.
Checks the range for a numeric trait and the ordinal list for an enum
one, and answers true for anything the accessory did not constrain –
this is what the write path tests, and refusing values on the strength
of information an accessory never gave would fail writes that work.
The step is deliberately not enforced. Accessories declare steps they then round to happily, and refusing 33 percent on a dimmer that declares fives would reject a value the hardware accepts.
Parameters
valueTraitValue- the value to test, or
null
Returns
true when the value is acceptable, or when the accessory declared no
constraint to test it against; false for a null value or one whose
kind does not match the traittoString
public String toString()