Skip to content

Firmware version issues and some improvements #3

@martinisonline

Description

@martinisonline

Hello,

First of all, thank you for sharing this code.
I've used it to build my own system, and include some small changes that I would like to share if they can be useful to others.

My system:
US5000 (Master)
US2000C (Slave)
US2000C (Slave)
US2000C (Slave)

The specs of the Master:

Device address      : 1

Manufacturer        : Pylon

Device name         : US5000

Board version       : V10R04

Board               : NF4.E3

Main Soft version   : B69.25.0.0

Soft  version       : V2.0

Boot  version       : V1.0

Comm version        : V2.0

Release Date        : 24-05-13
  • The pattern to retrieve the "pwr" command data was not working properly in my case, because this firmware version includes some additional columns
  • Instead of the "Interval" option, I've used the sntp platform to have additional control at which time the refresh is done (just personal preference)
  • Added the retrieval of the FCC (system full charge capacity) and RC (system remaining capacity) to have more detail about the SOC (at decimal level) and SOH.
  • Some additional code to have the ability to trigger individual commands to each battery (Like bat 1, bat 2, .... or stat 1, stat 2, etc...)

Image

Image

Below the code that could inspire other people:


globals:
  - id: id_menu_option
    type: int
    restore_value: no
    initial_value: '0'

*****  [INCLUDE HERE YOUR OWN DEVICE SETTINGS LIKE logger, wifi settings, etc] ******


time:
  - platform: homeassistant
    id: homeassistant_time  

  - platform: sntp
    on_time:
      # Every 5 minutes
      - seconds: 0
        minutes: /2
        then:
          - logger.log:
              level: INFO
              format: "This has send the pwr command"
          - uart.write: "pwr\r\n"
          - delay: 2s

      - seconds: 10
        minutes: /2
        then:
          - logger.log:
              level: INFO
              format: "This has send the pwr command"
          - uart.write: "pwrsys\r\n"
          - delay: 2s   

