@mega-yfue/eufy-sdk / EufyMegaOptions
Interface: EufyMegaOptions
Properties
appName?
optional appName?: string;Inherited from
MegaClientConfig.appNameappVersion?
optional appVersion?: string;Inherited from
MegaClientConfig.appVersionautoRealtime?
optional autoRealtime?: boolean;Auto-manage connectivity (default true). When on, a successful EufyMega.login brings up the always-on event channels itself — FCM push + secure MQTT (if the account has appliances) — and eagerly warms P2P only for wired stations (HomeBases / mains cameras). Battery cameras stay detached until a command / stream — or a pre-warm the caller opted into via EufyMegaOptions.prewarmEvents — needs them, and idle-detach afterwards. The host calls no connect* — connectivity is transport-agnostic. Set false to manage nothing automatically (advanced/testing).
cacheTtlMs?
optional cacheTtlMs?: number;Read-through cache freshness window in ms (default 15000). A getProperty/getProperties read of a value older than this schedules ONE coalesced background refresh and returns the last-known value immediately; realtime (push/P2P) updates keep values fresh so a live device rarely refetches.
countryCode?
optional countryCode?: string;Two-letter account country code (e.g. "GB", "US", "DE"). Routes the region.
Inherited from
MegaClientConfig.countryCodeemail
email: string;Inherited from
MegaClientConfig.emailffmpegLogLevel?
optional ffmpegLogLevel?:
| "debug"
| "info"
| "error"
| "quiet"
| "panic"
| "fatal"
| "warning"
| "verbose"
| "trace";ffmpeg's own -loglevel for the media paths that shell out to it (live snapshot / record). Default "error" (quiet). A raised level (e.g. "trace") reports a failing decode/mux; ffmpeg's stderr is then forwarded to the EufyMegaOptions.logger as [ffmpeg] debug lines — visible only where that logger shows debug. Independent of the SDK's own log level.
ffmpegPath?
optional ffmpegPath?: string;The ffmpeg executable the media paths that shell out should run (live snapshot / record). Default: the bare name "ffmpeg", looked up on PATH.
Set it when the host ships or manages its own build — an absolute path is resolved without any PATH lookup, so those paths work on a host that has no system ffmpeg at all. The SDK never edits process.env.PATH; naming the binary here is the supported way to point it at one. The path is not probed, so a wrong one surfaces as the media call's own "not runnable" rejection.
localAddresses?
optional localAddresses?: Record<string, string>;LAN address overrides for direct P2P, keyed by parent-station serial → host or host:port. The SDK normally derives a station's LAN address from its device record; an entry here overrides it where the record's IP is wrong/blocked (AP isolation, a stale ip_addr).
logger?
optional logger?: Logger;Diagnostics sink. Omit for silence; pass a Logger (or new ConsoleLogger()) to see logs.
Inherited from
MegaClientConfig.loggermediaUserAgent?
optional mediaUserAgent?: string;user-agent sent on the push-media download path (downloadMedia/downloadImage). Defaults to a realistic Android string consistent with phoneModel and seeded by openudid (stable across runs); an explicit value pins a fixed one. Not the account identity — that's phoneModel.
Inherited from
MegaClientConfig.mediaUserAgentnoBroadcast?
optional noBroadcast?: boolean;Suppress the 255.255.255.255 local-lookup broadcast (default false — broadcast is sent).
An unconnected P2P session broadcasts a local lookup once a second for the whole connect timeout, which is how a station on the same LAN is found without knowing its address. That is cheap when it works and not free when it does not: the datagram goes to every host on the segment, every associated client of a WLAN has to receive it, and a host that sets SO_BROADCAST on many sockets in quick succession is doing something unusual to its own network stack.
Turning it off costs the LAN-discovery path only. A station whose record carries a usable ip_addr is still found directly, and the PPCS cloud lookup — which is what actually connects a station in most topologies — is unaffected. Set it when the caller knows its stations' addresses, or when the broadcast is suspected of disturbing the host's own networking.
openudid?
optional openudid?: string;Stable per-install device id (the auth token binds to it). Derived from email if absent.
Inherited from
MegaClientConfig.openudidosVersion?
optional osVersion?: string;OS version string reported in headers.
Inherited from
MegaClientConfig.osVersionp2pIdleMs?
optional p2pIdleMs?: number;Idle window in ms before an on-demand P2P session to a battery station is closed so the device can sleep (default 300000 = 5 min). Wired stations stay persistent.
password
password: string;Inherited from
MegaClientConfig.passwordphoneModel?
optional phoneModel?: string;Phone model reported to the cloud as this install's device. Defaults to a realistic, RANDOM model (see randomPhoneModel) seeded by openudid so it is stable across runs — this keeps many SDK installs from all reporting one identical model. An explicit value pins a fixed identity.
Inherited from
MegaClientConfig.phoneModelpollMs?
optional pollMs?: number;How often to re-read the cloud device list and emit a semantic event for each param that changed (default 600000 = 10 min). Set 0 to disable polling entirely.
The default is paced to the data rather than to a host's refresh appetite — see the device's params for how slowly the cloud actually refreshes them. Polling faster costs requests without seeing anything sooner.
This channel carries the slow-moving state that has no push of its own (a battery level; a sensor that only reports to the cloud). Fast state — motion, doorbell, contact, lock — arrives over push/P2P/MQTT and is unaffected by this setting.
prewarmEvents?
optional prewarmEvents?: keyof DeviceEventMap[];Which semantic events speculatively pre-warm a camera's P2P session — opt-in, default [], an empty list being what disables it. Naming an event buys a stream or talkback opened right after it starting warm rather than paying a cold open, and costs what the three paragraphs below describe.
Any name in DeviceEventMap is accepted, so the list autocompletes and a typo won't compile. A pre-warm rides the push channel, so only an event push carries can trigger one — a poll-carried event is inert however it is listed, and each capability module declares which source carries its own events. An event from a device that is not a camera pre-warms the station behind it, which for an attached sensor is its HomeBase.
One camera pays for it. Wired stations are warmed at login and never idle-detach, and an attached camera's session lives on its wired base — so the only station a pre-warm genuinely opens is a standalone battery camera, the device class the on-demand session lifecycle exists to let sleep. EufyMegaOptions.prewarmTiers is how that class is spared while keeping the opt-in.
An unwatched pre-warm costs more than its window, per EufyMegaOptions.prewarmMs: the hold expiring arms the station's idle window instead of closing the session, and a second qualifying event inside that tail restarts it.
Frequency is a property of the installation, not of the event name. A camera set to report human detection only fires personDetected as often as a busier one fires raw motion, so the rate is the fleet's and not the event's.
prewarmMs?
optional prewarmMs?: number;How long a speculative pre-warm holds the session it opened, in ms (default 28000). Applies only to the events EufyMegaOptions.prewarmEvents opts into; pre-warm is off until then.
When the window expires with nothing attached, the session does not close — the hold is released and the station's own idle window takes over, which for a battery station is EufyMegaOptions.p2pIdleMs (5 min by default). Budget an unattended pre-warm at the sum of the two.
prewarmTiers?
optional prewarmTiers?: PowerTier[];Which station power tiers EufyMegaOptions.prewarmEvents may pre-warm (default: both). The tier is the one of the station whose session would open — a camera attached to a HomeBase is pre-warmed as wired, because that base's session is the one being held.
["wired"] keeps the opt-in and spends no battery: it is close to a no-op, since wired stations are already warmed at login and never idle-detach, so it only bites after a session drops.
pushStore?
optional pushStore?: FcmStore;Persist FCM push credentials + seen ids across runs (default: in-memory).
region?
optional region?: RegionShard;Force a region shard, skipping estimate_domain.
Inherited from
MegaClientConfig.regionstateSnapshotMs?
optional stateSnapshotMs?: number;How long EufyMega.getDevice waits (ms, default 4000) for a device whose state exists ONLY on its realtime wire to make its first report, before resolving it.
Such a device has no pollable cloud state, and the typed read getters are gated on what it has actually reported — so one resolved before its first report has no readable state, and no later report can add the getters to it. A short wait buys a populated read surface. 0 disables the wait and accepts that reads appear only on a Device fetched after the first report. Devices with a cloud record never wait.
store?
optional store?: SessionStore;Persist + reuse the session (token + session key) across runs. Default: in-memory.
Inherited from
MegaClientConfig.storestoredSnapshotCache?
optional storedSnapshotCache?: boolean;Eagerly retain validated push thumbnails in memory for camera.snapshotStored() (default true).
tuyaAllowUnverified?
optional tuyaAllowUnverified?: boolean;Opt into unverified Tuya DP writes for eufy_home_tuya clean-line devices (G-series / X8).
By default TuyaCommandRouter refuses to send dp.publish because the request shape has been reversed but not yet confirmed from a live on-device capture — a wrong shape comes back as a generic Tuya error indistinguishable from an actual device rejection. true sends it anyway, which is sound only where the full round-trip has been confirmed on a real device, or that ambiguity is accepted.