Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 

Repository files navigation

JK-BMS 55AA Passive Listener for ioBroker

Reads JK-BMS data via RS485/Ethernet directly into ioBroker using the JavaScript adapter — no MQTT broker, no additional drivers, no extra services needed.

Tested with: JK-BMS PB2A16S20P v19 (up to 16 cells, up to 4 parallel packs), connected to RS485-2 (right port) at Master BMS #0


How it works

The JK-BMS broadcasts binary frames in the 55AA protocol roughly every 200 ms automatically — no polling required. The script opens a TCP connection to a RS485/Ethernet converter, listens passively, validates each frame (CRC16 Modbus), and writes the parsed values into the ioBroker state tree every 10 seconds.

JK-BMS  ──RS485──►  Ethernet Converter  ──TCP──►  ioBroker JavaScript Adapter
         115200 Bd       transparent                    55AA passive listener

Three frame types are broadcast:

Register Type Content
0x1620 DYNAMIC Cell voltages, current, SOC, temperatures — parsed by this script
0x161C STATIC Hardware/software version, serial number
0x161E SETUP Protection thresholds, current limits

Hardware Requirements

  • JK-BMS PB2A16S20P with RS485-2 port
  • RS485-to-Ethernet converter, e.g.:
    • Waveshare USR-TCP232-306 / RS485 TO ETH (B)
    • Ebyte MA01-XXAC or similar
  • LAN connection from converter to ioBroker host

Converter settings

Example: Waveshare RS485 TO ETH (B) — web interface at http://<device-ip>

Network

Field Value
Work Mode TCP Server
Device Port 5000
IP mode DHCP (or static)
Destination Port 0

Serial

Field Value
Baud Rate 115200
Databits 8
Parity None
Stopbits 1
Flow control None

Advanced

Field Value
No-Data-Restart Disable
Enable Multi-host Yes

JK-BMS DIP switch

Connect to the Master BMS (Device ID 0):

Switch Position Meaning
1 OFF RS485 mode active
2 OFF
3 OFF
4 OFF Device ID = 0 (Master)

Connect to the RS485-2 (right) port on the Master BMS.


Installation

  1. In ioBroker, install the JavaScript adapter (if not already installed).
  2. Open the JavaScript adapter → + Add script.
  3. Copy the contents of jkbms_55aa.js into the editor.
  4. Adjust the CONFIG block at the top of the script (see below).
  5. Save and start the script.

The script creates all states automatically on first start. Check the ioBroker log for connection status.


Configuration

All settings are in the CONFIG block at the top of the script:

const CONFIG = {
    host:            '192.168.7.109', // IP of the RS485/Ethernet converter
    port:            5000,            // TCP port (default: 5000 or 8899)
    statePrefix:     'javascript.0.jkbms',
    reconnectMs:     5000,            // Reconnect delay in ms
    maxPackId:       3,               // Highest pack ID (0 = 1 pack, 3 = up to 4 packs)
    cacheMaxAgeS:    60,              // Pack goes offline after N seconds without a frame
    writeIntervalMs: 5000,            // Fast write interval: voltages, current, SOC, temps (5 s)
    slowIntervalMs:  300000,          // Slow write interval: cell resistances, SOH, cycles (5 min)
};
Parameter Default Description
host 192.168.7.109 IP address of the RS485/Ethernet converter
port 5000 TCP port of the converter
statePrefix javascript.0.jkbms ioBroker state path prefix
reconnectMs 5000 Delay before reconnect attempt (ms)
maxPackId 3 Highest expected pack ID (0-based). Set to 0 for a single BMS.
cacheMaxAgeS 60 Seconds after which a pack with no new frames is marked offline
writeIntervalMs 5000 Write interval for fast states (voltages, current, SOC, temps)
slowIntervalMs 300000 Write interval for slow states (cell resistances, SOH, cycle count, runtime)
writeBudget 80 Max. setState calls per write cycle (overflow protection, see below)

Write budget and ioBroker setState limit

The ioBroker JavaScript adapter throttles scripts that exceed ~1000 setState calls per minute. This script avoids that with two mechanisms:

Change-only: setState is only called when a value actually changed. In steady state (float charging, stable voltage) nearly zero writes occur per cycle.

Per-cycle budget (writeBudget): Even if many values change at once (startup, alarm storm), at most writeBudget setState calls are made per cycle. Values that exceed the budget are deferred to the next cycle — they remain "pending" in the change cache until written.

