Skip to content

Instantly share code, notes, and snippets.

@PhracturedBlue
Last active November 8, 2025 14:52
Show Gist options
  • Select an option

  • Save PhracturedBlue/7ef619594eaa4c27f4ff068b461865b8 to your computer and use it in GitHub Desktop.

Select an option

Save PhracturedBlue/7ef619594eaa4c27f4ff068b461865b8 to your computer and use it in GitHub Desktop.
Ecoworthy 50V server battery Modbus-RTU protocol

Info related to Eco Worthy JBD UP16S010

BMS: JBD UP16S010 Decoding based on firmware version 13.2.4

Commands can be sent via the RS485-1 port or by te RS232 port (9600baud, N81)

CRC calculation: crc16 with initial_value=0xffff and polynomial=0xa001, LSB 1st

The Modbus data-frames are generally MSB-1st except for the CRC. The CRC is calculated from the entire frame (minus the crc itself)

NOTE: The Eco-Worthy software uses the Modbus-RTU protocol. Most other software uses the JBD protocol documented here: https://github.com/syssi/esphome-jbd-bms/blob/main/docs/Jiabaida.communication.protocol.pdf There is also a variant of the JBD protocol where the battery bank is selectable (instead of dd a5, packets start dd 01 a5 where 01 is the bank address). At least on my batteries, only the direct-connected battery is accessible even using the 'addressable JBD' protocol, and the modbus-RTU protocol is the only one I've found capable of reading multiple banks with a single connection

Per marionw, here are the valid modbus function codes:

code function
0x42 ReadHostStartupData
0x50 ReadHostData
0x45 ReadSlaveData
0x46 SlaveResetCommand
0x47 SlaveChargingInstruction
0x78 ReadBMSInsideInformation
0x79 SetBMSInsideInformation

Pack Status

Request

01 78 10 00 10 a0 00 00 7f b2