uart:
  id: uart_bus
  tx_pin: 1
  rx_pin: 3
  baud_rate: 115200
  rx_buffer_size: 2048
  debug:
    direction: both
    dummy_receiver: true
    after:
      delimiter: "\n"
      #delimiter: "Command completed successfully" # > TENTAR SUBSTITUIR POR ALGO PARECIDO A JSON
      timeout: 500ms
    sequence:
      - lambda: |-
          UARTDebug::log_string(direction, bytes); // Logs the data line

          std::string str(bytes.begin(), bytes.end());

          int intValue = 0;

          //ESP_LOGD("main", "BLA: " %s, teste);


          //# Detecta qual o ultimo comando submetido. Inclui o numero da bateria (x=1,2,3,4,...)
          //1000 -> pwrsys
          //200x  -> bat x
          //4000  -> pwr
          //500x  -> stat x
          //########################################################
          if (strstr(str.c_str(), "pwr") != NULL) {
            id(id_menu_option) = 4000;
            return;
          }

          if (strstr(str.c_str(), "stat 1") != NULL) {
            id(id_menu_option) = 5001;
            return;
          }

          if (strstr(str.c_str(), "stat 2") != NULL) {
            id(id_menu_option) = 5002;
            return;
          }          

          if (strstr(str.c_str(), "stat 3") != NULL) {
            id(id_menu_option) = 5003;
            return;
          }  

          if (strstr(str.c_str(), "stat 4") != NULL) {
            id(id_menu_option) = 5004;
            return;
          }  


          //# ****STAT**** - Regista o Cycle times

          if (sscanf(str.c_str(), "CYCLE Times     : %d %%", &intValue) == 1) {
            
            switch (id(id_menu_option)) {
              case 5001:
                id(id_cycle_times_bat_1).publish_state(intValue);
                break;

              case 5002:
                id(id_cycle_times_bat_2).publish_state(intValue);
                break;   

              case 5003:
                id(id_cycle_times_bat_3).publish_state(intValue);
                break;

              case 5004:
                id(id_cycle_times_bat_4).publish_state(intValue);
                break;                                             
            }               

            return;
          } 


          //# ****PWRSYS****
          //*******************************************************************************
          if (sscanf(str.c_str(), " System SOH               : %d", &intValue) == 1) {
            id(id_system_soh).publish_state(intValue);
            return;
          }    

          if (sscanf(str.c_str(), " System Curr              : %d", &intValue) == 1) {
            id(id_system_current).publish_state(intValue);
            return;
          }   

          if (sscanf(str.c_str(), " Recommend chg current    : %d", &intValue) == 1) {
            id(id_system_recommended_charge_current).publish_state(intValue);
            return;
          }   

          if (sscanf(str.c_str(), " Recommend dsg current    : %d", &intValue) == 1) {
            id(id_system_recommended_discharge_current).publish_state(intValue);
            return;
          }                                

          // PWRSYS lowest voltage
          if (sscanf(str.c_str(), " Lowest voltage           : %d mV", &intValue) == 1) {
            id(id_system_cell_lowest_voltage).publish_state(intValue);
            return;
          }

          // PWRSYS highest voltage
          if (sscanf(str.c_str(), " Highest voltage          : %d mV", &intValue) == 1) {
            id(id_system_cell_highest_voltage).publish_state(intValue);
            return;
          }

          // PWRSYS FCC
          if (sscanf(str.c_str(), " System FCC               : %d mAH", &intValue) == 1) {
            id(id_system_fcc).publish_state(intValue);
            return;
          }  

          // PWRSYS RC
          if (sscanf(str.c_str(), " System RC                : %d mAH", &intValue) == 1) {
            id(id_system_rc).publish_state(intValue);
            return;
          }                   


          //# **** PWR *****
          // Mostra a informação de cada uma das baterias
          //*******************************************************************************************
          int matching_items=0;

          // Battery data lines:
          // Format:
          //Power     Volt   Curr   Tempr  Tlow   Tlow.Id  Thigh  Thigh.Id Vlow   Vlow.Id  Vhigh  Vhigh.Id Base.St  Volt.St  Curr.St  Temp.St  Coulomb  Time                 B.V.St   B.T.St  MosTempr M.T.St   SysAlarm.St
          //*1     *49628  *-5772  *21200  #20300  #8        #21000  #0        *3308   #1        *3309   #0        #Dischg   #Normal   #Normal   #Normal   94%      2025-02-06 02:57:52  Normal   Normal  21000    Normal   Normal  
          // Pattern to extract

          int battery_num, voltage, current, temperature, volts_cell_low, volts_cell_high, soc;

          matching_items = sscanf(str.c_str(), "%d %d %d %d %*d %*d %*d %*d %d %*d %d %*d %*s %*s %*s %*s %d%%", &battery_num, &voltage, &current, &temperature, &volts_cell_low, &volts_cell_high, &soc);

          if (id(id_menu_option) == 4000 && matching_items == 7) {
            if (battery_num >= 1 && battery_num <= 4) {
              switch (battery_num) {
                case 1:
                  //id(battery_1_voltage).publish_state(voltage);
                  id(battery_1_current).publish_state(current);
                  id(battery_1_temperature).publish_state(temperature);
                  id(battery_1_cell_voltage_low).publish_state(volts_cell_low);
                  id(battery_1_cell_voltage_high).publish_state(volts_cell_high);
                  id(battery_1_soc).publish_state(soc);
                  break;
                case 2:
                  //id(battery_2_voltage).publish_state(voltage);
                  id(battery_2_current).publish_state(current);
                  id(battery_2_temperature).publish_state(temperature);
                  id(battery_2_cell_voltage_low).publish_state(volts_cell_low);
                  id(battery_2_cell_voltage_high).publish_state(volts_cell_high);
                  id(battery_2_soc).publish_state(soc);
                  break;  
                case 3:
                  //id(battery_3_voltage).publish_state(voltage);
                  id(battery_3_current).publish_state(current);
                  id(battery_3_temperature).publish_state(temperature);
                  id(battery_3_cell_voltage_low).publish_state(volts_cell_low);
                  id(battery_3_cell_voltage_high).publish_state(volts_cell_high);
                  id(battery_3_soc).publish_state(soc);
                  break;
                case 4:
                  //id(battery_4_voltage).publish_state(voltage);
                  id(battery_4_current).publish_state(current);
                  id(battery_4_temperature).publish_state(temperature);
                  id(battery_4_cell_voltage_low).publish_state(volts_cell_low);
                  id(battery_4_cell_voltage_high).publish_state(volts_cell_high);
                  id(battery_4_soc).publish_state(soc);
                  break;                                                    
              }
            }
            //ESP_LOGD("main", "Matching ITEMS: %d BAT NUM: %d  VOLTS: %d  CURRENT: %d  TEMPERATURE: %d  CELL_V_LOW: %d CELL_V_HIGH: %d SOC: %d", matching_items, battery_num, voltage, current, temperature, volts_cell_low, volts_cell_high, soc);
            return;
          }

          
