Skip to content

@mega-yfue/eufy-sdk / SolixMqtt

Class: SolixMqtt ​

Subscribe to a Solix device's live telemetry and emit decoded reading events. Reuses SecureMqtt for the connection; adds only the Solix data topic + ff09 param decoding.

const mqtt = new SolixMqtt({ mqttInfo: await solix.getUserMqttInfo() }); mqtt.on("reading", (r) => console.log(r.deviceSn, r.values.meterVoltageL1)); await mqtt.watch(device); // device = a SolixClient.getDevices() entry

Extends ​

  • EventEmitter

Constructors ​

Constructor ​

ts
new SolixMqtt(opts): SolixMqtt;

Bind to one account's MQTT plane. The envelope client_id takes the app's shape (android-{app}-{uid}-{mqttUuid}-{ts}); its mqttUuid half must be stable across restarts, or every restart presents itself to the broker as a new client, so it defaults deterministically from the user id (see SolixMqttOptions.mqttUuid) rather than a fresh random per instance.

Parameters ​

opts ​

SolixMqttOptions

Returns ​

SolixMqtt

Overrides ​

EventEmitter.constructor

Methods ​

close() ​

ts
close(): Promise<void>;

Tear down the connection and stop the re-arm timer.

Returns ​

Promise<void>


setDisplayTimeout() ​

ts
setDisplayTimeout(device, index): Promise<void>;

Set a Solarbank's display screen-off timeout — publishes the captured cmd-17 command (ff09 msgtype 0x68, tag a5 = [01, index]) on the device's …/req channel via the same envelope the arming poll uses (sign_code:1, no per-message signature — which the device accepts for cmd 17). index is the 1-based dropdown position (10s=1, 20s=2, 30s=3, 1m=4, 5m=5, 30m=6); "Never" is a separate command not handled here. Fire-and-forget: the device does not ack on a subscribed channel.

Parameters ​

device ​

SolixMqttDevice

index ​

number

Returns ​

Promise<void>


watch() ​

ts
watch(device): Promise<void>;

Connect, subscribe to the device's telemetry (+ command-reply) topics, ARM realtime reporting, and start the re-arm/heartbeat timer so telemetry keeps flowing without the app. Idempotent per device.

Subscribes to param_info (+ the device/account command-reply channels) AND the device's …/req channel. …/req is the app→device request side — the broker copies the APP's own publishes there to any co-subscriber, so watching it lets us read a control the app changed that the telemetry does NOT reflect: the Solarbank's ambient light and display timeout ride an …/req cmd-17 (0x68) command (tags a4/a5), and the param_info ba bit only tracks OUR set_device_attrs write, never the app's separate command path. onMessage filters these — our own arming/echoes carry no a4/a5 — and turns an app command into a reading with the app-set state. A …/req grant denial is non-fatal (only param_info is required); we just won't see app-side changes.

Throws when param_info was not granted. A scope-denied filter comes back as SUBACK_FAILURE rather than an error (see SecureMqtt.subscribe), so an unusable subscription otherwise looks like success: the call would resolve and arm on every interval while no reading ever arrives.

The re-arm timer is unreffed, so a caller that watches and returns can still exit.

Parameters ​

device ​

SolixMqttDevice

Returns ​

Promise<void>

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