Nouveau protocole Daly BMS

Bonjour,

Mon problème

Nouveau protocole Daly BMS !
Intégration EspHome désormais non fonctionnelle.

Depuis plusieurs mois j’ai une batterie domestique qui fonctionne (8kWh, BMS 8s 100A)) dont je remonte les informations sur HA via l’intégration DalyBMS sur ESPhome, à travers un ESP32 et une liaison UART.

Je me décide en septembre, de me fabriquer une batterie portable type ‹ EcoFlow ›, sur les mêmes briques, mais en me limitant à 1300Wh.

J’achète un nouveau BMS Daly (4s 100A) avec les caractéristiques adéquates, et … plus rien ne fonctionne.

Après beaucoup de temps de recherche et d’essai, je trouve que Daly a changé son protocole de la liaison UART.
Le décodage de l’intégration DalyBMS d’ESPHome ne fonctionne plus.

Il semble que c’est depuis mi-juillet 2024 et les BMS livré avec le dongle Wifi+BT (anciennement uniquement BT).

Je vous mets mon code ci-dessous, qui fonctionne pour mon cas, avec les champs modifiables en lecture/écriture, en type Select, Number.
Les champs en lecture dans les Sensors.

J’espère que ça pourra vous aider et éviter de perdre du temps.

Pour le reste de la configuration, même schéma de branchement qu’avant, RX, TX et GND aux mêmes endroits sur le port UART.

J’ai eu aussi pas mal de problème car mon BMS ne s’activait pas quand j’allumais mon onduleur, en ayant accès à id(dischargingMOSSwitch) ça permet d’activer le tout.
Personnellement j’ai couplé l’action à un bouton :

binary_sensor:       
  - platform: gpio
    pin:
      number: 7
      inverted: true
      mode:
        input: true
        pullup: true
    id: bouton_activation
    name: "Bouton Activation"
    publish_initial_state: True
    filters:
      - delayed_on_off: 5ms
    on_press:
        - select.set:
            id: dischargingMOSSwitch
            option: "ON"
    on_release:
        - select.set:
            id: dischargingMOSSwitch
            option: "OFF"

Ma configuration


uart:
  - id: uart_1
    baud_rate: 9600
    tx_pin: GPIO43
    rx_pin: GPIO44
    debug:
      direction: BOTH
      dummy_receiver: true
      after:
        timeout: 100ms
      sequence:
        - lambda: UARTDebug::log_hex(direction, bytes, ' ');

modbus:
  - id: modbus_client
    uart_id: uart_1

modbus_controller:
- id: modbus_device
  address: 0xd2
  modbus_id: modbus_client
  update_interval: 10s

sensor:
  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: cell1
    id: cell1
    register_type: holding
    address: 0x00
    unit_of_measurement: "V"
    value_type: U_WORD
    accuracy_decimals: 3
    lambda: return .001 * (float)x;

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: cell2
    id: cell2
    register_type: holding
    address: 0x01
    unit_of_measurement: "V"
    value_type: U_WORD
    accuracy_decimals: 3
    lambda: return .001 * (float)x;

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: cell3
    id: cell3
    register_type: holding
    address: 0x02
    unit_of_measurement: "V"
    value_type: U_WORD
    accuracy_decimals: 3
    lambda: return .001 * (float)x;

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: cell4
    id: cell4
    register_type: holding
    address: 0x03
    unit_of_measurement: "V"
    value_type: U_WORD
    accuracy_decimals: 3
    lambda: return .001 * (float)x;

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: voltage difference
    id: voltageDiff
    register_type: holding
    address: 0x38
    unit_of_measurement: "V"
    value_type: U_WORD
    accuracy_decimals: 3
    lambda: return .001 * (float)x;

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: temperature1
    id: temperature
    register_type: holding
    address: 0x20
    unit_of_measurement: "C"
    value_type: U_WORD
    accuracy_decimals: 0
    lambda: return x-40;

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: SOC
    id: niveau
    register_type: holding
    address: 0x2A
    unit_of_measurement: "%"
    value_type: U_WORD
    accuracy_decimals: 1
    lambda: return .1 * (float)x;
  
  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: Capacite restante
    id: capacity
    register_type: holding
    address: 0x30
    unit_of_measurement: "Ah"
    value_type: U_WORD
    accuracy_decimals: 1
    lambda: return .1 * (float)x;

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: voltage
    id: tension
    register_type: holding
    address: 0x28
    unit_of_measurement: "V"
    value_type: U_WORD
    accuracy_decimals: 1
    lambda: return .1 * (float)x;

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: current
    id: courant
    register_type: holding
    address: 0x29
    unit_of_measurement: "A"
    value_type: U_WORD
    accuracy_decimals: 1
    lambda: return .1 * (float)(x-30000);

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: status BMS
    id: statusBMS
    register_type: holding
    address: 0x2F
    unit_of_measurement: ""
    value_type: U_WORD
    accuracy_decimals: 0
    lambda: return (float)x;

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: power
    id: puissance
    register_type: holding
    address: 0x39
    unit_of_measurement: "W"
    value_type: U_WORD
    accuracy_decimals: 1
    lambda: return (float)x;

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: faultBitmap1
    id: erreur
    register_type: holding
    address: 0x3a
    unit_of_measurement: ""
    value_type: U_WORD

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: Cycles batterie realise
    register_type: holding
    address: 0x33
    skip_updates: 10
    unit_of_measurement: ""
    value_type: U_WORD

  - platform: template
    name: fin_charge
    id: fin_charge
    update_interval: 1s
    lambda: return 60.0*((id(ratedCapacity).state - id(capacity).state) / id(courant).state);
  
  - platform: template
    name: fin_decharge
    id: fin_decharge
    update_interval: 1s
    lambda: return -60.0*(id(capacity).state / id(courant).state);

text_sensor:
  - platform: modbus_controller
    modbus_controller_id: modbus_device
    register_type: holding
    address: 0x35
    name: charge MOS status
    id: chargeMOSStatus
    lambda: |-
      uint16_t value = modbus_controller::word_from_hex_str(x, 0);
      switch (value) {
        case 0: return std::string("Off");
        case 1: return std::string("On");
        default: return std::string("Unknown");
      }
      return x;

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    register_type: holding
    address: 0x36
    name: discharge MOS status
    id: dischargeMOSStatus
    lambda: |-
      uint16_t value = modbus_controller::word_from_hex_str(x, 0);
      switch (value) {
        case 0: return std::string("Off");
        case 1: return std::string("On");
        default: return std::string("Unknown");
      }
      return x;
    
  - platform: modbus_controller
    modbus_controller_id: modbus_device
    register_type: holding
    address: 0x2F
    name: MOS status
    lambda: |-
      uint16_t value = modbus_controller::word_from_hex_str(x, 0);
      switch (value) {
        case 0: return std::string("Stationary");
        case 1: return std::string("Charging");
        case 2: return std::string("Discharging");
        default: return std::string("Unknown");
      }
      return x;
    
  - platform: modbus_controller
    modbus_controller_id: modbus_device
    register_type: holding
    address: 0xA9
    name: Version logiciel BMS
    skip_updates: 10
  
  - platform: modbus_controller
    modbus_controller_id: modbus_device
    register_type: holding
    address: 0xB1
    name: Version materiel BMS
    skip_updates: 10

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    register_type: holding
    address: 0xCC
    name: Date de production BMS
    skip_updates: 10
    raw_encode: HEXBYTES

number:    
  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: "Battery SOC Number"
    address: 0xA7
    value_type: U_WORD
    unit_of_measurement: "%"
    min_value: 0
    max_value: 100
    step: 1
    lambda: return  x * .1;
    write_lambda: return  x * 10;

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: "Rated capacity"
    id: ratedCapacity
    address: 0x80
    value_type: U_WORD
    unit_of_measurement: "Ah"
    min_value: 0
    max_value: 150
    step: 1
    lambda: return  x * .1;
    write_lambda: return  x * 10;

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: "Tension reference cellule"
    address: 0x81
    value_type: U_WORD
    unit_of_measurement: "mV"
    min_value: 1000
    max_value: 5000
    step: 100

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: "Tension debut equilibrage"
    address: 0xA3
    value_type: U_WORD
    unit_of_measurement: "mV"
    min_value: 1000
    max_value: 5000
    step: 100

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: "Difference tension debut equilibrage"
    address: 0xA4
    value_type: U_WORD
    unit_of_measurement: "mV"
    min_value: 0
    max_value: 200
    step: 10

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: "Temperature de protection"
    address: 0xA8
    value_type: U_WORD
    unit_of_measurement: "°C"
    min_value: 0
    max_value: 60
    step: 1
    lambda: return  x - 40;
    write_lambda: return  x + 40;

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    name: "Sleep wait time"
    id: sleepWaitTime
    address: 0x8A
    value_type: U_WORD
    unit_of_measurement: "s"
    min_value: 0
    max_value: 10000
    step: 100

select:
  - platform: modbus_controller
    name: "charging MOS switch"
    id: chargingMOSSwitch
    address: 0xA5
    optionsmap:
      "OFF": 0
      "ON": 1
  
  - platform: modbus_controller
    name: "discharging MOS switch"
    id: dischargingMOSSwitch
    address: 0xA6
    optionsmap:
      "OFF": 0
      "ON": 1

  - platform: modbus_controller
    modbus_controller_id: modbus_device
    id: batteryType
    skip_updates: 10
    address: 0x89
    name: Battery type
    optionsmap:
      "LiFePO4": 0
      "ternary": 1
      "Lithium titanate": 2


En espérant vous aider d’une manière ou d’une autre.

Bonne soirée :wink:

1 « J'aime »