Closed balloob closed 3 years ago
A comment on on/off as I added that:
off
is not the same as idle
. On
/Off
is a setting while idle
is an observation. A device can switch on its own from idle to another state.
While we could merge idle
into off
I think we would lose important information.
That said, maybe operation_mode
should be an attribute and not a state?
Some obervations, some of which come from the stale https://github.com/home-assistant/home-assistant.github.io/pull/3910 :
Regarding on/off
: Yes, idle
is an observation, @andrey-git . I think that every property of a climate device should have a current_*
and a requested_*
version. Thus, if the requested_operation_mode
is e.g., auto
, the current_operation_mode
can still be idle
to indicate that the device is currently not doing anything. Obviously, when the requested_operation_mode
is set to off
, the current_operation_mode
should also go to off
, or the device is doing something wrong. This way, we can get rid of the separate on/off
property, I think.
I'm all in favor of throwing out econet
. Maybe it should become its own component that offers some switches or something?
I still think we need to split up the values we allow for operation_mode
, something like the suggested action
(which has a very limited range of allowed values, e.g., off
, auto
, heat
and cool
). Maybe we would then need to add the same thing for humidity (humidity_action
? With values off
, auto
, humidify
and dry
?) Everything else should go somewhere else. A value of electric
or fan_only
just isn't the same type of choice as auto
vs. heat
.
We need a abstraction how a thermostat should look like on HomeAssistant.
I think the state should be the current temperature. All others are attributes. Like before the refactory of this components.
I think the state
should be current running state, like heat
, cool
, idle
and off
. Off means the component is turned off. There also should heave operation_mode
, it shows current mode, auto
, off
, heat
, cool
.
I don't know if a idle
current state is necessary. It's the same as currently off
. Otherwise thats the way HomeKit handles it as well @fanthos.
I think the off
state means manually turned off and should not turn on by temperature or other reason. idle
means the component is in "working" state and it will turn into heat
or cool
when temperature goes cool or warm.
Isn't that covered by operation_mode=Auto
? Or should that just be a list of supported modes?
Regarding feature flags, the Alexa.ThermostatController design allows thermostats to report whether they support single, dual and triple setpoints (target temperatures). There's an extended series of examples here: https://developer.amazon.com/docs/device-apis/alexa-thermostatcontroller.html#thermostat-setpoints Note that these may be the same thermostat device but in different operational modes.
There may certainly be thermostat devices out there that only support an upper and lower setpoint in certain modes (though it is unspecified in the Alexa documentation which setpoint a AdjustTargetTemperature
request would apply to). Our climate entity has assumptions that there is always a target temperature value separate from the higher/lower ones, so it does not provide an accurate representation of these devices.
I think the off state means manually turned off and should not turn on by temperature or other reason. idle means the component is in "working" state and it will turn into heat or cool when temperature goes cool or warm.
You seem to be describing climate.STATE_AUTO
, which is the state where the device will automatically maintain temperatures between the high and low target temperatures. climate.STATE_IDLE
means the device is not operating, but will accept operation mode or target temperature changes.
I agree that there should be an "off" state for when the device is not allowed to be turned on/operated through software.
Regarding operation modes: Looking at implementations of "eco" mode such as Nest and Honeywell it appears to behave similarly to "away" mode in that it changes the target temperature range, without replacing the current setpoints. There may be limitations on the target temperatures allowed, such as in the case of Nest. While this may be considered a variant of "auto, "heat", or "cool" mode the way "away" mode is, given the independent setpoint(s) it may be necessary to express this as its own mode.
I believe "high demand" mode only applies to water heaters. "performance" mode seems to also be for water heaters, though climate.toon
is abusing climate.STATE_PERFORMANCE
to mean "auto" mode right now.
There are a lot of commonalities between thermostats and water heaters (or other temperature control devies) that make it attractive to use a single entity type (and in some cases such as climate.zwave
, platform) to support them. Perhaps it is sufficient to have operation modes that are distinct for e.g. thermostat devices, and use a feature flag to specify the type of device?
@tinloaf aaah there the issue is! I was looking for. I remember us talking about it but couldn't find it.
I think that idle is not a correct operation mode. There is a difference between "current operation" and "current operation mode". Ours is the latter. Being in an operation mode doesn't mean that you are currently doing something. For example, a climate component in heat mode with a target temperature of 21 and a current temperature of 23, will not be doing something, yet it's mode remains "HEAT".
I would expect "off" to be a correct operation mode as it means that we will not do anything regardless of target and current temperature.
@trisk about the overlapping part: we should make it a separate component or else we end up with a lot of if…else things. The same reason light and switch are different components.
Adding some from my thermostats that gets registered as climate entities. Off and Idle are two different things.
Those two should most likely not be merged since it could vary with each device.
- Idle with mine equals to it waiting and adjusting temperature when necessary.
- Off equals to it doing no actions.
What thermostat model is this? Most thermostats only adjust temperatures when in the operating modes "heat", "cool", or "auto". Both terms "idle" and "off" are usually reserved for modes where the thermostat will not attempt to adjust temperatures, though there may be a separate mode for when the device must be turned back on manually.
This is where the current state and operational mode differ: some devices report a state to indicate whether a heating or cooling cycle is actually running at a moment in time and this should not be confused with the (user selected) operational mode, which determines which setpoints the device will try to adjust temperatures between.
Trisk is right and our current naming is confusing, we actually want to represent "HVAC operation mode" but named it "current operation", which is confused with the current state. Oops.
So to make it clear, let's add hvac
to the name and rename them. I suggest:
hvac_mode
. Limited to off
, cool
, heat
, auto
, auxHeatOnly
(for ecobee). Operation mode values are defined via constants starting with names HVAC_MODE_
.operation_list
will be renamed to hvac_modes
. It will list all available HVAC operation modes for this device.current_operation
property will be renamed to hvac_state
and will be limited to off
, cool
, heat
. Current operation values are defined in constants starting with names HVAC_STATE_
.state
will return hvac_state
Some popular climate APIs that I checked that all use "off" for hvac mode:
I suggest that HVAC_STATE have both idle
and off
. idle
for turned on but idling, off for HVAC_MODE is off.
By adding idle
as a state we are again conflating mode and state. Look at mode to see if a device is off, look at the state if a device is cooling/heating a room.
@balloob, is there a way in your proposal to distinguish between HVAC set to heat and actually heating and one set to heat and doing nothing because the room is hit enough?
@balloob most of thermostat device can only heat
and other can cool
. That make the state in 70% to a constant and we store no constant into statemachine?
100% of a thermostat is the temperature in the focus of device. All other will be construct around this value. I vote for a temperature state and other will be construct around this as attribute.
EDIT
Hmm, there are other device they use also humidity and they make the temperature as state a bit wired. Difficult, but the state like you describe will be also bit mess.
@andrey-git set hvac_mode to heat and hvac_state is either heat or off
@pvizeli you're right that HVAC state can be derived from comparing current and target temp. We can't have the decice state be a temperature because target temperature can be a range when device is set to hvac mode "auto".
I guess HVAC mode is not that important as it indeed can be derived from target and current temperature.
We should change state to be just HVAC mode. Because HVAC state can be confusing. You'll see off but the actually heating but is not currently heating.
@balloob that would be enough for automation, but would be less usefull for visualization.
Hvac_mode could also be fan or dry.
The frontend can calculate itself what the current state would be? We should aim for single source of truth and if data can be derived from other pieces of data, we should not include it.
After reading this article on what "dry mode" is, I agree that we should include dry. (tl;dr: it dehumidifies the air)
I don't like the "FAN" HVAC mode because we already have a "fan mode" property. In case a unit is set to fan, I expect fan mode to be set to "on" and hvac_mode set to off.
As maintainer of the fritzbox thermostate implemenation I can tell that there is no way to get the actual state of the thermostate. The thermostate is a device directly mounted to valve at the radiator and controls the state of the valve always automatically. Its only setteble parameter is the desired target temperature. The other parameters like eco
or comfort
temperatures are only values that come from the schedule form inside the fritzbox webfrontend to plan the target temperature change. The state of the valve (open, close or something in between) cannot be read.
Additionally an away mode (for holidays) can be set and also a mode where the valve is forced to close (for sommer).
So my suggestion for these kind of devices is to have an automatic mode, away mode and maybe something . But I dont't know how to handle the state.
We already support away mode and you don't have to implement the set_operation_mode service either. Eco and comfort are profiles, and are not related to hvac modes.
Given the fact that some devices cannot report if e.g. heating or cooling equipment is currently running, if we keep the operational mode as an attribute, what should the the entity's actual state be? A placeholder state like STATE_UNKNOWN
or STATE_ON
that never changes?
@balloob When a device is in "eco" mode it will use different (not exposed directly) setpoints than when it is in "auto" mode. How should this be expressed to the user?
"The frontend can calculate itself what the current state would be?"
Not necessarily. I know with my Nest atleast the heat is set to not kick on until it drops 2 degrees below the setpoint. If we're just comparing mode against current and target temps, HA will be saying the unit is running a lot more than it actually is. Most of the smart thermostats report back their current state in the APIs, I think that's the best source of truth for what the state of the device is, as opposed to trying to calculate if it's actually running or not based on other factors.
I think "heating" "cooling" "idle" "off" etc would be the best states for the actual climate entity.
"The frontend can calculate itself what the current state would be?"
Not necessarily. I know with my Nest atleast the heat is set to not kick on until it drops 2 degrees below the setpoint. If we're just comparing mode against current and target temps, HA will be saying the unit is running a lot more than it actually is.
Agreed, we don't always have access to all of the parameters for the state machine used by the device internally, which in modern devices may be more complex than "start heat/cool when above/below X with a hysteresis of Y". This is almost certainly not something that can be simulated by a generic frontend. We could suggest that platforms which don't report the current state to simulate it if the logic is known and the necessary parameters are exposed by the device (and fixed between firmware updates) but this is not applicable to all platforms.
I think "heating" "cooling" "idle" "off" etc would be the best states for the actual climate entity.
Is there value in including "off" as a different state from "idle"?
Is there value in including "off" as a different state from "idle"?
Good point, probably not. My initial thought was using "off" if the thermostat was set to off, and idle if it was set to heat/cool but not actually running. But you could figure out the difference there based on what mode the thermostat is set to, so there's not really value in separate off and idle states
@trisk: When a device is in "eco" mode it will use different (not exposed directly) setpoints than when it is in "auto" mode. How should this be expressed to the user?
So Eco is just AUTO with different setpoints. The setpoints would be target_temp_high and target_temp_low?
We can include an hvac_state attribute but as it stands right now in the frontend, we won't show it because state
will become equal to hvac_mode
. If it it's not available for a device (because we can't know), we'll just return None
.
So Eco is just AUTO with different setpoints. The setpoints would be target_temp_high and target_temp_low?
"eco" mode overrides the original setpoints with temporary values (like away mode) and restores the original setpoints once the device leaves "eco" mode. The "eco" mode setpoints usually require different API calls and in some cases do not allow arbitrary changes (just a range, or read-only).
Not sure if the regular target_temp_
* attributes should reflect eco mode or if they should be in a separate attribute. Regardless there needs to be some way to indicate and enter/leave eco mode.
So a profile attribute right? Profile is "normal" or "eco". targettemp* should represent the current used setpoints. If a current set point is not used because a different profile is selected, it should not be part of the current state.
IMHO, there is a hierarchy of modes/states. The zone thermostat may be in Auto
, but it would be 'overruled' by the hub, which is dictating (say) Away
or Eco
mode... Unless the zone itself detects an open window, and sets the target temp to 5C until the window is closed...
Many of the newer heating systems have a relatively complex hierarchy regarding Operating Mode, maybe like:
We have to be careful about derived values - for example, setting a heating object to IDLE
just because its target temp is lower than its current temp is folly. For example, the zone calls for heat, even though its current temp is higher than its target temp because it knows that in 30 mins it needs to be (say) 5C higher than it is now.
TL;DR - HA cannot expect to encompass all climate objects, and so some flexibility is required. For example:
REQUESTED_*
and CURRENT_*
mentioned above)========================
I am in the throws of re-writing the EU (US is different) Honeywell evohome component, as a custom component because the existing (honeywell) component is no longer up to the task. I have some observations that are directly relevant to the above, and some additional issues. It may be useful to describe how the evohome system works...
An evohome account has multiple locations, each with multiple gateways, each with multiple controllers, each with up to 12 zones. The vast majority of installations would consist of one account/location/gateway with one zone (and the existing code assumes this).
However it is sufficient, I think, to assume a 1 to many relationship by merging account/location/gateway/controller into one, to get a controller:zones(s) setup in 1:many (I know others have asked for multiple locations, but the underlying API actively does not currently support this). The zones (each is a collection of actuators and one thermostat) act as you'd expect but have 3 modes (this is not strictly true):
FollowSchedule
: follow the scheduled setpoints/target temperaturesTemporaryOverride
: have some fixed temperature for some time (e.g. until the next setpoint)PermanentOverride
: have some fixed temperature indefinitelyNote that zones do not have an On
, Off
, or Away
state; they are always on (and it is not possible to know if they are active, or idle). For an Away
mode, the target temp may be set to (say) 10C, and for Off
, it would (usually) be 5C.
The controller has no temperature, and no target temperature. It does have the following modes (in addition to 'Auto' - follow the programmed schedule) that override the target temperature of any zone in 'FollowSchedule' mode
AutoWithEco
: all target temps dropped by (say) 3C,DayOff
: pretend today is (say) Saturday,Away
: all target temps to (say) 10C,HeatingOff
: all target temps to (say) 5C,Custom
: impose a different schedule on some zones
Note again, there is no Off
state - the system is always on, but it may (for an Off
mode) configure the setpoint of all the zones to 5C. There is also a situation where two Operating modes (Auto
, AutoWithReset
) lead to the same State (Auto
). An in other cases, it can revert back to Auto
after a period of time.
Sorry if I have rambled on.
So a profile attribute right? Profile is "normal" or "eco". targettemp* should represent the current used setpoints. If a current set point is not used because a different profile is selected, it should not be part of the current state.
I agree (but there would be a hierarchy of these profiles). The way I think about it is that the schedule consists of a whole bunch of setpoints (from a particular time the target temp is...), unless overridden by a mode (you say profile), or some other state.
The hierarchy of operating modes (and other event-driven modes) is resolved against the schedule to produce a current target temp. Thus, the target_temp
and current_temp
are states of the zone. If I want to know the scheduled setpoint, then (for evohome), the only way to know is to interrogate the schedule.
Only if the Controller is in Auto
mode and the Zone is in FollowSchedule
mode, would the target temp then be the setpoint, unless (for example) the zone is in 'OpenWindow' state (there are other such states).
So Eco is just AUTO with different setpoints. The setpoints would be target_temp_high and target_temp_low?
With evohome, if the Controller is in AutoWithEco
mode, the the zones that are in FollowSchedule
mode follow their scheduled setpoints, only 3C lower; they only have a target_temp
.
The state of a climate component should always show the actual state. So if we're in eco mode and because of that the target setpoint changes, we should show the eco target as our target temperature, as that's what is the current state. What is overriden is not important.
We will include both operation mode and operation state as attributes and will make the state be equal to the operation mode.
It is currently out of scope for our climate entity to also represent a multizone setup with temporary overrides. We first need to fix it up to a place where it will support the majority of the thermostat models out there.
Actually, it would be enough to decouple operation mode (as requested) from operating state (as it eventuates for whatever reason) - the controller can be instantiated with different supported_features
to its zones.
How do you feel about a climate object without a temperature?
Just for your information, here's the way MAX! thermostats work (and also the eq3 bluetooth smart, basically the same device with different RF).
The are mounted directly on the radiator. You can program a weekly schedule. Then you can switch between three operation modes, manual, auto and boost. (There is also temporary, but I don't remember what it does).
In manual mode, the thermostat tries to keep the currently set temperature. In auto mode, it follows the weekly schedule. In boost mode it fully opens the valve for a configurable amount of time and then goes back into the previous mode.
Modes like heat
, cool
or idle
don't make much sense for these devices. The auto mode is probably not very interesting in the context of homeassistant, as most users would probably use automations and not the schedule in the thermostat. Manual is the preferred mode, because the thermostat will then not change the target temperature it self. However, boost mode is also interesting as it can be used to quickly heat up a room.
For HomematicIP_cloud the same as for MAX! thermostats holds. A STATE_BOOST and several STATE_AUTO1...5? for different time/temperature profile would be great.
Profiles are not hvac states, they are profiles.
Hi @balloob, but you have also to admit a time/temperature profile is a kind of automatic state for devices like a radiator thermostat. I just have implemented the climatic platform for homematicip_cloud and I had in mind to implement the profiles as different automatic modes. This has been refused and I also fully support this if you wanna keep things consistent.
https://github.com/home-assistant/home-assistant/pull/14388
What's the status on this? This seems to block some climate platform implementations.
Somebody needs to implement it.
Is there even a consensus on how to implement it yet? Implementing the changes would probably also require rewriting all existing platforms right?
Correct. It will cause some breaking changes
Obviusly this needs to be sorted out, before adding anymore fancy bells and whistles, like new gauges and a new UI. Important stuff first, please ;-)
This is an attempt to summarize the target implementation of mode/state/profile, since there has been a bit of discussion which I think has evolved and clarified things since the initial comment. But it's an opinionated summary, including some opinions I don't think have been expressed above.
Defines what action(s) the thermostat is instructed to take. Where verbs make sense, use imperative.
Values: heat
, cool
, auto
, off
, auxHeatOnly
, dry
, ~humidify
~
What the thermostat is currently instructing the controlled system(s) to do, i.e. the action of the system based on the mode and target temperature (/humidity). Use progressive verbs to avoid confusion/conflation.
Values: heating
, cooling
, idle
, drying
, ~humidifying
~
This concept is less clear and much more device specific. Maybe it defines what approach should be taken in carrying out the action (i.e. eco
, normal
, comfort
, boost
)? Or what motivates the current targets (home
, away
, bed
, override
)? This might not be clear enough, but then again it might be OK for this to be a more nebulous category for anything the thermostat uses to describe its operation that doesn't clearly fit into "operation mode" or "state" as defined above.
Avoid using the same word more than once, i.e. all modes, states, and profile names should be unique, even if the most obvious names would overlap. Confusion will continue to arise, so we should do everything we can to keep the target concepts clear.
you're right that HVAC state can be derived from comparing current and target temp (https://github.com/home-assistant/architecture/issues/22#issuecomment-377702014)
Putting this here just for reference, in case people see the argument but not the counter-arguments here and here, which I think are persuasive.
I don't like the "FAN" HVAC mode because we already have a "fan mode" property. In case a unit is set to fan, I expect fan mode to be set to "on" and hvac_mode set to off. (https://github.com/home-assistant/architecture/issues/22#issuecomment-377715891)
This seems sensible to me.
It is currently out of scope for our climate entity to also represent a multizone setup with temporary overrides. We first need to fix it up to a place where it will support the majority of the thermostat models out there.
Hear, hear! I would also argue that devices that control climate but are so different from a typical HVAC thermostat that they can't be properly implemented on this model should be handled separately rather than allowed to stretch the bounds of what the climate component needs to handle.
Thanks for summarizing it @KlaasH. It looks like you included humidify
for operation and operating mode, but we should remove that. It's the same as dry
(as per this comment).
I included it based on this comment and because it seems reasonable that there'd be a corollary to dry
for increasing humidity. But I don't know if there are actually systems that have an operation mode specific to targeting higher humidity (in my head it's possible, maybe in the desert?), and if it's not a real thing then it definitely shouldn't be taking up space in the component. I edited the comment to strike them out.
This issue was triggered by https://github.com/home-assistant/home-assistant/pull/13340 which was adding Alexa controls for our thermostats. I also just did a rewrite of Google Assistant and made it so it only supports our official operation modes.
I think that it's time to do a review of our climate entity. Clean it up and then be better in code reviews in enforcing the rules of the climate component.
Supported features
We have individual support flags for setting a temperature, setting the upper bound of a temp range and setting the lower bound of a temp range. This is still an artifact from when supported features was used to show/hide frontend controls.
Cleanup of made up values
The goal of our abstract base class is to specify which values can be used. That way we can build things on top like frontend, Alexa integration, Google Assistant integration or compare the usage history of two thermostats from different brands with machine learning.
However, there are a bunch of platforms that return their own values for properties. Especially operation mode suffers a lot here. Instead of using the
STATE_*
constants, these platforms return their own made up values. It works with our frontend because we also allow returning an operation list. It does not, however, work with Google Assistant or Alexa. Both have been coded now to be very strict and ignore any non standard operation.STATE_*
toOPERATION_MODE_*
Operation mode
Operation mode describes in what kind of operation the thermostat currently is. This is what we have right now:
Here are just some initial observations:
Actually: I noticed that we have a platform called econet that is not a climate device but is a water heater. It's the only one that uses STATE_GAS, STATE_HEAT_PUMP and STATE_HIGH_DEMAND (they are also used by Wink, but that's because Wink represents econet via their API). I think that econet should not be a climate device.
State property
This should be just operation_mode. Right now it's a combination of is_on and operation_mode. By trying to blend two attributes, we've made the value pretty much useless.
is_on property
Do we need this? Can we blend this in with operation mode? For example, if something is an on/off device, it could just have operation mode be heat/idle or cool/idle. Idle and off are obviously the same kind of action: nothing is happening.
References