@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
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
Returns
SolixMqtt
Overrides
EventEmitter.constructor
Methods
close()
close(): Promise<void>;Tear down the connection and stop the re-arm timer.
Returns
Promise<void>
setDisplayTimeout()
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
index
number
Returns
Promise<void>
watch()
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
Returns
Promise<void>