Graph HVAC action as a line graph?

I created a sensor for hvac_action in hopes that I can graph the run time of heating with the temperature of the room temp sensor in the same graph. I wanted it to look like the graph for climate.thermostat which has thermostat heating and thermostat target temp high and thermostat target temp low and thermostat current temp all as line graph data.

  #######Thermostat HVAC Action#######
  - platform: template
    sensors:
      ###New sensor name
      hvac_action:
        ####New friendly name
        friendly_name: "HVAC Action Sensor"
        value_template: "{{ state_attr('climate.thermostat', 'hvac_action') }}"

When I graph sensor.hvac_action I get a graph that doesn’t changes levels, only colors for the state, even if I add sensor.room_temp which causes them to be two different graphs within the same graph card.

What do I need to do to in order for heating from sensor.hvac_action to be a line graph?

I figured out why the sensor.hvac_action graph looks like it does. At https://www.home-assistant.io/lovelace/history-graph/ it has an example which looks the same and states it shows as it does since the sensor has no unit_of_measurement defined

I still have no idea how to get that into a defined unit of measurement. Should this be a solution? I would like the time to be accurate to the minute.

  - platform: history_stats
    name: Heating On
    entity_id: sensor.hvac_action
    state: 'heating'
    type: time
    start: '{{ 0 }}'
    end: '{{ now() }}'

Hi - I’m not clear on what you are specifically trying to graph. If it is the cumulative on-time for the day, then the units would be seconds (or minutes or hours - depends on how you do the calculation). Can you let me know what it is you are trying to graph? In my config, I use the history_stats platform to create a sensor called sensor.boiler_on_time_today to total up how many hours my HVAC is on each day - it’s like this:

- platform: history_stats
  name: Boiler On Time Today
  entity_id: binary_sensor.boiler_on
  state: 'on'
  type: time
  start: '{{ now().replace(hour=0).replace(minute=0).replace(second=0) }}'
  end: '{{ now() }}'

The binary_sensor.boiler_on is based on the thermostat-created sensor sensor.dining_room_thermostat_hvac_state (I included the A/C units, too, for completeness):

- platform: template
  sensors:
    boiler_on:
      friendly_name: "Boiler"
      value_template: "{{ is_state('sensor.dining_room_thermostat_hvac_state', 'heat')}}"
    first_floor_air_conditioner_on:
      friendly_name: "1st Fl A/C"
      value_template: "{{ is_state('sensor.dining_room_thermostat_hvac_state', 'cool')}}"
    second_floor_air_conditioner_on:
      friendly_name: "2nd Fl A/C"
      value_template: "{{ is_state('sensor.second_floor_thermostat_hvac_state', 'cool')}}"

I then show the time as a number (default for history_stats is an hour). I never actually tried plotting it out before, but here’s what it gave me:
image

That might give you what you are after (?). Oof - I just noticed it was on for 8 hours yesterday! It was cold here!! :cold_face:

1 Like

To answer this one, it seems history_stats based on time has a unit of hour. I didn’t do anything special in my previous post of the graph. It’s as simple as this in lovelace:

      - entities:
          - sensor.boiler_on_time_today
        show_header_toggle: false
        title: HVAC Trends
        type: history-graph

Without knowing if I needed it I had already set up binary_sensor.hvac_heating and I can see it in the Developer Tools under States.

  - platform: template
    sensors:
      hvac_heating:
        friendly_name: "HVAC Heating"
        value_template: >-
          {{ is_state('sensor.hvac_action', 'heating') }}

Based on what I am reading what I needed to do was setup the history_stats to pull from binary_sensor.hvac_heating like this -

  - platform: history_stats
    name: Binary Heating On
    entity_id: binary_sensor.hvac_heating
    state: 'on'
    type: time
    start: '{{ now().replace(hour=0, minute=0, second=0) }}'
    end: '{{ now() }}'

I added that to my sensors.yaml and restarted. I now have sensor.binary_heating_on under States in Developer Tools and I was able to graph that.

However I was looking more for a graph with a data point for each second it is on and no data point for each second it is off as opposed to what we get now with our setups where there is a data point regardless if it is off or on.

Is there a way to make ‘on’ the number 100 and ‘off’ the number 0 and that way there is a defined unit_of_measurement for HVAC Heating?

