BydCanProtocol
A "reverse engineering" of the BYD CAN protocol when used with Victron/Venus OS
Install / Use
/learn @dfch/BydCanProtocolREADME
BYD Battery-Box Premium LVS CAN Protocol
A "reverse engineering" of the BYD Battery-Box Premium LVS CAN protocol when used with Victron/Venus OS. See the source code for a full working implementation.
The following information has been discovered between a BYD Battery-Box Premium LVS B019 / v1.23 and a Victron Venus OS v3.00. Battery-Box consist of 2 batteries in 1 tower (48V, 2* 78Ah).
CAN protocol is set to 500kBit/s (no FD). All frames are sent with 8 bytes length (zero padded).
When emulating a BYD battery it seems to be sufficient to just periodically send the following frames with a 900ms and 1000ms delay:
- 0x35E, ManufacturerInfo
- 0x382, ProductInfo
- 0x35F, BatteryInfo
- 0x35A, AlarmsWarnings
- 0x35B, EventsUnused
- 0x351, Dvcc
- 0x355, StateInfo
- 0x356, BatteryStats
- 0x360, Unknown0
- 0x372, BankInfo
- 0x373, CellInfo
- 0x374, CellVoltMinId
- 0x375, CellVoltMaxId
- 0x376, CellTempMinId
- 0x377, CellTempMaxId
- 0x378, History
- 0x379, BatterySize
Things to note:
- Frames sent from Victron seem to be ignorable. We can just start sending the frames at any time.
- I did not check if the order of the frames is important. The above sequence seems to work.
- If frames are not sent completeley or properly, Venus OS tends to recognise the sender as "Pylontech" or "CAN bus BMS".
- If frames are not sent frequently enough, Venus OS interprets the sender as being disconnected (offering to remove the device).
- "Redetect battery" in Venus OS seems to send some frames to the "battery". It seems to be sufficient to just keep on sending the above frames (no other sequence needed).
- All information has been dumped on a Raspberry 4 with Venus OS v3.00 (as written above) and a RS485 CAN HAT with
candump. - Emulation of the battery has been done from an Espressif ESP32 (and S2, S3) with a TJA1050/1 transceiver.
- (not really BYD related) Extended frames (with 29bit identifiier) seem to get ignored by Venus OS. So, in theory, it would be possible to connect a Venus OS to different CAN devices / batteries and have a single device aggregate the messages from each battery into a BYD message and send that to Venus OS.
- Here is a short video that shows the emulation of a BYD LVS BatteryBox.
Victron Communication / Identifiers
| Id | Hex | Ascii | Description | | --- | ----------------------- | -------- | --- | | 305 | 00 00 00 00 00 00 00 00 | ........ | ? it seems when no battery present: 305 and 307 are sent rapdily | | 306 | 00 00 00 00 00 00 00 00 | ........ | ? it seems when battery is present: 305, 306 and 307 are sent periodically | | 307 | 12 34 56 78 56 49 43 00 | .4VxVIC. | ? it seems when no battery present: 305 and 307 are sent rapdily |
BYD Communication / Identifiers
| Id | Hex | Ascii | Description | | --- | ----------------------- | -------- | --- | | 350 | | | not seen | | 351 | 48 02 00 05 00 05 AE 01 | H....... | Dvcc: CVL, CCL, DCL, DVL | | | | | [00:01] "48 02" (V10, DeciVolt) 58.4V CVL | | | | | [02:03] "00 05" (A/10, DeciAmp) 128.0A CCL | | | | | [04:05] "00 05" (A/10, DeciAmp) 128.0A DCL | | | | | [06:07] "AE 01" (V10, DeciVolt) 43.0V DVL | | 352 | | | not seen | | 353 | | | not seen | | 354 | | | not seen | | 355 | 43 00 64 00 00 00 00 00 | C.d..... | StateInfo: State of Charge, State of Health | | | | | [00:01] "43 00" (%) 67% SoC | | | | | [02:03] "64 00" (%) 100% SoH | | | | | [04:05] always null, ??? | | | | | [06:07] always null, ??? | | 356 | BE 14 F9 FF 8C 00 00 00 | ........ | BatteryStats: Voltage, Amps, Temperature | | | | | [00:01] "BE 14" (mV, MilliVolt) 53.1V current voltage | | | | | [02:03] "F9 FF" (A/10, DeciAmp, signed) -0.7A consumed Amps; "-" discharge / "+" charge | | | | | [04:05] "8C 00" (°C/10, Deci, signed) 14.0°C battery temperature | | | | | [06:07] always found to be null, definitely not Watts | | 357 | | | not seen | | 358 | | | not seen | | 359 | | | not seen | | 35A | AA AA AA AA AA AA AA AA | ........ | Alarms and Warnings, bit field, 'AA' means OK | | | 10 .. .. .. .. .. .. .. | ........ | [00] "10" Low battery voltage: Alarm | | | .. .. .. .. 10 .. .. .. | ........ | [04] "10" Low battery voltage: Warning | | | 04 .. .. .. .. .. .. .. | ........ | [00] "04" High battery voltage : Alarm | | | .. .. .. .. 04 .. .. .. | ........ | [04] "04" High battery voltage : Warning | | | .. .. 01 .. .. .. .. .. | ........ | [02] "01" High charge current: Alarm | | | .. .. .. .. .. .. 01 .. | ........ | [06] "01" High charge current: Warning | | | .. 40 .. .. .. .. .. .. | ........ | [01] "40" High discharge current: Alarm | | | .. .. .. .. .. 40 .. .. | ........ | [05] "40" High discharge current: Warning | | | .. 01 .. .. .. .. .. .. | ........ | [01] "01" Low temperature: Alarm | | | .. .. .. .. .. 01 .. .. | ........ | [05] "01" Low temperature: Warning | | | 40 .. .. .. .. .. .. .. | ........ | [00] "40" High temperature: Alarm | | | .. .. .. .. 40 .. .. .. | ........ | [04] "40" High temperature: Warning | | | .. 10 .. .. .. .. .. .. | ........ | [01] "10" Low charge temperature: Alarm | | | .. .. .. .. .. 10 .. .. | ........ | [05] "10" Low charge temperature: Warning | | | .. 04 .. .. .. .. .. .. | ........ | [01] "04" High charge temperature: Alarm | | | .. .. .. .. .. 04 .. .. | ........ | [05] "04" High charge temperature: Warning | | | .. .. 40 .. .. .. .. .. | ........ | [02] "40" Internal failure: Alarm | | | .. .. .. .. .. .. 40 .. | ........ | [06] "40" Internal failure: Warning | | | .. .. .. 01 .. .. .. .. | ........ | [03] "01" Cell imbalance: Alarm | | | .. .. .. .. .. .. .. 01 | ........ | [07] "01" Cell imbalance: Warning | | 35B | 00 00 00 00 00 00 00 00 | ........ | ??? always found to be null, aka Events | | 35C | | | not seen | | 35D | | | not seen | | 35E | 42 59 44 00 00 00 00 00 | BYD..... | ManufacturerInfo | | | | | [00:02] "BYD" (string) "BYD" manufacturer identification | | | | [04:07] always found to be null | 35F | 4C 69 01 17 69 00 00 00 | Li..i... | BatteryInfo: Product/Firmware version, Ah available | | | | | [00:01] "4C 69" product code, always seen that value | | | | | [02:03] "01 17" v1.17 firmware version | | | | | [04:05] "69 00" (Ah) 105Ah capacity available | | | | | [06:07] ??? always found to be null, might be hardware version according to MrConstantin84 | | 360 | 00 00 00 00 00 00 00 00 | ........ | ??? always found to be null | | 361 | | | not seen | | 362 | | | not seen | | 363 | | | not seen | | 364 | | | not seen | | 365 | | | not seen | | 366 | | | not seen | | 367 | | | not seen | | 368 | | | not seen | | 369 | | | not seen | | 36A | | | not seen | | 36B | | | not seen | | 36C | | | not seen | | 36D | | | not seen | | 36E | | | not seen | | 36F | | | not seen | | 370 | | | not seen | | 371 | | | not seen | | 372 | 02 00 00 00 00 00 00 00 | ........ | BankInfo | | | | ........ | 2 batteries online, 0 batteries offline | | | 02 00 .. .. .. .. .. .. | ........ | [00:01] "02 00" batteries online | | | | ........ | [02:03] "00 00" ???, seems to be ignored by Venus OS, see below | | | | ........ | [04:05] "00 00" ???, seems to be ignored by Venus OS, see below | | | .. .. .. .. .. .. 01 00 | ........ | [06:07] "01 00" batteries offline | | |
