home-assistant / architecture

Repo to discuss Home Assistant architecture
313 stars 100 forks source link

Climate scheduler #148

Closed alex-torregrosa closed 1 year ago

alex-torregrosa commented 5 years ago

Triggered from: home-assistant/home-assistant/pull/21017

It would be useful to add a scheduler to the climate component, specially for the generic_thermostat platform. You can actually do this by using automations in HA, but this way the ui would be more user-friendly.

It should enable the user to set rules triggering temperature changes at certain hours and days of the week. It could also be useful to add a sort of timer to manual temperature changes (making them last 1h for example), but that should be optional and enabled in the component configuration.

This could be done as a standalone componenent (see PR at the beggining) or integrate the functionality into the climate component. The standalone component approach would make sharing a single schedule between different climate entities easier.

ardeus-ua commented 5 years ago

Workday sensor usage will also be useful

awarecan commented 5 years ago

I would like to see a "smart" scheduler be implemented in future, something can compete with Nest's "learning thermostat". That scheduler should consider the weather forecast, the current temperature, and user usage pattern, etc.

If you want to implement a "time" scheduler component with a user friendly UI, I would suggest we implement a generalized scheduler component, not only for climate, but can call any service at a given time.

alex-torregrosa commented 5 years ago

The generalized scheduler component sounds good. However, how can we make it work with the different components? Multiple platforms for a schedule component? It is way different to call 'switch.turn_on' than 'climate.set_temperature'. The differences would also affect the UI.

If you think this is the way to go, I can try to refactor the existing code and turn it to a generic platform (and I think a new PR would be needed, am I correct?).

I also like the idea of the 'smart' scheduler, but It may be something more for the long term, and maybe it could be extended to other components as well. Fore the climate component, I have been thinking of applying some machine learning to the turn-on times of the 'generic_thermostat', as it overshoots the set temperature (When it turns off, the radiators are still hot, warming the house a little bit more). However, I don't have enough data collected yet to try anything.

alex-torregrosa commented 5 years ago

I've been thinking of another approach:

Instead of showing a component with a card, a new panel could be added, which would allow to have a single 'schedule' component with more complex UI options that unifies events for multiple platforms.

For example, you should be able to select a time and day/days/workday/holiday and then a event to fire. Simple events like turning on/off a light or changing a climate's temperature should have a predefined UI, and perhaps an editor for custom events.

The problem with this approach is that it would be like reinventing automations...

bob1de commented 5 years ago

Hi,

As the author of Schedy, I just want to add my two cents here.

While it's certainly easy to design an UI for a simple scheduler with time slots for different workdays, maybe even weeks, months etc. I can't imagine a way to account for external conditions such as weather sensors, presence and that sort of things without creating if ... then... rules, which we already have with automations, although they become very complicated to maintain when used for scheduling.

What has to be considered as well is what happens when HA wasn't running at the time the scheduled value switched, there has then to be a mechanism to find out what to set at startup, so whatever the scheduling algorithm looks like, it has to be able to find a suitable value at every time.

I once also thought about integrating Schedy as a component into HA directly, but had no time to dive into it, hence it still requires AppDaemon. Since the rules concept is quite powerful, maybe that would also be an option?

Best regards Robert

alex-torregrosa commented 5 years ago

Thanks Robert!

I think that the easiest thing to do would be to integrate into HA just the time-based rule functionality of Schedy. If someone wants to write more complex rules, Schedy or automations can be used.

bob1de commented 5 years ago

Yeah, at least that's the part which it should be relatively straightforward to create an UI for.

However, automations aren't suited well for scheduling IMHO. When you just want to execute service X at time Y, that's straightforward. But I think it'd be more appropriate to have a mapping between - let's say - a time slot and the state of an arbitrary entity to be maintained during that time slot. How to bring the entity to that state then differs from entity type to type.

At least that's the concept used in Schedy. You have actors (entities) of a specific type (thermostat, switch, fan or any other customizable type) and a schedule that maps time slots (and, if you go the advanced route via expressions, also arbitrary state conditions) to states of the specific actor type. It can then easily ensure all actors are in the state dictated by the schedule while still allowing for manual adjustments and, if desired, revert these adjustments after a given time.

All in all, the code isn't that small (~4000 lines) and, at the moment, tightly coupled with the AppDaemon API. I also wished to move away from using AppDaemon for it, but simply don't have the time to work on it.

