@mega-yfue/eufy-sdk / KNOWN_VALUE_KINDS
Variable: KNOWN_VALUE_KINDS
ts
const KNOWN_VALUE_KINDS: readonly ["boolean", "percent", "celsius", "dbm", "seconds", "hours", "megabytes", "degrees", "scalar", "bitfield", "enum", "identifier", "timestamp", "text"];What a value MEANS, as opposed to how it is stored — the semantic annotation that makes a reading convertible without a hardcoded table per property.
PropertyValueType says a value is a number; this says whether that number is a battery percentage, a temperature, a signal strength, a duration or an instant. The distinction is not cosmetic: a seconds duration and a timestamp instant are both numbers of seconds, and treating one as the other is wrong in a way no type check catches.
boolean— an on/off state (always paired withtype: "bool").percent/celsius/dbm/seconds/hours/megabytes/degrees— a measured quantity in the unit the device reports it in; each pairs with the matchingunit. Values are never converted on the way out — a converted reading is an invented one.secondsandhoursare separate kinds for exactly that reason: a robot reports a run in seconds and a consumable's wear in hours, and normalising one into the other would publish a number the device never sent.scalar— a plain number in no unit at all: a step on a ladder, a mode index, a raw level, a segment count. Ordered and comparable, but its range and direction are the device's, so nothing but the device says what a given value means.bitfield— a number whose individual bits carry the meaning, not its magnitude.enum— one of a named set; the set is the property'senumValues(raw → label) or, for a value a read decodes, the read's ownvalues.identifier— an opaque id whose domain lives elsewhere (a cloud-fetched list), so it is not ordered and not arithmetic.timestamp— an instant, unix seconds.text— free-form or structured text with no further promise.
Three pairs are close enough to pick wrongly, so the test for each:
scalarvs a measured quantity — is there a unit the device reports it in? A sensitivity step, a mode index and a segment count are allscalarprecisely because there is none; they are NOT counts of anything, and the name says only "a bare number". A quantity with a unit takes the kind naming that unit, and the two are checked against each other in both directions.identifiervsenum— can we publish the set? Anenumships its options with it, so its label needs nothing else. Anidentifieris a number whose domain is held somewhere we do not control (a catalogue the app fetches), so there is no set to ship and arithmetic on it — ordering, nearest-value, a range — is meaningless.bitfieldvsenum— one value, or several at once? A bitfield's bits combine, so it has no single label and its magnitude means nothing. The named bits belong to the capability that decodes them and are exported beside that decoder; unlike an enum's options they are not carried here, which is a gap this vocabulary does not close on its own.