Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Climate scheduler #148

Open
alex-torregrosa opened this issue Feb 13, 2019 · 93 comments
Open

Climate scheduler #148

alex-torregrosa opened this issue Feb 13, 2019 · 93 comments

Comments

@alex-torregrosa
Copy link

@alex-torregrosa alex-torregrosa commented Feb 13, 2019

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

This comment has been minimized.

Copy link

@ardeus-ua ardeus-ua commented Feb 13, 2019

Workday sensor usage will also be useful

@awarecan

This comment has been minimized.

Copy link

@awarecan awarecan commented Feb 14, 2019

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

This comment has been minimized.

Copy link
Author

@alex-torregrosa alex-torregrosa commented Feb 14, 2019

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

This comment has been minimized.

Copy link
Author

@alex-torregrosa alex-torregrosa commented Feb 14, 2019

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...

@efficiosoft

This comment has been minimized.

Copy link

@efficiosoft efficiosoft commented Feb 16, 2019

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

This comment has been minimized.

Copy link
Author

@alex-torregrosa alex-torregrosa commented Feb 16, 2019

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.

@efficiosoft

This comment has been minimized.

Copy link

@efficiosoft efficiosoft commented Feb 16, 2019

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.

@efficiosoft

This comment has been minimized.

Copy link

@efficiosoft efficiosoft commented Feb 16, 2019

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.

@timstanley1985

This comment has been minimized.

Copy link

@timstanley1985 timstanley1985 commented Feb 16, 2019

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

This comment has been minimized.

Copy link

@pszafer pszafer commented Feb 19, 2019

@timstanley1985 can you share your code of timers?

@timstanley1985

This comment has been minimized.

Copy link

@timstanley1985 timstanley1985 commented Mar 1, 2019

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

This comment has been minimized.

Copy link

@b4dpxl b4dpxl commented Mar 1, 2019

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.

@efficiosoft

This comment has been minimized.

Copy link

@efficiosoft efficiosoft commented Mar 1, 2019

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

This comment has been minimized.

Copy link

@b4dpxl b4dpxl commented Mar 1, 2019

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

This comment has been minimized.

Copy link
Author

@alex-torregrosa alex-torregrosa commented Mar 1, 2019

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

@efficiosoft

This comment has been minimized.

Copy link

@efficiosoft efficiosoft commented Mar 1, 2019

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

This comment has been minimized.

Copy link

@pszafer pszafer commented Mar 1, 2019

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

This comment has been minimized.

Copy link

@dgomes dgomes commented Mar 1, 2019

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

This comment has been minimized.

Copy link

@pszafer pszafer commented Mar 1, 2019

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

This comment has been minimized.

Copy link

@dgomes dgomes commented Mar 1, 2019

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

@efficiosoft

This comment has been minimized.

Copy link

@efficiosoft efficiosoft commented Mar 1, 2019

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

This comment has been minimized.

Copy link

@dgomes dgomes commented Mar 1, 2019

@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

This comment has been minimized.

Copy link

@pszafer pszafer commented Mar 2, 2019

@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)

@efficiosoft

This comment has been minimized.

Copy link

@efficiosoft efficiosoft commented Mar 2, 2019

@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

This comment has been minimized.

Copy link

@b4dpxl b4dpxl commented Mar 2, 2019

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

This comment has been minimized.

Copy link

@pszafer pszafer commented Mar 2, 2019

@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.

@timstanley1985

This comment has been minimized.

Copy link

@timstanley1985 timstanley1985 commented Mar 2, 2019

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

This comment has been minimized.

Copy link

@tsvi tsvi commented Mar 4, 2019

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.

@efficiosoft

This comment has been minimized.

Copy link

@efficiosoft efficiosoft commented Mar 10, 2019

@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.
@bachya

This comment has been minimized.

Copy link
Contributor

@bachya bachya commented Nov 27, 2019

No need to apologize! I'm excited, too. 👍

Going to get some sleep; hopefully I will dream of an elegant way to represent schedule recurrences. 😴

@Misiu

This comment has been minimized.

Copy link

@Misiu Misiu commented Nov 27, 2019

