litinoveweedle / hass-template-climate

❄️Templatable Climate Device for Home Assistant, Supports Running Actions On Service Calls.
MIT License
24 stars 1 forks source link

Target Temperature should be null in case of ATTR_HVAC_MODE == heat_cool, currently UI is broken since if switching single to dual mode since temperature is preferred over temp_high/low #24

Closed Maharshi-Pathak closed 1 month ago

Maharshi-Pathak commented 1 month ago

https://github.com/litinoveweedle/hass-template-climate/blob/0a625358d0a2843780c1f6b80f49ef1d817985bb/custom_components/climate_template/climate.py#L1587 current behavior: image expected behavior: image

litinoveweedle commented 1 month ago

Hello, thank you for the report. May I ask you for a more detailed description, together with the step by step guide to reproduce the issue?

Maharshi-Pathak commented 1 month ago

I am trying to create an automation that captures the current conditions of my Ecobee thermostat (via Home Assistant integration) when I turn on a conditional switch. The goal is to show non-admin users of my Home Assistant instance that these conditions are set according to their preferences, while the automation applies an energy-saving temperature delta to the setpoint.

However, I am encountering an issue with the configuration where all three attributes—target_temperature, target_temperature_high, and target_temperature_low—are set up using a template entity. When the HVAC mode is set to heat_cool, only the target_temperature is being read by the entity. This is because the input_text entity used as a template for the target_temperature attribute is null in heat_cool mode. The climate_template entity is missing a check for HVAC modes and only verifies whether the target_temperature is not None, regardless of the HVAC mode.

In real thermostats, see the Ecobee integration's set_temperature method for proper handling of such cases.

My climate_template conf:

  - platform: climate_template
    unique_id: de0bf8db-b826-44e1-8911-446fdb66c7bf
    name: Smart Cities Snapshot 2
    mode_action: restart
    min_temp: 45.0
    max_temp: 95.0

    hvac_modes:
      - "heat_cool"
      - "heat"
      - "off"
      - "cool"
      - "fan_only"
    fan_modes:
      - "auto"
      - "on"
    preset_modes:
      - "away"
      - "home"
      - "sleep"
      - "away_indefinitely"
      - "temp"
    current_temperature_template: "{{ float(state_attr('climate.office', 'current_temperature'), None) }}"
    target_temperature_template: "{{ states('input_text.smart_cities_snapshot_temperature')|float(None) }}"
    target_temperature_high_template: "{{ states('input_text.smart_cities_snapshot_target_temp_high') | float(None)}}"
    target_temperature_low_template: "{{ states('input_text.smart_cities_snapshot_target_temp_low') | float(None)}}"
    hvac_mode_template: "{{ states('climate.office')}}"
    hvac_action_template: "{{ state_attr('climate.office', 'hvac_action')}}"
    fan_mode_template: "{{ states('input_text.smart_cities_snapshot_fan_mode') }}"
    preset_mode_template: "{{ states('input_text.smart_cities_snapshot_preset_mode') | lower }}"

    temp_step: 0.5
    set_temperature:
      - service: climate.set_temperature
        target:
          entity_id: climate.smart_cities_snapshot_2
        data: >
          {% if states('climate.office') in ['heat_cool']  %}
            {"target_temp_high": {{ float(state_attr('climate.smart_cities_snapshot_2', 'target_temp_high'), None) }},
            "target_temp_low": {{ float(state_attr('climate.smart_cities_snapshot_2', 'target_temp_low'), None) }} }
          {% elif states('climate.office') in ['heat', 'cool']  %}
            {"temperature": {{ float(state_attr('climate.smart_cities_snapshot_2', 'target_temperature'), None) }},
          {% else %}
            {"hvac_mode": 'Off'}
          {% endif %}

    set_hvac_mode:
      - service: climate.set_hvac_mode
        target:
          entity_id: climate.smart_cities_snapshot_2
        data:
          entity_id: climate.smart_cities_snapshot_2
          hvac_mode: "{{ states('climate.office')}}" 
Maharshi-Pathak commented 1 month ago

image real thermostat vs climate_template thermostat in heating mode - Works as expected image real thermostat vs climate_template thermostat in heat_cool mode -breaks as the temperature attributes wants to be set as null as expected but carries the heating mode's setpoint value since the target_temperature is None https://github.com/litinoveweedle/hass-template-climate/blob/0a625358d0a2843780c1f6b80f49ef1d817985bb/custom_components/climate_template/climate.py#L1590

Maharshi-Pathak commented 1 month ago

I guess it is easier to showcase in the states table: the real thermostat -

image

the climate_template thermostat that is supposed to mimick the real thermostat -

image
litinoveweedle commented 1 month ago

I am still perplexed, sorry. First the the code you refer to is inside of the async_set_temperature. That has nothing to do with the fact if any attribute is reported as None - as in the picture

This depends on the integration reporting back value of the property target_temperature. In case of the ecobee it is this code which is responsible for it:

    @property
    def target_temperature(self) -> float | None:
        """Return the temperature we try to reach."""
        if self.hvac_mode == HVACMode.HEAT_COOL:
            return None
        if self.hvac_mode == HVACMode.HEAT:
            return self.thermostat["runtime"]["desiredHeat"] / 10.0
        if self.hvac_mode == HVACMode.COOL:
            return self.thermostat["runtime"]["desiredCool"] / 10.0
        return None

So set_temperture method has no impact to this whatsoever. I checked and this is the way how it is handled in other integrations as well. I will prepare branch with the change if you will be willing to test and report back.

litinoveweedle commented 1 month ago

You will find proposed fix in this branch. it is enough to replace climate.py file

litinoveweedle commented 1 month ago

@Maharshi-Pathak Any update on testing?

Maharshi-Pathak commented 1 month ago

Hey @litinoveweedle, sorry I was preoccupied. I just checked the udpate with copying the change you made in my local climate.py. That fixed the UI issue. Apologies if my effort to debug what part of the code is causing the issue was misleading and thank you for promptly fixing the actual issue. We can close this issue with your test branch's merge.

litinoveweedle commented 1 month ago

@Maharshi-Pathak no problem, thank you for confirmation. I will merge the branch into master and release it soon.