Explanation of climate history chart?

I’ve been experimenting with the climate component for the MQTT platform (MQTT HVAC) and I have a question about the climate history chart. Here is its appearance in the UI widget:

Here is its appearance in the History menu:

What does the green-shaded area represent?

My guess is it represents the component’s current operation mode. In the example above it is set to heating mode. If operation mode is ‘off’ then the shaded area is white.

What it does not represent is when the HVAC system was actually heating. In other words, the green-shaded area doesn’t show when my furnace was producing heat. Is that correct?

The reason I’m asking is because the MQTT HVAC platform definitely handles operating mode (auto, heat, cool, off) but, after checking its source code, not operating state (heating, cooling, idle). Without knowledge of operating state, the platform doesn’t know when the HVAC system is actively heating or cooling.

Is this limitation only in MQTT HVAC (or due to my misconfiguring it)? Or is everyone else using Ecobee, Nest, Lyric, etc see operation state in the history chart?

… crickets …

I can’t be the only HA user with a thermostat! :slight_smile:

Does your climate platform (Next, Ecobee, Prolyphix, Lyric, etc) indicate when the HVAC system is actually heating/cooling (as opposed to simply being in the heat/cool mode)?

Not for nothing but it does say right in the key that the shaded green area is ‘thermostat heating’.

Haha!, Yeah, that true except my furnace has definitely not been running for 24 hours straight like the shaded area shows! :confused:

That’s why I asked what other people see in their history chart because this one is not useful. It’s telling me when the heat mode is enabled, not when heating is active.

I’ve looked at the frontend code for the climate component’s history chart and line 169 says:

// The “heating” series uses steppedArea to shade the area below the current
// temperature when the thermostat is calling for heat.|

That’s not what I’m seeing in the MQTT HVAC’s history chart. I’m seeing a shaded area for the entire duration the HVAC system is in heat mode and not just when it’s ‘calling for heat’.

Line 163 determines if the chart should show a shaded area. Unfortunately, due to my limited grasp of the code, I don’t understand which of the climate platform’s properties is represented by state.state.

const hasHeat = states.states.some((state) => state.state === "heat");

I’m having a hard time believing this chart is the norm who all users of MQTT HVAC. Surely someone else has noticed the solid green area, representing many hours of either heating and cooling, and said “That’s not right.”

I have to accept the possibility that I’ve misconfigured my MQTT HVAC platform. However, it has no state topic for HVAC status, only HVAC mode, so I don’t see how it can possibly know when the HVAC system is active. The only thing it knows about the HVAC system’s condition is the mode_state_topic which tells it the current operation mode, not operation status.

EDIT
It looks like there’s a pull request to address this issue.

This is the normal state. Meaning, the operation mode if the device is on. And yes, this is how it behaves for ALL climate devices. The state is set in the base ClimateDevice class. Unless the component overrides the state method, it will always be returning the operation mode. (FYI generic thermostat overrides the state method).

As for your PR, the generic thermostat returns the operation mode as well. I debugged into both components. The only difference between the 2 is that the generic thermostat will always remain in IDLE mode when an operation mode is not set. The PR you posted added IDLE mode to the MQTT state.

EDIT: Just debugged into a few other climate components, it’s hit or miss weather the device overrides the state method. So, to answer your original question:

No, it’s in other climate platforms.

Ecobee does not override the states method and works the same way as MQTT. This does have extra operation modes though which will impact the state.

Nest does not override the states method and works the same way as MQTT. This does have extra operation modes though which will impact the state.

Couldn’t find the lyric component.

Thank you for helping me understand the connection between the frontend’s chart history and the climate component.

Just to confirm that I understand your explanation, I’ve put together all the links in the chain:

From the climate base class, state is set to self.current_operation:

class ClimateDevice(Entity):
    """Representation of a climate device."""

    @property
    def state(self):
        """Return the current state."""
        if self.is_on is False:
            return STATE_OFF
        if self.current_operation:
            return self.current_operation
        if self.is_on:
            return STATE_ON
        return STATE_UNKNOWN

MQTT HVAC doesn’t override this method so its state is the same as self.current_operation. Its current_operation method returns an internal property called self._current_operation.

    @property
    def current_operation(self):
        """Return current operation ie. heat, cool, idle."""
        return self._current_operation

That internal property is handled in several places but, most importantly, in the handle_mode_received method. Here it gets set to the payload of CONF_MODE_STATE_TOPIC.

        @callback
        def handle_mode_received(topic, payload, qos):
            """Handle receiving mode via MQTT."""
            if CONF_MODE_STATE_TEMPLATE in self._value_templates:
                payload = self._value_templates[CONF_MODE_STATE_TEMPLATE].\
                  async_render_with_possible_json_value(payload)

            if payload not in self._operation_list:
                _LOGGER.error("Invalid mode: %s", payload)
            else:
                self._current_operation = payload
                self.async_schedule_update_ha_state()