I think your sensor.hvac_heating just need slight modification to:

  - platform: template
    sensors:
      hvac_heating:
        friendly_name: "HVAC Heating"
        value_template: >-
          {% if is_state('sensor.hvac_action', 'heating') %}100{% else %}0{% endif %}
        unit_of_measurement: "%"

You can then use that in history-graph directly, something like this:
image

1 Like

Yes - the template sensor replaces the history_stats sensor. If you want to graph it with your other temperatures, you might want to make the of measurement °F or °C, depending on what you are using. Otherwise, they will end up on two different graphs, at least that’s been my experience.

Here’s my edit (for completeness) which is very much like @JTPublic’s:

- platform: template
  sensors:
    binary_heating_on:
      friendly_name: Binary Heating On
      unit_of_measurement: '°F'
      value_template: >
        {% if   is_states('binary_sensor.hvac_heating','on') %}
          100
        {% else %}
          0
        {% endif %}
2 Likes

I have friendly_name: “HVAC Heating” as the binary_sensor.hvac_heating. Does the fact that it is no longer going to be binary cause it to be a regular sensor? Can I do as KSC suggested and use unit_of_measurement: ‘°F’ instead? If so, does that eliminate the need for the template sensor that converts to ‘°F’ ?

Yes, it is now a regular sensor, not binary_sensor anymore, any numeric unit_of_measurement will work. You need such unit_of_measurement to tell history-graph to plot the entity as numeric line.

Thanks. I got it to work as the following in sensors.yaml

  - platform: template
    sensors:
      hvac_heating:
        friendly_name: "HVAC Heating F"
        value_template: >-
          {% if is_state('sensor.hvac_action', 'heating') %}72{% else %}0{% endif %}
        unit_of_measurement: "°F"

Is there a way to combine my edited version

  - platform: template
    sensors:
      hvac_heating:
        friendly_name: "HVAC Heating F"
        value_template: >-
          {% if is_state('sensor.hvac_action', 'heating') %}72{% else %}0{% endif %}
        unit_of_measurement: "°F"

with the sensor.hvac.action so that it is just one sensor by changing value_template of sensor.hvac.action and eliminating sensor.hvac_heating?

Sure, if you just want one regular sensor:

  - platform: template
    sensors:
      hvac_heating:
        friendly_name: "HVAC Heating F"
        value_template: >-
          {% if state_attr('climate.thermostat', 'hvac_action') %}72{% else %}0{% endif %}
        unit_of_measurement: "°F"

The hvac_action has three states - heating, cooling or idle. Is there a way to make that single sensor know if it is heating?

Assuming you are getting the 3 states from climate.thermostat, and you want heating/cooling set to 72:

  - platform: template
    sensors:
      hvac_heating:
        friendly_name: "HVAC Heating F"
        value_template: >-
          {% if states.climate.thermostat.attributes.hvac_action in ['heating','cooling'] %}72{% else %}0{% endif %}
        unit_of_measurement: "°F"
1 Like

I was able to use your solution to create one for heating and one for cooling for the days like today where the outside low temp in the morning created the need for heating and the outside high temp in the afternoon created the need for cooling. So now the graph has them as different colored lines.

  - platform: template
    sensors:
      hvac_heating:
        friendly_name: "HVAC Heating"
        value_template: >-
          {% if states.climate.thermostat.attributes.hvac_action in ['heating'] %}72{% else %}0{% endif %}
        unit_of_measurement: "°F"

  - platform: template
    sensors:
      hvac_cooling:
        friendly_name: "HVAC Cooling"
        value_template: >-
          {% if states.climate.thermostat.attributes.hvac_action in ['cooling'] %}72{% else %}0{% endif %}
        unit_of_measurement: "°F"
2 Likes

This worked for me as well.

Another improvement that can be made is to get the exact temperature set value from the thermostat by replacing “72” with {{states.climate.thermostat.attributes.temperature}}

  - platform: template
    sensors:
      hvac_heating:
        friendly_name: "HVAC Heating"
        value_template: >-
          {% if states.climate.thermostat.attributes.hvac_action in ['heating'] %}{{states.climate.thermostat.attributes.temperature}}{% else %}0{% endif %}
        unit_of_measurement: "°F"

  - platform: template
    sensors:
      hvac_cooling:
        friendly_name: "HVAC Cooling"
        value_template: >-
          {% if states.climate.thermostat.attributes.hvac_action in ['cooling'] %}{{states.climate.thermostat.attributes.temperature}}{% else %}0{% endif %}
        unit_of_measurement: "°F"
3 Likes