Smart Sprinkler Automation (skip watering if there is rain in next 48 hours - 2 days)

Hello everyone,
I just started using hassio and I do have all my homemade sprinkler system (mqtt switches controlling valves). on my previous automation system I was able to read openweathermaps forecast objects and check if there will be a rain in the next 48 hours to skip my watering schedule. I’m not sure how can I achieve that in HA. Here is more detail on my automation.yaml:

- id: '1560827530261'
  alias: Switch Walkway Sprinkler
  trigger:
  - at: 06:00:00
    platform: time
  condition:
  - condition: time
    weekday:
    - mon
    - wed
    - fri
  action:
  - data:
      entity_id: switch.walkway_sprinkler
    service: switch.turn_on
  - delay: 00:15:00
  - data:
      entity_id: switch.walkway_sprinkler
    service: switch.turn_off

as you can see I’m watering my walkway Monday, Wednesday and Friday at 6 AM for 15 minutes.
this automation is working without any issues.
now I want to make it smarter! and skip a watering schedule if there will be a rain in the next 48 hour.
I know that openweathermaps is providing forecast for the next 5 days so could anyone tell me how can I grab that data and check if forecast precipitation object is null for the first two returning objects?
here is what openweathermaps returns:

{
  "temperature": 63.7,
  "humidity": 93,
  "pressure": 30.03,
  "wind_bearing": 290,
  "wind_speed": 4.7,
  "attribution": "Data provided by OpenWeatherMap",
  "forecast": [
    {
      "datetime": 1561658400000,
      "temperature": 64.3,
      "precipitation": null,
      "condition": "sunny"
    },
    {
      "datetime": 1561744800000,
      "temperature": 66.4,
      "precipitation": null,
      "condition": "sunny"
    },
    {
      "datetime": 1561831200000,
      "temperature": 68.3,
      "precipitation": null,
      "condition": "cloudy"
    },
    {
      "datetime": 1561917600000,
      "temperature": 68.9,
      "precipitation": null,
      "condition": "sunny"
    },
    {
      "datetime": 1562004000000,
      "temperature": 66.3,
      "precipitation": null,
      "condition": "sunny"
    }
  ],
  "friendly_name": "OpenWeatherMap"
}

anyone can help with this?
I really appreciate any help or guidance
Thank you

1 Like

Use the OpenWeatherMap integration:

Once you have that configured and operational, it will make it easier for your automation to access OpenWeatherMap’s data (and decide if it should skip a watering period).

Thank you for your reply.
I already have the openweathermaps working but I need help with using the the data.
I’m receiving an object from openweathermaps and don’t know how to use that.
should I create an item to return true of false and then use it in automation?

something like:

{% if ('{{states.weather.openweathermap.attributes.forecast[0].precipitation}}', 'null' and '{{states.weather.openweathermap.attributes.forecast[1].precipitation}}', 'null') -%}not_rainy{%- else -%}rainy{%- endif -%}

I think the null value in the JSON data will be interpreted by Home Assistant as an Undefined value.

Assuming I’m correct about that, this template should report if it’s rainy/not_rainy.

{% set p0 = state_attr('weather.openweathermap', 'forecast[0].precipitation') is undefined %}
{% set p1 = state_attr('weather.openweathermap', 'forecast[1].precipitation') is undefined %}
{{ 'not_rainy' if p0 and p1 else 'rainy' }}

You can paste this version into the Template Editor and experiment with it:

{% set p0 = state_attr('weather.openweathermap', 'forecast[0].precipitation') is undefined %}
p0 is {{ p0 }}
{% set p1 = state_attr('weather.openweathermap', 'forecast[1].precipitation') is undefined %}
p1 is {{ p1 }}
result is {{ 'not_rainy' if p0 and p1 else 'rainy' }}

EDIT

Corrected typo. Changed states_attr to state_attr.

I’ll send an update when I implemented your code and make it working
Thank you

Error rendering template: UndefinedError: 'states_attr' is undefined

doesn’t recognize states_attr so I changed it to:

{% set p0 = ('states.weather.openweathermap.attributes.forecast[0].precipitation') is undefined %}
p0 is {{ p0 }}
{% set p1 = ('states.weather.openweathermap.attributes.forecast[1].precipitation') is undefined %}
p1 is {{ p1 }}
result is {{ 'not_rainy' if p0 and p1 else 'rainy' }}

image

any ideas why it is not considering two false and saying rainy?

1 Like

Sorry, that’s my mistake.

Change:
states_attr
to:
state_attr

I’ll correct my original post.

The template’s logic is identical to what you posted in your original pseudo-code (which I’ve streamlined here:

if forecast[0].precipitation is 'null' and forecast[1].precipitation is 'null' then 
  not_rainy
else 
  rainy
endif

If precipitation is ‘null’ for both forecast days (True for both days, when using the template) then the pseudo-code says to report ‘not_rainy’. If either, or both, are not ‘null’ (False using the template) then the pseudo-code says to report ‘rainy’. Therefore the template is behaving like the pseudo-code. If p0 and p1 are both False the result is rainy.

HOWEVER, if precipitation is currently ‘null’ for both days but the template is reporting False for both p0 and p1 then that means the template’s test is incorrect. It should be reporting True for both forecast days.

What does this report in the Template Editor:

p0 is {{ states.weather.openweathermap.attributes.forecast[0].precipitation }}
p1 is {{ states.weather.openweathermap.attributes.forecast[1].precipitation }}

the result is:
p0 is None
p1 is None

Try this version

{% set p0 = state_attr('weather.openweathermap', 'forecast[0].precipitation') == None %}
p0 is {{ p0 }}
{% set p1 = state_attr('weather.openweathermap', 'forecast[1].precipitation') == None %}
p1 is {{ p1 }}
result is {{ 'not_rainy' if p0 and p1 else 'rainy' }}

thank you so much for all your help and time, the last version you’ve sent is working.
one last question. how can I use above statement in HA. I only tried it in template editor.
When I put it in my sensor value template it returns too many things.

value_template: >-
          {% set p0 = state_attr('weather.openweathermap', 'forecast[0].precipitation') == None %}
            p0 is {{ p0 }}
          {% set p1 = state_attr('weather.openweathermap', 'forecast[1].precipitation') == None %}
            p1 is {{ p1 }}
          result is {{ 'false' if p0 and p1 else 'true' }}

Like this:

        value_template: >-
          {% set p0 = state_attr('weather.openweathermap', 'forecast[0].precipitation') == None %}
          {% set p1 = state_attr('weather.openweathermap', 'forecast[1].precipitation') == None %}
          {{ 'false' if p0 and p1 else 'true' }}

or like this:

        value_template: >-
          {% set p0 = state_attr('weather.openweathermap', 'forecast[0].precipitation') == None %}
          {% set p1 = state_attr('weather.openweathermap', 'forecast[1].precipitation') == None %}
          {{ not (p0 and p1) }}
2 Likes

That worked.
I used the first one
Thank you Thank you

here is my completed working setup configuration:

configuration.yaml

weather:
  - platform: openweathermap
    api_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    latitude: 00.00000
    longitude: 000.00000
    mode: freedaily

switches.yaml

# EspEasy and MQTT (created a switch device to monitor gpio status)
  - platform: mqtt
    name: "Walkway Sprinkler"
    command_topic: "/WalkwaySprinkler/gpio/14"
    state_topic: "/WalkwaySprinkler/Sprinkler/Switch"
    qos: 1
    payload_on: "0"
    payload_off: "1"
    retain: true

sensors.yaml

# Using openweathermap forecast for today and tomorrow ([0] and [1])
rainy_day:
        friendly_name: "Rainy in next 48 Hours"
        value_template: >-
          {% set p0 = state_attr('weather.openweathermap', 'forecast[0].precipitation') == None %}
          {% set p1 = state_attr('weather.openweathermap', 'forecast[1].precipitation') == None %}
          {{ 'false' if p0 and p1 else 'true' }}

automation.yaml

- id: '1560827530261'
  alias: Switch Walkway Sprinkler
  trigger:
# Start watering at 6AM
  - at: 06:00:00
    platform: time
  condition:
  - condition: state
    entity_id: sensor.rainy_day
    state: 'false'
  - condition: time
# only on below weekdays
    weekday:
    - mon
    - wed
    - fri
  action:
  - data:
      entity_id: switch.walkway_sprinkler
    service: switch.turn_on
# Water for 15 Minutes
  - delay: 00:15:00
  - data:
      entity_id: switch.walkway_sprinkler
    service: switch.turn_off
1 Like

Glad to hear that the latest version of the template works correctly for you.

To make it easier for others seeking a similar solution, please mark my previous post (the one containing the two functional versions of the template) as the ‘Solution’ (only the author of a topic can mark a post with this tag). After you do that, a link to the ‘Solution’ post will automatically appear under your first post.

marked it :slight_smile:

1 Like

Trying to implement your logic. When I run the following in Template Editor
p0 is {{ states.weather.openweathermap.attributes.forecast[0].precipitation }}
p1 is {{ states.weather.openweathermap.attributes.forecast[1].precipitation }}

result is
p0 is None
p1 is 0.6

When I run this in Template Editor from your sensor.yam
{% set p0 = state_attr(‘weather.openweathermap’, ‘forecast[0].precipitation’) == None %}
{% set p1 = state_attr(‘weather.openweathermap’, ‘forecast[1].precipitation’) == None %}
{{ ‘false’ if p0 and p1 else ‘true’ }}
the result is
false

Shouldn’t I be getting true since I am showing 0.6 for p1 in the first result? I am not clear what the 0.6 represents?

when there will be no rain (precipitation) then the result is None and in my logic when there is no rain today or tomorrow then it will send false, otherwise you get true.
precipitation result represents the amount of rain.
e.g.
Light Rain: A rain rate of 0.10 inches per hour or less
Rain: A rain rate of 0.11 to 0.30 inches per hour
Heavy Rain: A rain rate of 0.31 inches per hour or greater.

I just updated my logic to below and it’s working for me

{% set p0 = state_attr('weather.openweathermap', 'forecast')[0].precipitation != None %}
{% set p1 = state_attr('weather.openweathermap', 'forecast')[1].precipitation != None %}
{{ 'true' if p0 or p1 else 'false' }}

so if today or tomorrow precipitation result exists you will get true and the last line is checking if there is a true for today OR tomorrow.
there are many different paths you can take like instead of using precipitation you can use condition

{% set p0 = state_attr('weather.openweathermap', 'forecast')[0].condition == "rainy" %}
{% set p1 = state_attr('weather.openweathermap', 'forecast')[1].condition == "rainy" %}
{{ 'true' if p0 or p1 else 'false' }}

hope this help you

2 Likes

@arvage is there a possibility to activate the trigger at 6AM the next day?
Then I could be sure, that the day before was no rain too.

Thanks for this, just implemented! Stupid question but so it displays nicely in Lovelace, I’m assuming we can just change true/false to Yes/No?

Yes you can customize it the way you like

1 Like

Hey Armin. I’ve just moved OWM over to the integration under 0.115.2 and I’ve lost sensor.openweathermap_forecast_precipitation and sensor.openweathermap_forecast_temperature_low. Have you see that too?