@mega-yfue/eufy-sdk / DeviceEventMap
Interface: DeviceEventMap
The typed event surface, keyed by semantic event name → payload type. THE projection point for events (the sibling of DeviceActionMap): a capability that emits a new event name adds one line here. EufyMega's typed on/once/off/emit overloads are derived from this map, so eufy.on("motion", e => e.deviceSn) autocompletes the name and types the payload. Names MUST match the module emit: / decodeEvent event: strings.
Properties
alarm
alarm: PushSemanticEvent & object;Station alarm lifecycle; phase says whether it fired or is counting down.
Type Declaration
phase?
optional phase?: "triggered" | "delayed";armingModeChanged
armingModeChanged: PushSemanticEvent;The guard mode changed. Carries no mode value — re-read the current mode.
batteryAlert
batteryAlert: PushSemanticEvent & object;Battery alert — state discriminates low / hot / full.
Type Declaration
state?
optional state?: "low" | "hot" | "full";cameraEnabledChanged
cameraEnabledChanged: PushSemanticEvent;A camera's own enablement was confirmed changed, after a write this SDK issued was read back off the device. Carries no value — re-read enabled, which has converged by the time this fires.
Distinct from propertyChanged, which reports enabled moving for any reason on whichever inbound path saw it. This one says a write LANDED, which is a different fact and the only thing that can be known about a value nothing pushes.
contactState
contactState: PushSemanticEvent & PollSemanticEvent & object;Entry sensor opened/closed. Arrives via push (seconds) or cloud poll (minutes), which carry the state under different raw keys — read open, which both normalise to. Absent when the signal carried no contact value, so undefined means "not reported here", not "closed".
Type Declaration
open?
optional open?: boolean;cryingDetected
cryingDetected: PushSemanticEvent;Crying detected (indoor/baby-monitor families).
dogDetected
dogDetected: PushSemanticEvent & object;A dog was detected; kind distinguishes the licking/fouling sub-events when the device reports one.
Type Declaration
kind?
optional kind?: "lick" | "poop";doorbellPress
doorbellPress: PushSemanticEvent;Doorbell button pressed.
lockState
lockState: PushSemanticEvent;Lock (un)locked or a lock alarm fired.
motion
motion: PushSemanticEvent;Motion detected (camera / PIR sensor).
packageDelivered
packageDelivered: PushSemanticEvent;A package was delivered (drop/porch).
packageStranded
packageStranded: PushSemanticEvent;A delivered package has been left unattended too long.
packageTaken
packageTaken: PushSemanticEvent;A previously-delivered package was taken.
personDetected
personDetected: PushSemanticEvent;A recognized/known or stranger person detected.
petDetection
petDetection: PushSemanticEvent;Pet detected.
propertyChanged
propertyChanged: SemanticEventBase & PropertyChange & object;A property this device reports changed value — the generic announcement, derived from the same members table the getters are, for every readable property of every capability.
property is the name Device.getProperty takes and the one a capability getter answers, so a caller can re-read immediately; Device.describe() publishes the { accessor, property } pair, which maps the name back to the fluent accessor behind it. value is what getProperty now serves, narrowed the way the capability getter narrows it and read from the same live state rather than re-converted from the wire. It is absent where no scalar can honestly be given — a property whose stored form is a payload, or one whose stored value does not match its declared type — which means "this moved, re-read it". No wire id travels with it: several ids resolve to one property, which is the point.
Announced from the cloud poll, from a realtime report, and from the read-through cache's own background re-read, for a change with any cause — the SDK cannot tell its own write's echo from a change made in the vendor app, and suppressing on a guess would lose a real external change in exchange for one redundant re-read. Not announced on first sight of a device (that is discovery, not a transition), nor inside a write's own confirmation (already reported through that command's outcome).
Announced against a Device the caller is holding, since the value is read out of that device's own live state and the SDK holds the devices it hands out weakly.
Every readable property of every capability, with nothing filtered for being uninteresting. So a sensor's own check-in timestamp is announced too, even though the deviceState event already carries that fact.
Latency is the inbound path's: seconds for a property a device reports over realtime. For one that only ever arrives as a cloud param — which is most of them — it is whichever comes first of the poll (EufyMegaOptions.pollMs, EufyMega.setPollInterval) and the cache's re-read (EufyMegaOptions.cacheTtlMs), both the caller's to choose.
Type Declaration
deviceSn
deviceSn: string;ptzNotify
ptzNotify: SemanticEventBase & object;Pan/tilt status streamed while the camera moves.
Type Declaration
coords?
optional coords?: [number, number][];kind
kind: "rotate" | "zoom" | "position";payload?
optional payload?: unknown;smartLightState
smartLightState: SemanticEventBase & object;A eufy_life smart light reported its state (secure-MQTT DP status report). Every field is optional: a report carries only the fields the device sent, and an absent one is silence about that field rather than a change to it.
Type Declaration
brightness?
optional brightness?: number;cloudEffectId?
optional cloudEffectId?: number;colorGradient?
optional colorGradient?: boolean;effectId?
optional effectId?: number;lightLength?
optional lightLength?: number;power?
optional power?: boolean;soundDetected
soundDetected: PushSemanticEvent;Sound above the configured threshold.
strangerDetected
strangerDetected: PushSemanticEvent;A person the device does NOT recognise (distinct from personDetected).
vehicleDetected
vehicleDetected: PushSemanticEvent;A vehicle was detected.