Enum TraitUnit
- All Implemented Interfaces:
Comparable<TraitUnit>
A unit of measure for a Trait value.
Conversion is affine, with one honest exception
canonical = value * scale + offset, the same model
com.codename1.health.HealthUnit uses, because temperature needs the
offset. Converting between units of different
TraitUnitDimensions throws IllegalArgumentException: that is a bug in
the calling code, not a condition to report through an AsyncResource.
Mireds and Kelvin are reciprocal, not affine, so Kelvin is deliberately
not a constant here -- it cannot be expressed in the table, and forcing it
in would produce a colour temperature that is silently wrong rather than
obviously wrong. Use miredToKelvin(double) and
kelvinToMired(double), or TraitValue.getColorTemperatureKelvin(),
which are named so that stepping outside the conversion table is a visible
act.
And the trap that catches everyone once: a higher mired value is a warmer light, because mireds are the reciprocal of Kelvin. 153 mireds is a cold blue-white; 400 is candlelight.
Why this is an enum where HealthUnit is a class
HealthUnit is an interned final class because its symbol is the wire
format Apple's HKUnit(from:) parses, and because the set grows with the
data types. Neither is true here: the set is small, closed and defined by
what the two backends can actually express, and nothing about a home
accessory will need a unit that is not already on this list. An enum gets
switch and exhaustive reasoning for free.
The one thing an enum does not get for free is a stable wire form --
ordinal() shifts the moment a constant is inserted in the middle -- so
each carries an explicit getWireId() and forWireId(int) resolves it.
-
Enum Constant Summary
Enum ConstantsEnum ConstantDescriptionDegrees of arc, 0 to 360.Degrees Celsius.Degrees Fahrenheit.Lux.Micrograms per cubic metre.Mireds -- micro reciprocal degrees, the reciprocal of colour temperature in Kelvin scaled by a million.No unit: an ordinal, a count, a plain number.Percent, 0 to 100.Parts per billion.Parts per million. -
Method Summary
Modifier and TypeMethodDescriptionstatic doubleConverts a value between two units of the same dimension.static TraitUnitforWireId(int wireId) Resolves a unit by its wire identifier, total: an unrecognized id answersnullrather than throwing, so a value from a newer port degrades to "no value" instead of taking down the decode.What this unit measures.intThe stable identifier this unit crosses the native boundary as.booleanisCompatibleWith(TraitUnit other) Whether a value in this unit can be converted into the supplied one.static doublekelvinToMired(double kelvin) Converts Kelvin to mireds.static doublemiredToKelvin(double mireds) Converts mireds to Kelvin.static TraitUnitReturns the enum constant of this type with the specified name.static TraitUnit[]values()Returns an array containing the constants of this enum type, in the order they are declared.Methods inherited from class Enum
clone, compareTo, equals, getDeclaringClass, getEnumValues, hashCode, name, ordinal, setEnumValues, toString, valueOf
-
Enum Constant Details
-
NONE
No unit: an ordinal, a count, a plain number. The canonical unit ofTraitUnitDimension.DIMENSIONLESS. -
PERCENT
Percent, 0 to 100. The canonical unit of
TraitUnitDimension.RATIO, and the unit of every proportion in this API -- brightness, saturation, covering position, fan speed, battery level, humidity.Both backends carry these as scaled integers with different scales (Matter's level control is 0 to 254, its covering position is 0 to 10000, its battery percentage is in halves) and every one of those conversions happens inside the port. Application code sees percent.
-
CELSIUS
Degrees Celsius. The canonical unit ofTraitUnitDimension.TEMPERATURE. -
FAHRENHEIT
Degrees Fahrenheit. -
ARC_DEGREE
Degrees of arc, 0 to 360. The canonical unit ofTraitUnitDimension.ANGLE, used for colour hue. -
MIRED
Mireds -- micro reciprocal degrees, the reciprocal of colour temperature in Kelvin scaled by a million. The canonical unit of
TraitUnitDimension.COLOR_TEMPERATURE.Chosen over Kelvin because it is what both platforms use natively: HomeKit's
HMCharacteristicTypeColorTemperatureis in mireds and Matter'sColorTemperatureMiredsis in mireds. Making Kelvin canonical would mean a reciprocal on every read and every write, in both ports, for no gain. -
LUX
Lux. The canonical unit ofTraitUnitDimension.ILLUMINANCE. -
PPM
Parts per million. The canonical unit ofTraitUnitDimension.CONCENTRATION_PARTS. -
PPB
Parts per billion. -
MICROGRAM_PER_CUBIC_METER
Micrograms per cubic metre. The canonical unit ofTraitUnitDimension.CONCENTRATION_MASS, used for particulate matter.
-
-
Method Details
-
values
Returns an array containing the constants of this enum type, in the order they are declared.- Returns:
- an array containing the constants of this enum type, in the order they are declared
-
valueOf
Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)- Parameters:
name- the name of the enum constant to be returned.- Returns:
- the enum constant with the specified name
- Throws:
IllegalArgumentException- if this enum type has no constant with the specified nameNullPointerException- if the argument is null
-
getWireId
public int getWireId()The stable identifier this unit crosses the native boundary as.
Fixed per constant and never reused, so inserting a unit into the middle of this list cannot silently re-label values a port already sends.
Returns
the wire identifier
-
getDimension
What this unit measures.
Returns
the dimension, never
null -
isCompatibleWith
Whether a value in this unit can be converted into the supplied one.
Parameters
other: the target unit, ornull
Returns
truewhen both measure the same dimension -
convert
Converts a value between two units of the same dimension.
Parameters
-
value: the quantity to convert -
from: the unitvalueis expressed in -
to: the unit to express it in
Returns
the converted quantity
Throws
IllegalArgumentException: when either unit isnullor they measure different dimensions
-
-
forWireId
Resolves a unit by its wire identifier, total: an unrecognized id answers
nullrather than throwing, so a value from a newer port degrades to "no value" instead of taking down the decode.Parameters
wireId: an identifier previously returned bygetWireId()
Returns
the matching unit, or
null -
miredToKelvin
public static double miredToKelvin(double mireds) Converts mireds to Kelvin.
Outside the
convert(double, TraitUnit, TraitUnit)table on purpose: the relationship is reciprocal, and an affine table that pretended otherwise would return a plausible number that is wrong everywhere except at one point.Parameters
mireds: a colour temperature in mireds; must be greater than zero
Returns
the same colour temperature in Kelvin
Throws
IllegalArgumentException: whenmiredsis zero, negative or not a number
-
kelvinToMired
public static double kelvinToMired(double kelvin) Converts Kelvin to mireds. See
miredToKelvin(double)for why this is a named method rather than a table entry.Parameters
kelvin: a colour temperature in Kelvin; must be greater than zero
Returns
the same colour temperature in mireds
Throws
IllegalArgumentException: whenkelvinis zero, negative or not a number
-