ESP32 + Tianpower BLE: Reboots Caused by Long MQTT Blocks

I have a problem with an ESP32 that reads a Tianpower BMS over BLE using ESPHome. After several tests the BLE part is stable and no longer shows errors. I also disabled the BLE tracker (which is not needed for this component) and I disabled several Tianpower sensors that I don’t use. This improved the situation a bit, but the issue is not solved.

The ESP32 still reboots every 20–40 minutes.
Wi‑Fi is good (–57 dBm), so it doesn’t seem to be a signal issue.
In the logs I see very long MQTT blocks, sometimes 1–4 seconds, like these:

mqtt took a long time for an operation (1401 ms)
mqtt took a long time for an operation (1745 ms)
mqtt took a long time for an operation (4213 ms)
10:40:30][W][component:493]: Components should block for at most 30 ms
[11:10:59][W][component:373]: mqtt cleared Warning flag
[11:10:59][W][component:490]: mqtt took a long time for an operation (107 ms)
[11:10:59][W][component:493]: Components should block for at most 30 ms
[11:10:59][W][component:490]: mqtt took a long time for an operation (53 ms)
[11:10:59][W][component:493]: Components should block for at most 30 ms
[11:10:59][W][component:490]: mqtt took a long time for an operation (69 ms)
[11:10:59][W][component:493]: Components should block for at most 30 ms

These delays are far above the ESPHome limit and they trigger the watchdog, causing the ESP32 to reboot.
BLE doesn’t seem involved anymore, and Wi‑Fi is stable. The problem seems to be MQTT getting blocked when many sensors are published at the same time.
I’m looking for advice from anyone with experience with Tianpower BLE, ESP32 freezing on MQTT publish, QoS settings, sensor bursts, or any optimization to avoid these long MQTT blocks.
Any help is appreciated.
Thanks,
Francesco

What platform are you running your HomeAssistant on? How much memory?
How much MQTT traffic do you have inbound?
What code is running the ESP32? Is it a bit chatty? Post the ESPHome code [formatted </> please]

Hello! Thank you so much for answering. Attached you will find the image of my VM and the dashboard with the ESP32 data. I just have this little problem with the Tianpower BMS.

substitutions:
  external_components_source: github://syssi/esphome-tianpower-bms@main
  name: esphome-web-568b34
  mac_address: 2C:C6:82:77:40:5C

esphome:
  name: ${name}
  friendly_name: Esp32 Basen
  min_version: 2025.10.3
  name_add_mac_suffix: false
  project:
    name: "syssi.esphome-tianpower-bms"
    version: 2.1.0
  build_path: build/${name}

esp32:
  board: esp32dev
  framework:
   type: arduino
external_components:
  - source: ${external_components_source}
    refresh: 0s

logger:
  level: WARN
  

mqtt:
  broker: 192.168.8.8
  username: esp32basen
  password: basen
  id: mqtt_client
  topic_prefix: ${name}
  discovery: true
  discovery_prefix: homeassistant
  reboot_timeout: 0s
  

wifi:
  ssid: 1111
  password: 1111
  power_save_mode: NONE  
ota:
  platform: esphome


# Necessario per BLE Client
esp32_ble_tracker:
  scan_parameters:
    active: false
ble_client:
  - mac_address: ${mac_address}
    id: client0

tianpower_bms_ble:
  - ble_client_id: client0
    id: bms0
    update_interval: 10s

binary_sensor:
  - platform: tianpower_bms_ble
    tianpower_bms_ble_id: bms0
    charging:
      name: "${name} charging"
    discharging:
      name: "${name} discharging"
    limiting_current:
      name: "${name} limiting current"