bytes value position count description
01 1 0 1 address (battery #)
78 0x78 1 1 function code (read)
10 00 0x1000 2 2 start address
10 a0 0x10a0 4 2 end address
00 00 0 6 2 data length
7f b2 0xb27f 8 2 crc (LSB 1st)

Response

bytes value position count description
01 1 0 1 address (battery #)
78 0x78 1 1 function code (read)
10 00 0x1000 2 2 start address
10 a0 0x10a0 4 2 end address
00 a2 162 6 2 data length
14 8f 52.63V 8 2 pack voltage
00 00 - 10 2
00 04 93 E0 0.00A 12 4 A = (val - 300000) / 100
1c 98 73.20% 16 2 state of charge
1c 98 73.20Ah 18 2 residual pack capacity
27 10 100.00Ah 20 2 full pack capacity
27 10 100.00Ah 22 2 rated pack capacity
02 78 13.2°C 24 2 MOSFET temperature: °C = (val - 500) / 10
02 82 14.2°C 26 2 ambient temperature: °C = (val - 500) / 10
00 00 - 28 2 Operation status (0: Idle, 1: Charging, 2: Discharging)
00 64 100% 30 2 state of health
00 00 - 32 2 protected state fault code. bitmask
0: Temperature difference too large
1: SOC too low
2: Short circuit protection
3: Monomer offline
4: Temperature drop
5: Charge MOS fult
6: DischargeMOS fault
7: Current limiting anomaly
8: Aerosol Fault
9: Full Charge Protection
10: Abnormal AFE communication
00 00 - 34 2 protected state fault code. bitmask
0: Cell over-voltage
1: Cell undervoltage
2: Total overvoltage
3: Total undervoltage
4: Charge overcurrent 1
5: Charge overcurrent 2
6: discharge overcurrent 1
7: discharge overcurrent 2
8: charge high temperature
9: charge low temperature
10: discharge high temperature
11: discharge low temperature
12: MOS high temperature
13: Ambient high temperature
14: Ambient low temperature
15: Pressure difference too large
00 00 - 36 2 alarm code. bitmask
0: EEP Fault
1: RTC Abnormal
00 00 - 38 2 alarm code. bitmask
0: Cell overvoltage
1: Cell undervoltage
2: Total overvoltage
3: Total undervoltage
4: Charge overcurrent
5: Discharge overcurrent
6: charge high temperature
7: charge low temperature
8: discharge high temperature
9: discharge low temperature
10: MOS hightemperature
11: Ambient hightemperature
12: Ambient low temperature
13: pressure difference is too large
14: temperature difference is too large
15: SOC is too low
00 03 - 40 2 MOSFET state bitmask (bit 1=discharge, 2=charge, 3=precharge, 4=heat, 5=fan, 6: node1, 7: node2, 8: limiting)
00 04 - 42 bitmask:
0: Charger
1: LOAD
2: SW
00 02 - 44 2 Number of charge cycles
00 09 9 46 2 cell # with highest voltage
0c db 3.291V 48 2 highest cell voltage
00 01 1 50 2 cell # with lowest voltage
0c d9 3.289V 52 2 lowest cell voltage
0c d9 3.289V 54 2 avg cell voltage
00 04 4 56 2 cell # with highest temperature
02 76 13.0°C 58 2 highest cell temperature: °C = (val - 500) / 10
00 01 1 60 2 cell # with lowest temperature
02 74 12.8°C 62 2 lowest cell temperature: °C = (val - 500) / 10
02 75 12.9°C 64 2 avg cell temperature: °C = (val - 500) / 10
02 48 - 66 2
07 d0 2000 68 2
01 c0 - 70 2
07 d0 2000 72 2 ?? value becomes 1000 when MOSFETS are both switched off
00 10 16 74 2 number of cells
0c d9 3.289 76 2 cell voltage 1
0c d9 3.289 78 2 cell voltage 2
0c da 3.290 80 2 cell voltage 3
0c d9 3.289 82 2 cell voltage 4
0c da 3.290 84 2 cell voltage 5
0c da 3.290 86 2 cell voltage 6
0c d9 3.289 88 2 cell voltage 7
0c da 3.290 90 2 cell voltage 8
0c db 3.291 92 2 cell voltage 9
0c d9 3.289 94 2 cell voltage 10
0c db 3.291 96 2 cell voltage 11
0c da 3.290 98 2 cell voltage 12
0c da 3.290 100 2 cell voltage 13
0c db 3.291 102 2 cell voltage 14
0c da 3.290 104 2 cell voltage 15
0c d9 3.289 106 2 cell voltage 16
00 04 4 108 2 number of temperature sensors
02 74 12.8°C 110 2 temperature 1: °C = (val - 500) / 10
02 75 12.9°C 112 2 temperature 2: °C = (val - 500) / 10
02 75 12.9°C 114 2 temperature 3: °C = (val - 500) / 10
02 76 13.0°C 116 2 temperature 4: °C = (val - 500) / 10
00 00 00 00 - 118
0d 02 - 122
4a 42 44 34 38 31 30 30 30 30 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 JBD48100000 124 30 sn code
00 02 2 154 2 Number of parallel packs
00 03 0x0003 156 2 bitmask of which packs are available (master only)
5a a6
00 00 00 00 00 00 00 00 00 00
bc 9a 0x9abc 170 2 crc

Pack Parameters

Request

01 78 1c 00 1c a0 00 00 7c 2e

bytes value position count description
01 1 0 1 address (battery #)
78 0x78 1 1 function code (read)
1c 00 0x1c00 2 2 start address
1c a0 0x1ca0 4 2 end address
00 00 0 6 2 data length
7c 2e 0x2e7c 8 2 crc (LSB 1st)

Response

bytes value position count description
01 1 0 1 address (battery #)
78 0x78 1 1 function code (read)
1c 00 0x1c00 2 2 start address
1c a0 0x1ca0 4 2 end address
00 88 136 6 2 data length
00 00 - 8 2
00 00 - 10 2
0d 48 3.400V 12 2 balance voltage
00 1e 0.030C 14 2 balance difference
01 f4 500 16 2 hot open temp
02 58 600 18 2 hot close temp
16 30 56.80V 20 2 full adjust voltage
05 dc 15.00A 22 2 full adjust current
55 50 31 36 53 30 31 39 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 00 00 00 00 UP16S019xxxxxxxxxxxxxxxxxx 24 30 bms code
07e8 2024 54 2 bms year
000c 12 56 2 bms month
00xx xx 58 2 bms day
4a 42 44 34 38 31 30 30 30 30 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 JBD48100000 60 30 sn code
07e8 2024 90 2 pack year
0006 6 92 2 pack month
00xx xx 94 2 pack day
45 43 4f 2d 4c 46 50 34 38 31 30 30 2d 33 55 2d xx xx xx xx 00 00 00 00 00 00 00 00 00 00 ECO-LFP48100-3U-xxxx 96 30 mfg code
00 00 - 126 2 deal type
0b b8 3000 128 2 sleep voltage
0b 40 2880 130 2 sleep delay
00 00 - 132 2 balance mode
00 00 - 134 2 RS485 type
00 00 - 136 2 CAN baud rate
00 00 - 138 2 RS485 baud rate
00 0a 10 140 2 sleep current
00 00 - 142 2
8e bf 0xbf8e 144 2 crc

Request

01 78 20 00 20 50 00 00 75 71

bytes value position count description
01 1 0 1 address (battery #)
78 0x78 1 1 function code (read)
20 00 0x2000 2 2 start address
20 50 0x2050 4 2 end address
00 00 0 6 2 data length
75 71 0x7175 8 2 crc (LSB 1st)

Response

bytes value position count description
01 1 0 1 address (battery #)
78 0x78 1 1 function code (read)
20 00 0x2000 2 2 start address
20 50 0x2050 4 2 end address
00 40 64 6 2 data length
27 10 100.00Ah 8 2 nominal capacity
27 10 100.00Ah 10 2 full capacity
1c 72 72.82Ah 12 2 remaining capacity
1c 72 72.82Ah 14 2 state of charge
00 64 100 16 2 state of health
00 02 2 18 2 charge cycles
00 96 150 20 2 cycle falloff factor
00 50 80 22 2 cycle factor
00 00 0 24 2 allowed charge - high
0d dd 3.549V 26 2 allowed charge - low
00 00 0 28 2 allowed discharge - high
08 e6 2.278V 30 2 allowed discharge - low
00 1e 20 32 2 self power factor
0c 1c 3.100V 34 2 ocv adjust voltage 1
00 14 20% 36 2 ocv adjust soc 1
0c 80 3.200V 38 2 ocv adjust voltage 2
00 1e 30% 40 2 ocv adjust soc 2
0d 7a 3.450V 42 2 ocv adjust voltage 3
00 50 80% 44 2 ocv adjust soc 3
0d de 3.550V 46 2 ocv adjust voltage 4
00 5a 90% 48 2 ocv adjust soc 4
02 48 584 50 2 charge need voltage
03 e8 1000 52 2 charge need current
01 c0 448 54 2 discharge need voltage
03 e8 1000 56 2 discharge need current
00 10 10 58 2 number of cells in pack
00 d2 210 60 2 rsns
00 04 - 62 2
05 34 - 64 2
00 7d - 66 2
00 00 - 68 2
10 00 - 70 2
f8 4c 0x4cf8 72 2 crc

Get current date/time from battery

Request

01 78 28 00 28 0F 00 00 46 4B

bytes value position count description
01 1 0 1 address (battery #)
78 0x78 1 1 function code (read)
28 00 0x2800 2 2 start address
28 0f 0x280f 4 2 end address
00 00 0 6 2 data length
46 4b 0x4b46 8 2 crc (LSB 1st)

Response

bytes value position count description
01 1 0 1 address (battery #)
78 0x78 1 1 function code (read)
28 00 0x2800 2 2 start address
28 0f 0x280f 4 2 end address
00 0c 0 6 2 data length
07 e9 2025 8 2 year
00 0a 10 10 2 month
00 1a 26 12 2 day
00 06 6 14 2 hour
00 2a 42 16 2 minute
00 07 7 18 2 second
c9 e1 0xe1c9 20 2 crc (LSB 1st)

Set current date/time on battery

Request

01 79 28 00 28 0C 00 10 11 4A 42 44 07 E9 00 05 00 14 00 06 00 27 00 1B 16 D0

bytes value position count description
01 1 0 1 address (battery #)
789 0x78 1 1 function code (set)
28 00 0x2800 2 2 start address
28 0c 0x280c 4 2 end address
00 10 16 6 2 data length
11 4A 42 44 \x11 JBD 8 4 identifier(?)
07 E9 2025 12 2 year
00 05 5 14 2 month
00 14 20 16 2 day
00 06 6 18 2 hour
00 27 39 20 2 minute
00 1B 27 22 2 second
16 d0 0xd016 24 2 crc (LSB 1st)

Response

bytes value position count description
01 1 0 1 address (battery #)
79 0x78 1 1 function code (set)
28 00 0x2800 2 2 start address
28 0c 0x280c 4 2 end address
00 0c 0 6 2 data length
07 E9 2025 8 2 year
00 05 5 10 2 month
00 14 20 12 2 day
00 06 6 14 2 hour
00 27 39 16 2 minute
00 1B 27 18 2 second
89 26 0x2689 20 2 crc (LSB 1st)

Unknown

Request

01 78 18 00 19 00 00 00 7d 44

bytes value position count description
01 1 0 1 address (battery #)
78 0x78 1 1 function code (read)
18 00 0x1800 2 2 start address
19 00 0x1900 4 2 end address
00 00 0 6 2 data length
7d 44 0x447d 8 2 crc (LSB 1st)

Response

bytes value position count description
01 1 0 1 address (battery #)
78 0x78 1 1 function code (read)
18 00 0x1800 2 2 start address
19 00 0x1900 4 2 end address
00 d0 208 6 2 data length
0e100d480bb80e420d480bb80a8c0b54
0bb809c40bb80bb8168015400bb816d0
15400bb8106812c003e80fa012c00bb8
041a03e807d004b007d00258000a0514
01f40258041a03e807d004b007d0003c
000a057800c8003c041a03e80bb8047e
03e80bb80226025803e801f4022603e8
041a03e803e8047e03e803e8015e0190
03e8012c015e03e805aa051403e8060e
054603e8044c03e80bb8047e044c0bb8
00fa012c0bb8012c015e0bb800500050
0bb8005000500bb8025801f41f400320
01f41f40000a000f07d00003000507d0
17 82 0x8217 8 2 crc (LSB 1st)

WiFi Module info

Request

01 78 24 00 24 50 00 00 75 c5

bytes value position count description
01 1 0 1 address (battery #)
78 0x78 1 1 function code (read)
24 00 0x2400 2 2 start address
24 50 0x2450 4 2 end address
00 00 0 6 2 data length
75 c5 0xc575 8 2 crc (LSB 1st)

Response (V2 battery has no WiFi module)

bytes value position count description
01 1 0 1 address (battery #)
78 0x78 1 1 function code (read)
24 00 0x2400 2 2 start address
24 50 0x2450 4 2 end address
00 0e 14 6 2 data length
00 00
00 00
00 00
00 00
00 00
00 00
00 00
f7 b5 0xb5f7 8 2 crc (LSB 1st)

Debug info

Request

01 78 2900 2910 0000 77a0

Response

017829002910000e000000000000000000000000000079d2

Unknown

Request

01 79 2914 2916 0006 114a 4244 6688 616b

Reset

Request Restart

01 79 2912 2914 0006 114a 4244 4a4a fbd2

Request Param default

0179290c290e0006114a424455aa2122

Request Factory reset

0179290e29100006114a42445a5aae8e

Set MOS control state

Request

bytes value position count description
01 1 0 1 address (battery #)
79 0x79 1 1 function code (write)
29 02 0x2902 2 2 start address
29 04 0x2904 4 2 end address
00 06 6 6 2 data length
11 4a 42 44 \x11 JBD 8 4 identifier
00 01 0x0001 12 2 bitmask:
bit 1: turn on CHG MOS
bit 2: turn on DSG MOS
bit 3: turn on Precharge MOS
bit 4: turn on HOT MOS
bit 5: turn on FAN MOS
bit 6: Turn on CHG Limit
15 85 0x8515 14 2 crc

Set sleep mode

bytes value position count description
01 1 0 1 address (battery #)
79 0x79 1 1 function code (write)
29 08 0x2908 2 2 start address
29 0a 0x290a 4 2 end address
00 06 6 6 2 data length
11 4a 42 44 \x11 JBD 8 4 identifier
a5 01 0xa501 12 2 0xa501 = Standby sleep
0xa502 = Deep sleep
03 6d 0x6d03 14 2 crc

Debug Mode

bytes value position count description
01 1 0 1 address (battery #)
79 0x79 1 1 function code (write)
29 00 0x2900 2 2 start address
29 02 0x2902 4 2 end address
00 06 6 6 2 data length
11 4a 42 44 \x11 JBD 8 4 identifier
00 00 0x0000 12 2 0x0000 = Normal mode
0x5a01 = Tooling mode
0x5a02 = DV/DP mode
f4 5d 0x5df4 14 2 crc

Dry Contact

bytes value position count description
01 1 0 1 address (battery #)
79 0x79 1 1 function code (write)
29 04 0x2904 2 2 start address
29 06 0x2906 4 2 end address
00 06 6 6 2 data length
11 4a 42 44 \x11 JBD 8 4 identifier
00 00 0x0000 12 2 bitmask
bit 1: dry contact 1
bit 2: dry contact 2
bit 3: ADDR OUT
bit 4: trip
d3 ad 0xadd3 14 2 crc

Set all debug params (?)

Request

01792900292c0030114a42440000002000000000a5020000000000000000000066880000000000000000000000000000000000000000000097fb

Alternate Pack Status

Request

01 45 00 00 00 54 00 00 d4 d3

bytes value position count description
01 1 0 1 address (battery #)
45 0x45 1 1 function code (read)
00 00 0x0000 2 2 start address
00 54 0x0054 4 2 end address
00 00 0 6 2 data length
d4 d3 0xd3d4 8 2 crc (LSB 1st)

Response

The decoding comes from marionw @ https://diysolarforum.com/threads/eco-worthy-48v-100ah-5120wh-lifepo4-server-rack-battery.92299/post-1447436

bytes value position count description
01 1 0 1 address (battery #)
45 0x45 1 1 function code (read)
00 00 0x0000 2 2 start address
00 54 0x0054 4 2 end address
00 7c 124 6 2 data length
00 10 16 8 2 number of cells
0c d8 3.288V 10 2 cell voltage 1
0c d8 3.288V 12 2 cell voltage 2
0c d8 3.288V 14 2 cell voltage 3
0c d8 3.288V 16 2 cell voltage 4
0c d8 3.288V 18 2 cell voltage 5
0c d9 3.289V 20 2 cell voltage 6
0c d8 3.288V 22 2 cell voltage 7
0c d8 3.288V 24 2 cell voltage 8
0c da 3.290V 26 2 cell voltage 9
0c d7 3.287V 28 2 cell voltage 10
0c da 3.290V 30 2 cell voltage 11
0c d9 3.289V 32 2 cell voltage 12
0c d9 3.289V 34 2 cell voltage 13
0c d9 3.289V 36 2 cell voltage 14
0c d9 3.289V 38 2 cell voltage 15
0c d8 3.288V 40 2 cell voltage 16
0c da 3.288V 42 2 maximum cell voltage
0c d7 3.287V 44 2 minimum cell voltage
14 8d 52.61V 46 2 total pack voltage
00 00 0A 48 2 max pack current
00 00 0A 50 2 min pack current
0b 23 28.51°C 52 2 temperature 1
0b 21 28.49°C 54 2 temperature 2
27 10 100.00% 56 2 full charge capacity
1c 7e 72.94% 58 2 remaining capacity
00 02 0.02A 60 2 current
00 48 72% 62 2 state of charge
00 64 100% 64 2 state of health
00 00 - 66 2
00 00 - 68 2
00 03 - 70 2 MOSFET state bitmask (bit 1=charge, 2=discharge)
00 00 - 72 2
42 4a 34 44 31 38 30 30 30 30 00 30 00 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 JBD48100000 74 30 sn code (bytes stored LSB in 16bit pairs, null terminated
03 e8 100.0 104 2 max charge current
03 e8 100.0 106 2 max discharge current
00 04 0x04 108 2 mosfet bitflags (?)
0b 25 28.53°C 110 2 MOSFET temperature
0b 30 28.64°C 112 2 ambient temperature
04 02 - 114 2
0b 21 28.49°C 116 2 temperatre sensor 1
0b 21 28.49°C 118 2 temperatre sensor 2
0b 22 28.50°C 120 2 temperatre sensor 3
0b 23 28.51°C 122 2 temperatre sensor 4
00 00 00 00 00 00 00 00 - 124 8
d3 c9 0xc9d3 132 2 crc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment