Thermostat automation: Script needs streamlining

Hi yalls,

I have written a script which controls my BOSCH smart home thermostats gen. II by means of the new controller II. It works well.

Purpose of the script: Deactivation of thermostats for x minutes during venting of whole appartment.
The thermostats are always on auto (running a heating plan) and are temporarily set to manual 18°C during venting.

Background: My appartment is rented, so no extensive installation of sensors etc. makes sense currently, I want to work with only the existing thermostats.

Script:

alias: Lüften 5 Minuten
sequence:
  - service: climate.set_temperature
    data:
      temperature: 18
      hvac_mode: heat
    target:
      area_id:
        - bad
        - arbeitszimmer
        - vigo
        - wohnzimmer
        - schlafzimmer
  - delay:
      hours: 0
      minutes: 5
      seconds: 0
      milliseconds: 0
  - service: climate.set_hvac_mode
    data:
      hvac_mode: auto
    target:
      area_id:
        - arbeitszimmer
        - bad
        - schlafzimmer
        - vigo
        - wohnzimmer
  - service: climate.set_preset_mode
    data:
      preset_mode: eco
    target:
      area_id:
        - bad
        - arbeitszimmer
        - vigo
        - wohnzimmer
        - schlafzimmer
  - service: notify.mobile_app_pumpel_pro
    data:
      message: Fenster zu!
      title: Lüften
  - service: notify.mobile_app_sm_g970f
    data:
      message: Fenster zu!
      title: Lüften
mode: single
icon: mdi:air-filter

Questions for streamlining:

  1. Can I group the areas into e.g. whole appartment? I tried creating a group but did not know how in this case.
  2. Can I group the notification receivers?
  3. Is there anything else that I can do to get rid of redundant lines in this script?

Currently, it’s not possible to group areas. But you can use a variable for it.

In the script UI, switch to yaml mode and insert the following under the line sequence: :


  - variables:
      bereiche: bad, arbeitszimmer, vigo, wohnzimmer, schlafzimmer

Then under target: :


    target:
      area_id: "{{ bereiche }}"

For the notification part have a look at notify-groups.

The whole would look like this:


alias: Lüften 5 Minuten
sequence:

  - variables:
      bereiche: bad, arbeitszimmer, vigo, wohnzimmer, schlafzimmer

  - service: climate.set_temperature
    data:
      temperature: 18
      hvac_mode: heat
    target:
      area_id: "{{ bereiche }}"

  - delay:
      hours: 0
      minutes: 5
      seconds: 0
      milliseconds: 0

  - service: climate.set_hvac_mode
    data:
      hvac_mode: auto
    target:
      area_id: "{{ bereiche }}"

  - service: climate.set_preset_mode
    data:
      preset_mode: eco
    target:
      area_id: "{{ bereiche }}"

  - service: notify.alle_mobilphone
    data:
      message: Fenster zu!
      title: Lüften
mode: single
icon: mdi:air-filter

Thank you so much, exactly what I was looking for. Can global variables be defined (e.g. as entities?) so they can be reused in different scripts/automations?

About the notification group: I’ll try to implement it with your hint and will share the result.

Thanks again!

There’s an interesting topic about that: Make variables global - #8 by finity

1 Like

I do a similar thing with the thermostat in my garage, when the garage door opens an automation set the hvac _mode to off, then 15 minutes later turns it back into heat mode.

Anyways, that all works fine, except last week the command to turn the thermostat timed out and the integration (zwave) did not return an error,

So, to make this reliable, you’ll want to add a delay, check to see if the thermostat did turn on and if not retry. Also you should be setting continue_on_error to true otherwise if one of those calls errors the automation will terminate.

I’m working on a project to make the retries transparent and easy to do vs coding into each automation.

1 Like

Hi - thanks for the heads up !!! Of course, I would not be the only one looking for variables, how could I think that :slight_smile:

Have you checked out the other variable integration ???

That’s funny - I thought of exactly the same robustness improvement. A little simpler currently: Just issue the same script commands twice with a delay between. The whole status checking will take some more time for me as a newbee. But thanks to your kind provision of resources (HASS-RS) maybe not so much time after all.

Love your approach!

1 Like

I like that simple and robust.

1 Like

It’s easy to use repeat for this purpose. The service call will be repeated only the number of times necessary or until it reaches a maximum number of attempts.

For added robustness, add an if-then after the repeat to check if the service call was ultimately successful. If it wasn’t then, at a minimum, post a notification reporting the failure.


FWIW, I have a ‘goodnight’ script that runs through a long list of things to lock, turn off, etc. For my situation, it doesn’t employ repeat (to try multiple times) but a wait_for_trigger with a timeout. For example, after locking a doorlock, it waits for the lock’s state to change to ‘locked’. If it fails to change within the timeout period, the script announces the failure (and then proceeds to execute the balance of the script).

1 Like

Hi pedolsky,

for some reason the variable definition (- variables: bereiche: bad, ...) and reference (area_id: "{{ bereiche }}") doesn’t work. No error is displayed when saving script (so correct indentation as per your suggestion), but no effect.
Trying this as an alternative: Loop in script with variables - #5 by mullischlumpf

My current working synthesis looks like this:

alias: Lüften 5 Minuten (Duplizieren)
variables:
  wohnung:
    - bad
    - arbeitszimmer
    - vigo
    - wohnzimmer
    - schlafzimmer
sequence:
  - repeat:
      count: 2
      sequence:
        - repeat:
            count: "{{ wohnung | count }}"
            sequence:
              - service: climate.set_temperature
                data:
                  temperature: 18
                  hvac_mode: heat
                target:
                  area_id: "{{ wohnung[repeat.index -1] }}"
        - delay:
            seconds: 2
  - delay:
      minutes: 5
  - repeat:
      count: 2
      sequence:
        - repeat:
            count: "{{ wohnung | count }}"
            sequence:
              - service: climate.set_hvac_mode
                data:
                  hvac_mode: auto
                target:
                  area_id: "{{ wohnung[repeat.index -1] }}"
              - service: climate.set_preset_mode
                data:
                  preset_mode: eco
                target:
                  area_id: "{{ wohnung[repeat.index -1] }}"
        - delay:
            seconds: 2
  - service: notify.mobile_app_pumpel_pro
    data:
      message: Fenster zu!
      title: Lüften
  - service: notify.mobile_app_sm_g970f
    data:
      message: Fenster zu!
      title: Lüften
mode: single
icon: mdi:air-filter

Now I want to add a while loop like in the following code snippet, but I don’t yet know how the variables would work in a nested repeat loop (I need a repeat count from the superordinate repeat loop) and also how the climate. entities can be called using concatenations of climate.room_climate_ and the values of the variables array.

sequence:
  - repeat:
      count: "{{ wohnung | count }}"
      sequence:
        - repeat:
            while:
              - condition: not
                conditions:
                  - condition: state
                    entity_id: climate.room_climate_badezimmer
                    attribute: temperature
                    state: "18"
            sequence:
              - service: climate.set_temperature
                data:
                  temperature: 18
                  hvac_mode: heat
                target:
                  area_id: "{{ wohnung[repeat.index -1] }}"
1 Like

Yeah, had a Bad-HA-Day and mixed up automation variables. :woozy_face: Sorry for that and glad to hear that you’ve found a working solution!

1 Like

I wasn’t able to “simply/quickly” implement your RS but quickly wrote my own while loop solution draft here.

While it is this similar, but slightly different to your solution, I would like to know

  • which way you prefer (repeat until or repeat while not) and
  • how I could solve the problem with the iteration of multiple entities in a nested repeat loop (see my linked thread)

Very interested in your opinion: ME!

I have opened a new thread with a robustness improvement as to sensor reaction:
https://community.home-assistant.io/t/sensor-reaction-robustness-by-means-of-while-loop-concatenation-of-strings-for-variable-evaluation-in-nested-loops/535472/2

Thanks for the note. I am working on an updated version of RS that will be an integration instead of the scripts. I see from your example, that you periodically poll the device (via update_entity) and your condition contains multiple parts. Are there any other missing capabilities?

Either way can work on the repeat. If it works then it’s good! I do like to have things be efficient as possible, I don’t know that you get an advantage of polling every second vs polling at a longer interval? Also note, that if the update_entity fails, the automation will end, you may want to consider using the continue_on_error flag, so that a WIFI dropout doesn’t cause the automation to exit.

1 Like