syssi / esphome-jk-bms

ESPHome component to monitor and control a Jikong Battery Management System (JK-BMS) via UART-TTL or BLE
Apache License 2.0
472 stars 161 forks source link

Stayability - ESP frequently restarts several times a day #622

Open peff74 opened 6 days ago

peff74 commented 6 days ago

When expanding my system, I noticed that the ESP restarts quite frequently. As I don't have any experience with ESP home devices... I can't judge whether this is normal. image The last reboots are mine, I wanted to get some logs.

[16:22:07][D][Avg Temp:432]: Sensor 2: 17.200001
[16:22:07][D][Avg Temp:442]: Sensor 3 ist ungültig
[16:22:07][D][Avg Temp:450]: Sensor 4 ist ungültig
[16:22:07][D][Avg Temp:458]: Durchschnittstemperatur: 17.049999
[16:22:07][D][sensor:094]: 'Avg BMS Temp': Sending state 17.05000  with 1 decimals of accuracy
[16:22:07][D][climate:396]: 'heat_mat' - Sending state:
[16:22:07][D][climate:399]:   Mode: HEAT
[16:22:07][D][climate:401]:   Action: IDLE
[16:22:07][D][climate:419]:   Current Temperature: 17.05°C
[16:22:07][D][climate:425]:   Target Temperature: 16.00°C
[16:22:07][W][component:237]: Component template.sensor took a long time for an operation (52 ms).
[16:22:07][W][component:238]: Components should block for at most 30 ms.
[16:22:10][W][jk_bms_ble:240]: [20:22:08:25:26:8B] Not connected
[16:22:15][W][jk_bms_ble:240]: [20:22:08:25:26:8B] Not connected
[16:22:17][D][Avg Temp:424]: Sensor 1: 16.900000
[16:22:17][D][Avg Temp:432]: Sensor 2: 17.200001
[16:22:17][D][Avg Temp:442]: Sensor 3 ist ungültig
[16:22:17][D][Avg Temp:450]: Sensor 4 ist ungültig
[16:22:17][D][Avg Temp:458]: Durchschnittstemperatur: 17.049999
[16:22:17][D][sensor:094]: 'Avg BMS Temp': Sending state 17.05000  with 1 decimals of accuracy
[16:22:17][D][climate:396]: 'heat_mat' - Sending state:
[16:22:17][D][climate:399]:   Mode: HEAT
-----------------------------REBOOT--------------------------------
[16:22:28][W][component:170]: Component mqtt cleared Warning flag
[16:22:28][I][mqtt:286]: MQTT Connected!
[16:22:29][I][app:062]: setup() finished successfully!
[16:22:29][I][app:100]: ESPHome version 2024.10.2 compiled on Oct 28 2024, 21:54:25
[16:22:29][I][app:102]: Project syssi.esphome-jk-bms version 2.1.0
[16:22:29][C][logger:185]: Logger:
[16:22:29][C][logger:186]:   Level: DEBUG
[16:22:29][C][logger:188]:   Log Baud Rate: 115200
[16:22:29][C][logger:189]:   Hardware UART: UART0
[16:22:29][C][template.sensor:022]: Template Sensor 'Avg BMS Temp'
[16:22:29][C][template.sensor:022]:   State Class: ''
[16:22:29][C][template.sensor:022]:   Unit of Measurement: ''
[16:22:29][C][template.sensor:022]:   Accuracy Decimals: 1
[16:22:29][C][template.sensor:023]:   Update Interval: 10.0s
[16:22:29][C][uptime.sensor:033]: Uptime Sensor 'Uptime'
[16:22:29][C][uptime.sensor:033]:   Device Class: 'duration'
[16:22:29][C][uptime.sensor:033]:   State Class: 'total_increasing'
[16:22:29][C][uptime.sensor:033]:   Unit of Measurement: 's'
[16:22:29][C][uptime.sensor:033]:   Accuracy Decimals: 0
[16:22:29][C][uptime.sensor:033]:   Icon: 'mdi:timer-outline'
[16:22:29][C][uptime.sensor:034]:   Type: Seconds
[16:22:29][C][switch.gpio:068]: GPIO Switch 'heat_mat'
[16:22:29][C][switch.gpio:091]:   Restore Mode: always OFF

But I can't really see anything in the logs, the device just restarts. I had already replaced the hardware on suspicion, a WT32-ETH01

here my YAML:

substitutions:
  name: jk-bms
  bms0: "${name}"
  bms1: "${name}1"
  device_description: "Monitor and control a JK-BMS via bluetooth"
  external_components_source: github://syssi/esphome-jk-bms@main
  # Akku gross
  bms0_mac_address: 20:22:09:27:7c:44
  # Akku klein
  # mac_address: 20:22:08:25:0f:a9
  # Akku gross_2
  bms1_mac_address: 20:22:08:25:26:8b
  # Please use "JK02_24S" if you own a old JK-BMS < hardware version 11.0 (hardware version >= 6.0 and < 11.0)
  # Please use "JK02_32S" if you own a new JK-BMS >= hardware version 11.0 (f.e. JK-B2A8S20P hw 11.XW, sw 11.26)
  # Please use "JK04" if you have some old JK-BMS <= hardware version 3.0 (f.e. JK-B2A16S hw 3.0, sw. 3.3.0)
  bms0_protocol_version: JK02_32S
  bms1_protocol_version: JK02_32S

esphome:
  name: ${name}
  comment: ${device_description}
  min_version: 2024.6.0
  project:
    name: "syssi.esphome-jk-bms"
    version: 2.1.0
  on_boot:
    priority: 600  
    then:
      - climate.control:
          id: climate_heat_mat
          mode: HEAT  

esp32:
  board: esp-wrover-kit
  framework:
    type: esp-idf

external_components:
  - source: ${external_components_source}
    refresh: 0s

web_server:
  local: false

#wifi:
#  ssid: !secret wifi_ssid
#  password: !secret wifi_password

ethernet:
  type: LAN8720
  mdc_pin: GPIO23
  mdio_pin: GPIO18
  clk_mode: GPIO0_IN
  phy_addr: 1
  power_pin: GPIO16

ota:
  - platform: esphome
    password: ""
    on_begin:
      then:
        - switch.turn_off: ble_client_switch0
        - switch.turn_off: ble_client_switch1
        - logger.log: "BLE connection suspended for OTA update"

logger:
  level: DEBUG

# If you don't use Home Assistant please remove this `api` section and uncomment the `mqtt` component!
# api:

mqtt:
   broker: !secret mqtt_host
   username: !secret mqtt_username
   password: !secret mqtt_password
   id: mqtt_client
   discovery: false

esp32_ble_tracker:
  scan_parameters:
   active: false
  on_ble_advertise:
    then:
      - lambda: |-
          if (x.get_name().rfind("JK-", 0) == 0 || x.get_name().rfind("JK_", 0) == 0) {
            ESP_LOGI("ble_adv", "New JK-BMS found");
            ESP_LOGI("ble_adv", "  Name: %s", x.get_name().c_str());
            ESP_LOGI("ble_adv", "  MAC address: %s", x.address_str().c_str());
            ESP_LOGD("ble_adv", "  Advertised service UUIDs:");
            for (auto uuid : x.get_service_uuids()) {
              ESP_LOGD("ble_adv", "    - %s", uuid.to_string().c_str());
            }
          }

ble_client:
  - mac_address: ${bms0_mac_address}
    id: client0
  - mac_address: ${bms1_mac_address}
    id: client1

jk_bms_ble:
  - ble_client_id: client0
    protocol_version: ${bms0_protocol_version}
    throttle: 5s
    id: bms0
  - ble_client_id: client1
    protocol_version: ${bms1_protocol_version}
    throttle: 5s
    id: bms1