bob1de commented 5 years ago

Just an idea for the simple time-based scheduling... Can't this be acomplished with a calendar + an automation that triggers when an event in the calendar starts? Maybe even the temperature/value/whatever could be supplied with the event.

That way no new interface for creating the schedules has to be written, since there are plenty of good UIs for managing calendars out there.

EDIT: Even restoring state at startup would be possible with an additional automation trigger.

tim-devel commented 5 years ago

Hi, I have implemented heating timers using an automation and some input selects and scripts to set the profile. Have been using them for 18 months now and they are very stable. I am also pretty happy with how it looks in the UI too.... I can share the code if you are interested.

screenshot_20190216-183426

pszafer commented 5 years ago

@timstanley1985 can you share your code of timers?

tim-devel commented 5 years ago

I have pasted the automations, input selects and input booleans below. You will just need to create a clock.yaml file which is a list of available times (i have every 15 mins from 05:00 - 22:00) and a profiles.yaml which is a list of available profiles. You then need to create a script with a name that matches each profile. For example, script.heating_off that turns off the heating. script.heating_medium which sets the heating to a medium setting etc. I have per room control on my set up so have about 6 profiles for heating different parts of the house.

You can then copy and paste these automations, increasing the number by 1, and create any number of timers, I have 9 currently.

########## Heating rules ##########
automation:
 - alias: Heat Profile 1
   initial_state: 'on'
   trigger:
    - platform: template
      value_template: '{%if  states.input_select.heating_timer_1_time.state == states.sensor.time.state %} true {% endif %}'
   condition:
    - condition: state
      entity_id: input_boolean.heating_timer_1_switch
      state: 'on'
    - condition: state
      entity_id: input_boolean.summer_mode
      state: 'off'
    - condition: or
      conditions:
       - condition: state
         entity_id: input_boolean.heating_holiday_mode
         state: 'off'
       - condition: state
         entity_id: input_select.heating_timer_1_profile
         state: 'Off'
    - condition: or
      conditions:
       - condition: template
         value_template: '{{ is_state("input_boolean.heating_timer_1_weekday", "on") and is_state("binary_sensor.workday_sensor", "on") }}'
       - condition: template
         value_template: '{{ is_state("input_boolean.heating_timer_1_weekend", "on") and is_state("binary_sensor.workday_sensor", "off") }}'
   action:
    - service: script.turn_on
      data_template:
        entity_id: script.heating_{{ states.input_select.heating_timer_1_profile.state }}

input_boolean:
  heating_timer_1_switch:
    name: Active
    icon: mdi:gesture-double-tap
  heating_timer_1_weekday:
    name: Weekdays
    icon: mdi:calendar-check
  heating_timer_1_weekday:
    name: Weekdays
    icon: mdi:calendar-check
  ########## Overrides ########
  summer_mode:
    name: "Summer Mode"
    icon: mdi:weather-sunny
  heating_holiday_mode:
    name: "Heating Holiday Mode"
    icon: mdi:beach

input_select:
  heating_timer_1_time:
    name: Time
    icon: mdi:clock
    options: !include clock.yaml
  heating_timer_1_profile:
    name: Heat Profile
    icon: mdi:thermometer-lines
    options: !include profiles.yaml

  heating_timer_1_profile:
    name: Heat Profile
    icon: mdi:thermometer-lines
    options: !include profiles.yaml

sensor:
 - platform: time_date
   display_options:
    - 'time'
    - 'date'
b4dpxl commented 5 years ago

I'd like to see this as a scheduler, instead of using automations. Please can it also consider #20154 though. With the current setup, using automations overrides any temperature set by enabling away_mode.

bob1de commented 5 years ago

A real scheduler would be the right way of solving those sorts of tasks. But again, it shouldn't be specific to the climate component IMHO.

What about the idea of using a calendar and just fetch the temperature to set from it? Reacting to away mode etc. would then be not difficult with just a few plain automations.

b4dpxl commented 5 years ago

Automations shouldn't have to know about away_mode, etc, for setting temperatures. The end climate component should be able to handle that.

alex-torregrosa commented 5 years ago

I'm currently working on a generic schedule component, I'll try to make a pull request next week.

bob1de commented 5 years ago

