Issue integrating 100balance BMS with ESPHome via RS-485

Greetings.
I am trying to read 100balance BMS data with ESPHome, via RS-485 using my poorly assembled code (poor coder here):



---
esphome:
  name: 100balancebms
  friendly_name: 100balancebms
esp32:
  board: esp32dev
  framework:
    type: arduino
    
logger:
  level: DEBUG

api:
  encryption:
    key: "9m9SELxwXDJiWu1s/Kgs4N12efaD1u5/6v9bKtX5sUs="
ota:
  password: "50a122ebadf07ef55ed908b52c7c51b5"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  
  manual_ip:
    static_ip: 192.168.1.87
    gateway: 192.168.1.1
    subnet: 255.255.255.0
  ap:
    ssid: 100balancebms Fallback Hotspot
    password: HMVA5x3DAjDy

captive_portal:

uart:
  - id: uart_0
    baud_rate: 9600
    tx_pin: GPIO17
    rx_pin: GPIO16
    
    debug:
      direction: BOTH
      

modbus:
  - id: modbus0
    uart_id: uart_0
    send_wait_time: 1000ms

modbus_controller:
  
  - id: bms
    address: 0x81
    modbus_id: modbus0
    command_throttle: 5000ms
    update_interval: 10s
    setup_priority: -20
    
    
sensor:
  
  - platform: modbus_controller
    modbus_controller_id: bms
    name: Temperature 1
    address: 0x30
    register_type: holding
    value_type: U_WORD
    unit_of_measurement: C
    device_class: temperature
    state_class: measurement
    accuracy_decimals: 1
    filters:
      - multiply: 0.001
      - offset: -40

And the the log output is as follows:

INFO ESPHome 2024.5.5
INFO Reading configuration /config/100balancebms.yaml...
INFO Starting log output from 192.168.1.87 using esphome API
INFO Successfully connected to 100balancebms @ 192.168.1.87 in 0.115s
INFO Successful handshake with 100balancebms @ 192.168.1.87 in 0.106s
[15:46:58][I][app:100]: ESPHome version 2024.5.5 compiled on Jul 17 2024, 15:45:13
[15:46:58][C][wifi:580]: WiFi:
[15:46:58][C][wifi:408]:   Local MAC: FC:E8:C0:7D:BE:58
[15:46:58][C][wifi:413]:   SSID: [redacted]
[15:46:58][C][wifi:416]:   IP Address: 192.168.1.87
[15:46:58][C][wifi:420]:   BSSID: [redacted]
[15:46:58][C][wifi:421]:   Hostname: '100balancebms'
[15:46:58][C][wifi:423]:   Signal strength: -72 dB ▂▄▆█
[15:46:58][C][wifi:427]:   Channel: 1
[15:46:58][C][wifi:428]:   Subnet: 255.255.255.0
[15:46:58][C][wifi:429]:   Gateway: 192.168.1.1
[15:46:58][C][wifi:430]:   DNS1: 0.0.0.0
[15:46:58][C][wifi:431]:   DNS2: 0.0.0.0
[15:46:58][C][logger:185]: Logger:
[15:46:58][C][logger:186]:   Level: DEBUG
[15:46:58][C][logger:188]:   Log Baud Rate: 115200
[15:46:58][C][logger:189]:   Hardware UART: UART0
[15:46:58][C][uart.arduino_esp32:137]: UART Bus 1:
[15:46:58][C][uart.arduino_esp32:138]:   TX Pin: GPIO17
[15:46:58][C][uart.arduino_esp32:139]:   RX Pin: GPIO16
[15:46:58][C][uart.arduino_esp32:141]:   RX Buffer Size: 256
[15:46:58][C][uart.arduino_esp32:143]:   Baud Rate: 9600 baud
[15:46:58][C][uart.arduino_esp32:144]:   Data Bits: 8
[15:46:58][C][uart.arduino_esp32:145]:   Parity: NONE
[15:46:58][C][uart.arduino_esp32:146]:   Stop bits: 1
[15:46:58][C][modbus:143]: Modbus:
[15:46:58][C][modbus:145]:   Send Wait Time: 1000 ms
[15:46:58][C][modbus:146]:   CRC Disabled: NO
[15:46:58][C][modbus_controller.sensor:010]: modbus_controller.sensorModbus Controller Sensor 'Temperature 1'
[15:46:58][C][modbus_controller.sensor:010]: modbus_controller.sensor  Device Class: 'temperature'
[15:46:58][C][modbus_controller.sensor:010]: modbus_controller.sensor  State Class: 'measurement'
[15:46:58][C][modbus_controller.sensor:010]: modbus_controller.sensor  Unit of Measurement: 'C'
[15:46:58][C][modbus_controller.sensor:010]: modbus_controller.sensor  Accuracy Decimals: 1
[15:46:58][C][captive_portal:088]: Captive Portal:
[15:46:58][C][mdns:115]: mDNS:
[15:46:58][C][mdns:116]:   Hostname: 100balancebms
[15:46:58][C][ota:096]: Over-The-Air Updates:
[15:46:58][C][ota:097]:   Address: 192.168.1.87:3232
[15:46:58][C][ota:100]:   Using Password.
[15:46:58][C][ota:103]:   OTA version: 2.
[15:46:58][C][api:139]: API Server:
[15:46:58][C][api:140]:   Address: 192.168.1.87:6053
[15:46:58][C][api:142]:   Using noise encryption: YES
[15:46:58][C][modbus_controller:298]: ModbusController:
[15:46:58][C][modbus_controller:299]:   Address: 0x81
[15:47:00][D][uart_debug:114]: >>> 81:03:00:30:00:01:9B:C5
[15:47:00][W][modbus:135]: Got Modbus frame from unknown address 0x51! 
[15:47:00][D][uart_debug:114]: <<< 51:03:02:00:43:39:B9
[15:47:05][W][modbus_controller:136]: Duplicate modbus command found: type=0x3 address=48 count=1
[15:47:05][D][uart_debug:114]: >>> 81:03:00:30:00:01:9B:C5
[15:47:05][W][modbus:135]: Got Modbus frame from unknown address 0x51! 
[15:47:05][D][uart_debug:114]: <<< 51:03:02:00:43:39:B9
[15:47:10][D][uart_debug:114]: >>> 81:03:00:30:00:01:9B:C5
[15:47:10][W][modbus:135]: Got Modbus frame from unknown address 0x51! 
[15:47:10][D][uart_debug:114]: <<< 51:03:02:00:43:39:B9
[15:47:15][W][modbus_controller:136]: Duplicate modbus command found: type=0x3 address=48 count=1
[15:47:15][D][uart_debug:114]: >>> 81:03:00:30:00:01:9B:C5
[15:47:15][W][modbus:135]: Got Modbus frame from unknown address 0x51! 
[15:47:15][D][uart_debug:114]: <<< 51:03:02:00:43:39:B9