Whew! The chain is complete. The operation mode is ultimately what is represented in the shaded area of chart history for MQTT HVAC.

So the ultimate question is: What’s more informative?

  • Seeing a chart of when the HVAC system is enabled.
  • Seeing a chart of when the HVAC system is operating (actively heating or cooling).

Personally, I think the second option is more useful. Seeing a chart of when my furnace is producing heat (and consuming energy) is more interesting than a multi-hour chart of the furnace sitting in “heat mode”.

I don’t know if there’s a design guide for climate platforms but, even if there is, the authors of each platform have decided to go their own way. I agree with you that the first option (charting the operation mode) appears to be the norm. However, the author of the Proliphix platform appears to have chosen the second option (charting the operation state).

In the Proliphix platform, current_operation is set to the result of self._pdp.hvac_state.

    @property
    def current_operation(self):
        """Return the current state of the thermostat."""
        state = self._pdp.hvac_state
        if state in (1, 2):
            return STATE_IDLE
        if state == 3:
            return STATE_HEAT
        if state == 6:
            return STATE_COOL

The Proliphix API, provides one command (thermHvacMode) to return the HVAC system’s mode and a separate one (thermHvacState) for its state.

The Proliphix platform sets current_operation to the HVAC system’s state, not mode. Therefore its history chart will look different from other platforms, shading the time periods when the furnace is actively heating.

That’s the way I believe MQTT HVAC platform should work. I’ll be modifying my local instance of the platform to function that way.

Last but not least, I’m puzzled by the decision to exclude Hold mode from the frontend UI. Oddly, Swing mode is displayed and that’s something normally buried in a physical thermostat’s configuration menu. In contrast, Hold is normally shown on a thermostats as plainly as temperature and fan control.

I found the relevant code and I know what needs to be done to display a control for Hold mode. However, I’m stumped by the next step, namely creating a modified local instance.

The instructions suggest I need to clone the entire frontend repo followed by many more steps that seem onerous for my need to just tweak a few lines in one file. It’s not as easy as with a platform where you just put a modified copy of it in config/custom_components. Is there any shortcut or am I obliged to download the entire repo, install node.js, etc?

It looks like the PR you found might do that as well. I didn’t look to deep into it though.

@123
I noticed that my Ecobee component did the same when I changed the operating mode to ‘heat’. I agree that the shaded are is not useful unless it is the current_operation.

Thanks for confirming this behavior is not limited to MQTT HVAC. Although I haven’t examined all of them, so far I believe only Generic and Proliphix platforms handles it in the, arguably, correct way and only show when the HVAC system is actively heating/cooling.

I’ve examined the enhancement in the pull request. It overrides state and introduces a new “activity topic”. If activity is true, state is set to the operation mode (“current_operation”). That means the history chart will now graph operation state and not mode. This is indeed what I’ve been driving at.

I’ve contacted the pull request’s author and pointed out that if the operation mode is “auto”, state will also be set to auto. However, the charting code only knows how to handled heat or cool, not auto. That means when the HVAC system is heating/cooling in auto mode, it won’t appear in the history chart.

My suggestion is to have the activity topic report the actual operation state and not simply on/off. Most communicating thermostats can report their current operation state. You can expect at least off/heat/cool and Proliphix reports several more. With a template, the activity topic can be rendered in a clean off/heat/cool presentation and used to set state (instead of using operation mode which can contain the ambiguous ‘auto’).

EDIT
The pull request’s author concurred and indicated the suggestion would be implemented. Today I noticed the pull request’s title has reverted to “WIP” (Work In Progress).

1 Like

I see the same issue with my ecobee thermostat. I could be wrong, but I don’t think it always behaved this way.

Here’s a lengthy thread discussing the climate component’s architecture. It’s possible that there were changes made to the ecobee climate platform to conform to the architectural proposals … and may explain why you’re observing new (less desirable) behavior. Maybe.

My takeaway from the thread is that it is understood that operating mode and state are different things (if mode is currently heat then state can be heating or idle). However, in practice, platforms for the climate component can conflate state with mode (and that makes for a less useful chart).

There was a recent attempt to distinguish state from mode for the MQTT HVAC platform but the PR was closed. I pity the developer because the guidance offered was simply a link back to the lengthy architectural thread. I may be wrong, but it appears the developer gave up … and so the release version of MQTT HVAC continues to conflate state with mode.