It's questionable whether away mode should be implemented in the climate component directly at all, since whether I'm away is something that could affect other domains as well, such as lights etc.

@alex-torregrosa I'm very interested in what you're developing. Maybe you could link the PR to this issue to have us notified?

pszafer commented 5 years ago

I think there should be scheduler class and it should be base class for other schedulers. Then we should create generic_climate_scheduler which is managed by HA schedule and then we will be able to implement scheduler for different platform.

Right now I'm writing bosch thermostat component and those devices has "built-in" week calendar with schedule to turn on comfort/eco program (for both climate and water_heater) I think it would be better if in such situation HA would be only kind of frontend for "calendar" and for climate components without such function we can use generic_scheduler.

dgomes commented 5 years ago

A thermostat should have it's own scheduler, sure you can use automations to connect the scheduler to the thermostat, but that is just an extra burden for the end user.

pszafer commented 5 years ago

isn't gonna be worse if user create some schedule in thermostat mobile app and then try to schedule something different in HA scheduler and be surprised that it's going crazy?

dgomes commented 5 years ago

What I would expect, would be for the HA component to synchronise both.

bob1de commented 5 years ago

Syncing schedules between platforms sounds like a huge effort to implement properly with not much benefit. Each manufacturer allows a different number of setpoints per day, different time resolution, single/multi-week schedules, to name just three of the problems this will cause.

Why not just have a central schedule to maintain in HA (or a calendar, for instance)?

Another problem is how to deal with manual overrides, e.g. when a window is opened or if I want to overwrite the scheduled value for an hour or two.

dgomes commented 5 years ago

@efficiosoft I think that depends on the platform. But I see various smart thermostats exposing their schedule and HA platforms being able to incorporate that.

Some others might just dumb down their thermostats due to lack of support.

pszafer commented 5 years ago

@efficiosoft I can see benefits for both approaches, but some thermostats has to have schedule set up if using auto mode. So in case we don't sync scheduler from manufacter we can't really control it (we have to ask user to use manual mode)

bob1de commented 5 years ago

@pszafer That has only usability impacts, right? So the user won't see whether schedule is active or not on the thermostat display?

Personally, I'd prefer to have HA control the thermostats, because it can make more sophisticated decisions than a thermostat can (time of day/day of week).

b4dpxl commented 5 years ago

A thermostat should have it's own scheduler, sure you can use automations to connect the scheduler to the thermostat, but that is just an extra burden for the end user.

It's worth remembering that this issue was raised "specially for the generic_thermostat platform". Whatever is designed needs to support that, which has no scheduling or other capabilities beyond determining temperature and state.

If a thermostat has its scheduler, it makes sense to me to use that instead, although I can see the benefit of being able to view/edit it from within HA. But a generic scheduler in HA could be tied into a thermostat and be used instead, assuming the thermostat's scheduler (if it exists) can be disabled.

pszafer commented 5 years ago

@efficiosoft Buderus setup is quite complex (I know 2 houses with similar setup). I'm not an expert but as far as I understand buderus (IP gateway is manufactured by bosch) thermostat schedule has to be configured. In set up where there is heat pump which is used for heating (climate device) and for water (water_heater). This thermostat can have solar panel as another heating device as well. I think it is easier to create frontend and backend of manufacturer scheduler which is send to thermostat than try to implement such inteligence which knows that it controls heating device which sends water to climate and water heater.

@b4dpxl I think this is best aproach, if device has scheduler capability implement it to HA, if not use generic scheduler.

tim-devel commented 5 years ago

I think you all may be over thinking this. The scheduler should be platform agnostic. All it needs to do is set thermostat parameters at a predetermined point in time. This should be independent of any platform (nest etc.) configured schedule. The user can then choose wether to use the platform and/or home assistant for scheduling

tsvi commented 5 years ago

Interesting how this issue pops up every time again. You want something with less options than full fledged automation, but dynamic enough so you can change the timing easily and manually.

Definitely think this should be platform agnostic.

I imagined it as something with the following UI: a table of entries with a + sign to add more entries. Each entry has a start time, end time (optional), service call, boolean whether it's on, input select for recurring and - sign for deletion.

bob1de commented 5 years ago

@tsvi +1 for the table approach.

