Bluetti Cloud (Open Platform) client
A tiny Node.js client for reading device telemetry from Bluetti's cloud Open Platform API. Use this for the newer encrypted models (Elite 300 / EL300, V2, EP600, AC180, AC200L …) where the local BLE channel is locked — the cloud path works today and needs no AES key.
This is not the ESP32 library — it's a separate, optional helper that talks to Bluetti's cloud over HTTPS. For older/plaintext models read locally with
BluettiBLE;BluettiADVwill cover newer models locally once Bluetti exposes the broadcast AES key.
Implemented from the official spec at https://open.bluetti.com/developers
(basePath: https://open.bluetti.com/open).
Auth: signed requests (not OAuth)
Each request carries four headers; the AppSecret is hashed in, never sent:
Authorization = SHA-256( "appKey=<AppKey>&appSecret=<AppSecret>&nonceStr=<nonce>&timeStamp=<unixSeconds>" )
x-app-key: <AppKey>
ETag: <nonce> # random hex, new per request
Date: <unixSeconds> # must match the timeStamp used in the hash
Setup
-
Register at https://open.bluetti.com/developers, create an application to get an AppKey and AppSecret, and apply for the IoT/telemetry API permission. Your device SN must also be authorized to the account, or the telemetry endpoints return a permission error even with a valid signature.
-
Run it (Node 18+, no
npm install):BLUETTI_APPKEY=xxx BLUETTI_APPSECRET=yyy BLUETTI_SN=EL3002546110146262 node bluetti.mjs
Endpoints used
| Purpose | Path (POST) | Body |
|---|---|---|
| List devices | /open/bluiotdata/device/telemetry/v1/userTelemetryDeviceList |
{pageNo, pageSize} |
| Reported data | /open/bluiotdata/device/telemetry/v1/telemetryDeviceReportedData |
{deviceSn, beginTimestamp, endTimestamp, pageNo, pageSize} (ms) |
| Control (set) | /open/bluiotdata/device/telemetry/v1/telemetryDeviceSetUp |
{deviceSn, functionCode, setValue} |
Responses use the UnifyResponse envelope — { code, msgCode, message, data, ... },
where msgCode == 0 means success. data for reported data is a paginated list
(content[]) of key→value telemetry maps.
When it works / doesn't
- 403 / permission error → your app lacks the telemetry permission, or the SN isn't authorized to your account. Apply on the developer portal.
- Signature failure → check that the
Dateheader equals thetimeStampstring used inside the SHA‑256 input, and that you hashed the literalappKey=…&appSecret=…&nonceStr=…&timeStamp=…string.
Once you can see a sample telemetry response, paste it back and the script can be tightened into a poller that pulls out SoC/power and logs on change.