public final class TraitConstraint

  1. Object
  2. 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

public static TraitConstraint of(Trait trait, boolean readable, boolean writable, boolean notifies)A constraint for a trait whose accessory declared no range – a boolean, or a numeric trait the platform did not describe.
public static TraitConstraint ranged(Trait trait, boolean readable, boolean writable, boolean notifies, double minimum, double maximum, double step)A constraint for a numeric trait whose accessory declared its range.
public static TraitConstraint choices(Trait trait, boolean readable, boolean writable, boolean notifies, int[] validOrdinals)A constraint for an enum trait whose accessory declared which values it can produce.
public Trait getTrait()The trait this describes.
public boolean isReadable()Whether this accessory will answer a read of this trait.
public boolean isWritable()Whether this accessory will accept a write of this trait.
public boolean notifiesOnChange()Whether this accessory pushes changes to this trait.
public boolean hasRange()Whether getMinimum(), getMaximum() and getStep() mean anything.
public double getMinimum()The smallest value this accessory accepts, in Trait.getUnit().
public double getMaximum()The largest value this accessory accepts, in Trait.getUnit().
public double getStep()The increment this accessory moves in, in Trait.getUnit().
public List<Integer> getValidOrdinals()The ordinals of the domain-enum constants this accessory can produce or accept.
public boolean accepts(TraitValue value)Whether a value falls inside what this accessory will accept.
public String toString()Returns a string representation of the object.

Inherited methods

Method details

of

public static TraitConstraint of(Trait trait, boolean readable, boolean writable, boolean notifies)
A constraint for a trait whose accessory declared no range – a boolean, or a numeric trait the platform did not describe.

Parameters

trait Trait
the trait this describes
readable boolean
whether the accessory will answer a read
writable boolean
whether the accessory will accept a write
notifies boolean
whether the accessory pushes changes, so a subscription on it can do better than polling

Returns

the constraint

Throws

IllegalArgumentException
when trait is null

ranged

public static TraitConstraint ranged(Trait trait, boolean readable, boolean writable, boolean notifies, double minimum, double maximum, double step)
A constraint for a numeric trait whose accessory declared its range.

Parameters

trait Trait
the trait this describes
readable boolean
whether the accessory will answer a read
writable boolean
whether the accessory will accept a write
notifies boolean
whether the accessory pushes changes
minimum double
the smallest accepted value, in Trait.getUnit()
maximum double
the largest accepted value, in Trait.getUnit()
step double
the increment the accessory moves in, or zero when it did not say

Returns

the constraint

Throws

IllegalArgumentException
when trait is null, or maximum is below minimum

choices

public static TraitConstraint choices(Trait trait, boolean readable, boolean writable, boolean notifies, int[] validOrdinals)
A constraint for an enum trait whose accessory declared which values it can produce.

Parameters

trait Trait
the trait this describes
readable boolean
whether the accessory will answer a read
writable boolean
whether the accessory will accept a write
notifies boolean
whether the accessory pushes changes
validOrdinals int[]
the ordinals of the constants this accessory can produce or accept, in the domain enum for this trait; null or empty means it did not say, which is not the same as “none”

Returns

the constraint

Throws

IllegalArgumentException
when trait is null

getTrait

public Trait getTrait()
The trait this describes.

Returns

the trait, never null

isReadable

public boolean isReadable()
Whether this accessory will answer a read of this trait.

Returns

true when the trait is readable here

isWritable

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 here

notifiesOnChange

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 own

hasRange

public boolean hasRange()
Whether getMinimum(), getMaximum() and getStep() mean anything.

Returns

true when the accessory declared a range

getMinimum

public double getMinimum()
The smallest value this accessory accepts, in Trait.getUnit().

Returns

the minimum, or zero when hasRange() is false

getMaximum

public double getMaximum()
The largest value this accessory accepts, in Trait.getUnit().

Returns

the maximum, or zero when hasRange() is false

getStep

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

the step, or zero

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

an immutable list of ordinals, possibly empty

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

value TraitValue
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 trait

toString

public String toString()
Returns a string representation of the object. In general, the toString method returns a string that “textually represents” this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method. The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@’, and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of: getClass().getName() + ‘@’ + Integer.toHexString(hashCode())