However, entering a service call in every table row would add quite some overhead I think. Maybe it should be a two-step process.

  1. Create some named service call templates with service and data, maybe even data_template to dynamically insert the entity id
  2. Select one of these templates in each of the table rows.
balloob commented 5 years ago

I think that a generic scheduler should work with scenes. Users can configure a scene for "active" and for "not active", or any other state that a scheduler would support.

It would be a bit more helpful if we extend our scene support to allow users to create them on the fly, including better restore support. But that's getting off topic.

Adminiuga commented 5 years ago

I think you all may be over thinking this. The scheduler should be platform agnostic. All it needs to do is set thermostat parameters at a predetermined point in time.

All scheduler should allow you to do is to call a service/script/scene. Could be climate.set_temperature

This should be independent of any platform (nest etc.) configured schedule. The user can then choose wether to use the platform and/or home assistant for scheduling

I agree. Pretty much the above obsoletes any thermostat "buil-in" schedules.

IMO if time_pattern trigger could be extended to become datetime_pattern trigger (crontab like?), that's essentially all we need for a generic scheduler? Maybe a nice UI could be a plus too :)

b4dpxl commented 5 years ago

It should also handle conditions. For example, I have a "schedule" which triggers at 06:30 on a workday (according to the workday sensor), unless a boolean input representing "holiday mode" is turned on.

Francisk0 commented 4 years ago

Hi, @timstanley1985 can you upload a example with all files for begginers?

Misiu commented 4 years ago

I think that a generic scheduler should work with scenes. Users can configure a scene for "active" and for "not active", or any other state that a scheduler would support.

It would be a bit more helpful if we extend our scene support to allow users to create them on the fly, including better restore support. But that's getting off-topic.

I think the solution proposed by @alex-torregrosa would be sufficient. Of course, the ability to activate a scene at a specific time would be a nice addition but think of potential use cases. I think those will apply to many users.

-set target temperature to a specific thermostat or a group of thermostats -set a mode to a specific thermostat or a group of thermostats -turn on/off a single light or multiple lights -open/close a roller shutter (or multiple roller shutters) or set it (them) to a specific percentage

For most of that, you don't need a scene. A scene is useful if you want to group multiple entities. Creating a scene per entity won't be very user-friendly. If you want to have four temperatures in a thermostat per day (24h) you must create four scenes and if you want different behavior per thermostat and assuming you have six thermostats that give 24 scenes to create (correct me if I'm wrong).

There are at least a dozen topics on the forum about a schedule solution.

Can we please ask the devs for at least looking into this one more time?

Jc2k commented 4 years ago

In your specific example you wouldn't need a scene for each of your thermostats, you could set each one differently within a single scene, I think.

But I think you are reading too much into "scenes" and what that means here. It doesn't have to be a heavyweight thing. This might not involve creating a new "Scene" entity at all. The scene 'engine' can apply (reproduce) a target state without having a predefined scene entity, allowing it to do all of your use cases. It's an implementation detail that the user might not even realise if we get it right. It's a way of turning imperative model (making a number of individual set_X service calls) into a declarative (describe the desired state) one, which will lend itself better to building a UI and validation.

AIUI there is already a scheduler of sorts built in, though I haven't used it (in the UI, under the Automations tab you can pick time as a trigger). Ultimately I'd like to see a nicer UI built on top of this. You would be able to use a widget to pick the time (its not clear what format to use etc) and then select one or more entities, then there would be UI to select which attributes like on/off, color, target temperature, mode, etc to change. This would respect any min/max ranges on the entitiy attributes of course. This would use the scene engine, but implicitly - it wouldn't turn it into a multi-stage process for the user.

Misiu commented 4 years ago

@Jc2k you are right, the implementation is transparent to the end-user, he doesn't have to know (and most of the time doesn't want to know) what is happening under the hood. @alex-torregrosa made a component and a UI panel I think that both should be considered as a start point.

I'm aware that I could use automations, but for me, this creates more problems than solutions. For example, if I create an automation that sets the target temperature to 21 at 06:PM, but my system will be offline (power off) from 05:59 PM to 06:02 PM. To handle that case I must create another automation that will fire at the system start, checks if the current time is after that trigger time and set the target temperature.

I hope that a proper scheduler component will solve this problem by triggering at a specific hour, but it also should check every scheduler at the system start and fire it if the conditions are met.