binary_sensor:
  - platform: jk_bms_ble
    jk_bms_ble_id: bms0
    balancing:
      name: "${bms0} balancing"
    charging:
      name: "${bms0} charging"
    discharging:
      name: "${bms0} discharging"
    online_status:
      name: "${bms0} online status"

  - platform: jk_bms_ble
    jk_bms_ble_id: bms1
    balancing:
      name: "${bms1} balancing"
    charging:
      name: "${bms1} charging"
    discharging:
      name: "${bms1} discharging"
    online_status:
      name: "${bms1} online status"

button:
  - platform: jk_bms_ble
    jk_bms_ble_id: bms0
    retrieve_settings:
      name: "${bms0} retrieve settings"
    retrieve_device_info:
      name: "${bms0} retrieve device info"

  - platform: jk_bms_ble
    jk_bms_ble_id: bms1
    retrieve_settings:
      name: "${bms1} retrieve settings"
    retrieve_device_info:
      name: "${bms1} retrieve device info"

number:
  - platform: jk_bms_ble
    jk_bms_ble_id: bms0
    balance_trigger_voltage:
      name: "${bms0} balance trigger voltage"
    cell_count:
      name: "${bms0} cell count"
    total_battery_capacity:
      name: "${bms0} total battery capacity"
    cell_voltage_overvoltage_protection:
      name: "${bms0} cell voltage overvoltage protection"
    cell_voltage_overvoltage_recovery:
      name: "${bms0} cell voltage overvoltage recovery"
    cell_voltage_undervoltage_protection:
      name: "${bms0} cell voltage undervoltage protection"
    cell_voltage_undervoltage_recovery:
      name: "${bms0} cell voltage undervoltage recovery"
    balance_starting_voltage:
      name: "${bms0} balance starting voltage"
    voltage_calibration:
      name: "${bms0} voltage calibration"
    current_calibration:
      name: "${bms0} current calibration"
    power_off_voltage:
      name: "${bms0} power off voltage"
    max_balance_current:
      name: "${bms0} max balance current"
    max_charge_current:
      name: "${bms0} max charge current"
    max_discharge_current:
      name: "${bms0} max discharge current"

  - platform: jk_bms_ble
    jk_bms_ble_id: bms1
    balance_trigger_voltage:
      name: "${bms1} balance trigger voltage"
    cell_count:
      name: "${bms1} cell count"
    total_battery_capacity:
      name: "${bms1} total battery capacity"
    cell_voltage_overvoltage_protection:
      name: "${bms1} cell voltage overvoltage protection"
    cell_voltage_overvoltage_recovery:
      name: "${bms1} cell voltage overvoltage recovery"
    cell_voltage_undervoltage_protection:
      name: "${bms1} cell voltage undervoltage protection"
    cell_voltage_undervoltage_recovery:
      name: "${bms1} cell voltage undervoltage recovery"
    balance_starting_voltage:
      name: "${bms1} balance starting voltage"
    voltage_calibration:
      name: "${bms1} voltage calibration"
    current_calibration:
      name: "${bms1} current calibration"
    power_off_voltage:
      name: "${bms1} power off voltage"
    max_balance_current:
      name: "${bms1} max balance current"
    max_charge_current:
      name: "${bms1} max charge current"
    max_discharge_current:
      name: "${bms1} max discharge current"   

sensor:
  - platform: jk_bms_ble
    jk_bms_ble_id: bms0
    min_cell_voltage:
      name: "${bms0} min cell voltage"
    max_cell_voltage:
      name: "${bms0} max cell voltage"
    min_voltage_cell:
      name: "${bms0} min voltage cell"
    max_voltage_cell:
      name: "${bms0} max voltage cell"
    delta_cell_voltage:
      name: "${bms0} delta cell voltage"
    average_cell_voltage:
      name: "${bms0} average cell voltage"
    cell_voltage_1:
      name: "${bms0} cell voltage 01"
    cell_voltage_2:
      name: "${bms0} cell voltage 02"
    cell_voltage_3:
      name: "${bms0} cell voltage 03"
    cell_voltage_4:
      name: "${bms0} cell voltage 04"
    cell_voltage_5:
      name: "${bms0} cell voltage 05"
    cell_voltage_6:
      name: "${bms0} cell voltage 06"
    cell_voltage_7:
      name: "${bms0} cell voltage 07"
    cell_voltage_8:
      name: "${bms0} cell voltage 08"
    cell_voltage_9:
      name: "${bms0} cell voltage 09"
    cell_voltage_10:
      name: "${bms0} cell voltage 10"
    cell_voltage_11:
      name: "${bms0} cell voltage 11"
    cell_voltage_12:
      name: "${bms0} cell voltage 12"
    cell_resistance_1:
      name: "${bms0} cell resistance 01"
    cell_resistance_2:
      name: "${bms0} cell resistance 02"
    cell_resistance_3:
      name: "${bms0} cell resistance 03"
    cell_resistance_4:
      name: "${bms0} cell resistance 04"
    cell_resistance_5:
      name: "${bms0} cell resistance 05"
    cell_resistance_6:
      name: "${bms0} cell resistance 06"
    cell_resistance_7:
      name: "${bms0} cell resistance 07"
    cell_resistance_8:
      name: "${bms0} cell resistance 08"
    cell_resistance_9:
      name: "${bms0} cell resistance 09"
    cell_resistance_10:
      name: "${bms0} cell resistance 10"
    cell_resistance_11:
      name: "${bms0} cell resistance 11"
    cell_resistance_12:
      name: "${bms0} cell resistance 12"
    total_voltage:
      name: "${bms0} total voltage"
    current:
      name: "${bms0} current"
    power:
      name: "${bms0} power"
    charging_power:
      name: "${bms0} charging power"
    discharging_power:
      name: "${bms0} discharging power"
    temperature_sensor_1:
      name: "${bms0} temperature sensor 1"
      id: temp_sensor_1
    temperature_sensor_2:
      name: "${bms0} temperature sensor 2"
      id: temp_sensor_2
    power_tube_temperature:
      name: "${bms0} power tube temperature"
    state_of_charge:
      name: "${bms0} state of charge"
    capacity_remaining:
      name: "${bms0} capacity remaining"
    total_battery_capacity_setting:
      name: "${bms0} total battery capacity setting"
    charging_cycles:
      name: "${bms0} charging cycles"
    total_charging_cycle_capacity:
      name: "${bms0} total charging cycle capacity"
    total_runtime:
      name: "${bms0} total runtime"
    balancing_current:
      name: "${bms0} balancing current"
    errors_bitmask:
      name: "${bms0} errors bitmask"

  - platform: jk_bms_ble
    jk_bms_ble_id: bms1
    min_cell_voltage:
      name: "${bms1} min cell voltage"
    max_cell_voltage:
      name: "${bms1} max cell voltage"
    min_voltage_cell:
      name: "${bms1} min voltage cell"
    max_voltage_cell:
      name: "${bms1} max voltage cell"
    delta_cell_voltage:
      name: "${bms1} delta cell voltage"
    average_cell_voltage:
      name: "${bms1} average cell voltage"
    cell_voltage_1:
      name: "${bms1} cell voltage 01"
    cell_voltage_2:
      name: "${bms1} cell voltage 02"
    cell_voltage_3:
      name: "${bms1} cell voltage 03"
    cell_voltage_4:
      name: "${bms1} cell voltage 04"
    cell_voltage_5:
      name: "${bms1} cell voltage 05"
    cell_voltage_6:
      name: "${bms1} cell voltage 06"
    cell_voltage_7:
      name: "${bms1} cell voltage 07"
    cell_voltage_8:
      name: "${bms1} cell voltage 08"
    cell_voltage_9:
      name: "${bms1} cell voltage 09"
    cell_voltage_10:
      name: "${bms1} cell voltage 10"
    cell_voltage_11:
      name: "${bms1} cell voltage 11"
    cell_voltage_12:
      name: "${bms1} cell voltage 12"
    cell_resistance_1:
      name: "${bms1} cell resistance 01"
    cell_resistance_2:
      name: "${bms1} cell resistance 02"
    cell_resistance_3:
      name: "${bms1} cell resistance 03"
    cell_resistance_4:
      name: "${bms1} cell resistance 04"
    cell_resistance_5:
      name: "${bms1} cell resistance 05"
    cell_resistance_6:
      name: "${bms1} cell resistance 06"
    cell_resistance_7:
      name: "${bms1} cell resistance 07"
    cell_resistance_8:
      name: "${bms1} cell resistance 08"
    cell_resistance_9:
      name: "${bms1} cell resistance 09"
    cell_resistance_10:
      name: "${bms1} cell resistance 10"
    cell_resistance_11:
      name: "${bms1} cell resistance 11"
    cell_resistance_12:
      name: "${bms1} cell resistance 12"
    total_voltage:
      name: "${bms1} total voltage"
    current:
      name: "${bms1} current"
    power:
      name: "${bms1} power"
    charging_power:
      name: "${bms1} charging power"
    discharging_power:
      name: "${bms1} discharging power"
    temperature_sensor_1:
      name: "${bms1} temperature sensor 1"
      id: temp_sensor_3
    temperature_sensor_2:
      name: "${bms1} temperature sensor 2"
      id: temp_sensor_4
    power_tube_temperature:
      name: "${bms1} power tube temperature"
    state_of_charge:
      name: "${bms1} state of charge"
    capacity_remaining:
      name: "${bms1} capacity remaining"
    total_battery_capacity_setting:
      name: "${bms1} total battery capacity setting"
    charging_cycles:
      name: "${bms1} charging cycles"
    total_charging_cycle_capacity:
      name: "${bms1} total charging cycle capacity"
    total_runtime:
      name: "${bms1} total runtime"
    balancing_current:
      name: "${bms1} balancing current"
    errors_bitmask:
      name: "${bms1} errors bitmask"

  - platform: uptime
    type: seconds
    name: Uptime

  - platform: template
    name: "Avg BMS Temp"
    id: avg_bms_temp
    update_interval: 10s
    lambda: |-
     float sum = 0.0;
     int count = 0;

     if (!isnan(id(temp_sensor_1).state)) {
       sum += id(temp_sensor_1).state;
       count += 1;
     ESP_LOGD("Avg Temp", "Sensor 1: %f", id(temp_sensor_1).state);
     } else {
       ESP_LOGD("Avg Temp", "Sensor 1 ist ungültig");
     }

     if (!isnan(id(temp_sensor_2).state)) {
       sum += id(temp_sensor_2).state;
       count += 1;
     ESP_LOGD("Avg Temp", "Sensor 2: %f", id(temp_sensor_2).state);
     } else {
       ESP_LOGD("Avg Temp", "Sensor 2 ist ungültig");
     }

     if (!isnan(id(temp_sensor_3).state)) {
       sum += id(temp_sensor_3).state;
       count += 1;
     ESP_LOGD("Avg Temp", "Sensor 3: %f", id(temp_sensor_3).state);
     } else {
       ESP_LOGD("Avg Temp", "Sensor 3 ist ungültig");
     }

     if (!isnan(id(temp_sensor_4).state)) {
       sum += id(temp_sensor_4).state;
       count += 1;
     ESP_LOGD("Avg Temp", "Sensor 4: %f", id(temp_sensor_4).state);
     } else {
       ESP_LOGD("Avg Temp", "Sensor 4 ist ungültig");
     }

     if (count == 0) {
       ESP_LOGD("Avg Temp", "Keine gültigen Temperatursensoren gefunden");
       return NAN;
     } else {
       float avg = sum / count;
       ESP_LOGD("Avg Temp", "Durchschnittstemperatur: %f", avg);
       return avg;
     }

climate:
  - platform: thermostat
    name: "heat_mat"
    sensor: avg_bms_temp
    heat_overrun: 1 °C
    min_idle_time: 60s
    min_heating_off_time: 1s
    min_heating_run_time: 60s
    heat_action:
      - switch.turn_on: heat_mat
    idle_action:
      - switch.turn_off: heat_mat
    visual:
      min_temperature: 0 °C
      max_temperature: 15 °C
      temperature_step: 0.5 °C  
    default_preset: Lower bound
    id: climate_heat_mat
    preset:
      - name: Lower bound
        default_target_temperature_low: 10 °C

switch:
  - platform: jk_bms_ble
    jk_bms_ble_id: bms0
    charging:
      name: "${bms0} charging"
    discharging:
      name: "${bms0} discharging"
    balancer:
      name: "${bms0} balancer"

  - platform: jk_bms_ble
    jk_bms_ble_id: bms1
    charging:
      name: "${bms1} charging"
    discharging:
      name: "${bms1} discharging"
    balancer:
      name: "${bms1} balancer"

  - platform: ble_client
    ble_client_id: client0
    id: ble_client_switch0
    name: "${bms0} enable bluetooth connection"
  - platform: ble_client
    ble_client_id: client1
    id: ble_client_switch1
    name: "${bms1} enable bluetooth connection"

  - platform: gpio
    name: "heat_mat"
    pin: GPIO14
    id: heat_mat

text_sensor:
  - platform: jk_bms_ble
    jk_bms_ble_id: bms0
    errors:
      name: "${bms0} errors"
    total_runtime_formatted:
      name: "${bms0} total runtime formatted"
  - platform: jk_bms_ble
    jk_bms_ble_id: bms1
    errors:
      name: "${bms1} errors"
    total_runtime_formatted:
      name: "${bms1} total runtime formatted"      

or do I have too many sensors or other errors?

syssi commented 5 days ago

Could you reduce your YAML configuration step by step just for testing. You are using a lot of heavy components (web_server, mqtt, two instances of the jk_bms_ble component etc.). Does the situation improve if you free some resources? Is you custom code stable / free of memory leaks in general?

peff74 commented 5 days ago

I will follow up on your suggestion. Firstly, I have now removed all my components and then deactivated the web server. I now only have a debug component in there to check the heap

image

My code used very little heap, the web used much more, now we are at 100KB free heap. Let's see how it goes image

syssi commented 5 days ago

You could free a lot of resources by changing the log level to INFO too.

peff74 commented 5 days ago

image something eats the heap and sometimes it comes to a bang...

So it's not in my code or the web server. I have now set the loglevel to Info. Let's wait and see how it reacts.

syssi commented 5 days ago

Good job!

peff74 commented 5 days ago

image

unfortunately there were more new starts despite loglevel INFO :-( Where else could I start to find out what is causing the problem?

which is clear, it starts with a significant heap loss

syssi commented 5 days ago

Please remove one of the BLE client connections as next step.

peff74 commented 5 days ago

done image

Now we got 114kb free heap. And the largest free block size has increased quite a bit to 64kb. Far right in the picture at 6:30 pm

peff74 commented 4 days ago

image the view this morning. A reboot around 10pm since then it has been running continuously image Here is a zoom into the crash at 10pm. Something seems to be stuck, once he makes it, then the second time it's over

syssi commented 4 days ago

Could you post your current YAML configuration? I would like to get an idea which components are still used.

syssi commented 4 days ago

Some next steps:

  1. Remove all jk_bms_ble entities from the YAML but don't remove the ble_client connection. We want still be able to connect to the BMS but we want to skip the data decoding.
  2. Remove the mqtt component and add the api or web_server component to check the uptime from time to time.
  3. Remove the complete BLE communication but add a number of template sensors which publish some random states periodically to generate some work/noise.

The idea is to identify the BLE stack or the network communication as root cause.

peff74 commented 4 days ago

this is then the YAML if I understand Step1 correctly?

substitutions:
  name: jk-bms
  bms0: "${name}"
#  bms1: "${name}1"
  device_description: "Monitor and control a JK-BMS via bluetooth"
  external_components_source: github://syssi/esphome-jk-bms@main
# Akku gross
  bms0_mac_address: 20:22:09:27:7c:44
# Akku klein
# mac_address: 20:22:08:25:0f:a9
# Akku gross_2
# bms1_mac_address: 20:22:08:25:26:8b
# Please use "JK02_24S" if you own a old JK-BMS < hardware version 11.0 (hardware version >= 6.0 and < 11.0)
# Please use "JK02_32S" if you own a new JK-BMS >= hardware version 11.0 (f.e. JK-B2A8S20P hw 11.XW, sw 11.26)
# Please use "JK04" if you have some old JK-BMS <= hardware version 3.0 (f.e. JK-B2A16S hw 3.0, sw. 3.3.0)
  bms0_protocol_version: JK02_32S
#bms1_protocol_version: JK02_32S

esphome:
  name: ${name}
  comment: ${device_description}
  min_version: 2024.6.0
  project:
    name: "syssi.esphome-jk-bms"
    version: 2.1.0
#  on_boot:
#    priority: 600
#    then:
#      - climate.control:
#          id: climate_heat_mat
#          mode: HEAT

esp32:
  board: esp-wrover-kit
  framework:
    type: esp-idf

external_components:
  - source: ${external_components_source}
    refresh: 0s

#web_server:
#  local: false

#wifi:
#  ssid: !secret wifi_ssid
#  password: !secret wifi_password

ethernet:
  type: LAN8720
  mdc_pin: GPIO23
  mdio_pin: GPIO18
  clk_mode: GPIO0_IN
  phy_addr: 1
  power_pin: GPIO16

ota:
  - platform: esphome
    password: ""
    on_begin:
      then:
        - switch.turn_off: ble_client_switch0
#        - switch.turn_off: ble_client_switch1
        - logger.log: "BLE connection suspended for OTA update"

logger:
#  level: DEBUG
  level: INFO

debug:
  update_interval: 5s

# If you don't use Home Assistant please remove this `api` section and uncomment the `mqtt` component!
# api:

mqtt:
   broker: !secret mqtt_host
   username: !secret mqtt_username
   password: !secret mqtt_password
   id: mqtt_client
   discovery: false

esp32_ble_tracker:
  scan_parameters:
   active: false
  on_ble_advertise:
    then:
      - lambda: |-
          if (x.get_name().rfind("JK-", 0) == 0 || x.get_name().rfind("JK_", 0) == 0) {
            ESP_LOGI("ble_adv", "New JK-BMS found");
            ESP_LOGI("ble_adv", "  Name: %s", x.get_name().c_str());
            ESP_LOGI("ble_adv", "  MAC address: %s", x.address_str().c_str());
            ESP_LOGD("ble_adv", "  Advertised service UUIDs:");
            for (auto uuid : x.get_service_uuids()) {
              ESP_LOGD("ble_adv", "    - %s", uuid.to_string().c_str());
            }
          }

ble_client:
  - mac_address: ${bms0_mac_address}
    id: client0
#  - mac_address: ${bms1_mac_address}
#    id: client1

# jk_bms_ble:
#  - ble_client_id: client0
#    protocol_version: ${bms0_protocol_version}
#    throttle: 5s
#    id: bms0
#  - ble_client_id: client1
#    protocol_version: ${bms1_protocol_version}
#    throttle: 5s
#    id: bms1

binary_sensor:
#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms0
#    balancing:
#      name: "${bms0} balancing"
#    charging:
#      name: "${bms0} charging"
#    discharging:
#      name: "${bms0} discharging"
#    online_status:
#      name: "${bms0} online status"

#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms1
#    balancing:
#      name: "${bms1} balancing"
#    charging:
#      name: "${bms1} charging"
#    discharging:
#      name: "${bms1} discharging"
#    online_status:
#      name: "${bms1} online status"

button:
#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms0
#    retrieve_settings:
#      name: "${bms0} retrieve settings"
#    retrieve_device_info:
#      name: "${bms0} retrieve device info"

#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms1
#    retrieve_settings:
#      name: "${bms1} retrieve settings"
#    retrieve_device_info:
#      name: "${bms1} retrieve device info"

number:
#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms0
#    balance_trigger_voltage:
#      name: "${bms0} balance trigger voltage"
#    cell_count:
#      name: "${bms0} cell count"
#    total_battery_capacity:
#      name: "${bms0} total battery capacity"
#   cell_voltage_overvoltage_protection:
#      name: "${bms0} cell voltage overvoltage protection"
#    cell_voltage_overvoltage_recovery:
#      name: "${bms0} cell voltage overvoltage recovery"
#    cell_voltage_undervoltage_protection:
#      name: "${bms0} cell voltage undervoltage protection"
#    cell_voltage_undervoltage_recovery:
#      name: "${bms0} cell voltage undervoltage recovery"
#    balance_starting_voltage:
#      name: "${bms0} balance starting voltage"
#    voltage_calibration:
#      name: "${bms0} voltage calibration"
#    current_calibration:
#      name: "${bms0} current calibration"
#    power_off_voltage:
#      name: "${bms0} power off voltage"
#    max_balance_current:
#      name: "${bms0} max balance current"
#    max_charge_current:
#      name: "${bms0} max charge current"
#    max_discharge_current:
#      name: "${bms0} max discharge current"

#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms1
#    balance_trigger_voltage:
#      name: "${bms1} balance trigger voltage"
#    cell_count:
#      name: "${bms1} cell count"
#    total_battery_capacity:
#      name: "${bms1} total battery capacity"
#    cell_voltage_overvoltage_protection:
#      name: "${bms1} cell voltage overvoltage protection"
#    cell_voltage_overvoltage_recovery:
#      name: "${bms1} cell voltage overvoltage recovery"
#    cell_voltage_undervoltage_protection:
#      name: "${bms1} cell voltage undervoltage protection"
#    cell_voltage_undervoltage_recovery:
#      name: "${bms1} cell voltage undervoltage recovery"
#    balance_starting_voltage:
#      name: "${bms1} balance starting voltage"
#    voltage_calibration:
#      name: "${bms1} voltage calibration"
#    current_calibration:
#      name: "${bms1} current calibration"
#    power_off_voltage:
#      name: "${bms1} power off voltage"
#    max_balance_current:
#      name: "${bms1} max balance current"
#    max_charge_current:
#      name: "${bms1} max charge current"
#    max_discharge_current:
#      name: "${bms1} max discharge current"

sensor:
#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms0
#    min_cell_voltage:
#      name: "${bms0} min cell voltage"
#    max_cell_voltage:
#      name: "${bms0} max cell voltage"
#    min_voltage_cell:
#      name: "${bms0} min voltage cell"
#    max_voltage_cell:
#      name: "${bms0} max voltage cell"
#    delta_cell_voltage:
#      name: "${bms0} delta cell voltage"
#    average_cell_voltage:
#      name: "${bms0} average cell voltage"
#    cell_voltage_1:
#      name: "${bms0} cell voltage 01"
#    cell_voltage_2:
#      name: "${bms0} cell voltage 02"
#    cell_voltage_3:
#     name: "${bms0} cell voltage 03"
#   cell_voltage_4:
#      name: "${bms0} cell voltage 04"
#    cell_voltage_5:
#      name: "${bms0} cell voltage 05"
#    cell_voltage_6:
#      name: "${bms0} cell voltage 06"
#    cell_voltage_7:
#      name: "${bms0} cell voltage 07"
#    cell_voltage_8:
#      name: "${bms0} cell voltage 08"
#    cell_voltage_9:
#      name: "${bms0} cell voltage 09"
#    cell_voltage_10:
#      name: "${bms0} cell voltage 10"
#    cell_voltage_11:
#      name: "${bms0} cell voltage 11"
#    cell_voltage_12:
#      name: "${bms0} cell voltage 12"
#    cell_resistance_1:
#      name: "${bms0} cell resistance 01"
#    cell_resistance_2:
#      name: "${bms0} cell resistance 02"
#    cell_resistance_3:
#      name: "${bms0} cell resistance 03"
#    cell_resistance_4:
#      name: "${bms0} cell resistance 04"
#    cell_resistance_5:
#      name: "${bms0} cell resistance 05"
#    cell_resistance_6:
#      name: "${bms0} cell resistance 06"
#    cell_resistance_7:
#      name: "${bms0} cell resistance 07"
#    cell_resistance_8:
#     name: "${bms0} cell resistance 08"
#    cell_resistance_9:
#      name: "${bms0} cell resistance 09"
#    cell_resistance_10:
#      name: "${bms0} cell resistance 10"
#    cell_resistance_11:
#      name: "${bms0} cell resistance 11"
#    cell_resistance_12:
#      name: "${bms0} cell resistance 12"
#    total_voltage:
#      name: "${bms0} total voltage"
#    current:
#      name: "${bms0} current"
#    power:
#      name: "${bms0} power"
#    charging_power:
#      name: "${bms0} charging power"
#    discharging_power:
#      name: "${bms0} discharging power"
#    temperature_sensor_1:
#     name: "${bms0} temperature sensor 1"
#     id: temp_sensor_1
#    temperature_sensor_2:
#      name: "${bms0} temperature sensor 2"
#      id: temp_sensor_2
#    power_tube_temperature:
#      name: "${bms0} power tube temperature"
#    state_of_charge:
#      name: "${bms0} state of charge"
#    capacity_remaining:
#      name: "${bms0} capacity remaining"
#    total_battery_capacity_setting:
#      name: "${bms0} total battery capacity setting"
#    charging_cycles:
#      name: "${bms0} charging cycles"
#    total_charging_cycle_capacity:
#      name: "${bms0} total charging cycle capacity"
#    total_runtime:
#      name: "${bms0} total runtime"
#    balancing_current:
#      name: "${bms0} balancing current"
#    errors_bitmask:
#      name: "${bms0} errors bitmask"

#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms1
#    min_cell_voltage:
#      name: "${bms1} min cell voltage"
#    max_cell_voltage:
#      name: "${bms1} max cell voltage"
#    min_voltage_cell:
#      name: "${bms1} min voltage cell"
#    max_voltage_cell:
#      name: "${bms1} max voltage cell"
#    delta_cell_voltage:
#      name: "${bms1} delta cell voltage"
#    average_cell_voltage:
#      name: "${bms1} average cell voltage"
#    cell_voltage_1:
#      name: "${bms1} cell voltage 01"
#    cell_voltage_2:
#      name: "${bms1} cell voltage 02"
#    cell_voltage_3:
#      name: "${bms1} cell voltage 03"
#    cell_voltage_4:
#      name: "${bms1} cell voltage 04"
#    cell_voltage_5:
#      name: "${bms1} cell voltage 05"
#    cell_voltage_6:
#      name: "${bms1} cell voltage 06"
#    cell_voltage_7:
#      name: "${bms1} cell voltage 07"
#    cell_voltage_8:
#      name: "${bms1} cell voltage 08"
#    cell_voltage_9:
#      name: "${bms1} cell voltage 09"
#    cell_voltage_10:
#      name: "${bms1} cell voltage 10"
#    cell_voltage_11:
#      name: "${bms1} cell voltage 11"
#    cell_voltage_12:
#      name: "${bms1} cell voltage 12"
#    cell_resistance_1:
#      name: "${bms1} cell resistance 01"
#    cell_resistance_2:
#      name: "${bms1} cell resistance 02"
#    cell_resistance_3:
#      name: "${bms1} cell resistance 03"
#    cell_resistance_4:
#      name: "${bms1} cell resistance 04"
#    cell_resistance_5:
#      name: "${bms1} cell resistance 05"
#    cell_resistance_6:
#      name: "${bms1} cell resistance 06"
#    cell_resistance_7:
#      name: "${bms1} cell resistance 07"
#    cell_resistance_8:
#      name: "${bms1} cell resistance 08"
#    cell_resistance_9:
#      name: "${bms1} cell resistance 09"
#    cell_resistance_10:
#      name: "${bms1} cell resistance 10"
#    cell_resistance_11:
#      name: "${bms1} cell resistance 11"
#    cell_resistance_12:
#      name: "${bms1} cell resistance 12"
#    total_voltage:
#      name: "${bms1} total voltage"
#    current:
#      name: "${bms1} current"
#    power:
#      name: "${bms1} power"
#    charging_power:
#      name: "${bms1} charging power"
#    discharging_power:
#      name: "${bms1} discharging power"
#    temperature_sensor_1:
#      name: "${bms1} temperature sensor 1"
#      id: temp_sensor_3
#    temperature_sensor_2:
#      name: "${bms1} temperature sensor 2"
#      id: temp_sensor_4
#    power_tube_temperature:
#      name: "${bms1} power tube temperature"
#    state_of_charge:
#      name: "${bms1} state of charge"
#    capacity_remaining:
#      name: "${bms1} capacity remaining"
#    total_battery_capacity_setting:
#      name: "${bms1} total battery capacity setting"
#    charging_cycles:
#      name: "${bms1} charging cycles"
#    total_charging_cycle_capacity:
#      name: "${bms1} total charging cycle capacity"
#    total_runtime:
#      name: "${bms1} total runtime"
#    balancing_current:
#      name: "${bms1} balancing current"
#    errors_bitmask:
#      name: "${bms1} errors bitmask"

#  - platform: template
#    name: "Avg BMS Temp"
#    id: avg_bms_temp
#    update_interval: 10s
#    lambda: |-
#     float sum = 0.0;
#     int count = 0;

#     if (!isnan(id(temp_sensor_1).state)) {
#       sum += id(temp_sensor_1).state;
#       count += 1;
#     ESP_LOGD("Avg Temp", "Sensor 1: %f", id(temp_sensor_1).state);
#     } else {
#       ESP_LOGD("Avg Temp", "Sensor 1 ist ungültig");
#     }

#     if (!isnan(id(temp_sensor_2).state)) {
#       sum += id(temp_sensor_2).state;
#       count += 1;
#     ESP_LOGD("Avg Temp", "Sensor 2: %f", id(temp_sensor_2).state);
#     } else {
#       ESP_LOGD("Avg Temp", "Sensor 2 ist ungültig");
#     }

#     if (!isnan(id(temp_sensor_3).state)) {
#       sum += id(temp_sensor_3).state;
#       count += 1;
#     ESP_LOGD("Avg Temp", "Sensor 3: %f", id(temp_sensor_3).state);
#     } else {
#       ESP_LOGD("Avg Temp", "Sensor 3 ist ungültig");
#     }

#     if (!isnan(id(temp_sensor_4).state)) {
#       sum += id(temp_sensor_4).state;
#       count += 1;
#     ESP_LOGD("Avg Temp", "Sensor 4: %f", id(temp_sensor_4).state);
#     } else {
#       ESP_LOGD("Avg Temp", "Sensor 4 ist ungültig");
#     }

#     if (count == 0) {
#       ESP_LOGD("Avg Temp", "Keine gültigen Temperatursensoren gefunden");
#       return NAN;
#     } else {
#       float avg = sum / count;
#       ESP_LOGD("Avg Temp", "Durchschnittstemperatur: %f", avg);
#       return avg;
#     }

  - platform: uptime
    type: seconds
    name: Uptime

  - platform: debug
    free:
      name: "Debug_Heap Free"
#    fragmentation:
#      name: "Debug_Heap Fragmentation"
    block:
      name: "Debug_Heap Max Block"
#    loop_time:
#      name: "Debug_Loop Time"
#    psram:
#      name: "Debug_Free PSRAM"

#climate:
#  - platform: thermostat
#    name: "heat_mat"
#    sensor: avg_bms_temp
#    heat_overrun: 1 °C
#    min_idle_time: 60s
#    min_heating_off_time: 1s
#    min_heating_run_time: 60s
#    heat_action:
#      - switch.turn_on: heat_mat
#    idle_action:
#      - switch.turn_off: heat_mat
#    visual:
#      min_temperature: 0 °C
#      max_temperature: 20 °C
#      temperature_step: 0.5 °C
#    default_preset: Lower bound
#    id: climate_heat_mat
#    preset:
#      - name: Lower bound
#        default_target_temperature_low: 10 °C

switch:
#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms0
#    charging:
#      name: "${bms0} charging"
#    discharging:
#      name: "${bms0} discharging"
#    balancer:
#      name: "${bms0} balancer"

#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms1
#    charging:
#      name: "${bms1} charging"
#    discharging:
#      name: "${bms1} discharging"
#    balancer:
#      name: "${bms1} balancer"

  - platform: ble_client
    ble_client_id: client0
    id: ble_client_switch0
    name: "${bms0} enable bluetooth connection"
#  - platform: ble_client
#    ble_client_id: client1
#    id: ble_client_switch1
#    name: "${bms1} enable bluetooth connection"

  - platform: gpio
    name: "heat_mat"
    pin: GPIO14
    id: heat_mat

text_sensor:
#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms0
#    errors:
#      name: "${bms0} errors"
#    total_runtime_formatted:
#      name: "${bms0} total runtime formatted"
#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms1
#    errors:
#      name: "${bms1} errors"
#    total_runtime_formatted:
#      name: "${bms1} total runtime formatted"
  - platform: debug
    device:
      name: "Device Info"
    reset_reason:
      name: "Reset Reason"
syssi commented 4 days ago

Correct!

peff74 commented 4 days ago

uploaded image

now we got 132kb free heap and the biggest block is ~90kb. And very few changes to the heap. I therefore now log every value and not just the changes

peff74 commented 3 days ago

image almost 24 hours without anything...

What would be the next steps?

syssi commented 3 days ago

Re-add a single BMS sensor f.e. total voltage.

peff74 commented 3 days ago
substitutions:
  name: jk-bms
  bms0: "${name}"
#  bms1: "${name}1"
  device_description: "Monitor and control a JK-BMS via bluetooth"
  external_components_source: github://syssi/esphome-jk-bms@main
# Akku gross
  bms0_mac_address: 20:22:09:27:7c:44
# Akku klein
# mac_address: 20:22:08:25:0f:a9
# Akku gross_2
# bms1_mac_address: 20:22:08:25:26:8b
# Please use "JK02_24S" if you own a old JK-BMS < hardware version 11.0 (hardware version >= 6.0 and < 11.0)
# Please use "JK02_32S" if you own a new JK-BMS >= hardware version 11.0 (f.e. JK-B2A8S20P hw 11.XW, sw 11.26)
# Please use "JK04" if you have some old JK-BMS <= hardware version 3.0 (f.e. JK-B2A16S hw 3.0, sw. 3.3.0)
  bms0_protocol_version: JK02_32S
#bms1_protocol_version: JK02_32S

esphome:
  name: ${name}
  comment: ${device_description}
  min_version: 2024.6.0
  project:
    name: "syssi.esphome-jk-bms"
    version: 2.1.0
#  on_boot:
#    priority: 600
#    then:
#      - climate.control:
#          id: climate_heat_mat
#          mode: HEAT

esp32:
  board: esp-wrover-kit
  framework:
    type: esp-idf

external_components:
  - source: ${external_components_source}
    refresh: 0s

#web_server:
#  local: false

#wifi:
#  ssid: !secret wifi_ssid
#  password: !secret wifi_password

ethernet:
  type: LAN8720
  mdc_pin: GPIO23
  mdio_pin: GPIO18
  clk_mode: GPIO0_IN
  phy_addr: 1
  power_pin: GPIO16

ota:
  - platform: esphome
    password: ""
    on_begin:
      then:
        - switch.turn_off: ble_client_switch0
#        - switch.turn_off: ble_client_switch1
        - logger.log: "BLE connection suspended for OTA update"

logger:
#  level: DEBUG
  level: INFO

debug:
  update_interval: 5s

# If you don't use Home Assistant please remove this `api` section and uncomment the `mqtt` component!
# api:

mqtt:
   broker: !secret mqtt_host
   username: !secret mqtt_username
   password: !secret mqtt_password
   id: mqtt_client
   discovery: false

esp32_ble_tracker:
  scan_parameters:
   active: false
  on_ble_advertise:
    then:
      - lambda: |-
          if (x.get_name().rfind("JK-", 0) == 0 || x.get_name().rfind("JK_", 0) == 0) {
            ESP_LOGI("ble_adv", "New JK-BMS found");
            ESP_LOGI("ble_adv", "  Name: %s", x.get_name().c_str());
            ESP_LOGI("ble_adv", "  MAC address: %s", x.address_str().c_str());
            ESP_LOGD("ble_adv", "  Advertised service UUIDs:");
            for (auto uuid : x.get_service_uuids()) {
              ESP_LOGD("ble_adv", "    - %s", uuid.to_string().c_str());
            }
          }

ble_client:
  - mac_address: ${bms0_mac_address}
    id: client0
#  - mac_address: ${bms1_mac_address}
#    id: client1

jk_bms_ble:
  - ble_client_id: client0
    protocol_version: ${bms0_protocol_version}
    throttle: 5s
    id: bms0
#  - ble_client_id: client1
#    protocol_version: ${bms1_protocol_version}
#    throttle: 5s
#    id: bms1

binary_sensor:
#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms0
#    balancing:
#      name: "${bms0} balancing"
#    charging:
#      name: "${bms0} charging"
#    discharging:
#      name: "${bms0} discharging"
#    online_status:
#      name: "${bms0} online status"

#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms1
#    balancing:
#      name: "${bms1} balancing"
#    charging:
#      name: "${bms1} charging"
#    discharging:
#      name: "${bms1} discharging"
#    online_status:
#      name: "${bms1} online status"

button:
#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms0
#    retrieve_settings:
#      name: "${bms0} retrieve settings"
#    retrieve_device_info:
#      name: "${bms0} retrieve device info"

#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms1
#    retrieve_settings:
#      name: "${bms1} retrieve settings"
#    retrieve_device_info:
#      name: "${bms1} retrieve device info"

number:
#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms0
#    balance_trigger_voltage:
#      name: "${bms0} balance trigger voltage"
#    cell_count:
#      name: "${bms0} cell count"
#    total_battery_capacity:
#      name: "${bms0} total battery capacity"
#   cell_voltage_overvoltage_protection:
#      name: "${bms0} cell voltage overvoltage protection"
#    cell_voltage_overvoltage_recovery:
#      name: "${bms0} cell voltage overvoltage recovery"
#    cell_voltage_undervoltage_protection:
#      name: "${bms0} cell voltage undervoltage protection"
#    cell_voltage_undervoltage_recovery:
#      name: "${bms0} cell voltage undervoltage recovery"
#    balance_starting_voltage:
#      name: "${bms0} balance starting voltage"
#    voltage_calibration:
#      name: "${bms0} voltage calibration"
#    current_calibration:
#      name: "${bms0} current calibration"
#    power_off_voltage:
#      name: "${bms0} power off voltage"
#    max_balance_current:
#      name: "${bms0} max balance current"
#    max_charge_current:
#      name: "${bms0} max charge current"
#    max_discharge_current:
#      name: "${bms0} max discharge current"

#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms1
#    balance_trigger_voltage:
#      name: "${bms1} balance trigger voltage"
#    cell_count:
#      name: "${bms1} cell count"
#    total_battery_capacity:
#      name: "${bms1} total battery capacity"
#    cell_voltage_overvoltage_protection:
#      name: "${bms1} cell voltage overvoltage protection"
#    cell_voltage_overvoltage_recovery:
#      name: "${bms1} cell voltage overvoltage recovery"
#    cell_voltage_undervoltage_protection:
#      name: "${bms1} cell voltage undervoltage protection"
#    cell_voltage_undervoltage_recovery:
#      name: "${bms1} cell voltage undervoltage recovery"
#    balance_starting_voltage:
#      name: "${bms1} balance starting voltage"
#    voltage_calibration:
#      name: "${bms1} voltage calibration"
#    current_calibration:
#      name: "${bms1} current calibration"
#    power_off_voltage:
#      name: "${bms1} power off voltage"
#    max_balance_current:
#      name: "${bms1} max balance current"
#    max_charge_current:
#      name: "${bms1} max charge current"
#    max_discharge_current:
#      name: "${bms1} max discharge current"

sensor:
  - platform: jk_bms_ble
    jk_bms_ble_id: bms0
#    min_cell_voltage:
#      name: "${bms0} min cell voltage"
#    max_cell_voltage:
#      name: "${bms0} max cell voltage"
#    min_voltage_cell:
#      name: "${bms0} min voltage cell"
#    max_voltage_cell:
#      name: "${bms0} max voltage cell"
#    delta_cell_voltage:
#      name: "${bms0} delta cell voltage"
#    average_cell_voltage:
#      name: "${bms0} average cell voltage"
#    cell_voltage_1:
#      name: "${bms0} cell voltage 01"
#    cell_voltage_2:
#      name: "${bms0} cell voltage 02"
#    cell_voltage_3:
#     name: "${bms0} cell voltage 03"
#    cell_voltage_4:
#      name: "${bms0} cell voltage 04"
#    cell_voltage_5:
#      name: "${bms0} cell voltage 05"
#    cell_voltage_6:
#      name: "${bms0} cell voltage 06"
#    cell_voltage_7:
#      name: "${bms0} cell voltage 07"
#    cell_voltage_8:
#      name: "${bms0} cell voltage 08"
#    cell_voltage_9:
#      name: "${bms0} cell voltage 09"
#    cell_voltage_10:
#      name: "${bms0} cell voltage 10"
#    cell_voltage_11:
#      name: "${bms0} cell voltage 11"
#    cell_voltage_12:
#      name: "${bms0} cell voltage 12"
#    cell_resistance_1:
#      name: "${bms0} cell resistance 01"
#    cell_resistance_2:
#      name: "${bms0} cell resistance 02"
#    cell_resistance_3:
#      name: "${bms0} cell resistance 03"
#    cell_resistance_4:
#      name: "${bms0} cell resistance 04"
#    cell_resistance_5:
#      name: "${bms0} cell resistance 05"
#    cell_resistance_6:
#      name: "${bms0} cell resistance 06"
#    cell_resistance_7:
#      name: "${bms0} cell resistance 07"
#    cell_resistance_8:
#     name: "${bms0} cell resistance 08"
#    cell_resistance_9:
#      name: "${bms0} cell resistance 09"
#    cell_resistance_10:
#      name: "${bms0} cell resistance 10"
#    cell_resistance_11:
#      name: "${bms0} cell resistance 11"
#    cell_resistance_12:
#      name: "${bms0} cell resistance 12"
    total_voltage:
      name: "${bms0} total voltage"
#    current:
#      name: "${bms0} current"
#    power:
#      name: "${bms0} power"
#    charging_power:
#      name: "${bms0} charging power"
#    discharging_power:
#      name: "${bms0} discharging power"
    temperature_sensor_1:
     name: "${bms0} temperature sensor 1"
     id: temp_sensor_1
    temperature_sensor_2:
      name: "${bms0} temperature sensor 2"
      id: temp_sensor_2
#    power_tube_temperature:
#      name: "${bms0} power tube temperature"
#    state_of_charge:
#      name: "${bms0} state of charge"
#    capacity_remaining:
#      name: "${bms0} capacity remaining"
#    total_battery_capacity_setting:
#      name: "${bms0} total battery capacity setting"
#    charging_cycles:
#      name: "${bms0} charging cycles"
#    total_charging_cycle_capacity:
#      name: "${bms0} total charging cycle capacity"
#    total_runtime:
#      name: "${bms0} total runtime"
#    balancing_current:
#      name: "${bms0} balancing current"
#    errors_bitmask:
#      name: "${bms0} errors bitmask"

#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms1
#    min_cell_voltage:
#      name: "${bms1} min cell voltage"
#    max_cell_voltage:
#      name: "${bms1} max cell voltage"
#    min_voltage_cell:
#      name: "${bms1} min voltage cell"
#    max_voltage_cell:
#      name: "${bms1} max voltage cell"
#    delta_cell_voltage:
#      name: "${bms1} delta cell voltage"
#    average_cell_voltage:
#      name: "${bms1} average cell voltage"
#    cell_voltage_1:
#      name: "${bms1} cell voltage 01"
#    cell_voltage_2:
#      name: "${bms1} cell voltage 02"
#    cell_voltage_3:
#      name: "${bms1} cell voltage 03"
#    cell_voltage_4:
#      name: "${bms1} cell voltage 04"
#    cell_voltage_5:
#      name: "${bms1} cell voltage 05"
#    cell_voltage_6:
#      name: "${bms1} cell voltage 06"
#    cell_voltage_7:
#      name: "${bms1} cell voltage 07"
#    cell_voltage_8:
#      name: "${bms1} cell voltage 08"
#    cell_voltage_9:
#      name: "${bms1} cell voltage 09"
#    cell_voltage_10:
#      name: "${bms1} cell voltage 10"
#    cell_voltage_11:
#      name: "${bms1} cell voltage 11"
#    cell_voltage_12:
#      name: "${bms1} cell voltage 12"
#    cell_resistance_1:
#      name: "${bms1} cell resistance 01"
#    cell_resistance_2:
#      name: "${bms1} cell resistance 02"
#    cell_resistance_3:
#      name: "${bms1} cell resistance 03"
#    cell_resistance_4:
#      name: "${bms1} cell resistance 04"
#    cell_resistance_5:
#      name: "${bms1} cell resistance 05"
#    cell_resistance_6:
#      name: "${bms1} cell resistance 06"
#    cell_resistance_7:
#      name: "${bms1} cell resistance 07"
#    cell_resistance_8:
#      name: "${bms1} cell resistance 08"
#    cell_resistance_9:
#      name: "${bms1} cell resistance 09"
#    cell_resistance_10:
#      name: "${bms1} cell resistance 10"
#    cell_resistance_11:
#      name: "${bms1} cell resistance 11"
#    cell_resistance_12:
#      name: "${bms1} cell resistance 12"
#    total_voltage:
#      name: "${bms1} total voltage"
#    current:
#      name: "${bms1} current"
#    power:
#      name: "${bms1} power"
#    charging_power:
#      name: "${bms1} charging power"
#    discharging_power:
#      name: "${bms1} discharging power"
#    temperature_sensor_1:
#      name: "${bms1} temperature sensor 1"
#      id: temp_sensor_3
#    temperature_sensor_2:
#      name: "${bms1} temperature sensor 2"
#      id: temp_sensor_4
#    power_tube_temperature:
#      name: "${bms1} power tube temperature"
#    state_of_charge:
#      name: "${bms1} state of charge"
#    capacity_remaining:
#      name: "${bms1} capacity remaining"
#    total_battery_capacity_setting:
#      name: "${bms1} total battery capacity setting"
#    charging_cycles:
#      name: "${bms1} charging cycles"
#    total_charging_cycle_capacity:
#      name: "${bms1} total charging cycle capacity"
#    total_runtime:
#      name: "${bms1} total runtime"
#    balancing_current:
#      name: "${bms1} balancing current"
#    errors_bitmask:
#      name: "${bms1} errors bitmask"

#  - platform: template
#    name: "Avg BMS Temp"
#    id: avg_bms_temp
#    update_interval: 10s
#    lambda: |-
#     float sum = 0.0;
#     int count = 0;

#     if (!isnan(id(temp_sensor_1).state)) {
#       sum += id(temp_sensor_1).state;
#       count += 1;
#     ESP_LOGD("Avg Temp", "Sensor 1: %f", id(temp_sensor_1).state);
#     } else {
#       ESP_LOGD("Avg Temp", "Sensor 1 ist ungültig");
#     }

#     if (!isnan(id(temp_sensor_2).state)) {
#       sum += id(temp_sensor_2).state;
#       count += 1;
#     ESP_LOGD("Avg Temp", "Sensor 2: %f", id(temp_sensor_2).state);
#     } else {
#       ESP_LOGD("Avg Temp", "Sensor 2 ist ungültig");
#     }

#     if (!isnan(id(temp_sensor_3).state)) {
#       sum += id(temp_sensor_3).state;
#       count += 1;
#     ESP_LOGD("Avg Temp", "Sensor 3: %f", id(temp_sensor_3).state);
#     } else {
#       ESP_LOGD("Avg Temp", "Sensor 3 ist ungültig");
#     }

#     if (!isnan(id(temp_sensor_4).state)) {
#       sum += id(temp_sensor_4).state;
#       count += 1;
#     ESP_LOGD("Avg Temp", "Sensor 4: %f", id(temp_sensor_4).state);
#     } else {
#       ESP_LOGD("Avg Temp", "Sensor 4 ist ungültig");
#     }

#     if (count == 0) {
#       ESP_LOGD("Avg Temp", "Keine gültigen Temperatursensoren gefunden");
#       return NAN;
#     } else {
#       float avg = sum / count;
#       ESP_LOGD("Avg Temp", "Durchschnittstemperatur: %f", avg);
#       return avg;
#     }

  - platform: uptime
    type: seconds
    name: Uptime

  - platform: debug
    free:
      name: "Debug_Heap Free"
#    fragmentation:
#      name: "Debug_Heap Fragmentation"
    block:
      name: "Debug_Heap Max Block"
#    loop_time:
#      name: "Debug_Loop Time"
#    psram:
#      name: "Debug_Free PSRAM"

#climate:
#  - platform: thermostat
#    name: "heat_mat"
#    sensor: avg_bms_temp
#    heat_overrun: 1 °C
#    min_idle_time: 60s
#    min_heating_off_time: 1s
#    min_heating_run_time: 60s
#    heat_action:
#      - switch.turn_on: heat_mat
#    idle_action:
#      - switch.turn_off: heat_mat
#    visual:
#      min_temperature: 0 °C
#      max_temperature: 20 °C
#      temperature_step: 0.5 °C
#    default_preset: Lower bound
#    id: climate_heat_mat
#    preset:
#      - name: Lower bound
#        default_target_temperature_low: 10 °C

switch:
#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms0
#    charging:
#      name: "${bms0} charging"
#    discharging:
#      name: "${bms0} discharging"
#    balancer:
#      name: "${bms0} balancer"

#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms1
#    charging:
#      name: "${bms1} charging"
#    discharging:
#      name: "${bms1} discharging"
#    balancer:
#      name: "${bms1} balancer"

  - platform: ble_client
    ble_client_id: client0
    id: ble_client_switch0
    name: "${bms0} enable bluetooth connection"
#  - platform: ble_client
#    ble_client_id: client1
#    id: ble_client_switch1
#    name: "${bms1} enable bluetooth connection"

  - platform: gpio
    name: "heat_mat"
    pin: GPIO14
    id: heat_mat

text_sensor:
#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms0
#    errors:
#      name: "${bms0} errors"
#    total_runtime_formatted:
#      name: "${bms0} total runtime formatted"
#  - platform: jk_bms_ble
#    jk_bms_ble_id: bms1
#    errors:
#      name: "${bms1} errors"
#    total_runtime_formatted:
#      name: "${bms1} total runtime formatted"
  - platform: debug
    device:
      name: "Device Info"
    reset_reason:
      name: "Reset Reason"

done, but I took three sensor^^

now we got 130kb free heap and the biggest block is ~86kb.

peff74 commented 2 days ago

image the current status. I had to activate my thermo function yesterday because it was getting too cold. Since I was unable to set the thermostat via MQTT, it always reset itself to the value I had set on the website, I also had to activate the web server. Nevertheless, it seems to be stable. So it seems to be the number of BMS sensors, or one of them has a problem?

What I found noteworthy is that opening the website has such a strong effect on the max block size. I don't know that from Arduino

syssi commented 2 days ago

It's too early to make assumptions but we are on a good track.

peff74 commented 2 days ago

What should I do next to continue testing? Can you tell me why the thermostat always gets the values that were last set on the website, even if the web server is no longer active? Do you save the settings on the ESP?

syssi commented 2 days ago

Let's stick to two sensors (per BMS) but add the second BMS again.

I'm on the road and cannot provide answers to your other questions ATM.

peff74 commented 1 day ago

I didn't get around to expanding it today. The system as last described is now running 24 hours stable :-)

I think tomorrow I will add the second BMS again

syssi commented 1 day ago

Please keep in mind, we have changed a lot of parameters and a lot of components are running faster now. It's possible the issue occurs on heavy load only.

peff74 commented 1 day ago

yes I understand, I think we will then add the components back in bit by bit and see what the problem is. Right?

syssi commented 1 day ago

Correct!

peff74 commented 9 hours ago

This morning I finally got round to adding the second BMS.

image

now we got 102kb free heap and the biggest block is ~60kb.

You can now clearly see how the largest block of the heap fluctuates and when the BMS went online, the free memory dropped further.

What I also noticed is that something about ‘cell resistance’ first appeared in the logs, although I didn't even have it active.