Skip to content

@mega-yfue/eufy-sdk / PropertySpec

Interface: PropertySpec

A single device property, mapped to its P2P param_type. This is pure data — the same spec is reused across every device whose capability contributes it.

Properties

decode?

ts
optional decode?: (raw) => string | number | boolean;

Custom decode for a value the wire delivers as a code the app reinterprets — a bitfield/enum that means something other than its face value. Given the raw param value, returns the decoded property value. When present it REPLACES the default type-coercion (and invert). Example: the battery charging flag is derived from the reported charge status, matching the app's own Hermes decode — see capabilities/battery.ts.

Parameters

raw

string | number | boolean

Returns

string | number | boolean


description?

ts
optional description?: string;

Short description for docs / discovery.


enumValues?

ts
optional enumValues?: Record<number, string>;

Allowed values for type: "enum" (raw → label).


invert?

ts
optional invert?: boolean;

Wire polarity for a bool property whose param is a disable flag: when true, a raw 0/false means the property is TRUE (e.g. a camera's enabled — the flag is the disable bit, so "0" ⇒ enabled). Ignored for non-bool types.


kind?

ts
optional kind?: ValueKind;

What the value means (ValueKind) — the machine-readable half of unit.

Absent when the stored value carries no scalar meaning of its own: a structured payload whose semantic value is a field inside it declares the kind on the member that decodes it instead, since that is where the meaning becomes true.


name

ts
name: string;

Stable, code-facing name (e.g. "battery", "light", "motionDetection").


paramType

ts
paramType: number;

The eufy P2P param_type carrying this value (the wire id).


provenance?

ts
optional provenance?: PropertySource;

Trust level of this paramType mapping. Default (absent) = guessed. Anything still guessed is a candidate for confirmation against a first-party source, never relied on.


raw?

ts
optional raw?: true;

This param carries a STRUCTURED PAYLOAD rather than a scalar — a base64 protobuf that the capability's own getter reads a field out of, with the injected codec in scope.

The stored value is that payload verbatim, and type describes what the getter ANSWERS rather than what arrives on the wire. Those are different for every Raw DP on the clean line: nine consumable counters are "number" over one base64 string, and reading the value as a number is exactly what must NOT happen at ingest.

Storage already keeps such a value intact — a non-numeric string cannot be coerced to a number, so it is passed through. What this flag changes is that the pass-through stops being reported as a mistake: a robot reporting ten Raw DPs on every push logged ten warnings a time saying its properties were misdeclared, which is how a real warning goes unread.


readAliases?

ts
optional readAliases?: readonly object[];

Extra wire param ids that ALSO carry this property on some device families, with their own polarity. The device's own paramType wins; otherwise the first alias the device reports wins. Lets one property (e.g. enabled) read correctly across families that report it under different ids (a battery camera and a standalone one disagree) — the family variance lives in the capability spec, not in per-device branches.


type

ts
type: PropertyValueType;

unit?

ts
optional unit?: string;

Human unit, when meaningful (e.g. "%", "°C", "dBm").


writable

ts
writable: boolean;

Whether the value can be written back to the device (a setter exists).

Independent and unofficial. Not affiliated with, endorsed by, or sponsored by Anker Innovations, Anker eufy, or eufy. "Anker eufy", "eufy" and "Anker" are trademarks of their respective owners. Use responsibly — rapid or failed logins can trigger captcha or temporary cooldowns.