Jc2k commented 4 years ago

Again though we are talking about the features as the devs see them vs as the user sees them. I’d argue that such a capability to run timers that were missed during downtime should be built into the timer automation and the scheduler is just a UI for leveraging that. Rather than adding an entirely different new set of APIs.

Misiu commented 4 years ago

@Jc2k I'm a .NET developer, so I sometimes write from a developer point of view. But try to be an end-user: You set a schedule to change the temperature in your house at specific hours, 21 Celcius degrees at 06:00 PM and 18 Celcius at 09:00 PM. So if for some reason there was downtime at 06:00 PM you want that temperature to be set to 21 as soon as the system starts. Of course, you could create a schedule every 5 minutes between 06:00 and 09:00 PM to set the temperature to 21 (just to be sure), but that's not ideal from the end-user point of view. You want the temperature to be set to 21 and that's the problem the schedule should solve.

I'm aware that this will probably require some extra API's, but I think the devs should be aware of such needs and at least should consider supporting such scenarios.

Jc2k commented 4 years ago

Last reply was from phone so did a crap job of explaining myself.

Let me start by saying I don't disagree with the user experiences you want at all. I want them myself 😁 I think that's important to point out because I don't want to argue or make you think I don't agree with the use cases you mention or the user experience you want to have. If anything, all I want to do is try and help build consensus or at the very least help understand where we are and why.

Also I'm not a core dev, I maintain one small integration. So you don't need to convince me of anything, and doing so won't help with your goals to get this resolved 😄 Earlier I said you might be reading too much into the talk about scenes, but of course i might be reading too little as well (but this makes me thing i'm not too wrong... maybe 🥈 )

As a dev i'm sure you'll already appreciate this point but... one of the big sticking points of Home Assistant is that due to its size when you implement something and get it wrong then it's hard to change because you have 100's of users that are sensivity to changes to it. That's why the team cannot sometimes do the "obvious" and "easy" thing first and plan to do it right later. They don't want 100's of users using a feature that has any sort of planned obsolescence - it will lead to hundreds of support tickets. So big new features like this are going to be slow. We need to take the time to try and get it right, plus everyone is busy.

As you saw yourself a few hours ago, the generic scheduler PR does not actually support all the entities that the existing scene engine does. It doesn't support covers for example. So even if that PR had been merged it would not have handled at least one of your use cases. If the "rules" in that system were scene fragments that were passed to the scene engine just like in the PR i linked to then it would - and it would automatically get support for new entities and entity attributes that the scene engine got support for. There is even potential for sharing UI components around configuring the desired entity state with the main scene engine as well.

