Skip to content

eufy-mega / client/eufy-mega / EufyMega

Class: EufyMega

The package entry point — one client per eufy account. Handles the login state machine (captcha/2FA/persistence), resolves the account's devices (getDevices/getDevice → capability-driven Devices), auto-manages the realtime channels (FCM push + secure MQTT start on login; P2P opens on demand per station and idle-detaches battery cameras), and fans every transport's traffic into one typed semantic event stream (eufy.on("motion", …)). Construct it with an EufyMegaOptions (email/password + optional session/push stores), then drive login() to completion — no connect* call needed (set autoRealtime:false to opt out). Call disconnect to tear the realtime channels down.

Extends

  • EventEmitter

Constructors

Constructor

ts
new EufyMega(opts): EufyMega;

Parameters

opts

EufyMegaOptions

Returns

EufyMega

Accessors

api

Get Signature

ts
get api(): MegaHttpClient;

Raw mega HTTP client, for endpoints not yet wrapped.

Returns

MegaHttpClient


loggedIn

Get Signature

ts
get loggedIn(): boolean;

True if a usable session (restored from store or freshly logged in) is held.

Returns

boolean

Methods

clearSession()

ts
clearSession(): void;

Forget the persisted session (forces a fresh login + 2FA next time).

Returns

void


deviceState()

ts
deviceState(sn): DeviceState;

The liveness facts for one device — see DeviceState. Facts, not an online verdict: "how long is too long" is a threshold that belongs to the caller, and it differs per device class.

Pair it with the deviceState event to be told when a device reports in, rather than polling this.

Parameters

sn

string

Returns

DeviceState


disconnect()

ts
disconnect(): Promise<void>;

Tear down every realtime channel: close the secure-MQTT transport, all P2P sessions, and the FCM push socket. Idempotent — safe to call when nothing is connected. Leaves the login session intact (call login again to reconnect without re-authenticating).

Returns

Promise<void>


emit()

ts
emit<E>(event, ...args): boolean;

Type Parameters

E

E extends | "error" | "p2p" | "connect" | "disconnect" | "message" | "push" | "event" | keyof DeviceEventMap | "deviceAdded" | "deviceRemoved" | "deviceCapabilities" | "deviceState" | "p2pConnect" | "p2pClose" | "p2pLevel2Ready" | "pushConnect" | "pushDisconnect" | "pushRaw" | "commandAck"

Parameters

event

E

args

...EufyMegaEventMap[E]

Returns

boolean


getDevice()

ts
getDevice(sn): Promise<Device>;

Build a live Device model object for one serial: the resolved codec/capabilities with its current param values applied (named via the param dictionary; unknown ids kept as unknown_<pt>). This is the device primitive a host reads — dev.getProperties(), dev.has(cap), etc. Prefers fresh get_device_param_list, falls back to the device-list params. Under auto-realtime the returned Device is wired with a read-through freshness cache (see Device.setFreshnessPolicy), so a host that reuses it (e.g. a periodic polling loop) serves repeat reads from cache instead of re-fetching, and realtime updates keep values fresh.

Parameters

sn

string

Returns

Promise<Device>

Example

ts
const dev = await eufy.getDevice(sn);
if (dev.has("camera")) await dev.camera()?.snapshot();
console.log(dev.getProperty("battery"));

getDeviceParamList()

ts
getDeviceParamList<T>(deviceSn): Promise<T>;

Live param list for one owned device. See MegaHttpClient.getDeviceParamList.

Type Parameters

T

T = unknown

Parameters

deviceSn

string

Returns

Promise<T>


getDevices()

ts
getDevices(): Promise<EufyDevice[]>;

List + classify devices across all houses (mega API). Each device is tagged with its API backend

  • realtime transport. Camera/HomeBase records still appear here for inventory; driving them is P2P. Delegates to DeviceRegistry (the house-scoped merge/dedupe lives there).

Returns

Promise<EufyDevice[]>


getMqttDevices()

ts
getMqttDevices(): EufyDevice[];

Devices that this client drives over MQTT (transport ≠ p2p).

Returns

EufyDevice[]


getP2pDevices()

ts
getP2pDevices(): EufyDevice[];

Devices that require P2P (cameras/HomeBases).

Returns

EufyDevice[]


getP2pSessions()

ts
getP2pSessions(): Map<string, P2PSession>;

Stations with a live P2P session. P2P is auto-managed: wired stations are warmed at login, battery stations open on demand (command / stream / doorbell pre-warm) and idle-detach — so this map grows and shrinks over time. p2pConnect(stationSn) / p2pClose(stationSn) events track the changes.

Returns

Map<string, P2PSession>


getProductDataPoint()

ts
getProductDataPoint<T>(code): Promise<T>;

Per-SKU data-point (param) schema from the mega things service — the authoritative param_type catalogue for a product code (the same call the v6 app uses). Works for ANY SKU, not just owned devices. See MegaHttpClient.getProductDataPoint.

Type Parameters

T

T = unknown

Parameters

code

string

Returns

Promise<T>


getUserMqttInfo()

ts
getUserMqttInfo(appName?): Promise<SecureMqttCredentials>;

Fetch the per-user secure-MQTT credentials for realtime appliance control. Pass appName to request a specific capability scope on the current session without re-logging in — security devices (locks/garage) need the eufy_security scope, which the default scope can't reach.

Parameters

appName?

string

Returns

Promise<SecureMqttCredentials>


inspectAllDevices()

ts
inspectAllDevices(): Promise<DeviceInspection[]>;

Inspect every owned device (the bulk enrichment export).

Returns

Promise<DeviceInspection[]>


inspectDevice()

ts
inspectDevice(sn): Promise<DeviceInspection>;

Inspect one device by serial: resolve its codec/capabilities, cross-reference every reported param_type against the param dictionary, and emit a paste-ready registry.ts row plus dictionary snippets for anything unknown. The enrichment tool — run it on a new/unconfirmed device and send back the export to grow the device catalog. Loads the device list if needed; prefers the live get_device_param_list for freshest params, falling back to the device-list params.

Parameters

sn

string

Returns

Promise<DeviceInspection>


login()

ts
login(opts?): Promise<LoginResult>;

Begin (or resume) login. Returns a LoginResult — switch on status:

  • ok → authenticated (result.session).
  • captcha → show result.image, then solveCaptcha(answer).
  • 2fa → a code was sent; submitVerifyCode(code).

A restored session resolves straight to ok. No exceptions for the expected captcha/2FA flow.

Parameters

opts?
messageType?

number

Returns

Promise<LoginResult>

Example

ts
const res = await eufy.login();
if (res.status === "captcha") await eufy.solveCaptcha(await ask(res.image));
else if (res.status === "2fa") await eufy.submitVerifyCode(await ask());

off()

ts
off<E>(event, listener): this;

Type Parameters

E

E extends | "error" | "p2p" | "connect" | "disconnect" | "message" | "push" | "event" | keyof DeviceEventMap | "deviceAdded" | "deviceRemoved" | "deviceCapabilities" | "deviceState" | "p2pConnect" | "p2pClose" | "p2pLevel2Ready" | "pushConnect" | "pushDisconnect" | "pushRaw" | "commandAck"

Parameters

event

E

listener

(...args) => void

Returns

this


on()

ts
on<E>(event, listener): this;

Type Parameters

E

E extends | "error" | "p2p" | "connect" | "disconnect" | "message" | "push" | "event" | keyof DeviceEventMap | "deviceAdded" | "deviceRemoved" | "deviceCapabilities" | "deviceState" | "p2pConnect" | "p2pClose" | "p2pLevel2Ready" | "pushConnect" | "pushDisconnect" | "pushRaw" | "commandAck"

Parameters

event

E

listener

(...args) => void

Returns

this


once()

ts
once<E>(event, listener): this;

Type Parameters

E

E extends | "error" | "p2p" | "connect" | "disconnect" | "message" | "push" | "event" | keyof DeviceEventMap | "deviceAdded" | "deviceRemoved" | "deviceCapabilities" | "deviceState" | "p2pConnect" | "p2pClose" | "p2pLevel2Ready" | "pushConnect" | "pushDisconnect" | "pushRaw" | "commandAck"

Parameters

event

E

listener

(...args) => void

Returns

this


renameDevice()

ts
renameDevice(sn, name): Promise<void>;

Rename a device (or station). The new name propagates to the eufy cloud automatically, so no separate HTTP update is needed. Fire-and-forget; re-read with getDevice to confirm the new name. ASCII names only for now.

Parameters

sn

string

name

string

Returns

Promise<void>


setProperty()

ts
setProperty(
   sn, 
   name, 
value): Promise<void>;

Write a device property. Asks the capability modules to build the command for this (name, value) — the module owns how THIS device applies it. No (name, value) recipe → the device doesn't support the property, so we throw CapabilityNotSupportedError rather than a silent no-op. On success the device echoes the new state back as a param update — read it with getDevice to confirm.

Parameters

sn

string

device serial.

name

string

property name (e.g. "light", "brightness", "enabled").

value

string | number | boolean

desired value.

Returns

Promise<void>

Example

ts
await eufy.setProperty(sn, "brightness", 50);
await eufy.setProperty(sn, "light", true);

solveCaptcha()

ts
solveCaptcha(answer, opts?): Promise<LoginResult>;

Continue a {status:"captcha"} login with the solved answer. See login.

Parameters

answer

string

opts?
messageType?

number

Returns

Promise<LoginResult>


submitVerifyCode()

ts
submitVerifyCode(code): Promise<LoginResult>;

Continue a {status:"2fa"} login with the verify code that was sent. See login.

Parameters

code

string

Returns

Promise<LoginResult>

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.