sensor:

  # Dados do comando pwrsys
  - platform: template
    name: "${device_name} SYSTEM SOH"
    id: id_system_soh
    unit_of_measurement: "%"
    accuracy_decimals: 1  

  - platform: template
    name: "${device_name} SYSTEM Current"
    id: id_system_current
    device_class: current
    state_class: measurement
    unit_of_measurement: "A"
    accuracy_decimals: 1
    filters:
      - multiply: 0.001

  - platform: template
    name: "${device_name} Recommended Charge Current"
    id: id_system_recommended_charge_current
    device_class: current
    state_class: measurement
    unit_of_measurement: "A"
    accuracy_decimals: 1
    filters:
      - multiply: 0.001

  - platform: template
    name: "${device_name} Recommended Discharge Current"
    id: id_system_recommended_discharge_current
    device_class: current
    state_class: measurement
    unit_of_measurement: "A"
    accuracy_decimals: 1
    filters:
      - multiply: 0.001    


  - platform: template
    name: "${device_name} SYSTEM Cell Lower Voltage"
    id: id_system_cell_lowest_voltage
    unit_of_measurement: "V"
    accuracy_decimals: 3
    device_class: voltage
    state_class: measurement
    filters:
      - multiply: 0.001

  - platform: template
    name: "${device_name} SYSTEM Cell highest Voltage"
    id: id_system_cell_highest_voltage
    unit_of_measurement: "V"
    accuracy_decimals: 3
    device_class: voltage
    state_class: measurement
    filters:
      - multiply: 0.001

  - platform: template
    name: "${device_name} SYSTEM FCC"
    id: id_system_fcc
    state_class: measurement
    unit_of_measurement: "mAH"
    accuracy_decimals: 0

  - platform: template
    name: "${device_name} SYSTEM RC"
    id: id_system_rc
    state_class: measurement
    unit_of_measurement: "mAH"
    accuracy_decimals: 0  




  # Dados do comando STAT x
  - platform: template
    name: "${device_name} Cycle Times BAT 1"
    id: id_cycle_times_bat_1
    accuracy_decimals: 0

  - platform: template
    name: "${device_name} Cycle Times BAT 2"
    id: id_cycle_times_bat_2
    accuracy_decimals: 0

  - platform: template
    name: "${device_name} Cycle Times BAT 3"
    id: id_cycle_times_bat_3
    accuracy_decimals: 0

  - platform: template
    name: "${device_name} Cycle Times BAT 4"
    id: id_cycle_times_bat_4
    accuracy_decimals: 0            


  # Dados do comando PWR *********************************

  # - platform: template
  #   name: "${device_name} Battery 1 Voltage"
  #   id: battery_1_voltage
  #   unit_of_measurement: "V"
  #   accuracy_decimals: 2
  #   device_class: voltage
  #   state_class: measurement    
  #   filters:
  #     - multiply: 0.001    

  # - platform: template
  #   name: "${device_name} Battery 2 Voltage"
  #   id: battery_2_voltage
  #   unit_of_measurement: "V"
  #   accuracy_decimals: 2
  #   device_class: voltage
  #   state_class: measurement    
  #   filters:
  #     - multiply: 0.001

  # - platform: template
  #   name: "${device_name} Battery 3 Voltage"
  #   id: battery_3_voltage
  #   unit_of_measurement: "V"
  #   accuracy_decimals: 2
  #   device_class: voltage
  #   state_class: measurement    
  #   filters:
  #     - multiply: 0.001  

  # - platform: template
  #   name: "${device_name} Battery 4 Voltage"
  #   id: battery_4_voltage
  #   unit_of_measurement: "V"
  #   accuracy_decimals: 2
  #   device_class: voltage
  #   state_class: measurement    
  #   filters:
  #     - multiply: 0.001                   



  - platform: template
    name: "${device_name} Battery 1 Current"
    id: battery_1_current
    unit_of_measurement: "A"
    accuracy_decimals: 2
    device_class: current
    state_class: measurement    
    filters:
      - multiply: 0.001  

  - platform: template
    name: "${device_name} Battery 2 Current"
    id: battery_2_current
    unit_of_measurement: "A"
    accuracy_decimals: 2
    device_class: current
    state_class: measurement    
    filters:
      - multiply: 0.001  

  - platform: template
    name: "${device_name} Battery 3 Current"
    id: battery_3_current
    unit_of_measurement: "A"
    accuracy_decimals: 2
    device_class: current
    state_class: measurement    
    filters:
      - multiply: 0.001  

  - platform: template
    name: "${device_name} Battery 4 Current"
    id: battery_4_current
    unit_of_measurement: "A"
    accuracy_decimals: 2
    device_class: current
    state_class: measurement    
    filters:
      - multiply: 0.001 


  - platform: template
    name: "${device_name} Battery 1 Temperature"
    id: battery_1_temperature
    unit_of_measurement: "°C"
    accuracy_decimals: 1
    device_class: temperature
    state_class: measurement    
    filters:
      - multiply: 0.001 

  - platform: template
    name: "${device_name} Battery 2 Temperature"
    id: battery_2_temperature
    unit_of_measurement: "°C"
    accuracy_decimals: 1
    device_class: temperature
    state_class: measurement    
    filters:
      - multiply: 0.001 

  - platform: template
    name: "${device_name} Battery 3 Temperature"
    id: battery_3_temperature
    unit_of_measurement: "°C"
    accuracy_decimals: 1
    device_class: temperature
    state_class: measurement    
    filters:
      - multiply: 0.001 

  - platform: template
    name: "${device_name} Battery 4 Temperature"
    id: battery_4_temperature
    unit_of_measurement: "°C"
    accuracy_decimals: 1
    device_class: temperature
    state_class: measurement    
    filters:
      - multiply: 0.001       


  - platform: template
    name: "${device_name} Battery 1 Cell Voltage Low"
    id: battery_1_cell_voltage_low
    unit_of_measurement: "V"
    accuracy_decimals: 3
    device_class: voltage
    state_class: measurement    
    filters:
      - multiply: 0.001  

  - platform: template
    name: "${device_name} Battery 2 Cell Voltage Low"
    id: battery_2_cell_voltage_low
    unit_of_measurement: "V"
    accuracy_decimals: 3
    device_class: voltage
    state_class: measurement    
    filters:
      - multiply: 0.001  

  - platform: template
    name: "${device_name} Battery 3 Cell Voltage Low"
    id: battery_3_cell_voltage_low
    unit_of_measurement: "V"
    accuracy_decimals: 3
    device_class: voltage
    state_class: measurement    
    filters:
      - multiply: 0.001  

  - platform: template
    name: "${device_name} Battery 4 Cell Voltage Low"
    id: battery_4_cell_voltage_low
    unit_of_measurement: "V"
    accuracy_decimals: 3
    device_class: voltage
    state_class: measurement    
    filters:
      - multiply: 0.001                    


  - platform: template
    name: "${device_name} Battery 1 Cell Voltage High"
    id: battery_1_cell_voltage_high
    unit_of_measurement: "V"
    accuracy_decimals: 3
    device_class: voltage
    state_class: measurement    
    filters:
      - multiply: 0.001   

  - platform: template
    name: "${device_name} Battery 2 Cell Voltage High"
    id: battery_2_cell_voltage_high
    unit_of_measurement: "V"
    accuracy_decimals: 3
    device_class: voltage
    state_class: measurement    
    filters:
      - multiply: 0.001 

  - platform: template
    name: "${device_name} Battery 3 Cell Voltage High"
    id: battery_3_cell_voltage_high
    unit_of_measurement: "V"
    accuracy_decimals: 3
    device_class: voltage
    state_class: measurement    
    filters:
      - multiply: 0.001 

  - platform: template
    name: "${device_name} Battery 4 Cell Voltage High"
    id: battery_4_cell_voltage_high
    unit_of_measurement: "V"
    accuracy_decimals: 3
    device_class: voltage
    state_class: measurement    
    filters:
      - multiply: 0.001                       


  - platform: template
    name: "${device_name} Battery 1 SOC"
    id: battery_1_soc
    unit_of_measurement: "%"
    accuracy_decimals: 1
    device_class: battery
    state_class: measurement    

  - platform: template
    name: "${device_name} Battery 2 SOC"
    id: battery_2_soc
    unit_of_measurement: "%"
    accuracy_decimals: 1
    device_class: battery
    state_class: measurement   

  - platform: template
    name: "${device_name} Battery 3 SOC"
    id: battery_3_soc
    unit_of_measurement: "%"
    accuracy_decimals: 1
    device_class: battery
    state_class: measurement   

  - platform: template
    name: "${device_name} Battery 4 SOC"
    id: battery_4_soc
    unit_of_measurement: "%"
    accuracy_decimals: 1
    device_class: battery
    state_class: measurement               