sensor:
  - platform: tianpower_bms_ble
    tianpower_bms_ble_id: bms0
  #   voltage_protection_bitmask:
  #     name: "${name} voltage protection bitmask"
  #   current_protection_bitmask:
  #     name: "${name} current protection bitmask"
  #   temperature_protection_bitmask:
  #     name: "${name} temperature protection bitmask"
  # error_bitmask:
  #   name: "${name} error bitmask"
    total_voltage:
      name: "${name} total voltage"
    current:
      name: "${name} current"
    power:
      name: "${name} power"
    charging_power:
      name: "${name} charging power"
    discharging_power:
      name: "${name} discharging power"
    capacity_remaining:
      name: "${name} capacity remaining"
    state_of_charge:
      name: "${name} state of charge"
    nominal_capacity:
      name: "${name} nominal capacity"
    charging_cycles:
      name: "${name} charging cycles"
    min_cell_voltage:
      name: "${name} min cell voltage"
    max_cell_voltage:
      name: "${name} max cell voltage"
    delta_cell_voltage:
      name: "${name} delta cell voltage"
    average_cell_voltage:
      name: "${name} average cell voltage"
    average_temperature:
      name: "${name} average temperature"
    ambient_temperature:
      name: "${name} ambient temperature"
    mosfet_temperature:
      name: "${name} mosfet temperature"
    #state_of_health:
     # name: "${name} state of health"
    temperature_1:
      name: "${name} temperature 1"
    temperature_2:
      name: "${name} temperature 2"
    temperature_3:
      name: "${name} temperature 3"
    temperature_4:
      name: "${name} temperature 4"
    cell_voltage_1:
      name: "${name} cell voltage 1"
    cell_voltage_2:
      name: "${name} cell voltage 2"
    cell_voltage_3:
      name: "${name} cell voltage 3"
    cell_voltage_4:
      name: "${name} cell voltage 4"
    cell_voltage_5:
      name: "${name} cell voltage 5"
    cell_voltage_6:
      name: "${name} cell voltage 6"
    cell_voltage_7:
      name: "${name} cell voltage 7"
    cell_voltage_8:
      name: "${name} cell voltage 8"
    cell_voltage_9:
      name: "${name} cell voltage 9"
    cell_voltage_10:
      name: "${name} cell voltage 10"
    cell_voltage_11:
      name: "${name} cell voltage 11"
    cell_voltage_12:
      name: "${name} cell voltage 12"
    cell_voltage_13:
      name: "${name} cell voltage 13"
    cell_voltage_14:
      name: "${name} cell voltage 14"
    cell_voltage_15:
      name: "${name} cell voltage 15"
    cell_voltage_16:
      name: "${name} cell voltage 16"
      
  - platform: uptime
    name: Uptime Sensor
    filters:
      - lambda: return x / 3600.0;
    unit_of_measurement: "h"
    accuracy_decimals: 2
  - platform: wifi_signal
    name: "ESP32 WiFi Strength"
    update_interval: 60s  


  
text_sensor:
  # - platform: tianpower_bms_ble
  #   tianpower_bms_ble_id: bms0
  #   software_version:
  #     name: "${name} software version"
  #   device_model:
  #     name: "${name} device model"
  #   voltage_protection:
  #     name: "${name} voltage protection"
  #   current_protection:
  #     name: "${name} current protection"
  #   temperature_protection:
  #     name: "${name} temperature protection"
  #   errors:
  #     name: "${name} errors"

  - platform: wifi_info
    ip_address:
      name: "${name} IP Address"
    ssid:
      name: "${name} WiFi SSID"


Just wondering if the Uptime Sensor code might be refactored to check for status less frequently as your WiFi doesn’t drop out that often I hope.

Are you getting you 10second TianPower readings often enough to hammer things too much? Does the information you received go up and down that often? Maybe experiment with that?

I note the device they tested the code on was a ESP32C6.

I read about every 10 seconds, because I’m interested in seeing the data almost in real time. I have 12 ESP32 and I assure you that a stable WiFi connection does not restart them. In the past I had this problem restarting with some ESP32, but after optimizing the database, reporting the signals with -57dB, the problems disappeared. From the logs I had noticed problems connecting with the MQTT server, but I believe this can be misleading because the server responds quickly. Perhaps, I’m not 100% sure, it’s an excessive load for ESP32, which is why in the code you’ve seen so many comments in the code lines.

Maybe refactor your ESPHome WiFi code to use on_disconnect if you don’t experience WiFi reliability issues.
The WiFi and BlueTooth are switched internally by the ESP32, back and forth as far as I know. This may be contributing to your problem.

Constant polling interval of 10sec may be overloading things. Have you tried increasing that to give yourself some breathing space for everything to catch up? To reassure yourself, how often do the actual figures returned by the BMS actually change? Plot a graph over a 5 minute window and watch the wiggles - any? Are you needing the data to be polled so often?

Consider going to RS485 instead of BLE if you need your data more reliably.

The BLE portion of ESPHome got some love recently. Are you using the latest versions? Your BMS BLE integration also? Try clearing the ESPHome cache and recompiling to bring in the latest in case there are some lingering leftovers.

I believe that BLE and WiFi can be used simultaneously by ESP32. I tried to activate the ESP32 BLE tracker, but it didn’t work. I tried a project with RS485, but that didn’t work either. I turned off the only app downloaded from HACS, TP_BS-25H-16-12 BLE Battery Management, and it works with my ESP32 proxy! The sissy code is more complete, with single cell data and more. I’ll show you in the attachment the graph of the resets.


