eufy-mega / model/device / Device
Class: Device
A eufy device: one class, capability-driven. Construct from a resolved record (or a raw CloudRecord via Device.fromRecord), then feed it param updates.
Extends
Constructors
Constructor
new Device(
sn,
resolved,
logger?): Device;Parameters
sn
string
resolved
ResolvedDevice
logger?
Logger = noopLogger
Returns
Device
Properties
arming?
optional arming?: () =>
| ArmingActions
| undefined;Guard mode: setMode(ArmingMode) + setAlarmDelayConfig(mode, config). Of the 8 ArmingMode values only away/home/disarmed are confirmed on-device.
Returns
| ArmingActions | undefined
audio?
optional audio?: () =>
| AudioActions
| undefined;Audio/volume (family-gated): mic, speaker + volume, in-video recording, doorbell ringtone, HomeBase alarm/prompt.
Returns
| AudioActions | undefined
battery?
optional battery?: () =>
| BatteryActions
| undefined;Battery/power: power source, working mode, and the custom-mode clip/interval/auto-stop settings.
Returns
| BatteryActions | undefined
camera?
optional camera?: () =>
| CameraActions
| undefined;Camera: on/off, privacy, status LED; snapshot/live/record when bound to a live client.
Returns
| CameraActions | undefined
capabilities
capabilities: readonly Capability[];Resolved capability set. Widens if the device later reports evidence for more.
co?
optional co?: () => CoActions | undefined;CO-detector reads (read-only): coDetected, lastSeen.
Returns
CoActions | undefined
codec
codec: Codec;Resolved command-codec family.
contact?
optional contact?: () =>
| ContactActions
| undefined;Entry (door/window) sensor reads (read-only): open, lastSeen, rssi.
Returns
| ContactActions | undefined
doorbell?
optional doorbell?: () =>
| DoorbellActions
| undefined;Doorbell: playQuickResponse(voiceId) (the canned voice replies).
Returns
| DoorbellActions | undefined
fanSpeed?
optional fanSpeed?: () =>
| FanSpeedActions
| undefined;RoboVac fan-speed reads (read-only): fanSpeed, boostIq.
Returns
| FanSpeedActions | undefined
info?
optional info?: () => DeviceInfo | undefined;Identity metadata (read-only): { manufacturer, model, serialNumber, name, deviceType?, firmwareVersion?, hardwareVersion? } for a host's device registry / device-info surface.
Returns
DeviceInfo | undefined
keypad?
optional keypad?: () =>
| KeypadActions
| undefined;Security-keypad reads (read-only): rssi.
Returns
| KeypadActions | undefined
leak?
optional leak?: () =>
| LeakActions
| undefined;Water-leak / freeze sensor reads (read-only): leakDetected, lastSeen.
Returns
| LeakActions | undefined
light?
optional light?: () =>
| LightActions
| undefined;Floodlight/spotlight: on/off/set, setBrightness/setColorTemp/setEnabled, setAutoSpotlight.
Returns
| LightActions | undefined
lock?
optional lock?: () =>
| LockActions
| undefined;Smart lock: lock()/unlock() + verified setRainMode/setAutoLock. The 6 source-confirmed-but-uncaptured setting toggles are ABSENT until captured (present method ⇒ wire verified).
Returns
| LockActions | undefined
motion?
optional motion?: () =>
| MotionActions
| undefined;Motion/PIR: setDetection(on) (sensitivity is read-only until its write wire is captured).
Returns
| MotionActions | undefined
name
name: string;Display name.
personDetection?
optional personDetection?: () =>
| PersonDetectionActions
| undefined;Person-detection reads (read-only): detectionEnabled, detected.
Returns
| PersonDetectionActions | undefined
properties
properties: readonly PropertySpec[];Merged property schema (one entry per known property this device exposes).
ptz?
optional ptz?: () =>
| PtzActions
| undefined;Pan/tilt/zoom control: rotate(dir, step) + left/right/up/down, zoom, preset() namespace (goto/preview/save/setDefault/delete/list/image).
Returns
| PtzActions | undefined
siren?
optional siren?: () =>
| SirenActions
| undefined;Siren: read-only on mega (active). The switch wire is unverified, so on()/off() are absent until confirmed on-device (present method ⇒ wire verified).
Returns
| SirenActions | undefined
smartLight?
optional smartLight?: () =>
| SmartLightActions
| undefined;eufy_life smart light (T8L0x): on/off, setBrightness, setEffect(lightId).
Returns
| SmartLightActions | undefined
smoke?
optional smoke?: () =>
| SmokeActions
| undefined;Smoke-detector reads (read-only): smokeDetected, lastSeen.
Returns
| SmokeActions | undefined
sn
readonly sn: string;Serial number (station/device SN).
source
source: "category" | "model" | "inferred";Which resolver tier produced the codec/caps.
storage?
optional storage?: () =>
| StorageActions
| undefined;Local-storage reads (read-only): sdCard, free, total.
Returns
| StorageActions | undefined
vacuumClean?
optional vacuumClean?: () =>
| VacuumCleanActions
| undefined;RoboVac core reads (read-only): power, activity (WorkStatus), volume, battery.
Returns
| VacuumCleanActions | undefined
Methods
applyParams()
applyParams(params, ts?): string[];Apply a raw param map (cloud record or P2P notification). Known params update their named property; unrecognised params are retained as unknown_<paramType> so nothing is lost.
Parameters
params
param_type → raw value.
ts?
number = ...
observation time (epoch ms); defaults to Date.now().
Returns
string[]
the list of property names whose value changed.
bindActions()
bindActions(
ctx,
sink,
media?,
lockSettings?): void;Wire this device to a CommandSink so its semantic action objects become live (device.light?.on()). ctx carries the evidence a capability uses to resolve the right command variant. Called by EufyMega.getDevice; a raw model object left unbound simply has no action objects (all accessors return undefined). lockSettings is a deliberate, capability-named exception to this layer's usual capability-neutrality — see CapabilityModule.actions's doc before threading a second one. The final buildActions arg is the live-state reader backing the capabilities' typed read getters (dev.battery()?.level): it closes over this.getProperty, so a getter built once here stays current as realtime/poll updates land in this.state.
Parameters
ctx
sink
media?
lockSettings?
Returns
void
getProperties()
getProperties(): Record<string, PropertyValue>;Snapshot of all current property values (named + unknown passthrough) — the untyped bulk read, for diagnostics / discovery. Prefer the typed fluent capability getters (dev.battery()?.level, …) for reading a specific known property; this loose map is for dumping everything (e.g. the CLI / device inspector), not per-property access. Under a freshness policy, schedules a background refresh when the OLDEST observed value is stale (one fetch covers every param) and returns the current snapshot immediately.
Returns
Record<string, PropertyValue>
getProperty()
getProperty(name): PropertyValue | undefined;Low-level property read by name — the untyped escape hatch. Prefer the typed fluent capability getters (dev.battery()?.level, dev.contact()?.open) where the property is exposed by a capability: they return the value already narrowed to its declared type instead of the loose PropertyValue.value (boolean|number|string|object) you get here. Use this only for an unbound model object (no live client → no dev.<cap>()) or a param not yet surfaced on a capability. Returns undefined if never observed.
Parameters
name
string
Returns
PropertyValue | undefined
has()
has(cap): boolean;Does this device have the given capability?
Parameters
cap
Capability
Returns
boolean
hasProperty()
hasProperty(name): boolean;Is the given property name part of this device's schema?
Parameters
name
string
Returns
boolean
reresolve()
reresolve(rec): Capability[];Re-resolve against a fresher record and adopt the result if the capability set grew.
A capability is granted on evidence the device reports, so a device that hadn't reported a param when it was first resolved lacks the capability that param proves — and would keep lacking it for the object's whole lifetime, even as the value itself started arriving. Re-resolving on fresh evidence closes that: the accessor appears, already bound if the device is bound.
Only ever widens. A param the device stops reporting does not retract a capability, because the cloud record is a snapshot that can lose a field for reasons that have nothing to do with the hardware, and revoking an accessor a caller already holds is worse than keeping a quiet one.
Returns the capabilities gained, empty when nothing changed — so a caller can skip re-binding.
Parameters
rec
CloudRecord
Returns
Capability[]
setFreshnessPolicy()
setFreshnessPolicy(policy): void;Wire a read-through freshness policy. When a cached property is older than staleAfterMs, a getProperty/getProperties read schedules ONE coalesced background refresh() (the facade supplies it, choosing the cheapest live transport) and returns the last-known value immediately — reads never block. Push / P2P realtime updates refresh ts themselves via applyParams, so a device kept fresh by realtime never re-fetches (a fresh entry is never stale). Keeps model/ transport-free: the device only calls the injected callback.
Parameters
policy
refresh
() => Promise<void>
staleAfterMs
number
Returns
void
toJSON()
toJSON(): Record<string, unknown>;Plain-object view, handy for the CLI / discovery / debugging.
Returns
Record<string, unknown>
fromRecord()
static fromRecord(
sn,
rec,
logger?): Device;Build a Device from a raw cloud record (runs the 3-tier resolver).
Parameters
sn
string
rec
CloudRecord
logger?
Logger = noopLogger
Returns
Device