Skip to content

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

ts
new Device(
   sn, 
   resolved, 
   logger?): Device;

Parameters

sn

string

resolved

ResolvedDevice

logger?

Logger = noopLogger

Returns

Device

Properties

arming?

ts
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?

ts
optional audio?: () => 
  | AudioActions
  | undefined;

Audio/volume (family-gated): mic, speaker + volume, in-video recording, doorbell ringtone, HomeBase alarm/prompt.

Returns

| AudioActions | undefined


battery?

ts
optional battery?: () => 
  | BatteryActions
  | undefined;

Battery/power: power source, working mode, and the custom-mode clip/interval/auto-stop settings.

Returns

| BatteryActions | undefined


camera?

ts
optional camera?: () => 
  | CameraActions
  | undefined;

Camera: on/off, privacy, status LED; snapshot/live/record when bound to a live client.

Returns

| CameraActions | undefined


capabilities

ts
capabilities: readonly Capability[];

Resolved capability set. Widens if the device later reports evidence for more.


co?

ts
optional co?: () => CoActions | undefined;

CO-detector reads (read-only): coDetected, lastSeen.

Returns

CoActions | undefined


codec

ts
codec: Codec;

Resolved command-codec family.


contact?

ts
optional contact?: () => 
  | ContactActions
  | undefined;

Entry (door/window) sensor reads (read-only): open, lastSeen, rssi.

Returns

| ContactActions | undefined


doorbell?

ts
optional doorbell?: () => 
  | DoorbellActions
  | undefined;

Doorbell: playQuickResponse(voiceId) (the canned voice replies).

Returns

| DoorbellActions | undefined


fanSpeed?

ts
optional fanSpeed?: () => 
  | FanSpeedActions
  | undefined;

RoboVac fan-speed reads (read-only): fanSpeed, boostIq.

Returns

| FanSpeedActions | undefined


info?

ts
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?

ts
optional keypad?: () => 
  | KeypadActions
  | undefined;

Security-keypad reads (read-only): rssi.

Returns

| KeypadActions | undefined


leak?

ts
optional leak?: () => 
  | LeakActions
  | undefined;

Water-leak / freeze sensor reads (read-only): leakDetected, lastSeen.

Returns

| LeakActions | undefined


light?

ts
optional light?: () => 
  | LightActions
  | undefined;

Floodlight/spotlight: on/off/set, setBrightness/setColorTemp/setEnabled, setAutoSpotlight.

Returns

| LightActions | undefined


lock?

ts
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?

ts
optional motion?: () => 
  | MotionActions
  | undefined;

Motion/PIR: setDetection(on) (sensitivity is read-only until its write wire is captured).

Returns

| MotionActions | undefined


name

ts
name: string;

Display name.


personDetection?

ts
optional personDetection?: () => 
  | PersonDetectionActions
  | undefined;

Person-detection reads (read-only): detectionEnabled, detected.

Returns

| PersonDetectionActions | undefined


properties

ts
properties: readonly PropertySpec[];

Merged property schema (one entry per known property this device exposes).


ptz?

ts
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?

ts
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?

ts
optional smartLight?: () => 
  | SmartLightActions
  | undefined;

eufy_life smart light (T8L0x): on/off, setBrightness, setEffect(lightId).

Returns

| SmartLightActions | undefined


smoke?

ts
optional smoke?: () => 
  | SmokeActions
  | undefined;

Smoke-detector reads (read-only): smokeDetected, lastSeen.

Returns

| SmokeActions | undefined


sn

ts
readonly sn: string;

Serial number (station/device SN).


source

ts
source: "category" | "model" | "inferred";

Which resolver tier produced the codec/caps.


storage?

ts
optional storage?: () => 
  | StorageActions
  | undefined;

Local-storage reads (read-only): sdCard, free, total.

Returns

| StorageActions | undefined


vacuumClean?

ts
optional vacuumClean?: () => 
  | VacuumCleanActions
  | undefined;

RoboVac core reads (read-only): power, activity (WorkStatus), volume, battery.

Returns

| VacuumCleanActions | undefined

Methods

applyParams()

ts
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

RawParams

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()

ts
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

CommandContext

sink

CommandSink

media?

MediaProvider

lockSettings?

LockSettingsReader

Returns

void


getProperties()

ts
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()

ts
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()

ts
has(cap): boolean;

Does this device have the given capability?

Parameters

cap

Capability

Returns

boolean


hasProperty()

ts
hasProperty(name): boolean;

Is the given property name part of this device's schema?

Parameters

name

string

Returns

boolean


reresolve()

ts
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()

ts
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()

ts
toJSON(): Record<string, unknown>;

Plain-object view, handy for the CLI / discovery / debugging.

Returns

Record<string, unknown>


fromRecord()

ts
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

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