(To be clear i'm not saying that you as a user would even know that we were using the scene backend to do this. It would be seamless)

The alternative is maintaining that code in both components, doubling the work for an already stretched team. Again, for avoidance of doubtt. From a user POV, both of these acheive exactly the same thing. They may have the same UI. But by not using the scene engine you potentially causes duplication and/or feature disparity.

That's why i said to not read too much into the terminology. You might be implying a user experience was not being implied at all.

Your example of a current limitation of the time automation is a good one and I think the time automation trigger should gain anacron like powers. I'd be interested to know what other people think of that idea.

Santobert commented 4 years ago

@Jc2k 100% agreed! It would be great to have something like a scheduling engine based on reproducing states. This could be done using automations and scenes, but with an improved ui. Something like a subset of automations that are not visible in the automation editor, but in a schedule editor. This schedule editor could look similar to the one of nodered.

Misiu commented 4 years ago

@Santobert as @Jc2k wrote the implementation is transparent to the end-user. I don't know the guts of Home Assistant, so can't say what would be the best way to build this, 27298 got merged, 25681 is almost finished, so I guess that APIs needed for this will be almost ready.

I like the idea of anacron (didn't hear that phrase before 😉), it would be a lifesaver. Do You think this should be a separate arch issue?

@balloob any comments? What do You think about both ideas?

balloob commented 4 years ago

I think that my earlier comment is still spot on: https://github.com/home-assistant/architecture/issues/148#issuecomment-502945601

This should work only with scenes, as scenes delegate the actual reproducing states to the integrations. So a scheduler would only have to deal with what scene to activate when.

The better scene support has been added by @Santobert + others in 101 👍

Misiu commented 4 years ago

This should work only with scenes, as scenes delegate the actual reproducing states to the integrations. So a scheduler would only have to deal with what scene to activate when.

The better scene support has been added by @Santobert + others in 101 👍

@balloob does this mean that the user will have to create scenes manually? Ideally, the user should be able to use the scheduler to set temperature for a given thermostat, the UI should allow him to enter the temperature or the color of the lights or turn a switch on. From the end-user perspective, it doesn't matter how this will be implemented, but please don't require us to manually create scenes.

Below type of UI would be a good start (taken from https://github.com/home-assistant/home-assistant-polymer/pull/2929): image

What I especially like about this UI is the ability to support two hours (from and to). This way the scheduler would work like anacron - if the HA would be offline at the exact time when the schedule should trigger, then after start if would check what schedule should be active during specific hours and start it.

b4dpxl commented 4 years ago

@Misiu that UI would be neat, but we need to have support for conditions. That’s what separates HA from a dumb thermostat or timer. For example, I have a “schedule” which only fires early on a weekday if it’s not a public holiday and I’ve not manually toggled a Boolean value indicating we’re on holiday. I also have non-heating schedules which trigger at set times if the outside temperature is above a certain threshold, or the sun hasn’t set yet. Calling a script might be an option for some cases, but the basics should be handled from the UI

Misiu commented 4 years ago

@b4dpxl I can't disagree. Conditions would be an awesome addition, but that's an advanced usage. In the UI I attached you can see a checkbox that probably is used to enable/disable a Scheduler. Is such advanced scenarios automation could be used to enable/disable a scheduler.

For standard scenarios, the end-user should be able to edit the scheduler, for example, set the hours during which the scheduler will be active, or set the target temperature.

Without easy to use UI this component won't be very useful - I don't think my parents (60 years +) or my wife will be happy if she will have to manually edit yaml file just to change the target temperature.

b4dpxl commented 4 years ago

Without easy to use UI this component won't be very useful - I don't think my parents (60 years +) or my wife will be happy if she will have to manually edit yaml file just to change the target temperature.

Agreed @Misiu , I currently use number inputs to set my various temperatures, with a “config” Lovelace panel. Basic conditions should be possible though, as they are through the automation editor. Or at least allow advanced schedules to be created using the same scheduling engine via yaml directly, as with automations today.

balloob commented 4 years ago

@Misiu see https://github.com/home-assistant/home-assistant/issues/27023

At the end of the day, this is going to just be automations right? They have time triggers, conditions (including for weekday) etc. The only difference is what to do when a user changes devices on their own. For thermostats, if you change the schedule there are override options to say that the change is permanent, until the next schedule change or for next X time.

pszafer commented 4 years ago

I think scenes+automations are almost perfect for scheduler already. I'd add scene with service eg planned_temperature and that way the real thermostat would follow schedule, and HA would just map schedule of thermostat to HA and allow to edit times, but not invoke real service like set_temperature or set_mode.

Misiu commented 4 years ago

Agreed @Misiu , I currently use number inputs to set my various temperatures, with a “config” Lovelace panel. Basic conditions should be possible though, as they are through the automation editor. Or at least allow advanced schedules to be created using the same scheduling engine via yaml directly, as with automations today.

I know that this is a bit off-topic, but could You share your setup? I have 5 generic thermostats and I'm looking for a way to easily set the temperature based on a basic scheduler (until a first-class scheduler is added into HA). Thanks!

b4dpxl commented 4 years ago

@Misiu I have 5 virtual_thermostats (my own fork of generic_thermostat) linked into a climate_group. These are connected to powered radiator valves and ds18b20 temperature sensors. There are 2 automations to turn on (after 3 minutes due to the time to open a valve) and off the boiler itself (using a Shelly 1 connected in place of the thermostat) when any of the radiators are open.

I have a number of input_number variables for different room temperatures at different times, an input_boolean to specify when we’re on holiday (and get a lie-in), and a workday binary sensor. I also have some window sensors which set the virtual_thermostat in that room to “away” when opened; the missus likes to open windows when the heating is on :)

My automations look something like this:

I run my home office at slightly different temperatures/times and don’t actively heat over the weekend either. I have an RF switch by my desk that I can hit for a boost in that room, if I’m working late.

I can’t post screenshots or get my config at the moment, but I’ll put some up later when I can.