{"id":166,"date":"2017-08-20T13:28:13","date_gmt":"2017-08-20T13:28:13","guid":{"rendered":"http:\/\/www.beer.org\/blog\/?p=166"},"modified":"2017-08-20T13:28:13","modified_gmt":"2017-08-20T13:28:13","slug":"use-environment-canada-weather-forecast-atom-feed-to-decide-whether-to-irrigate","status":"publish","type":"post","link":"https:\/\/www.beer.org\/blog\/index.php\/2017\/08\/20\/use-environment-canada-weather-forecast-atom-feed-to-decide-whether-to-irrigate\/","title":{"rendered":"Use Environment Canada Weather forecast atom feed to decide whether to irrigate"},"content":{"rendered":"<p>I have more or less switched to using Home Assistant to automate things at the cabin. \u00a0One of the things I&#8217;ve had to do is integrate the Etherrain\/8 from\u00a0<a href=\"http:\/\/www.quicksmart.com\/qs_etherrain.html\">QuickSmart<\/a>\u00a0into HomeAssistant by creating a new component and switch module. \u00a0This is currently (as of this writing) on a <a href=\"https:\/\/github.com\/hpeyerl\/home-assistant\/blob\/dev\/homeassistant\/components\/etherrain.py\">branch<\/a> waiting for release integration.<\/p>\n<p>Now the next thing was to automate the irrigation. \u00a0HomeAssistant&#8217;s automation scripts take a bit of getting used to.. It&#8217;s certainly not very intuitive but it is what it is.<\/p>\n<p>First the automation, to water the front beds at 7 AM on Mon\/Wed\/Fri if the chance of rain is &lt;60%:<\/p>\n<pre><code class=\"hljs sql\">    - id: water_front_beds_on\r\n      alias: <span class=\"hljs-keyword\">Start<\/span> Watering Front Beds mon\/wed\/fri <span class=\"hljs-keyword\">at<\/span> <span class=\"hljs-number\">7<\/span>AM\r\n      initial_state: <span class=\"hljs-keyword\">on<\/span>\r\n      <span class=\"hljs-keyword\">trigger<\/span>:\r\n        platform: <span class=\"hljs-keyword\">time<\/span>\r\n        hours: <span class=\"hljs-number\">7<\/span>\r\n        minutes: <span class=\"hljs-number\">0<\/span>\r\n        seconds: <span class=\"hljs-number\">0<\/span>\r\n      condition:\r\n        condition: <span class=\"hljs-keyword\">and<\/span>\r\n        conditions:\r\n          - condition: state\r\n            entity_id: binary_sensor.rain_unlikely\r\n            state: <span class=\"hljs-string\">'on'<\/span>\r\n          - condition: <span class=\"hljs-keyword\">time<\/span>\r\n            <span class=\"hljs-keyword\">weekday<\/span>:\r\n              - mon\r\n              - wed\r\n              - fri\r\n      <span class=\"hljs-keyword\">action<\/span>:\r\n        service: switch.turn_on\r\n        entity_id: switch.front_beds<\/code><\/pre>\n<p>So the next question is likely &#8220;where does rain_unlikely come from&#8221;? \u00a0It&#8217;s here:<\/p>\n<pre><code class=\"hljs bash\">    binary_sensor:\r\n      - platform: threshold\r\n        name: rain_unlikely\r\n        threshold: 59\r\n        <span class=\"hljs-built_in\">type<\/span>: lower\r\n        entity_id: sensor.environment_canada_pop\r\n    \r\n      - platform: mqtt\r\n        state_topic: environment_canada\/pop\r\n        name: environment_canada_pop<\/code><\/pre>\n<p>Essentially, an MQTT message with a percentage that is the &#8220;probability of precipitation&#8221;. \u00a0But who generates this MQTT message? \u00a0In fact, nobody really. \u00a0This is just a placeholder sensor that holds the POP. \u00a0But something must populate this. Well, here&#8217;s an Appdaemon script written in Python:<\/p>\n<pre><code class=\"hljs ruby\">    import appdaemon.appapi as appapi\r\n    import feedparser\r\n    import sys\r\n    import time\r\n    import datetime\r\n\r\n    <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">EnvCanada<\/span>(<span class=\"hljs-title\">appapi<\/span>.<span class=\"hljs-title\">AppDaemon<\/span>):<\/span>\r\n\r\n      <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">initialize<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">self<\/span>)<\/span><\/span>:\r\n        <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-string\">\"locator\"<\/span> <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-keyword\">self<\/span>.<span class=\"hljs-symbol\">args:<\/span>\r\n          loc = <span class=\"hljs-keyword\">self<\/span>.args[<span class=\"hljs-string\">\"locator\"<\/span>]\r\n        <span class=\"hljs-symbol\">else:<\/span>\r\n          loc = <span class=\"hljs-string\">\"ab-52\"<\/span>  <span class=\"hljs-comment\"># Default to Calgary<\/span>\r\n        <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-string\">\"hr\"<\/span> <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-keyword\">self<\/span>.<span class=\"hljs-symbol\">args:<\/span>\r\n          hr = int(<span class=\"hljs-keyword\">self<\/span>.args[<span class=\"hljs-string\">\"hr\"<\/span>])\r\n        <span class=\"hljs-symbol\">else:<\/span>\r\n          hr = <span class=\"hljs-number\">4<\/span>\r\n        <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-string\">\"ahead\"<\/span> <span class=\"hljs-keyword\">in<\/span> <span class=\"hljs-keyword\">self<\/span>.<span class=\"hljs-symbol\">args:<\/span>\r\n          add=int(<span class=\"hljs-keyword\">self<\/span>.args[<span class=\"hljs-string\">\"ahead\"<\/span>])\r\n        <span class=\"hljs-symbol\">else:<\/span>\r\n          add = <span class=\"hljs-number\">0<\/span>\r\n\r\n        myargs={}\r\n        myargs[<span class=\"hljs-string\">\"loc\"<\/span>] = loc\r\n        myargs[<span class=\"hljs-string\">\"add\"<\/span>] = add\r\n        myargs[<span class=\"hljs-string\">\"module\"<\/span>] = <span class=\"hljs-keyword\">self<\/span>.args[<span class=\"hljs-string\">\"module\"<\/span>]\r\n        <span class=\"hljs-comment\"># First run immediately<\/span>\r\n        h = <span class=\"hljs-keyword\">self<\/span>.run_in(<span class=\"hljs-keyword\">self<\/span>.get_pop, <span class=\"hljs-number\">1<\/span>, **myargs)\r\n        <span class=\"hljs-comment\"># Then schedule a runtime for the specified hour.<\/span>\r\n        runtime = datetime.time(hr, <span class=\"hljs-number\">0<\/span>, <span class=\"hljs-number\">0<\/span>)\r\n        h = <span class=\"hljs-keyword\">self<\/span>.run_once(<span class=\"hljs-keyword\">self<\/span>.get_pop, runtime, **myargs)\r\n\r\n      <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">get_pop<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">self<\/span>, args)<\/span><\/span>:\r\n        loc = args[<span class=\"hljs-string\">\"loc\"<\/span>]\r\n        add = args[<span class=\"hljs-string\">\"add\"<\/span>]\r\n        d=feedparser.parse(<span class=\"hljs-string\">'http:\/\/weather.gc.ca\/rss\/city\/{0}_e.xml'<\/span>.format(loc))\r\n        weekdays=[<span class=\"hljs-string\">\"Monday\"<\/span>,<span class=\"hljs-string\">\"Tuesday\"<\/span>,<span class=\"hljs-string\">\"Wednesday\"<\/span>,<span class=\"hljs-string\">\"Thursday\"<\/span>,<span class=\"hljs-string\">\"Friday\"<\/span>,<span class=\"hljs-string\">\"Saturday\"<\/span>,<span class=\"hljs-string\">\"Sunday\"<\/span>]\r\n        today = (weekdays[time.localtime().tm_wday+add])\r\n        pop = <span class=\"hljs-number\">0<\/span>\r\n        <span class=\"hljs-keyword\">for<\/span> entry <span class=\"hljs-keyword\">in<\/span> iter(d.entries):\r\n          <span class=\"hljs-keyword\">if<\/span> today <span class=\"hljs-keyword\">in<\/span> entry.<span class=\"hljs-symbol\">title:<\/span>\r\n            <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-string\">\"howers\"<\/span> <span class=\"hljs-keyword\">in<\/span> entry.<span class=\"hljs-symbol\">title:<\/span>\r\n              pop = <span class=\"hljs-number\">100<\/span>\r\n            <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-string\">\"POP\"<\/span> <span class=\"hljs-keyword\">in<\/span> entry.<span class=\"hljs-symbol\">title:<\/span>\r\n              <span class=\"hljs-keyword\">next<\/span>=<span class=\"hljs-number\">0<\/span>\r\n              <span class=\"hljs-keyword\">for<\/span> word <span class=\"hljs-keyword\">in<\/span> iter(entry.title.split(<span class=\"hljs-string\">\" \"<\/span>)):\r\n                <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-symbol\">next:<\/span>\r\n                  pop = int(word.rstrip(<span class=\"hljs-string\">\"%\"<\/span>))\r\n                <span class=\"hljs-keyword\">if<\/span> word == <span class=\"hljs-string\">\"POP\"<\/span>:\r\n                  <span class=\"hljs-keyword\">next<\/span>=<span class=\"hljs-number\">1<\/span>\r\n        print(<span class=\"hljs-string\">\"{0}: Got POP {1}\"<\/span>.format(args[<span class=\"hljs-string\">\"module\"<\/span>], pop))\r\n        <span class=\"hljs-keyword\">self<\/span>.set_state(<span class=\"hljs-string\">\"sensor.environment_canada_pop\"<\/span>, state = pop)\r\n\r\n      <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">terminate<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">self<\/span>)<\/span><\/span>:\r\n        <span class=\"hljs-keyword\">self<\/span>.log(<span class=\"hljs-string\">\"Terminating!\"<\/span>, <span class=\"hljs-string\">\"INFO\"<\/span>)\r\n<\/code><\/pre>\n<p>This essentially grabs the Atom feed from Environment Canada, looks for the word &#8220;Showers&#8221; or &#8220;showers&#8221; or &#8220;POP&#8221; and generates that percentage. \u00a0It then reaches under the skirt of Home Assistant and populates the above mentioned &#8216;MQTT sensor&#8217;.. I really wish I could think of a better way to do that.<\/p>\n<p>Just for the sake of completion; here is the AppDaemon configuration to get it all started:<\/p>\n<pre><code>  EnvCanada:\r\n  module: environment_canada\r\n  class: EnvCanada\r\n  hr: 5\r\n  ahead: 0\r\n  locator: ab-53\r\n<\/code><\/pre>\n<p>The &#8216;ahead&#8217; attribute is &#8220;how many days ahead to determine the POP. \u00a0Ie: at 0, it returns todays probability of precipitation. \u00a0At 1, it will return tomorrow&#8217;s. \u00a0 the &#8216;hr&#8217; attribute is when AppDaemon should run this script. \u00a0In this case, at 05:00AM. \u00a0The &#8216;locator&#8217; is the portion of the URL that specifies which Environment Canada weather location to use. \u00a0&#8216;ab-53&#8217; is Sundre Alberta.<\/p>\n<p>&nbsp;<\/p>\n<p>Hope that helps someone.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I have more or less switched to using Home Assistant to automate things at the cabin. \u00a0One of the things I&#8217;ve had to do is integrate the Etherrain\/8 from\u00a0QuickSmart\u00a0into HomeAssistant by creating a new component and switch module. \u00a0This is currently (as of this writing) on a branch waiting for release integration. Now the next&#8230; <a class=\"moretag\" href=\"https:\/\/www.beer.org\/blog\/index.php\/2017\/08\/20\/use-environment-canada-weather-forecast-atom-feed-to-decide-whether-to-irrigate\/\">Continue reading &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-166","post","type-post","status-publish","format-standard","hentry","category-tech-stuff"],"_links":{"self":[{"href":"https:\/\/www.beer.org\/blog\/index.php\/wp-json\/wp\/v2\/posts\/166","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.beer.org\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.beer.org\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.beer.org\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.beer.org\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=166"}],"version-history":[{"count":1,"href":"https:\/\/www.beer.org\/blog\/index.php\/wp-json\/wp\/v2\/posts\/166\/revisions"}],"predecessor-version":[{"id":167,"href":"https:\/\/www.beer.org\/blog\/index.php\/wp-json\/wp\/v2\/posts\/166\/revisions\/167"}],"wp:attachment":[{"href":"https:\/\/www.beer.org\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=166"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.beer.org\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=166"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.beer.org\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=166"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}