Heaty will die, Schedy be born!

hello, thanks, for the moment I would be satisfied to see two lines of code with a start and stop at different times. I don’t understand how to do it.
translated with Google

Have you read the documentation?

hello, I read but with regards to the switch actor I didn’t find any examples, like those of the thermostat.

schedy_lights:  # This is our app instance name.
  module: hass_apps_loader
  class: SchedyApp

  actor_type: switch

  rooms:

    taverna:
      rescheduling_delay: 2
      actors:
        switch.taverna:
        
      schedule:
       - { v: "on", start: "09:15", end: "09:17",weekdays: 1-6 }
       - v: "off"

ok can this go?

I just re-read your first post. You want to switch a pump on for one minute, 24 times a day, every day.

Schedy is not needed. A simple home assistant automation (or two) will do it.

@gionni12 The scheduling semantics are all the same, regardless of the type of actor. The docs just use thermostats most of the time because they’re probably the most popular actor type among Schedy users.

As @taste and @nickrout already suggested, this is probably shorter with a plain HA automation.

OK thanks. I try by trial and error :smiley::smiley::smiley:

Good luck.

Just as an advice for the future: People are more likely to help you if you ask precise questions that show your understanding and concrete effort taken so far. Otherwise, they easily get the feeling of you wanting them to do your homework for you. That’s the same in all communities with voluntary members.

yes, of course, I don’t want porridge, :smiley:but just a small example to start with. Greetings and congratulations for this::+1:

And that’s exactly it, the docs are full of examples, simpler and more complex ones. Having said this, you’ll end up with a lot of rules, one for each hour, which is why it was suggested to you to use HA automations for your particular use case.

@roschi Now that I’ve had a chance to dig in, wanting to get your advice on how to properly implement my climate control scenario.

Background

I have an ADC T-2000 Z-Wave thermostat. It exposes itself as a single climate entity in Home Assistant and has four HVAC modes: heat, cool, heat_cool, and off.

I read your note in the thermostat actor documentation:

If your thermostat is used for both heating and cooling, there has to be an automatic HVAC mode which does heating/cooling based on the difference between current and set target temperature. Schedy will only switch the HVAC mode between on and off (exact names can be configured) and set the target temperature according to the room’s schedule.

…and it makes perfect sense. However, due to my family’s expected use of the thermostat (see below), using the heat_cool HVAC mode won’t be sufficient.

Current App Implementation

Note that this is not complete; it is merely a simple case that highlights the “Dilemma” below.

schedy_cool:
  module: hass_apps_loader
  class: SchedyApp

  actor_type: thermostat

  rooms:

    house:

      actors:
        climate.thermostat:
          hvac_mode_off: "off"
          hvac_mode_on: heat_cool
          max_temp: 95
          min_temp: 45

      rescheduling_delay: 0

      schedule:
        # Set to 72 for a nighttime period:
        - v: 72
          rules:
            - {start: "08:30", end: "07:00", weekdays: 1-5}
            - {start: "08:30", end: "08:30", weekdays: 6-7}
        # Default to 76
        - v: 76

Dilemma

I want to build a thermostat schedule that does one thing during “cooling” season and another thing “heating” season. There are two challenges with this:

  1. Where I live, it’s nearly impossible to determine actual times (months of the year, etc.) during which it is “cooling” or “heating” season. So, we generally determine this based on the thermostat’s current state: if we’ve set it to cool, then it’s “cooling” season, etc.
  2. We often set the temperature higher/lower than the current temperature with the intention of that “disabling” the climate until that temperature is reached. Example: if it’s “cooling” season, it’s currently 70°F, and we set the thermostat to 74°F, we don’t want heating to kick in (which the heat_cool HVAC mode would do); we just want the indoor temperature to drift naturally to 74°F.

#2, in particular, leads me to believe that the heat_cool HVAC mode won’t work.

What I’m Thinking of Doing

I’m thinking of creating two copies of my implementation: one that uses the cool HVAC mode and one that uses the heat HVAC mode (with appropriate expressions to skip schedules that don’t apply to the current HVAC mode):

schedy_cool:
  module: hass_apps_loader
  class: SchedyApp

  actor_type: thermostat

  expression_environment: |
    def hvac_mode():
      return state("climate.thermostat")

  rooms:

    house_cooling_season:

      actors:
        climate.thermostat:
          hvac_mode_off: "off"
          hvac_mode_on: cool
          max_temp: 95
          min_temp: 45

      rescheduling_delay: 0

      schedule:
        # Set the A/C to 72 for a nighttime period:
        - v: 72
          rules:
            - x: "Skip() if hvac_mode() != 'cool' else Break()"
            - {start: "08:30", end: "07:00", weekdays: 1-5}
            - {start: "08:30", end: "08:30", weekdays: 6-7}
        # Default A/C to 76
        - x: "76 if hvac_mode() == 'cool' else Skip()"

    house_heating_season:

      actors:
        climate.thermostat:
          hvac_mode_off: "off"
          hvac_mode_on: heat
          max_temp: 95
          min_temp: 45

      rescheduling_delay: 0

      schedule:
        # Set the heat to 68 for a nighttime period:
        - v: 68
          rules:
            - x: "Skip() if hvac_mode() != 'heat' else Break()"
            - {start: "08:30", end: "07:00", weekdays: 1-5}
            - {start: "08:30", end: "08:30", weekdays: 6-7}
        # Default heat to 70
        - x: "70 if hvac_mode() == 'cool' else Skip()"

I think this should work, but since (a) I’m new to Schedy and (b) I can’t alter the seasons, it’s difficult to test accurately. With these schedules in place, I do notice some (completely expected) errors in the log with this:

2019-08-15 09:11:14.025956 ERROR house_cooling_season: Unknown HVAC mode heat, ignoring thermostat.

I assume this is okay – it seems from the code that this evaluation will occur each time the thermostat’s state changes. Again, I assume that when I switch the thermostat to heat, I will see an error in the logs about cool (and vice versa), but that the actual functionality will continue to work.

Question

Hope this is a sufficient amount of detail. Thoughts? Are my assumptions off base? Is there a better way to accomplish what I’m looking to do?

Thanks so much for your help!

Hi @bachya

Well thought out and researched problem description.

  1. First thing I noticed are the start/end times in the config you provided. Those night rules will be active almost the whole day. I don’t think that was intended.

  2. Do you have only a single thermostat for the entire house? Just asking out of curiosity and to get a better understanding of your setup.

  3. This two-room solution is really creative and should, at first glance though, work as long as you don’t use rescheduling delay, in which case it could lead to a race condition.

  4. Have you thought of disabling HVAC mode support altogether (supports_hvac_modes: false)? That way, Schedy won’t care at all about the HVAC mode and just set the temperature. Sounds like this is exactly what you want. Of course, you can still select a sub-schedule based on the current HVAC mode, just that Schedy won’t alter it anymore. And don’t forget to add your climate entity to watched_entities.

Best regards
Robert

Thanks so much, @roschi!

Excellent catch – I wasn’t thinking in international time. :laughing:

Correct: we’re in a smaller house with one thermostat for the entire thing.

I can see where the race condition could occur… That said:

…this is a great idea! I didn’t consider that supports_hvac_modes could be used for this, but it makes perfect sense.

I’ll update my schedules with these thoughts, give everything a go, and report back. Thanks again!

Looking good so far! Here’s my consolidated schedule:

thermostat_schedule:
  module: hass_apps_loader
  class: SchedyApp
  constrain_input_boolean: input_boolean.climate_schedule_automation

  actor_type: thermostat

  expression_environment: |
    def hvac_mode():
      return state("climate.thermostat")
      
  schedule_snippets:
    cooling_season:
      - v: 72
        rules:
          - {start: "20:30", end: "07:00", weekdays: 1-5}
          - {start: "20:30", end: "08:30", weekdays: 6-7}
      - v: 75
    heating_season:
      - v: 68
        rules:
          - {start: "20:30", end: "07:00"}
      - v: 70

  rooms:

    whole_house:

      actors:
        climate.thermostat:
          supports_hvac_modes: false
          max_temp: 95
          min_temp: 45

      rescheduling_delay: 0

      schedule:
        - x: "IncludeSchedule(schedule_snippets['cooling_season']) if hvac_mode() == 'cool' else Skip()"
        - x: "IncludeSchedule(schedule_snippets['heating_season']) if hvac_mode() == 'heat' else Skip()"

  watched_entities:
    - climate.thermostat
    - input_boolean.climate_schedule_automation

Cheers, Now running Schedy :slight_smile:

@roschi Back with another question. I’m attempting to use Schedy to:

  • turn my backyard lights on at sunset
  • turn them off at 9:30pm on a school night
  • turn them off at 11pm on a weekend night

Here’s what I came up with:

outdoor_lights_schedule:
  module: hass_apps_loader
  class: SchedyApp

  actor_type: switch

  expression_environment: |
    def is_sun_down():
      return state("sun.sun") == "below_horizon"

  rooms:

    backyard:

      actors:
        switch.backyard_lights:

      rescheduling_delay: 0

      schedule:
        - v: "on"
          rules:
            - x: "Skip() if is_sun_down() else Break()"
            - {end: "21:30", weekdays: "1-4, 7"}
            - {end: "23:00", weekdays: 5-6}
        - v: "off"

  watched_entities:
    - sun.sun

The bug in this schedule occurs at midnight: the lights turn back on at midnight and don’t turn off again until sunrise. I assume this is because my omission of a start parameter in the first two schedules defaults them to end midnight (and turn the switch back on).

Any thoughts on how I can fix this bug? Thanks!

EDIT: here’s my horrible, hacky, brittle workaround – still hoping you have a better idea!

outdoor_lights_schedule:
  module: hass_apps_loader
  class: SchedyApp

  actor_type: switch

  expression_environment: |
    def is_before_midnight():
      from datetime import datetime, timedelta

      tomorrow = datetime.now() + timedelta(days=1)
      midnight = datetime(year=tomorrow.year, month=tomorrow.month, \
        day=tomorrow.day, hour=0, minute=0, second=0)

      return datetime.now() < midnight

    def is_sun_down():
      return state("sun.sun") == "below_horizon"

  rooms:

    backyard:

      actors:
        switch.backyard_lights:

      rescheduling_delay: 0

      schedule:
        - v: "on"
          rules:
            - x: "Skip() if is_sun_down() and is_before_midnight() else Break()"
            - {end: "21:30", weekdays: "1-4, 7"}
            - {end: "23:00", weekdays: 5-6}
        - v: "off"

  watched_entities:
    - sun.sun

EDIT 2: That didn’t work. I did see this issue in Schedy’s repo and followed the suggestion to read the section of the Tips and Tricks docs about dynamic start and end times. Will pursue this and follow up.

EDIT 3: Ended up with a newer, slightly-less-hacky idea:

outdoor_lights_schedule:
  module: hass_apps_loader
  class: SchedyApp

  actor_type: switch

  expression_environment: |
    def is_sun_down():
      return state("sun.sun") == "below_horizon"

  rooms:

    backyard:

      actors:
        switch.backyard_lights:

      rescheduling_delay: 0

      schedule:
        - v: "on"
          rules:
            - x: "Skip() if is_sun_down() else Break()"
            - {start: "17:00", end: "21:30", weekdays: "1-4, 7"}
            - {start: "17:00", end: "23:00", weekdays: 5-6}
        - v: "off"

  watched_entities:
    - sun.sun

In this case, I start the schedules well before sundown will ever occur; including it limits the schedule to a particular window. The first expression breaks out of the schedule if the sun isn’t actually down.

2 Likes

You’re right - I’ve read it, but I somehow missed to follow it. Your sentence helped me to be shure, that all the needed information is contained in configuration steps. Thank you.

Is there a way to split the config yaml with !include? I’d like to keep the schedule parts of different actors in different files respectively. The same way, like config.yaml… Thanks in advance for the advice.

Hi
I need some help with the “open door/window temp off” function. I have followed the tutorial and Tips &tricks in the documentation, but I can’t get it to work. Is it something I do wrong?
When I open a balcony door, Schedy sees it and reevaluate the room, but it never sets the thermostat to OFF.

Schedy app:

# Schedy termostatstyring for HM285
schedy_heating:
  module: hass_apps_loader
  class: SchedyApp

  actor_type: thermostat

  schedule_snippets:
    1_floor:
# At given times the themperature should be 22 degree celsius
    - { v: 22, start: "04:00", end: "09:00", weekdays: "1-5", weeks: "1-22, 32-52" }
    - { v: 22, start: "14:30", end: "23:00", weekdays: "1-5", weeks: "1-22, 32-52" }
    - { v: 22, start: "04:00", end: "23:00", weekdays: "6-7", weeks: "1-22, 32-52" }
# On all other times the themperature should be 19 degree celsius
    - { v: 19, weekdays: "1-7", weeks: "1-22, 32-52" }

  schedule_prepend:
  - x: "Mark(OFF, Mark.OVERLAY) if not is_empty(filter_entities('binary_sensor', window_room=room_name, state='on')) else Skip()"

  schedule_append:
  - v: "OFF"

  rooms:
    entre:
      actors:
        climate.thermofloor_as_heatit_thermostat_tf_021_heating_4:
      watched_entities:
      - binary_sensor.shenzhen_neo_electronics_co_ltd_door_window_detector_sensor
      schedule:
      - x: "IncludeSchedule(schedule_snippets['1_floor'])"
     
    kitchen:
      actors:
        climate.thermofloor_as_heatit_thermostat_tf_021_heating_5:
      watched_entities:
      - binary_sensor.door_window_sensor_158d00016c3d3d
      schedule:
      - x: "IncludeSchedule(schedule_snippets['1_floor'])"

    living:
      actors:
        climate.thermofloor_as_heatit_thermostat_tf_021_heating_6:
      watched_entities:
      - binary_sensor.door_window_sensor_158d00015a9291
      schedule:
      - x: "IncludeSchedule(schedule_snippets['1_floor'])"

customize.yaml:

binary_sensor.door_window_sensor_158d00016c3d3d:
  window_room: kitchen
binary_sensor.door_window_sensor_158d00015a9291:
  window_room: living
binary_sensor.shenzhen_neo_electronics_co_ltd_door_window_detector_sensor:
  window_room: entre

Appdaemon log 1:

[10:30:51] INFO: Starting AppDaemon…
2019-08-22 10:30:52.415558 INFO AppDaemon Version 3.0.5 starting
2019-08-22 10:30:52.415781 INFO Configuration read from: /config/appdaemon/appdaemon.yaml
2019-08-22 10:30:52.416832 INFO AppDaemon: Starting Apps
2019-08-22 10:30:52.420691 INFO AppDaemon: Loading Plugin HASS using class HassPlugin from module hassplugin
2019-08-22 10:30:52.545715 INFO AppDaemon: HASS: HASS Plugin Initializing
2019-08-22 10:30:52.546093 INFO AppDaemon: HASS: HASS Plugin initialization complete
2019-08-22 10:30:52.546355 INFO Starting Dashboards
2019-08-22 10:30:52.551206 INFO API is disabled
2019-08-22 10:30:52.555973 INFO AppDaemon: HASS: Connected to Home Assistant 0.97.2
2019-08-22 10:30:52.608660 INFO AppDaemon: Got initial state from namespace default
2019-08-22 10:30:54.617300 INFO AppDaemon: Reading config
2019-08-22 10:30:54.633019 INFO AppDaemon: /config/appdaemon/apps/varmestyring.yaml added or modified
2019-08-22 10:30:54.633171 INFO AppDaemon: /config/appdaemon/apps/apps.yaml added or modified
2019-08-22 10:30:54.633257 INFO AppDaemon: /config/appdaemon/apps/varmestyring.yaml added or modified
2019-08-22 10:30:54.633339 INFO AppDaemon: /config/appdaemon/apps/apps.yaml added or modified
2019-08-22 10:30:54.633418 INFO AppDaemon: App ‘schedy_heating’ added
2019-08-22 10:30:54.633495 INFO AppDaemon: App ‘hello_world’ added
2019-08-22 10:30:54.633641 INFO AppDaemon: Adding /config/appdaemon/apps to module import path
2019-08-22 10:30:54.634003 INFO AppDaemon: Loading App Module: /config/appdaemon/apps/hello.py
2019-08-22 10:30:54.652499 INFO AppDaemon: Loading App Module: /config/appdaemon/apps/hass_apps_loader.py
2019-08-22 10:30:54.654123 INFO AppDaemon: Initializing app schedy_heating using class SchedyApp from module hass_apps_loader
2019-08-22 10:30:54.744511 INFO schedy_heating: *** Welcome to schedy 0.5.0, running on AppDaemon 3.0.5.
2019-08-22 10:30:54.745477 INFO schedy_heating: ***
2019-08-22 10:30:54.746360 INFO schedy_heating: *** This is an app from the hass-apps package.
2019-08-22 10:30:54.747213 INFO schedy_heating: *** DOCS: https://hass-apps.readthedocs.io/en/stable/
2019-08-22 10:30:54.748070 INFO schedy_heating: ***
2019-08-22 10:30:54.749051 INFO schedy_heating: *** You like this app, want to honor the effort put into
2019-08-22 10:30:54.749913 INFO schedy_heating: *** it, ensure continuous development and support?
2019-08-22 10:30:54.750757 INFO schedy_heating: *** Then please consider making a donation.
2019-08-22 10:30:54.751599 INFO schedy_heating: *** DONATE: https://hass-apps.readthedocs.io/en/stable/#donations
2019-08-22 10:30:54.752440 INFO schedy_heating: *** Thank you very much and enjoy schedy!
2019-08-22 10:30:54.753309 INFO schedy_heating: ***
2019-08-22 10:30:54.761124 INFO schedy_heating: — Actor type is: ‘thermostat’
2019-08-22 10:30:54.771490 INFO schedy_heating: --> [R:entre] [A:climate.thermofloor_as_heatit_thermostat_tf_021_heating_4] Received value of 19.0��.
2019-08-22 10:30:54.853457 INFO schedy_heating: --> [R:kitchen] [A:climate.thermofloor_as_heatit_thermostat_tf_021_heating_5] Received value of 19.0��.
2019-08-22 10:30:54.933148 INFO schedy_heating: --> [R:living] [A:climate.thermofloor_as_heatit_thermostat_tf_021_heating_6] Received value of 19.0��.
2019-08-22 10:30:55.006381 INFO schedy_heating: *** Initialization done.
2019-08-22 10:30:55.006528 INFO AppDaemon: Initializing app hello_world using class HelloWorld from module hello
2019-08-22 10:30:55.007633 INFO hello_world: Hello from AppDaemon
2019-08-22 10:30:55.008405 INFO hello_world: You are now ready to run Apps!
2019-08-22 10:30:55.008970 INFO AppDaemon: App initialization complete

