# Two JK-BMS units on one ESP32-C3

This source accompanies the English article about monitoring two JK-BMS units
through one ESP32-C3, with independent BLE connections and browser telemetry.
It contains no real Wi-Fi credentials, device addresses, serial numbers or
prebuilt private image. Test addresses are synthetic.

## Tested installation

- ESP32-C3, `esp32-c3-devkitm-1`, 4 MB flash, native USB Serial/JTAG.
- ESPHome 2026.6.5 and ESP-IDF 5.5.4.
- Two JK-PB1A16S10P units, hardware 19A, 16 cells and 105 Ah each.
- JK firmware 19.31 and 19.34, using `JK02_32S`.
- External JK component pinned to `6a59290f839eb71a3adbf0724b6eb9d3e8fd0e62`.

The public UI text is English. Its selection and monitoring logic follows the
tested installation. Other JK hardware may need a different protocol; confirm
each model against the upstream project before using its readings.

## Configure and build

Run from the directory that contains this `source/` directory:

```sh
cp source/secrets.example.yaml source/secrets.yaml
```

Edit `source/secrets.yaml` with your 2.4 GHz Wi-Fi details. Keep that file private.
Then validate and compile:

```sh
docker run --rm -v "$PWD/source":/config \
  ghcr.io/esphome/esphome:2026.6.5 \
  config /config/jk-bms-c3.yaml

docker run --rm -v "$PWD/source":/config \
  ghcr.io/esphome/esphome:2026.6.5 \
  compile /config/jk-bms-c3.yaml
```

The factory image is generated at:

```text
source/.esphome/build/jk-bms-c3/.pioenvs/jk-bms-c3/firmware.factory.bin
```

For an existing compatible installation, use the ESPHome OTA installation
flow. Keep a known working source and image first. Ordinary OTA
retains Wi-Fi and selected BMS addresses; a full flash erase removes them.

For serial installation, identify the exact C3 and port, and make and verify a
full original-flash backup before writing. A factory image is written at
`0x0`; an application OTA image is not interchangeable with a factory image.
The article includes a backup example for a confirmed 4 MB board.

## Select the batteries

Power the bridge by USB. It must reach both BMS radios and the home Wi-Fi.
If the configured WLAN is unavailable, the temporary open AP is
`JK-BMS-C3 Setup`; the Wi-Fi form is at `http://192.168.4.1/wifi`.
This fallback has no AP password. Keep the board and setup network under your
control while provisioning it.

On the home LAN, open `http://jk-bms-c3.local/bms`. Choose the original unit as
BMS 1 and the new unit as BMS 2. Check each known address/name and confirm the
published identity, pack voltage and cell count. Do not assign one address to
both slots. Close a phone app if it is holding the BMS connection.

Metrics are at `http://jk-bms-c3.local/`. The browser root uses ESPHome Web
Server v3; its external JavaScript may be unavailable on an offline setup AP.
The standalone selector page does not need that JavaScript.

This sample uses unauthenticated HTTP, native API and OTA on a trusted LAN.
It is not intended for direct internet exposure. Add the authentication and
API encryption appropriate to your network before using it elsewhere.

## Tests and verification

Run the host C++ selector test with Python and g++ installed:

```sh
python3 source/tests/test_selector_host.py
```

Run the schema test in the pinned ESPHome image:

```sh
docker run --rm -v "$PWD/source":/config \
  --entrypoint python ghcr.io/esphome/esphome:2026.6.5 \
  /config/tests/test_selector_schema.py
```

These check selection, duplicate rejection, storage handling, startup and
delayed BLE disconnect states. They are not a replacement for checking real
telemetry. Confirm that both online flags are true, both identities are
correct and each pack voltage agrees with its own cell sum. Missing channels
are not zero-valued cells. Test both saved addresses after a physical restart
on your own installation.

The English package passed the host and schema tests, ESPHome configuration
validation and C++ source generation. Its translated UI was not separately
flashed; the hardware results below describe the author's deployed build.

The author's physical restart check covered the original slot. The second
slot was saved afterward; two-slot restore was covered by host tests, without
a second physical restart. During a 30-second hardware capture both units
reported live values, with seven and six voltage updates and no BMS errors.

The bridge is for monitoring. It does not change BMS protection settings or
replace the BMS, fuses or inverter controls.
