Use environment canada weather forecast to decide whether to irrigate

So I have this Etherrain/8 irrigation controller (http://www.quicksmart.com/qs_etherrain.html) for which I wrote a new homeassistant component (https://github.com/hpeyerl/home-assistant/blob/dev/homeassistant/components/etherrain.py) …

I wanted to control whether things get watered depending on the likelihood of precipitation today. The darksky “Precip Probability” seems to be instantaneous, not a prediction. In this neck of the woods, environment canada actually has a fairly decent forecast that I wanted to use instead.

Enter Appdaemon. Since Environment Canada published an Atom feed of the weekly forecast, I wrote a quick python script to grab the feed and parse the POP (probability of precipitation) for a configurable number of days in advance:

    import appdaemon.appapi as appapi
    import feedparser
    import sys
    import time
    import datetime

    class EnvCanada(appapi.AppDaemon):

      def initialize(self):
        if "locator" in self.args:
          loc = self.args["locator"]
        else:
          loc = "ab-52"  # Default to Calgary
        if "hr" in self.args:
          hr = int(self.args["hr"])
        else:
          hr = 4
        if "ahead" in self.args:
          add=int(self.args["ahead"])
        else:
          add = 0

        myargs={}
        myargs["loc"] = loc
        myargs["add"] = add
        myargs["module"] = self.args["module"]
        # First run immediately
        h = self.run_in(self.get_pop, 1, **myargs)
        # Then schedule a runtime for the specified hour.
        runtime = datetime.time(hr, 0, 0)
        h = self.run_once(self.get_pop, runtime, **myargs)

      def get_pop(self, args):
        loc = args["loc"]
        add = args["add"]
        d=feedparser.parse('http://weather.gc.ca/rss/city/{0}_e.xml'.format(loc))
        weekdays=["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"]
        today = (weekdays[time.localtime().tm_wday+add])
        pop = 0
        for entry in iter(d.entries):
          if today in entry.title:
            if "howers" in entry.title:
              pop = 100
            if "POP" in entry.title:
              next=0
              for word in iter(entry.title.split(" ")):
                if next:
                  pop = int(word.rstrip("%"))
                if word == "POP":
                  next=1
        print("{0}: Got POP {1}".format(args["module"], pop))
        self.set_state("sensor.environment_canada_pop", state = pop)

      def terminate(self):
        self.log("Terminating!", "INFO")

and appdaemon.yaml configuration:

  EnvCanada:
  module: environment_canada
  class: EnvCanada
  hr: 5
  locator: ab-53

configuration.yaml:

    binary_sensor:
      - platform: threshold
        name: rain_unlikely
        threshold: 59
        type: lower
        entity_id: sensor.environment_canada_pop
    
      - platform: mqtt
        state_topic: environment_canada/pop
        name: environment_canada_pop

and finally, after all that, my automations.yaml:

    - id: water_front_beds_on
      alias: Start Watering Front Beds mon/wed/fri at 7AM
      initial_state: on
      trigger:
        platform: time
        hours: 7
        minutes: 0
        seconds: 0
      condition:
        condition: and
        conditions:
          - condition: state
            entity_id: binary_sensor.rain_unlikely
            state: 'on'
          - condition: time
            weekday:
              - mon
              - wed
              - fri
      action:
        service: switch.turn_on
        entity_id: switch.front_beds

Comments welcome. I’m not entirely pleased with having to create a fake MQTT sensor so that appdaemon can set its state but I couldn’t see any other way to get appdaemon to create a sensor.

2 Likes

I really like the idea.
You can fetch the darksky precipitation instensity forecast with the forecast: parameter.

I happen to live in the hotter part of a temperate zone where showers can, locally, meet the extremes. So this is inspiring.

:tada: for the 0.51.2 garden (… yeah, 2.0 is so overated, ha versioning is kind of badass :stuck_out_tongue_closed_eyes:)