Cloud version, requires approval

This commit is contained in:
2026-06-04 22:48:26 +10:00
parent 890feae060
commit 71fc3abb90
2 changed files with 136 additions and 0 deletions
+60
View File
@@ -0,0 +1,60 @@
# 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`; `BluettiADV` will 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
1. 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.
2. Run it (Node 18+, no `npm install`):
```bash
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 `Date` header equals the `timeStamp`
string used inside the SHA256 input, and that you hashed the literal
`appKey=…&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.