Appdaemon log after door opening:

2019-08-22 10:30:54.654123 INFO AppDaemon: Initializing app schedy_heating using class SchedyApp from module hass_apps_loader
2019-08-22 10:30:54.744511 INFO schedy_heating: *** Welcome to schedy 0.5.0, running on AppDaemon 3.0.5.
2019-08-22 10:30:54.745477 INFO schedy_heating: ***
2019-08-22 10:30:54.746360 INFO schedy_heating: *** This is an app from the hass-apps package.
2019-08-22 10:30:54.747213 INFO schedy_heating: *** DOCS: https://hass-apps.readthedocs.io/en/stable/
2019-08-22 10:30:54.748070 INFO schedy_heating: ***
2019-08-22 10:30:54.749051 INFO schedy_heating: *** You like this app, want to honor the effort put into
2019-08-22 10:30:54.749913 INFO schedy_heating: *** it, ensure continuous development and support?
2019-08-22 10:30:54.750757 INFO schedy_heating: *** Then please consider making a donation.
2019-08-22 10:30:54.751599 INFO schedy_heating: *** DONATE: https://hass-apps.readthedocs.io/en/stable/#donations
2019-08-22 10:30:54.752440 INFO schedy_heating: *** Thank you very much and enjoy schedy!
2019-08-22 10:30:54.753309 INFO schedy_heating: ***
2019-08-22 10:30:54.761124 INFO schedy_heating: — Actor type is: ‘thermostat’
2019-08-22 10:30:54.771490 INFO schedy_heating: --> [R:entre] [A:climate.thermofloor_as_heatit_thermostat_tf_021_heating_4] Received value of 19.0��.
2019-08-22 10:30:54.853457 INFO schedy_heating: --> [R:kitchen] [A:climate.thermofloor_as_heatit_thermostat_tf_021_heating_5] Received value of 19.0��.
2019-08-22 10:30:54.933148 INFO schedy_heating: --> [R:living] [A:climate.thermofloor_as_heatit_thermostat_tf_021_heating_6] Received value of 19.0��.
2019-08-22 10:30:55.006381 INFO schedy_heating: *** Initialization done.
2019-08-22 10:30:55.006528 INFO AppDaemon: Initializing app hello_world using class HelloWorld from module hello
2019-08-22 10:30:55.007633 INFO hello_world: Hello from AppDaemon
2019-08-22 10:30:55.008405 INFO hello_world: You are now ready to run Apps!
2019-08-22 10:30:55.008970 INFO AppDaemon: App initialization complete
2019-08-22 10:33:31.021778 INFO schedy_heating: --> Attribute ‘state’ of ‘binary_sensor.shenzhen_neo_electronics_co_ltd_door_window_detector_sensor’ changed from ‘off’ to ‘on’, reevaluating .

@bachya Exactly, limiting the start time as well is the correct solution.