In the code I have inserted just one sensor for testing purposes. BMS default adress is 0x81, but the reply is according to the info from the seller from the adress0x51? It seems to recieve some frames from the BMS but with different adress. Does anybody know what else would be necessery to recieve data from the BMS?
I’ve contacted the manufacturer directly for RS-485 addressing and recieved such guidelines:


Will it work with ESPHome modbus component?
Here is a snippet of address table:

and the data type is declared as UNSIGNED SHORT INT. Does this correspond to U_WORD in ESPHome?
Would appriciate any guidelines and tips how to get it to work. I have a solar inverter connected already through RS-485 using syssi’s SMGII configuration from github, and it worked out of the box. I have used this config and modified it to try to connect to the BMS but to no avail apart from recieving random frames.

Response looks correct, it’s just not standard modbus protocol for the address part, so esphome gets confuse.
Is 0x43 ok for the temp? In deg it’s 67.
67-40=27

Yes, the temp looks right (arount 26-29 deg C ambient where the batteries are). Well, BMS has also normal UART and CAN communication. May as well try contact seller and ask them for those communication protocol details.
Thanks

Their uart communication might use same modbus protocol.

Anyway, modbus_controller has custom_command option, with lambda you probably can extract what you want from response.

Did you manage to do something?

Do you have the same BMS?

yes. i also found the 100Balance2MQTT project, but it asks for money for a license

And you tried that yaml from OP?
What you got in log?

same as yours

I don’t even have BMS.
Did you try with
address: 0x51
just in case there is mistake on that protocol sheet.

[16:40:55][C][modbus_controller:345]: ModbusController:
[16:40:55][C][modbus_controller:346]:   Address: 0x51
[16:40:55][D][uart_debug:114]: >>> 51 03 00 30 00 02 C8 54
[16:40:56][D][uart_debug:114]: >>> 51 03 00 30 00 02 C8 54
[16:40:57][D][uart_debug:114]: >>> 51 03 00 30 00 02 C8 54
[16:40:58][D][uart_debug:114]: >>> 51 03 00 30 00 02 C8 54
[16:40:59][D][modbus_controller:037]: Modbus command to device=81 register=0x30 countdown=0 no response received - removed from send queue

Slave address, not register address!!

  - id: bms
    address: 0x51
    modbus_id: modbus0
    command_throttle: 5000ms
    update_interval: 10s
    setup_priority: -20

This is the code I used

ok, but what is this then?

81 = 0x51 :upside_down_face:

Right, they really f…ked up their protocol.

So can you confirm that you get response when using 0x81, like OP got:

15:46:58][C][modbus_controller:298]: ModbusController:
[15:46:58][C][modbus_controller:299]:   Address: 0x81
[15:47:00][D][uart_debug:114]: >>> 81:03:00:30:00:01:9B:C5
[15:47:00][W][modbus:135]: Got Modbus frame from unknown address 0x51! 
[15:47:00][D][uart_debug:114]: <<< 51:03:02:00:43:39:B9
[17:06:27][C][modbus_controller:345]: ModbusController:
[17:06:27][C][modbus_controller:346]:   Address: 0x81
[17:06:29][D][uart_debug:114]: >>> 81 03 00 30 00 02 DB C4
[17:06:29][W][modbus:144]: Got Modbus frame from unknown address 0x51! 
[17:06:29][D][uart_debug:114]: <<< 51 03 04 00 41 00 40 FB D2
[17:06:29][D][uart_debug:114]: >>> 81 03 00 30 00 02 DB C4
[17:06:29][W][modbus:144]: Got Modbus frame from unknown address 0x51! 
[17:06:29][D][uart_debug:114]: <<< 51 03 04 00 41 00 40 FB D2
[17:06:29][D][uart_debug:114]: >>> 81 03 00 30 00 02 DB C4
[17:06:29][W][modbus:144]: Got Modbus frame from unknown address 0x51! 

Good.
What a ridiculous design they made.
Did you try if esphome let it pass when using custom_command?

i try send packed from doc’s

custom_command: [0x81, 0x03, 0x00, 0x00, 0x00, 0x7F, 0x1B, 0xEA]

answer

[17:14:14][D][uart_debug:114]: >>> 81 03 00 00 00 7F 1B EA 00 00
[17:14:14][W][component:237]: Component modbus took a long time for an operation (108 ms).
[17:14:14][W][component:238]: Components should block for at most 30 ms.
[17:14:14][D][uart_debug:114]: <<< 51 03 FE 0D 04 0D 04 0D 04 0D 04 0D 03 0D 04 0D 04 0D 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 41 00 40 00 00 00 00 00 00 00 00 00 00 00 00 01 0A 75 30 03 E8 00 7C 00 08 00 02 0D 04 00 01 0D 03 00 05 00 01 00 41 00 01 00 40 00 02 00 01 00 00 00
[17:14:14][W][component:237]: Component uart took a long time for an operation (106 ms).
[17:14:14][W][component:238]: Components should block for at most 30 ms.
[17:14:14][D][modbus:112]: Modbus CRC Check failed, but ignored! C071!=100
[17:14:14][W][modbus:144]: Got Modbus frame from unknown address 0x00! 
[17:14:14][D][modbus:112]: Modbus CRC Check failed, but ignored! 5070!=00
[17:14:14][W][modbus:144]: Got Modbus frame from unknown address 0x00! 
[17:14:14][D][modbus:112]: Modbus CRC Check failed, but ignored! C071!=30D
[17:14:14][W][modbus:144]: Got Modbus frame from unknown address 0x00! 
[17:14:14][D][modbus:112]: Modbus CRC Check failed, but ignored! C071!=00
[17:14:14][W][modbus:144]: Got Modbus frame from unknown address 0x00! 

try like this
edit, corrected 02 to 01

sensor:

  - platform: modbus_controller
    modbus_controller_id: bms
    name: Temperature 1
    #address: 0x30
    #register_type: holding
    custom_command: [ 0x81, 0x03, 0x00, 0x30,0x00, 0x01]
    value_type: U_WORD
    unit_of_measurement: C
    device_class: temperature
    state_class: measurement
    accuracy_decimals: 1
    filters:
      - multiply: 0.001
      - offset: -40