I just fixed this for the radiotherm component and ran into a similar “suggestion” to read the 10 page design thread. The correct fix for now is to implement the is_on property and return True or False. That gets combined with the operation mode to determine if it’s heating or cooling. Of course this doesn’t really work - if the operating mode is AUTO then you can’t tell what’s active. But, I was told that that I couldn’t fix that - it will have to wait until climate is rewritten.

So if you want to get the plot working, add the is_on property. You can see the update I made to radiotherm here: https://github.com/home-assistant/home-assistant/pull/20283 and you can see a bug report on this issue for ecobee here: https://github.com/home-assistant/home-assistant/issues/18244 (this thread also contains a possible fix I posted that may work - but I don’t have an ecobee so someone else will have to test it and PR it).

Thanks! I read Paulus’ suggestion to infer the state from the operation mode and current/target temperature. Like you said, if it’s AUTO mode, it gets more complicated to determine if the state is heating or cooling. I have some experience with this; I created a driver for a HAI Omnistat/2 thermostat (not for Home Assistant but for Premise).

The situation may be simpler for MQTT HVAC because it wouldn’t infer the state but simply acquire it from an MQTT topic. That’s what I did for the customized version I created for my own use (with version 0.80). However, as of version 0.86, it no longer works because of changes made deeper in the MQTT component.

I’m currently creating a revised version but will have to figure out a different way to handle the state. The way I originally did it is the way it was done in the PR that Paulus cancelled. I now want to do it a way that would pass muster in the event I ever wish to submit it as a PR.

Sorry - I’m confused. Any individual climate component doesn’t need to infer anything - they always have the state which is usually heating, cooling, or idle - it doesn’t matter whether it came from an mqtt payload or anything else. I don’t think you need to change anything about the internals of the mqtt climate component - the climate module is being redesigned. Once the design is finalized, all the climate components will need to be changed to meet that design. The point is to make the plot work, just add the is_on property to the current component which basically says “return True if the current state isn’t idle” and the plot will work properly.

123, I didn’t give up, just waiting for architectural changes. I update my component for every new release.

TD22057, It’s not actual state but mode and it never will be idle if you don’t set it manually or by thermostat (but it’s bad workaround because in this case, when mode is idle, there is not possible to determine actual operation mode), so chart is useless.

One more attempt to fix charts. It uses is_on property now. TD22057, thanks for suggestion.

Check out the long thread. Paulus introduced the idea that the operating state can be derived from the operating mode and other data like current temperature and target temperature. Personally, I disagree with this concept because many thermostats are able to report their operating state. To infer the operating state would only be required for thermostats that do not report it.

I’ll try that.
EDIT
Doesn’t the is_on property refer to the whether the HVAC system is powered or de-powered (i.e. master switch is on/off)? That’s different from whether the HVAC system is active or inactive (i.e. heating/cooling). In other words, does is_on refer to the system’s operating mode or to its state?

I feel it refers to its operating mode. I’m basing that on how it’s handled here in init.py. It’s self.current_operation that correctly reports the current operating state and is_on reports if the HVAC system is powered up or not .

Regarding this statement in the PR:
* No support for ‘idle’ state - show ‘off’ instead

Does this only apply for the operating mode? auto, cool, heat, off (no idle)
Or does it also apply to the operating state? cooling, heating, off (no idle)

For the operating state, I believe there is a distinction between idle and off.

  • If mode=off and state=off then the HVAC system is de-powered and inactive.
  • If mode=cool and state=cooling then the HVAC system is powered and active.
  • If mode=cool and state=idle then the HVAC system is powered and on standby.

When it comes to operating state, off and idle are not exactly synonyms because they also reflect the operating mode.

If the proposed architectural change has chosen to conflate the two terms, then it has discarded a useful distinction.

I think is_on property refer to mode too, but I doubt that adding new properties will be merged before architectural review. ‘current_operation’ is current mode not state.
There is no way to display ‘idle’ without changing state property that isn’t allowed. However if you have idle mode it will be shown as any other mode. You are right about distinction between idle and off, but we should wait until architectural changes will be completed before trying to implement it.

What if you set self.current_operation to STATE_IDLE. That’s not manipulating the state property directly and the climate component’s __init__.py contains this method which will set the state based on current_operation.

    def state(self):
        """Return the current state."""
        if self.is_on is False:
            return STATE_OFF
        if self.current_operation:
            return self.current_operation
        if self.is_on:
            return STATE_ON
return None

This is workaround that I mentioned early. It doesn’t require code changes but wil cause showing idle not only as state but as mode too instead of heat, cool, etc. That is serious problem if you have more than 1 modes.