Bang Bang Climate Controller, nan target temperatures

I have an esp32 minding my Daly BMS and have recently added a low wattage heat mat to the large battery box. I am attempting to use the Bang Bang Climate Controller to switch the heat mat on and off.

Sadly the default_target_temperature_low and default_target_temperature_high are being reported in the logs as nan

What have I missed or done incorrectly?

climate:
  - platform: bang_bang # can add cooling fan to this using cool_action
    name: "Battery Box Warmer"
    sensor: battery_temperature_1
    default_target_temperature_low: 13 °C
    default_target_temperature_high: 17 °C
    visual:
      min_temperature: -5 °C
      max_temperature: 45 °C
      temperature_step: 
        target_temperature: 1
        current_temperature: 1      

    heat_action:
      - if:
          condition:
            and:
              - lambda: 'return id(battery_level).state >= 25;'
              - lambda: 'return id(min_cell_voltage).state >= 3.201;'
          then:
            - switch.turn_on: battery_warmer
    idle_action:
      - switch.turn_off: battery_warmer

# Automation to turn off the warmer if battery level or cell voltage drops below threshold
interval:
  - interval: 10s
    then:
      - if:
          condition:
            or:
              - lambda: 'return id(battery_level).state < 25;'
              - lambda: 'return id(min_cell_voltage).state < 3.201;'
          then:
            - switch.turn_off: battery_warmer
[12:02:51][D][sensor:094]: 'Temperature 1': Sending state 12.00000 °C with 0 decimals of accuracy
[12:02:51][D][climate:396]: 'Battery Box Warmer' - Sending state:
[12:02:51][D][climate:399]:   Mode: HEAT
[12:02:51][D][climate:401]:   Action: OFF
[12:02:51][D][climate:419]:   Current Temperature: 12.00°C
[12:02:51][D][climate:423]:   Target Temperature: Low: nan°C High: nan°C

I am only guessing, but I see min_temperature and max_temperature are supposed to be reals floats. Maybe try

   min_temperature: -5.0 °C

etc

I realize this doesn’t accord with the example in the docs, with a try though.

Your YAML converted to JSON looks like:

{
  "climate": [
    {
      "platform": "bang_bang",
      "name": "Battery Box Warmer",
      "sensor": "battery_temperature_1",
      "default_target_temperature_low": "13 °C",
      "default_target_temperature_high": "17 °C",
      "visual": {
        "min_temperature": "-5 °C",
        "max_temperature": "45 °C",
        "temperature_step": {
          "target_temperature": 1,
          "current_temperature": 1
        }
      }
    }
  ]
}

Notice that your min and max temperatures are actually strings and not numbers. The validation for the component should have flagged that for you. Remove the °C from your values and they will be numbers, which should work.

Again, the docs say they should be like that (although it seems wrong to me).

# Example configuration entry
climate:
  - platform: bang_bang
    name: "Bang Bang Climate Controller"
    sensor: my_temperature_sensor
    default_target_temperature_low: 20 °C
    default_target_temperature_high: 22 °C

    heat_action:
      - switch.turn_on: heater
    idle_action:
      - switch.turn_off: heater

From https://esphome.io/components/climate/bang_bang

The docs also say:

default_target_temperature_high (Required, float):

When you do it the way you did you get NaN, which could be true for the string you provided depending on the way you interpret it.

Did you try changing it like I suggested?

I had tried that previously but have just tried again to no avail.

Not being able ot find a solution the other day I changed to using the Thermostat controller instead. That works but would prefer to use the bang bang…

Your YAML clearly shows that you did NOT remove the suffix, so you are providing a string where a number is needed.

try this:

- platform: bang_bang # can add cooling fan to this using cool_action
    name: "Battery Box Warmer"
    sensor: battery_temperature_1
    default_target_temperature_low: 13
    default_target_temperature_high: 17
    visual:
      min_temperature: -5
      max_temperature: 45
      temperature_step: 
        target_temperature: 1
        current_temperature: 1

My previous reply was a misquote, apologies.

I HAVE tried without the suffix and it does not work for me.

I am also seeing this problem with the latest dev branch
4c8f5275f9a82ad47c5687b9bc7393e6cd36e0ed

However, I think this is an artifact caused by incorrect saved preferences stored in the flash memory. Specifically in my case it was caused by switching from the thermostat platform to the bang_bang platform keeping the name of the climate component the same.

The way that I reproduced this is:

  1. Create a config with a climate component using the thermostat platform
  2. Compile, upload and run this config
  3. Modify the config from step 1 changing the the platform of the climate component to bang_bang
  4. Set default_target_temperature_low and default_target_temperature_high as appropriate for your application
  5. Compile, upload and run the modified config
  6. The log output and mqtt topics if enabled will show target_temperature_low nan and target_temperature_high nan

You can verify that the desired temperatures are present in the .esphome/build/some_config/src/main.cpp file, but despite this, the corrupt / incorrect preferences from the thermostat platform are loaded.

I was able to resolve this issue with two possible fixes:

  1. Publish a value to the appropriate mqtt control topics for the climate component. This replaces the nan with the value published to the broker.
  2. Use esptool.py to erase the flash E.g. esptool.py --chip esp32 erase_flash. Then reupload the config with the bang_bang climate component.

It may also be possible to use some other interface that can write to these values instead of the mqtt option I noted, but I have not tested that.

climate:
  - platform: bang_bang
    name: "My Thermostat"
    sensor: tstat1
    default_target_temperature_high: 25
    default_target_temperature_low: 21
    heat_action:
      then:
        - switch.turn_on: relay1
    idle_action:
      then:
        - switch.turn_off: relay1
#climate:
#  - platform: thermostat
#    name: "My Thermostat"
#    sensor: tstat1
#    heat_action:
#      then:
#        - switch.turn_on: relay1
#    idle_action:
#      then:
#        - switch.turn_off: relay1
#    heat_deadband: 3 °C
#    heat_overrun: 0 °C
#    default_preset: Home
#    preset:
#      - name: Home
#        default_target_temperature_low: 22 °C
#    min_idle_time: 30s
#    min_heating_off_time: 0s
#    min_heating_run_time: 0s
#    target_temperature_low_command_topic: climate/dhw_thermostat/target_temperature/command