@bachya that already looks awesome 🎉
Please also consider anacron times (as I described here #148 (comment)).
If you schedule a thermostat to set the temperature to 21 degrees as 5:00 PM but you lost the power or Raspberry rebooted at 4:59 PM and was offline at 5:00 PM then the temperature won't change.
If you set the temperature to be 21 degrees between 5 and 9 PM then when the system starts it should check if there is a scheduler that had the start time before the system started and should activate it.
I think this would be super useful.

@bachya

This comment has been minimized.

Copy link
Contributor

@bachya bachya commented Dec 1, 2019

@Misiu There are two separate (and equally valid) items to discuss in your suggestion: (1) how to ensure schedules are validated and (2) what format recurrence rules should take.

(1) is fairly straightforward: whenever HASS starts up, it should examine existing schedules and re-establish any active/valid ones. I need to test more, but in principle, that should already be in place.

(2) deserves some discussion. Using the cron format has some advantages – its "easy" to express complex schedules – but it’s more geared toward entry in a text file. We won’t be doing that here (not primarily, at least): we’ll be using some sort of UI to generate schedules and it may force the front-end to do an excess amount of translation work if cron is used.

@bachya

This comment has been minimized.

Copy link
Contributor

@bachya bachya commented Dec 1, 2019

After chatting with @balloob about (2), we’re going to go with representing recurrences via RFC5545 (https://tools.ietf.org/html/rfc5545), which is an already-established standard for representing this data structure.

This will require some rework of what I had previously, but it should make for more robust MVP.

More to come.

@Santobert

This comment has been minimized.

Copy link
Member

@Santobert Santobert commented Dec 1, 2019

I agree with @bachya. Cron it used to run a short running task multiple times per day/week/month. It would need some modifications to express time spans with it. A native calendar format should be more natural to use. Furthermore it would be easier to build a gui around it.

@bottiger

This comment has been minimized.

Copy link

@bottiger bottiger commented Dec 3, 2019

@bachya Without knowing the internals of home assistant. Couldn't you (re)use triggers from automations for schedules, instead of time slots? This would make them much more flexibel.

Regarding, what to do at HA startup when using triggers. It is obviously not something that is easy to implement, by I think a good compromise would just be to implement an optional "coldStartup"/"boot" condition which the user could provide. If it evaluates to true the schedule is regarded as active on startup.

If you only start and end schedules with timeslots you can of course search for the correct state, but you will run into problems with this approach as soon as someone wants something more advanced. Like, don't turn the heat on when I'm not home.

Personally I like the trigger approach because it should be familiar to the user (and developers!). And if the user does not provide any "coldStartup" condition the schedular will just adjust itself within a cycle.

@bottiger

This comment has been minimized.

Copy link

@bottiger bottiger commented Dec 3, 2019

@bachya One more thing. I took a look at you initial implementation. It seems like at the end of a schedule go back to the state before the scheduler started. While it's a good initial approach this can be a problem is there are more than two states of the entity.

I know that this probably isn't something one should focus on initially, but it's worth keeping in mind

@efficiosoft

This comment has been minimized.

Copy link

@efficiosoft efficiosoft commented Dec 3, 2019

If you only start and end schedules with timeslots you can of course search for the correct state, but you will run into problems with this approach as soon as someone wants something more advanced. Like, don't turn the heat on when I'm not home.

The correct concept for making schedules depend on entity states would be conditions, not triggers. They can be checked anytime, both on startup and when one of the participating entities changes its state. At least this is something I learned during the development of Schedy and what users have to understand first.

@bottiger

This comment has been minimized.

Copy link

@bottiger bottiger commented Dec 3, 2019

@efficiosoft Really? The main use case I have in my head is that I want my lights/heating/etc to be on during the evening and turn off during the night.

  • I want it to turn on at a specific time, or when I arrive home early.
  • I want it to turn off at 22:00, or when I push my "goodnight button" to shut off everything

If I represent "I'm home" as a condition I guess the system would need to poll for that all the time, in contrast to if you define it as a trigger. If it's a trigger it will be "triggered" once whenever the state of "I'm home" state changes.

And I'm not sure how you represent "I have pushed the goodnight button" as a condition either. I guess you could set a boolean value which then resets during the night, but it feels like hack.

@efficiosoft

This comment has been minimized.

Copy link

@efficiosoft efficiosoft commented Dec 3, 2019

If I represent "I'm home" as a condition I guess the system would need to poll for that all the time, in contrast to if you define it as a trigger. If it's a trigger it will be "triggered" once whenever the state of "I'm home" state changes.

The condition would only need to be reevaluated when the home state changes as well. The issue with using triggers is that their purpose is to react to events that happen at some point (I'm not talking about events as on the HA event bus). However, a schedule needs to be able to determine whether it should be active at any time, not just be activated in response to some event. Otherwise, it wouldn't be able to be activated at startup and we could just use automations as we have them today.

@bachya

This comment has been minimized.

Copy link
Contributor

@bachya bachya commented Dec 3, 2019

For MVP, the scheduler is going to focus on scheduling scenes (activating them and optionally unwinding them).

Automations and scripts aren’t a great fit:

  1. Automations and scripts can be infinitely complex; if we want to “unwind” an automation, HASS would have to understand all possible unwinding scenarios, which is a huge undertaking.
  2. Automations aren’t great candidates to be scheduled because, as already pointed out, their triggers and conditions already form a sort of “schedule.“ Want to turn on your lights when you get home? Create an automation.

I see a world where people can use all of these simultaneously. In my case, my house has:

  1. scenes that will benefit from the scheduler (allowing me to remove extraneous automations that exist just to trigger/unwind those scenes)
  2. automations that don’t need to be “scheduled” and can be left as-is
  3. Schedy instances to handle the hyper-complex cases not covered by (1) and (2)

I can see a v2 of the scheduler that includes support for conditions (in which I will definitely attempt to make use of the existing condition support for automations), but that will be after the MVP.

I’m closing in on a v1 of recurrences (allowing for more complicated repetitions of schedules). Will hopefully share today.

@efficiosoft

This comment has been minimized.

Copy link

@efficiosoft efficiosoft commented Dec 3, 2019

I can see a v2 of the scheduler that includes support for conditions (in which I will definitely attempt to make use of the existing condition support for automations), but that will be after the MVP.

With that in place, the schedules could have functionality similar to that of Schedy, but with the known semantics of HA conditions. Can't wait to see something like that.

@efficiosoft

This comment has been minimized.

Copy link

@efficiosoft efficiosoft commented Dec 3, 2019

@bachya Just something that came to my mind: Isn't solely relying on conditions, even for start and end time and repititions an option as well? A quick glance at the docs of the time condition show that it could benefit from some more options, e.g. for month or year, but actually the time condition is something users are already familiar with and that way, a schedule could be activated by anything we have a condition for (esp. cool for sun or state) without any extra work or new syntax.

EDIT: Of course I'm not against the idea of such a schedule activating a scene, just to make that clear.

@bottiger

This comment has been minimized.

Copy link

@bottiger bottiger commented Dec 3, 2019

I'm going to try to recap how I understand this:

@efficiosoft As I understand it, the main property you would like a system to have is: Be able to have a deterministic starts & stops so you can determine if it should be running without knowing the current state. i.e. after reboot/at startup. I think this is a reasonable property to pursue, albeit I don't feel I need it.

The property I am pursuing is instead: I really would like to transition my devices to the state they should be in now. The typical example is when you want to enable scene A for 5 minutes. You store the current scene B, transition to scene A, and after 5 minutes you can go back to scene B. However, depending on the circumstances this may or may not be correct.

In other words: I would like to write an automation which says: "Turn the light green for 5 minutes, and the go back to whatever state the scheduler thinks you should be in". Today the automation needs to keep track of every possible state the light could be in after 5 minutes have past.

@bachya Regarding "unwinding", I don't understand why it's so complex. Obviously you cannot unwind to something you don't know, but you can unwind to an active schedule - which is exactly the property I am looking for.

Admittedly there are some limitations, for instance: What happens if there are multiple active schedules ? (Why I would like to give them an optional priority)

Want to turn on your lights when you get home? Create an automation.

I think the statement above is a bit misunderstood. I can of course create an automation which turns on the correct scene when I come home, but if I ever change that scene I may have trouble coming back (unless the scheduler has started in the meantime). That said, I really think this is a minor issue for now.

@efficiosoft

This comment has been minimized.

Copy link

@efficiosoft efficiosoft commented Dec 3, 2019

I'm going to try to recap how I understand this:

Thanks, that's great since I sometimes am not sure whether I can clearly express what I want to in English.

@efficiosoft As I understand it, the main property you would like a system to have is: Be able to have a deterministic starts & stops so you can determine if it should be running without knowing the current state. i.e. after reboot/at startup. I think this is a reasonable property to pursue, albeit I don't feel I need it.

Exactly, I think it's crucial for a schedule to be applicable solely based on current time/state/whatever and not on a trigger.

The property I am pursuing is instead: I really would like to transition my devices to the state they should be in now. The typical example is when you want to enable scene A for 5 minutes. You store the current scene B, transition to scene A, and after 5 minutes you can go back to scene B. However, depending on the circumstances this may or may not be correct.

In other words: I would like to write an automation which says: "Turn the light green for 5 minutes, and the go back to whatever state the scheduler thinks you should be in". Today the automation needs to keep track of every possible state the light could be in after 5 minutes have past.

That's an important feature imho, however I would say it's not strictly related to schedules, it's rather a manual intervention. The reverting of a scene activation could get its own service call (maybe scene.rollback or something) which would then execute the unwinding logic @bachya implemented. Your automation could then activate a scene, delay for five minutes and finally call the rollback service. It then wouldn't matter whether the previous state was achieved by a schedule or not.

Does this make sense?

@bachya

This comment has been minimized.

Copy link
Contributor

@bachya bachya commented Dec 5, 2019

@efficiosoft:

@bachya Just something that came to my mind: Isn't solely relying on conditions, even for start and end time and repititions an option as well? A quick glance at the docs of the time condition show that it could benefit from some more options, e.g. for month or year, but actually the time condition is something users are already familiar with and that way, a schedule could be activated by anything we have a condition for (esp. cool for sun or state) without any extra work or new syntax.

The only challenge is that this syntax doesn't handle recurrences (9-10am every other Thursday). Additionally, we're envisioning some sort of calendar UI for this (using RFC5545 as the standard), so schedules won't be created through YAML. That doesn't mean we can't look at using the concept for dynamic times – like sunset – post-MVP.

@bachya

This comment has been minimized.

Copy link
Contributor

@bachya bachya commented Dec 5, 2019

Alrighty, round 2 has just been pushed to the PR – this is my first attempt at recurrences (using RFC5545 as the standard).

After successfully authenticating to the websocket API, you can perform these operations.

List Schedules

This endpoint lists all saved schedules.

Payload:

{
  "id": 123,
  "type": "scheduler/schedules"
}

Response:

{
  "id": 123,
  "type": "result",
  "success": true,
  "result": {
    "b88154e83f984f16bad3041a1bb069c4": {
      "schedule_id": "b88154e83f984f16bad3041a1bb069c4",
      "activation_context_id": "6f9991fea5c24d6f9fd5489ed104c808",
      "entity_id": "scene.turn_on_bedroom_light_to_purple",
      "start_datetime": "2020-01-01T00:00:00",
      "duration": null,
      "rrule": null
    },
    "86000ebf4e7d486aa94f314e483bcd42": {
      "schedule_id": "86000ebf4e7d486aa94f314e483bcd42",
      "activation_context_id": "3956cfbe5d884010afd0cf0a6bd1de2e",
      "entity_id": "scene.goodnight",
      "start_datetime": "2020-01-01T00:00:00",
      "duration": null,
      "rrule": null
    }
  }
}

Create Schedule

This endpoint creates a new schedule. The payload must include:

  • entity_id: a scene entity ID
  • start_datetime: the date/time for the scene to activate

...and can optionally include:

  • duration: the length of time (in seconds) that the schedule lasts for. Including it will reverse the scene activation when that duration is hit; omitting it will leave reversal out.
  • rrule: an RFC5545-compliant recurrence string

Let's look at some examples.

Turn on a scene this Christmas at noon

Payload:

{
  "id": 124,
  "type": "scheduler/schedules/create",
  "entity_id": "scene.turn_on_bedroom_light_to_purple",
  "start_datetime": "2019-12-25 12:00:00"
}

Response:

{
    "id": 124,
    "type": "result",
    "success": true,
    "result": {
        "schedule_id": "b88154e83f984f16bad3041a1bb069c4",
        "activation_context_id": "6f9991fea5c24d6f9fd5489ed104c808",
        "entity_id": "scene.turn_on_bedroom_light_to_purple",
        "start_datetime": "2019-12-25 12:00:00"
        "duration": null,
        "rrule": null
    }
}

Turn on a scene this Christmas at noon and reverse/undo it 1 hour later

Payload:

{
  "id": 124,
  "type": "scheduler/schedules/create",
  "entity_id": "scene.turn_on_bedroom_light_to_purple",
  "start_datetime": "2019-12-25 12:00:00"
  "duration": 3600,
}

Response:

{
    "id": 124,
    "type": "result",
    "success": true,
    "result": {
        "schedule_id": "b88154e83f984f16bad3041a1bb069c4",
        "activation_context_id": "6f9991fea5c24d6f9fd5489ed104c808",
        "entity_id": "scene.turn_on_bedroom_light_to_purple",
        "start_datetime": "2019-12-25 12:00:00"
        "duration": 3600,
        "rrule": null
    }
}

Turn on a scene this Christmas at noon, reverse/undo it 1 hour later, and repeat that every 2 days

Payload:

{
  "id": 124,
  "type": "scheduler/schedules/create",
  "entity_id": "scene.turn_on_bedroom_light_to_purple",
  "start_datetime": "2019-12-25 12:00:00"
  "duration": 3600,
  "rrule": "FREQ=DAILY;INTERVAL=2"
}

Response:

{
    "id": 124,
    "type": "result",
    "success": true,
    "result": {
        "schedule_id": "b88154e83f984f16bad3041a1bb069c4",
        "activation_context_id": "6f9991fea5c24d6f9fd5489ed104c808",
        "entity_id": "scene.turn_on_bedroom_light_to_purple",
        "start_datetime": "2019-12-25 12:00:00"
        "duration": 3600,
        "rrule": "FREQ=DAILY;INTERVAL=2"
    }
}

Note that the rrule format is defined by RFC5545; in our case, we'd anticipate that it would be created by some sort of calendar UI.

Update Schedule

This endpoint updates an existing schedule. The payload must include:

  • schedule_id: the ID of the schedule to update

...and must include at least one of:

  • entity_id: a scene entity ID
  • start_datetime: the date/time for the scene to activate
  • duration: the length of time (in seconds) that the schedule lasts for. Including it will reverse the scene activation when that duration is hit; omitting it will leave reversal out.
  • rrule: an RFC5545-compliant recurrence string

Payload:

{
  "id": 125,
  "type": "scheduler/schedules/update",
  "schedule_id": "b88154e83f984f16bad3041a1bb069c4",
  "duration": 7200
}

Response:

{
    "id": 125,
    "type": "result",
    "success": true,
    "result": {
        "schedule_id": "b88154e83f984f16bad3041a1bb069c4",
        "activation_context_id": "6f9991fea5c24d6f9fd5489ed104c808",
        "entity_id": "scene.turn_on_bedroom_light_to_purple",
        "start_datetime": "2019-12-25 12:00:00"
        "duration": 7200,
        "rrule": "FREQ=DAILY;INTERVAL=2"
    }
}

Delete Schedule

This endpoint deletes an existing schedule. The payload must include:

  • schedule_id: the ID of the schedule to update

Payload:

{
  "id": 126,
  "type": "scheduler/schedules/delete",
  "schedule_id": "b88154e83f984f16bad3041a1bb069c4",
}

Response:

{
    "id": 126,
    "type": "result",
    "success": true,
    "result": {
        "schedule_id": "b88154e83f984f16bad3041a1bb069c4",
        "activation_context_id": "6f9991fea5c24d6f9fd5489ed104c808",
        "entity_id": "scene.turn_on_bedroom_light_to_purple",
        "start_datetime": "2020-01-01T00:00:00",
        "duration": 7200,
        "rrule": "FREQ=DAILY;INTERVAL=2"
    }
}

Things I'm still chewing on:

  • Need to cancel an instance
  • Still thinking on what to do if HASS reboots in the middle of a schedule
@Santobert

This comment has been minimized.

Copy link
Member

@Santobert Santobert commented Dec 5, 2019

That looks really great! Thanks @bachya

@Misiu

This comment has been minimized.

Copy link

@Misiu Misiu commented Dec 5, 2019

  • Still thinking on what to do if HASS reboots in the middle of a schedule

And what in situation when HASS reboots just before schedule should start and starts after schedule should start (power off at 4:58 PM, start at 5:10 PM, the schedule should start at 5:00 PM)?

@bottiger

This comment has been minimized.

Copy link

@bottiger bottiger commented Dec 5, 2019

@efficiosoft is of the (reasonable) oppinion that you should be able to test if the schedule should be running at any time. i.e. at 5:10 PM - when HASS has started - it can test all the defined schedules so see if they should be running or not.

@efficiosoft

This comment has been minimized.

Copy link

@efficiosoft efficiosoft commented Dec 5, 2019

The only challenge is that this syntax doesn't handle recurrences (9-10am every other Thursday). Additionally, we're envisioning some sort of calendar UI for this (using RFC5545 as the standard), so schedules won't be created through YAML. That doesn't mean we can't look at using the concept for dynamic times – like sunset – post-MVP.

Well, the time condition syntax could be extended to handle this (automations would benefit from it as well), but I see that the RFC5545 syntax may be easier to parse for using it in a GUI. It seems like the general direction of Hass goes away from YAML and towards JSON and GUI-only management (which I personally don't like at all), but that's another story.

@electrofloat

This comment has been minimized.

Copy link

@electrofloat electrofloat commented Dec 5, 2019

It seems like the general direction of Hass goes away from YAML and towards JSON and GUI-only management (which I personally don't like at all), but that's another story.

The exact opposite: https://www.home-assistant.io/blog/2019/10/10/release-100/#goodbye-json-

@efficiosoft

This comment has been minimized.

Copy link

@efficiosoft efficiosoft commented Dec 5, 2019

The exact opposite: https://www.home-assistant.io/blog/2019/10/10/release-100/#goodbye-json-

Ah, good to know. But I was not talking about the particular serialization format used to enter data in the GUI, rather about the general fact that there are things you can only manage using the GUI (like these schedules or the ZWave config imported from YAML into JSON storage).

@bachya

This comment has been minimized.

Copy link
Contributor

@bachya bachya commented Dec 5, 2019

@efficiosoft Appreciate the feedback. We'll keep an eye on things; post-MVP, if there's a need for some other entry method (services, a YAML file, etc.), we'll certainly take a look.

@balloob

This comment has been minimized.

Copy link
Member

@balloob balloob commented Dec 6, 2019

As we did with the person integration etc, we can allow schedules to be defined in YAML.

@Ambidexter211

This comment has been minimized.

Copy link

@Ambidexter211 Ambidexter211 commented Dec 14, 2019

Keep in mind that an ideal, generic schedule feature would be able to work with any integration. Turn on / dim / off my lights at certain times, and when certain events happen. Turn up the volume on my media player when there are 10 people shopping in my store, etc.

But then we end up with regular automations, more or less.

I suppose it would be useful if automations could be...nested or atomic, that is, separate pieces of automations that are either subroutines/functions or macros. Once I get a function that turns on a lamp and sets the brightness to 70% brightness (or +20% brightness), I could call that atomic routine from any automation by passing the light or other entity, and the brightness value, and get a return of the current brightness of the entity.

This is certainly easy to do in Python, but maybe we need a library of such Python primitives that are callable by YAML automations?

Anyway, thanks for all your work folks!

Cheers,

Ambi

@Misiu

This comment has been minimized.

Copy link

@Misiu Misiu commented Jan 21, 2020

@bachya awesome piece of work! what's the status of this PR? Any plans to move this forward? No pressure at all, just wondering when this might be added. I think that many users will be happy to have Scheduler in Home Assistant 🙂

@bachya

This comment has been minimized.

Copy link
Contributor

@bachya bachya commented Jan 21, 2020

@Misiu It will be a bit; appreciate your patience. @balloob wanted to review the use case architecture before we proceeded further and he has a lot on his plate.

@antonverburg

This comment has been minimized.

Copy link

@antonverburg antonverburg commented Feb 1, 2020

Maybe I miss something, but did somebody already think about the fact that some processes take a lot of time? For example, if heating a room, a user preferably wants to tell the system when the room has to be on temperature. This means that the scheduler has to start long time before this time with heating the room, so that it is on temperature in time. I actually wrote a script that reads a google-calendar via the calendar integration, and that can predict how long to heat before it is on temperature (depending on outer temperature, and in future I also want to add wind speed & direction). Did we already take this prediction-features in account for the design of the scheduler?

@bachya

This comment has been minimized.

Copy link
Contributor

@bachya bachya commented Feb 1, 2020

@antonverburg Prediction is way outside of an MVP. On day 1, I would expect people to use the scheduler with these predictions implied (e.g., if you know that it takes your house an hour to heat up to where you want it by 5pm, add a schedule that starts at 4pm).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.