Right now it’s resisting 1.18 h !!! Random…
I need the sensors every 5 sc as per the attachment.

Have you tried using esp-idf instead of arduino framework type for your compile option?

Curious what your other 11 ESP devices are doing.

Curious what the ESPHome log displays leading up to a ESP32 crash. Anything is the system logs? MQTT logs?

Is verbose debugging offering any clues?


Hello! I tried with the logs, but unfortunately I closed the page and I can’t show you. He reported a problem of disconnection with the broker. I also tried with esp-idf and Arduino. I’m waiting to catch the mistake. Given your interest and kindness, I will be very happy to have you analyzed!
If I hadn’t installed the uptime I wouldn’t have noticed the restart …

The heart specialist has found a beating heart, and the brain specialist hasn’t got back to me yet! Grins!

Intermittent errors are the hardest to troubleshoot. If you do manage to gather an entire log from compile to crash, post the portion at the beginning as well as the end - the boring bits in between that repeat may just be space wasters.

What does the Mosquitto log say? You will find it in the same spot as your system log in the dropdown options.

1 Like

See this … 2 Hours 22 minuts up !

this is a mistery :rofl::rofl:

Those peaks are typical of missed readings finally catching up. If you average them out, your data should be quite smooth.
Go back and find the bottleneck/error.

nsor:135]: 'esphome-web-568b34 cell voltage 14': Sending state 3.31600 V with 3 decimals of accuracy
[23:31:12][D][sensor:135]: 'esphome-web-568b34 cell voltage 15': Sending state 3.31500 V with 3 decimals of accuracy
[23:31:12][D][sensor:135]: 'esphome-web-568b34 cell voltage 16': Sending state 3.32000 V with 3 decimals of accuracy
[23:31:12][D][sensor:135]: 'esphome-web-568b34 min cell voltage': Sending state 3.31400 V with 3 decimals of accuracy
[23:31:12][D][sensor:135]: 'esphome-web-568b34 max cell voltage': Sending state 3.32000 V with 3 decimals of accuracy
[23:31:12][D][sensor:135]: 'esphome-web-568b34 delta cell voltage': Sending state 0.00600 V with 3 decimals of accuracy
[23:31:12][W][component:490]: esp32_ble took a long time for an operation (3187 ms)
[23:31:12][W][component:493]: Components should block for at most 30 ms
[23:31:19][D][tianpower_bms_ble:665]: Send command (handle 0x15): 55.04.83.AA
[23:31:19][D][tianpower_bms_ble:665]: Send command (handle 0x15): 55.04.84.AA
[23:31:19][D][tianpower_bms_ble:665]: Send command (handle 0x15): 55.04.85.AA
[23:31:19][D][tianpower_bms_ble:665]: Send command (handle 0x15): 55.04.87.AA
[23:31:19][D][tianpower_bms_ble:665]: Send command (handle 0x15): 55.04.88.AA
[23:31:19][D][tianpower_bms_ble:665]: Send command (handle 0x15): 55.04.89.AA

Report it as a problem with the Tianpower integration in GitHub.

Blocking during network activity (especially BLE) is not encouraged and you have pushed the boundaries to expose the design flaw.

Are you sure the author has not updated their code recently, as your yaml looks like it points to a specific version?

Infatti volevo creare un post su giut .
Ti faccio vedere alcuni estratti :slight_smile:

mqtt:311]: Connected
[23:41:36][W][component:490]: mqtt took a long time for an operation (109 ms)
[23:41:36][W][component:493]: Components should block for at most 30 ms
[23:41:36][W][component:490]: mqtt took a long time for an operation (57 ms)
[23:41:36][W][component:493]: Components should block for at most 30 ms
[23:42:19][D][sensor:135]: 'esphome-web-568b34 max cell voltage': Sending state 3.32300 V with 3 decimals of accuracy
[23:42:19][D][sensor:135]: 'esphome-web-568b34 delta cell voltage': Sending state 0.00600 V with 3 decimals of accuracy
[23:42:25][I][safe_mode:042]: Boot seems successful; resetting boot loop counter
[23:42:25][D][esp32.preferences:149]: Writing 1 items: 0 cached, 1 written, 0 failed

At the moment I thank you for the time you have dedicated to me.

Hi, I posted the issue on Git. Meanwhile, I attach an image that shows that the ESP32 does not restart. I purposely changed the Tianpower MAC, so I put in one incorrect. Happy New Year! :tada: