Rain forecast automation

WOW! That looks lik witchcraft to me! I can understand each step you explained, but when you put it together, I’m lost. I have been triying to learn jinja2 since this past summer, but it’s like reading chinese to me…I’m a lawyer so I’m REAAAAALY far from my area of expertise.

I run your code, changing the condition to partially cloudy because there was no rain forecasted for the next days, but it does not trigger. Also, the log doesn’t show any errors, so there is nothing wrong with the code. Any thoughts?

- id: '1606432746526'
  alias: Rain alert
  description: ''
  trigger:
  - platform: time
    at: 00:38:00
  condition:
  - condition: template
    value_template: '"{{ ''cloudy'' in state_attr(''weather.my_home'', ''forecast'')[:days]
      | map(attribute=''condition'') }}"'
  action:
  - service: notify.telegram
    data:
      title: '*RAIN*'
      message: "The forecast shows rain for the nex {{days}} days"
  variables:
    days: 4
  mode: single

Silly question, but did you wait until 12:38 AM? That’s the only time it will fire.

You can open dev tools, click on templates, and you can paste that template right into the window. It should output True or False if it worked and also show the 4 day’s conditions.

{% set days = 4 %}
{{ ''cloudy'' in state_attr(''weather.my_home'', ''forecast'')[:days]  | map(attribute=''condition'') }}
{{ state_attr(''weather.my_home'', ''forecast'')[:days]  | map(attribute=''condition'') | list }}
2 Likes

Yes, of course! I tried tweaking it a few times changing the condition from rainy to cloudy and partially cloudy and putting [4] instead of [:days] and did not trigger, and every time I tried the template I changed the time of the trigger for a few mitutes ahead, so the system had time to record the changes.

When I paste the code in the developers tools it detects a coding error: “TemplateSyntaxError: expected token ‘end of print statement’, got ‘cloudy’”

I really appreciate your help!

This is an unfortunate effect of using the GUI for yaml. For some reason, it puts everything in single quotes, then used double single quotes where a single quote would be needed.

The template editor doesn’t like these quotes. So replace all instances of double single quotes with single quotes.

{% set days = 4 %}
{{ state_attr('weather.my_home', 'forecast')[:days]  | map(attribute='condition') }}
{{ 'sunny' in state_attr('weather.home', 'forecast')[:days]  | map(attribute='condition') }}

Also, if you’re using the automation editor, don’t put the outside quotes on it. It will add its own single quote to the front of it to be annoying.

 # In GUI, input it this way without the outside quotes.
 value_template: {{ 'cloudy' in state_attr('weather.my_home', 'forecast')[:days]  | map(attribute='condition') }}

Yesssss!! That did the trick. The syntax error was in the condition because of the quotes, as you said. Works like a charm now! Really appreciate it.

Is there a tutorial or documentation you would recommend to start from scratch on jinja2? I really would like to learn it.

I’ve learned everything through google lol.

I use the template editor a ton to try things out, and open that jinja2 website and see what things do. But even then it’s super confusing.

I used this post a ton with learning different things that could be done. Just trying out the different things in the template editor and modifying things to see what would output, etc.

Also I learn a lot by helping people here. I usually have some janky solution and someone else comes along and says “you can do that 1000 line jank in 2 lines like this”. I think I’m now at the point where I’m the one giving the 2 line solutions these days. Only took me a year!

2 Likes

This automation has been working like a charm for weeks now, but I realized that I need the variable of 4 days to be more specific. I need to calculate the remaining days untill next wednesday so the automation will check the forecast from today untill next wednesday and tell me if it’s gonna rain. I’ve been looking in the forum for the template to calculate the remaining days untill a specific week date and convert it on an integral number with the format %w, but I cant seem to tweak a template that works. Can you please help with this code?
Thanks

  variables:
    # now().weekday() returns 0 for monday, 1 for tuesday, 2 for wednesday, etc. 
    # Subtract wednesday from today. Then modulo to handle wrap around. 
    days: "{{ (2 - now().weekday()) % 7 }}"

Keep in mind this will return 0 on wednesday itself. If you want wednesday to return 7 for next week, do this

days: >
  {% set num_days = 2 - now().weekday()%}
  {{ num_days if num_days > 0 else (7 - num_days | abs) }}

That one will be a number between 7 and 1.

3 Likes

Seems to work flawlessly! Thanks a lot Jim!!

1 Like

Hi @Amaia_Espejo and @jocnnor. This is very helpful and inspirational thread. Thank you!
My weather data provider (FMI) has similar kind of data in developer tools. What I’m trying to figure out how could I refer to or get a single forecast item, like first condition or second temperature. Most likely an easy nut to crack, but I just can’t figure it out…

Hi @AriK !. Sorry but my Jinja2 skills are still very very limited and I also can’t make it work. I’ve been triying to twich it for a wile to get the temperature forecast two days from now without success.

Hi @Amaia_Espejo! I feel for you! Let’s hope that someone more skilled in Jinja2 will help us out :slight_smile:

Good news @Amaia_Espejo!

A friend gave a hint that this might work:

{{ state_attr('weather.hakametsa', 'forecast')[0].temperature }}

…and it did! Hopefully it helps you, too :slight_smile:

1 Like

Thanks for the tip!

@Amaia_Espejo, you might also want to take a look at this post, which will help me forward:

1 Like

I’m trying to write a script that does this but am having a hard time translating this knowledge/formatting into that use. Particularly the condition stuff. I basically want to be able to call a script (via an Alexa routine in this case) that sends notification if there is rain in the forecast for the next day. Any help would be appreciated.

Can you share your final automation code altogether ?

Sure! This is the code for the full automation.
What it does is to check the contact sensor I have installed at the washing machine door. If it detects a state change to closed it means that the washing machine is loaded so it turns on the power switch.
Then it checks the time and date because I have two different electric periods, summer and winter, so it checks if we are on the period of the year for the summer or winter period.
This automation is for the summer, I have a cloned automation just for the winter (surely both can be merged but I haven’t managed it).
So, if we are on summer period and the hour is between 23 and 13h (the cheap electric period), it allows the washing machine to continue.
If its outside this time frame it will stop the energy to the washing machine and it will resume the cycle when the cheap period starts (at 23h).
Once the washing machine is finished it checks the forecast until next Wednesday and sends me a message to unload the washing machine and tells me if it’s going to rain to load the clothes in the dryer. If rain is not forecasted until next Wednesday the message sent says that I can put the cloths to sun dry.

alias: Iniciar la lavadora en horario de verano
description: ''
trigger:
  - platform: state
    entity_id: binary_sensor.lavadora_contact
    to: 'off'
condition: []
action:
  - service: switch.turn_on
    target:
      entity_id: switch.lavadora
    data: {}
  - choose:
      - conditions:
          - condition: time
            after: '23:00'
            before: '13:00'
          - condition: template
            value_template: '{{ now().timetuple().tm_isdst > 0 }}'
        sequence:
          - wait_template: '{{ is_state(''sensor.lavadora_run_state'', ''Lavado'') }}'
          - service: telegram_bot.send_message
            data:
              title: '*Lavadora*'
              target: -470985966
              message: Pongo la lavadora en el tramo eléctrico barato.
          - wait_template: '{{ is_state(''sensor.lavadora'', ''off'') }}'
          - service: switch.turn_off
            target:
              device_id: e600a54e4007130fee3befce30b9543c
            data: {}
          - choose:
              - conditions:
                  - condition: template
                    value_template: >-
                      {{ 'rainy' in state_attr('weather.openweathermap',
                      'forecast')[:days] | map(attribute='condition') }}
                sequence:
                  - service: telegram_bot.send_message
                    data_template:
                      title: '*Lavadora*'
                      target: -470985966
                      message: >-
                        La lavadora ha terminado. Dan lluvia los próximos
                        {{days}} días. Pon la secadora.
            default:
              - service: telegram_bot.send_message
                data_template:
                  title: '*Fin de lavado*'
                  target: -470985966
                  message: >-
                    La lavadora ha terminado. No dan lluvia los próximos
                    {{days}} días. Puedes tender fuera.
      - conditions:
          - condition: time
            after: '13:00'
            before: '23:00'
          - condition: template
            value_template: '{{ now().timetuple().tm_isdst > 0 }}'
        sequence:
          - wait_template: '{{ is_state(''sensor.lavadora_run_state'', ''Lavado'') }}'
          - service: switch.turn_off
            target:
              device_id: e600a54e4007130fee3befce30b9543c
            data: {}
          - service: telegram_bot.send_message
            data:
              title: '*Lavadora*'
              target: -470985966
              message: >-
                Has encendido la lavadora dentro del tramo eléctrico caro. La
                apago y reanudo el lavado a las 23.
          - wait_template: '{{ states.sensor.time.state == ''23:00'' }}'
          - service: telegram_bot.send_message
            data:
              title: '*Lavadora*'
              target: -470985966
              message: Reanudo el lavado dentro del tramo horario barato.
          - service: switch.turn_on
            target:
              device_id: e600a54e4007130fee3befce30b9543c
            data: {}
          - wait_template: '{{ is_state(''sensor.lavadora'', ''off'') }}'
          - choose:
              - conditions:
                  - condition: template
                    value_template: >-
                      {{ 'rainy' in state_attr('weather.openweathermap',
                      'forecast')[:days] | map(attribute='condition') }}
                sequence:
                  - service: telegram_bot.send_message
                    data_template:
                      title: '*Lavadora*'
                      target: -470985966
                      message: >-
                        La lavadora ha terminado. Dan lluvia los próximos
                        {{days}} días. Pon la secadora
            default:
              - service: telegram_bot.send_message
                data_template:
                  title: '*Fin de lavado*'
                  target: -470985966
                  message: >-
                    La lavadora ha terminado. No dan lluvia los próximos
                    {{days}} días. Puedes tender fuera.
    default: []
variables:
  days: |

    {% set num_days = 2 - now().weekday()%}
    {{ num_days if num_days > 0 else (7 - num_days | abs) }}
mode: restart

3 Likes

Lovely. Thank you very much.

2 Likes

Thanks, that’s exactly what resolved my issue with rain detection in 2023!

sensor:
  - platform: template
    sensors:
      forecast_total:
        friendly_name: "Rain detector"
        value_template: "{{state_attr('weather.forecast_starovice_svecovi', 'forecast')[0].precipitation}}"
        unit_of_measurement: "mm"
        device_class: precipitation