button:
  - platform: restart
    name: "${device_name} Restart"

  # Botões de STAT -----------------------------
  - platform: template
    name: "${device_name} BUTTON STAT - Battery 1 "
    on_press:
      - uart.write: "stat 1\r\n"    

  - platform: template
    name: "${device_name} BUTTON STAT - Battery 2 "
    on_press:
      - uart.write: "stat 2\r\n" 

  - platform: template
    name: "${device_name} BUTTON STAT - Battery 3 "
    on_press:
      - uart.write: "stat 3\r\n" 

  - platform: template
    name: "${device_name} BUTTON STAT - Battery 4 "
    on_press:
      - uart.write: "stat 4\r\n"     
      
  # Botões de BAT -------------------------------
  - platform: template
    name: "${device_name} BUTTON BAT - Battery 1 "
    on_press:
      - uart.write: "bat 1\r\n"    

  - platform: template
    name: "${device_name} BUTTON BAT - Battery 2 "
    on_press:
      - uart.write: "bat 2\r\n" 

  - platform: template
    name: "${device_name} BUTTON BAT - Battery 3 "
    on_press:
      - uart.write: "bat 3\r\n" 

  - platform: template
    name: "${device_name} BUTTON BAT - Battery 4 "
    on_press:
      - uart.write: "bat 4\r\n"  



  - platform: template
    name: "${device_name} BUTTON INFO"
    on_press:
      - uart.write: "info\r\n"
      
  - platform: template
    name: "${device_name} BUTTON POWER"
    on_press:
      - uart.write: "pwr\r\n"
      
  - platform: template
    name: "${device_name} BUTTON DATA"
    on_press:
      - uart.write: "data\r\n"
      
      
  - platform: template
    name: "${device_name} BUTTON Login Debug"
    on_press:
      - uart.write: "login debug\r\n"
      
  - platform: template
    name: "${device_name} BUTTON PWRSYS"
    on_press:
      - uart.write: "pwrsys\r\n"
      
  - platform: template
    name: "${device_name} BUTTON Logout"
    on_press:
      - uart.write: "logout\r\n"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions