{"id":2148,"date":"2021-11-28T18:40:14","date_gmt":"2021-11-29T02:40:14","guid":{"rendered":"https:\/\/partofthething.com\/thoughts\/?p=2148"},"modified":"2021-12-10T09:34:07","modified_gmt":"2021-12-10T17:34:07","slug":"smart-holiday-lights-that-change-colors-for-the-next-upcoming-holiday","status":"publish","type":"post","link":"https:\/\/partofthething.com\/thoughts\/smart-holiday-lights-that-change-colors-for-the-next-upcoming-holiday\/","title":{"rendered":"Smart holiday lights that change colors for the next upcoming holiday"},"content":{"rendered":"\n<p>I rigged up some holiday lights that switch between a number of color palettes based on what holiday is coming up next. I used a $25 light strip, a $5 WiFi microcontroller (ESP8266), and Home Assistant to make it all happen. <\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Smart holiday lights that change as the holidays come and go\" width=\"660\" height=\"371\" src=\"https:\/\/www.youtube.com\/embed\/6RbaZGykVlg?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Setting up the light strip<\/h2>\n\n\n\n<p>Using a &#8220;NeoPixel&#8221;-like addressable RGB light strip is pretty well-covered online these days. I got <a href=\"https:\/\/www.amazon.com\/dp\/B07FVP54GQ\">this waterproof one<\/a>.  I plugged in one of my ESP8266&#8217;s and loaded it up with some demo code from the <a href=\"http:\/\/fastled.io\/\">FastLED library.<\/a>  I bought an outdoor waterproof enclosure for the 5V power supply and ran outdoor wires in a small trench over to my fence, where I then used one of these <a href=\"https:\/\/www.amazon.com\/dp\/B08CMQHYLL\">outdoor wire coupler things<\/a> to both protect the connection and store the ESP8266 itself. <\/p>\n\n\n\n<!--more-->\n\n\n\n<p>I wrote code to have it connect to my local <a href=\"https:\/\/mosquitto.org\/\">mosquitto MQTT server<\/a> (running on my home server, but you can also run on e.g. a raspberry pi) using the <a href=\"https:\/\/pubsubclient.knolleary.net\/\">PubSub arduino MQTT client library<\/a>. It subscribes to two topics, one for controlling the mode (off, twinkle, alarm, solid), and the other for controlling the color palette. <\/p>\n\n\n\n<p>Given a MQTT-controlled WiFi lightstrip, adding the holiday smarts to Home Assistant is the next step. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Figuring out what holiday is next<\/h2>\n\n\n\n<p>I surveyed the existing options for figuring out what the next holiday is but came up short, so I made <a href=\"https:\/\/github.com\/partofthething\/next-holiday-sensor\">a new custom component for home assistant that builds a Next Holiday sensor<\/a>. The sensor tells you what holiday is coming up next, how many days out it is, and whether or not today is that holiday. It also exposes a list of all holidays of the year. <\/p>\n\n\n\n<p>Arguably, this capability might make sense to integrate into the <a href=\"https:\/\/www.home-assistant.io\/integrations\/workday\">built-in workday sensor<\/a>, which uses the <a href=\"https:\/\/github.com\/dr-prodigy\/python-holidays\">same underlying library<\/a>. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/raw.githubusercontent.com\/partofthething\/next-holiday-sensor\/master\/screenshot.png\" alt=\"https:\/\/raw.githubusercontent.com\/partofthething\/next-holiday-sensor\/master\/screenshot.png\"\/><figcaption>The Next Holiday sensor for home assistant<\/figcaption><\/figure><\/div>\n\n\n\n<p>The underlying library only considers national and state\/provincial holidays in scope, so to get popular holidays like Easter and Hanukkah, I had to figure out which countries considered them official. The alternate would be to allow custom holiday labels in the config, but I wanted to leverage the complex logic for e.g. <a href=\"https:\/\/en.wikipedia.org\/wiki\/Date_of_Easter\">figuring out when Easter is. <\/a><\/p>\n\n\n\n<p>So here&#8217;s the configuration that gets some pretty common holidays for people in the USA:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  - platform: next_holiday\n    sources: \n     - country: \"USA\"\n       state: \"WA\"\n     - country: \"Australia\"\n       # Easter is a national holiday in NSW\n       province: \"NSW\"\n       filter:\n         - 'easter sunday'\n     - country: \"Jamaica\"\n       filter:\n         - 'valentine'\n     - country: \"Ireland\"\n       filter:\n         - 'patrick'\n     - country: \"Israel\"\n       # Hanukkah is a national holiday in Israel\n       multiday: true\n       filter:\n         - 'hanukkah'<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Setting the colors<\/h2>\n\n\n\n<p> For now, I just coded the color options directly into the ESP8266. I might upgrade later to allow Home Assistant to send the color palette over MQTT for better flexibility.  Here are the colors I set (FastLED lets you use HTML color names).<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"wp-block-code\"><code>\nCRGB cThanksgiving&#91;] = {\n  CRGB::Yellow,\n  CRGB::Orange,\n  CRGB::Red,\n  CRGB::Green,\n  };\n\nCRGB cHanukka&#91;] = {\n  CRGB::White,\n  CRGB::Blue,\n  };\n\nCRGB cChristmas&#91;] = {\n  CRGB::Red,\n  CRGB::Green,\n  };\n\n<\/code><\/pre>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"wp-block-code\"><code>\nCRGB cUsa&#91;] = {\n  CRGB::White,\n  CRGB::Blue,\n  CRGB::Red,\n  };\n\n  \nCRGB cPatrick&#91;] = {\n  CRGB::Green,\n  };\n\nCRGB cEaster&#91;] = {\n  CRGB::Pink,\n  CRGB::CornflowerBlue,\n  CRGB::LightSeaGreen,\n  };\n<\/code><\/pre>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"wp-block-code\"><code>\nCRGB cValentine&#91;] = {\n  CRGB::Pink,\n  CRGB::Red,\n  };\n\nCRGB cNewyear&#91;] = {\n  CRGB::Gold,\n  CRGB::White,\n  };<\/code><\/pre>\n<\/div>\n<\/div>\n\n\n\n<p>Then I just set up a Home Assistant input select to have all the holidays of interest:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"394\" height=\"345\" src=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/image-22.png\" alt=\"\" class=\"wp-image-2149\" srcset=\"https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/image-22.png 394w, https:\/\/partofthething.com\/thoughts\/wp-content\/uploads\/image-22-300x263.png 300w\" sizes=\"auto, (max-width: 394px) 100vw, 394px\" \/><figcaption>The color selector<\/figcaption><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Automatically updating colors when holiday changes<\/h2>\n\n\n\n<p>With colors, control, and holidays all loaded up, I just needed a few automations to tie them all together.  This one watches the Next Holiday sensor, and when it changes, it updates the color-choosing Input Selector to match the upcoming holiday.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>automation:\n- alias: Update holiday colors\n  # look at next holiday and set input select manually\n  trigger:\n    - platform: state\n      entity_id: sensor.next_holiday\n    - platform: time\n      at: '06:30:00'\n  action:\n    - service: input_select.select_option\n      target: \n        entity_id: input_select.lightstrip_colors\n      data:\n        option: | \n          {## Map holidays to color options ##}\n          {% set hol = states.sensor.next_holiday.state | lower  %}\n          {% if 'hanukkah' in hol -%}\n            Hanukkah\n          {%- elif 'thanksgiving' in hol -%}\n            Thanksgiving\n          {%- elif 'christmas' in hol -%}\n            Christmas\n          {%- elif 'memorial' in hol -%}\n            USA\n          {%- elif 'luther' in hol -%}\n            Christmas\n          {%- elif 'independence' in hol -%}\n            USA\n          {%- elif 'veterans' in hol -%}\n            USA\n          {%- elif 'washington' in hol -%}\n            USA\n          {%- elif 'patrick' in hol -%}\n            St. Patrick\n          {%- elif 'easter' in hol -%}\n            Easter\n          {%- elif 'valentine' in hol -%}\n            Valentine\n          {%- elif 'new year' in hol -%}\n            New Year\n          {%- endif %}\n<\/code><\/pre>\n\n\n\n<p>Then there&#8217;s one more automation that watches the Input Select for changes and sends MQTT commands to the light strip when it changes. This works both when you&#8217;re selecting the colors manually in the UI and when the automatic holiday-watching automation above changes it.  <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>automation:\n- alias: Lightstrip colors\n  trigger:\n    platform: state\n    entity_id: input_select.lightstrip_colors\n  action:\n    - service: mqtt.publish\n      data:\n        topic: home\/lightstrip\/colors\n        payload_template: |\n          {% set option_number = state_attr(trigger.entity_id,'options').index(states(trigger.entity_id)) %}\n          {{option_number}}\n        retain: true<\/code><\/pre>\n\n\n\n<p>The template code above just maps from input select name to input select numerical index for convenience, based on <a href=\"https:\/\/community.home-assistant.io\/t\/numeric-input-select-state-with-human-readable-labels\/71652\/2\">this<\/a>.<\/p>\n\n\n\n<p>On the ESP8266, the corresponding code in the callback function maps the indices to the actual color palettes.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>void callback(char* topic, byte* payload, unsigned int length) {\n  char command = (char)payload&#91;0];\n\n  if (strstr(topic, \"mode\")) {\n    \/\/ operation mode\n    if (command == '0') {\n      turn_off();\n    } else if (command == '1') {\n      run_default_mode();\n    } else if (command == '2') {\n      alarm();\n    } else if (command == '3') {\n      light_it_up();\n    } \n  }\n  else {\n    \/\/ color mode\n    if (command == '0') {\n      activate_cHanukka_colors();\n    } else if (command == '1') {\n      activate_thanksgiving_colors();\n    } else if (command == '2') {\n      activate_christmas_colors();\n    } else if (command == '3') {\n      activate_usa_colors();\n    } else if (command == '4') {\n      activate_patrick_colors();\n    } else if (command == '5') {\n      activate_easter_colors();\n    } else if (command == '6') {\n      activate_valentine_colors();\n    } else if (command == '7') {\n      activate_newyear_colors();\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>As seen in the video, there&#8217;s also a &#8216;security alert&#8217; mode that flashes the light and a light-up mode that just illuminates the area. Those will be integrated with a motion sensor soon to trigger them appropriately. <\/p>\n\n\n\n<p>Anyway, pretty fun stuff. I&#8217;m looking forward to watching the colors change as the years go on.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I rigged up some holiday lights that switch between a number of color palettes based on what holiday is coming up next. I used a $25 light strip, a $5 WiFi microcontroller (ESP8266), and Home Assistant to make it all happen. Setting up the light strip Using a &#8220;NeoPixel&#8221;-like addressable RGB light strip is pretty &hellip; <a href=\"https:\/\/partofthething.com\/thoughts\/smart-holiday-lights-that-change-colors-for-the-next-upcoming-holiday\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Smart holiday lights that change colors for the next upcoming holiday<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":2151,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":""},"categories":[75],"tags":[],"class_list":["post-2148","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-home-automation"],"_links":{"self":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts\/2148","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/comments?post=2148"}],"version-history":[{"count":4,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts\/2148\/revisions"}],"predecessor-version":[{"id":2156,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts\/2148\/revisions\/2156"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/media\/2151"}],"wp:attachment":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/media?parent=2148"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/categories?post=2148"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/tags?post=2148"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}