Scenario setState calls
Steady state ~0–5 per 5 s cycle
Worst case (all values change) 80 per cycle × 12 cycles/min = 960/min (incl. last_update)
Startup (4 packs, ~168 fast states) 80/cycle → all written within ~15 s

States per pack:

Category Count Interval
Voltage, current, power, SOC, remaining capacity 5 fast (5 s)
Balance current, MOS flags, alarm bits, status, wire alarm 7 fast (5 s)
Charger, heater, fault count 3 fast (5 s)
Temperatures (MOS + up to 5 NTC) 2–6 fast (5 s)
Cell stats (max, min, avg, diff) 4 fast (5 s)
16× cell voltage (cell_01_mv … cell_16_mv) 16 fast (5 s)
Fast total per pack ~37–41
SOH, full capacity, cycle count, cycle capacity, runtime 5 slow (5 min)
16× cell resistance (cell_01_mohm … cell_16_mohm) 16 slow (5 min)
Slow total per pack 21
Total per pack ~58–62

For 4 packs + aggregate totals: ~168 fast states + 84 slow states = ~252 states total.


State Tree

All values are written under javascript.0.jkbms (configurable via statePrefix).

Per pack — jkbms.pack0, .pack1, …

State Unit Description
voltage V Total pack voltage
current A Charge (+) / discharge (−) current
power W Power
soc % State of charge
soh % State of health
remain_cap Ah Remaining capacity
full_cap Ah Full charge capacity
cycle_count Total charge cycles
cycle_cap Ah Cumulative cycled capacity
balance_current A Active balance current
temp_mos °C MOSFET temperature
temp_bat1temp_bat5 °C Battery temperature sensors (NTC 1–5)
charge_mos bool Charge MOSFET enabled
discharge_mos bool Discharge MOSFET enabled
balance_mos bool Balancing active
heating_state bool Heater active
charger_plugged bool Charger connected
alarm_bits 32-bit alarm flags (see below)
wire_alarm Wire connection alarm bits
battery_state Raw status byte
fault_count Cumulative fault count
total_runtime_h h Total runtime in hours
last_update ISO Timestamp of last write
cell_01_mvcell_16_mv mV Individual cell voltages
cell_01_mohmcell_16_mohm Individual cell resistances
cell_max_mv mV Highest cell voltage
cell_min_mv mV Lowest cell voltage
cell_avg_mv mV Average cell voltage
cell_diff_mv mV Spread (max − min)

Aggregate totals — jkbms.total

State Unit Description
voltage_avg V Average voltage across all packs
current A Total current (sum of all packs)
power W Total power (sum of all packs)
soc % Weighted SOC (remainCap / fullCap)
remain_cap Ah Total remaining capacity
full_cap Ah Total full capacity
active_packs Number of packs currently online

Alarm Bits Reference

alarm_bits is a 32-bit field. Bit 0 = LSB.

Bit Meaning
0 Cell overvoltage
1 Cell undervoltage
2 Pack overvoltage
3 Pack undervoltage
4 Charge overcurrent
5 Discharge overcurrent
6 Charge overtemperature
7 Discharge overtemperature
8 Charge undertemperature
9 Discharge undertemperature
10 MOS overtemperature
11 Environment overtemperature
12 Environment undertemperature
13 Cell voltage difference too large
14 SOC low alarm
15 SOC high alarm
16–23 Sensor / hardware fault flags

To check a specific alarm in ioBroker scripts:

const bits = getState('javascript.0.jkbms.pack0.alarm_bits').val;
if (bits & (1 << 0)) { /* cell overvoltage */ }
if (bits & (1 << 1)) { /* cell undervoltage */ }

Deutsche Beschreibung

Dieses Script liest JK-BMS-Daten per RS485/Ethernet-Konverter passiv aus und schreibt sie direkt in den ioBroker-Objektbaum — über den JavaScript-Adapter, ohne MQTT, ohne externe Dienste.

Der JK-BMS sendet alle ~200 ms automatisch binäre 55AA-Frames. Das Script verbindet sich per TCP, parst die Frames kontinuierlich im Puffer und validiert mit CRC16-Modbus. Geschrieben wird nur bei Wertänderung (change-only), Messwerte alle 5 Sekunden, Zellwiderstände und Langzeitwerte alle 5 Minuten. Bis zu 4 parallele Packs (Master-Slave-Konfiguration) werden unterstützt und zu Gesamtwerten aggregiert.


License

MIT — free to use and adapt.

About

JK-BMS 55AA passive listener for ioBroker — reads up to 4 parallel packs via RS485/Ethernet TCP directly into the JavaScript adapter, no MQTT required.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages