Class TraitConstraint

java.lang.Object
com.codename1.home.TraitConstraint

public final class TraitConstraint extends Object

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.

  • 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: the trait this describes

      • readable: whether the accessory will answer a read

      • writable: whether the accessory will accept a write

      • notifies: 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: the trait this describes

      • readable: whether the accessory will answer a read

      • writable: whether the accessory will accept a write

      • notifies: whether the accessory pushes changes

      • minimum: the smallest accepted value, in Trait.getUnit()

      • maximum: the largest accepted value, in Trait.getUnit()

      • step: 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: the trait this describes

      • readable: whether the accessory will answer a read

      • writable: whether the accessory will accept a write

      • notifies: whether the accessory pushes changes

      • validOrdinals: 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: 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()
      Description copied from class: Object
      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())
      Overrides:
      toString in class Object