From 7100f272f24600c4f397dde33704ee10f43c7d58 Mon Sep 17 00:00:00 2001 From: Joshua Clark Date: Sun, 22 Dec 2024 14:03:27 -0700 Subject: [PATCH] holiday lighting - Add holiday lighting colors for front outside lights - Add Easy Time template --- automations.yaml | 34 +- configuration.yaml | 1 + custom_templates/easy_time.jinja | 1743 +++++++++++++++++ custom_templates/variables.jinja | 180 ++ entities/input_select/holiday_override.yaml | 20 + .../template/sensor/holiday_lighting.yaml | 148 ++ entities/template/sensor/seasonal_lights.yaml | 23 + scenes.yaml | 201 +- 8 files changed, 2336 insertions(+), 14 deletions(-) create mode 100644 custom_templates/easy_time.jinja create mode 100644 entities/input_select/holiday_override.yaml create mode 100644 entities/template/sensor/holiday_lighting.yaml create mode 100644 entities/template/sensor/seasonal_lights.yaml diff --git a/automations.yaml b/automations.yaml index aec36bd9..488360f5 100644 --- a/automations.yaml +++ b/automations.yaml @@ -778,12 +778,14 @@ - data: transition: 360 brightness_pct: 25 + kelvin: 3000 target: entity_id: light.outside_garage action: light.turn_on - data: transition: 360 brightness_pct: 1 + kelvin: 3000 target: entity_id: light.outside_entry action: light.turn_on @@ -807,22 +809,22 @@ - id: '1665686549835' alias: "\U0001F4A1 Front Lights on at Sunset" description: Turns the front lights on at sunset - trigger: - - platform: sun - event: sunset + triggers: + - event: sunset offset: -00:20:00 - condition: + trigger: sun + conditions: - condition: time before: input_datetime.lights_front_night_dim after: 00:00:00 - action: - - data: - brightness_pct: 100 + actions: + - variables: + scene: '{{ states(''sensor.seasonal_lights'')}}' + - action: scene.turn_on + metadata: {} + data: {} target: - entity_id: - - light.outside_garage - - light.outside_entry - action: light.turn_on + entity_id: '{{ scene }}' mode: single - id: '1665686584864' alias: "\U0001F4A1 Living Room Lamps on/off" @@ -5490,3 +5492,13 @@ action: script.notify_pipup alias: Send a notification to each device mode: single +- id: '1734643266064' + alias: ⚙️ Forward Reload Templates + description: Forwards the template reloaded event so other actions can be taken + triggers: + - event_type: event_template_reloaded + trigger: event + actions: + - delay: 00:00:01 + - event: templates_reloaded + event_data: {} diff --git a/configuration.yaml b/configuration.yaml index f8d21e15..fc7943a5 100644 --- a/configuration.yaml +++ b/configuration.yaml @@ -47,6 +47,7 @@ scene: !include scenes.yaml # Entities group: !include_dir_merge_named entities/group +input_select: !include_dir_merge_named entities/input_select media_player: !include_dir_list entities/media_player mqtt: binary_sensor: !include_dir_list entities/mqtt/binary_sensor diff --git a/custom_templates/easy_time.jinja b/custom_templates/easy_time.jinja new file mode 100644 index 00000000..e1f1d2d9 --- /dev/null +++ b/custom_templates/easy_time.jinja @@ -0,0 +1,1743 @@ +{%- set default_language = 'en' %} +{%- set languages = { + 'en':{ + '_language': 'English', + 'and': 'and', + 'in': 'in', + 'ago': 'ago', + 'now': 'now', + 'lose': 'lose', + 'gain': 'gain', + 'time':{ + 'format': '12-hr', + 'year': [ + 'yr', + 'year', + 'years', + ], + 'week': [ + 'wk', + 'week', + 'weeks', + ], + 'day': [ + 'd', + 'day', + 'days', + ], + 'hour': [ + 'hr', + 'hour', + 'hours', + ], + 'minute': [ + 'min', + 'minute', + 'minutes', + ], + 'second': [ + 'sec', + 'second', + 'seconds', + ], + }, + 'delta':{ + 'today': 'today', + 'tomorrow': 'tomorrow', + 'yesterday': 'yesterday', + 'next': 'next', + 'last': 'last', + }, + 'days':[ + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", + "Sunday", + ], + 'months':[ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December', + ], + 'time_of_hour':{ + 0: '{hour} o\'clock', + 1: 'a minute past {hour}', + 15: 'quarter past {hour}', + 30: 'half past {hour}', + 45: 'quarter to {hour}', + 59: 'a minute to {hour}', + 'past_hour': '{minute} past {hour}', + 'to_hour': '{minute} to {hour}', + }, + 'time_of_day':{ + 'midnight': 'midnight', + 'noon': 'noon', + }, + }, + 'sk':{ + '_language': 'Slovak', + 'and': 'a', + 'in': 'v', + 'ago': 'pred', + 'now': 'teraz', + 'lose': 'strata', + 'gain': 'zosilnenie', + 'time':{ + 'format': '12-hr', + 'year': [ + 'rok', + 'rok', + 'roky', + ], + 'week': [ + 'týž', + 'týždeň', + 'týždne', + ], + 'day': [ + 'd', + 'deň', + 'dni', + ], + 'hour': [ + 'hod', + 'hodina', + 'hodiny', + ], + 'minute': [ + 'min', + 'minúta', + 'minúty', + ], + 'second': [ + 'sek', + 'sekunda', + 'sekundy', + ], + }, + 'delta':{ + 'today': 'dnes', + 'tomorrow': 'zajtra', + 'yesterday': 'včera', + 'next': 'ďalší', + 'last': 'predchádzajúci', + }, + 'days':[ + "Pondelok", + "Utorok", + "Streda", + "Štvrtok", + "Piatok", + "Sobota", + "Nedeľa", + ], + 'months':[ + 'Január', + 'Február', + 'Marec', + 'Apríl', + 'Máj', + 'Jún', + 'Júl', + 'August', + 'September', + 'Október', + 'November', + 'December', + ] + }, + 'nl':{ + '_language': 'Nederlands', + 'and': 'en', + 'in': 'over', + 'ago': 'geleden', + 'now': 'nu', + 'lose': 'verliezen', + 'gain': 'krijgen', + 'time':{ + 'format': '24-hr', + 'year': [ + 'jr', + 'jaar', + 'jaar', + ], + 'week': [ + 'wk', + 'week', + 'weken', + ], + 'day': [ + 'd', + 'dag', + 'dagen', + ], + 'hour': [ + 'u', + 'uur', + 'uur', + ], + 'minute': [ + 'min', + 'minuut', + 'minuten', + ], + 'second': [ + 'sec', + 'seconde', + 'seconden', + ], + }, + 'delta':{ + 'today': 'vandaag', + 'tomorrow': 'morgen', + 'yesterday': 'gisteren', + }, + 'days':[ + "maandag", + "dinsdag", + "woensdag", + "donderdag", + "vrijdag", + "zaterdag", + "zondag", + ], + 'months':[ + 'januari', + 'februari', + 'maart', + 'april', + 'mei', + 'juni', + 'juli', + 'augustus', + 'september', + 'oktober', + 'november', + 'december', + ] + }, + 'sv':{ + '_language': 'Svenska', + 'and': 'och', + 'in': 'i', + 'ago': 'sedan', + 'now': 'nu', + 'lose': 'förlora', + 'gain': 'få', + 'time':{ + 'format': '24-hr', + 'year': [ + 'Å', + 'år', + 'år', + ], + 'week': [ + 'v', + 'vecka', + 'veckor', + ], + 'day': [ + 'd', + 'dag', + 'dagar', + ], + 'hour': [ + 't', + 'timme', + 'timmar', + ], + 'minute': [ + 'min', + 'minut', + 'minuter', + ], + 'second': [ + 'sek', + 'sekund', + 'sekunder', + ], + }, + 'delta':{ + 'today': 'idag', + 'tomorrow': 'imorgon', + 'yesterday': 'igår', + }, + 'days':[ + "måndag", + "tisdag", + "onsdag", + "torsdag", + "fredag", + "lördag", + "söndag", + ], + 'months':[ + 'januari', + 'februari', + 'mars', + 'april', + 'maj', + 'juni', + 'juli', + 'augusti', + 'september', + 'oktober', + 'november', + 'december', + ] + }, + 'de':{ + '_language': 'Deutsch', + 'and': 'und', + 'in': 'in', + 'ago': 'vor %s', + 'now': 'jetzt', + 'lose': 'Du verlierst', + 'gain': 'Du gewinnst', + 'time':{ + 'format': '24-hr', + 'year': [ + 'J', + 'Jahr', + 'Jahren', + ], + 'week': [ + 'W', + 'Woche', + 'Wochen', + ], + 'day': [ + 'T', + 'Tag', + 'Tagen', + ], + 'hour': [ + 'h', + 'Stunde', + 'Stunden', + ], + 'minute': [ + 'm', + 'Minute', + 'Minuten', + ], + 'second': [ + 's', + 'Sekunde', + 'Sekunden', + ], + }, + 'delta':{ + 'today': 'Heute', + 'tomorrow': 'Morgen', + 'yesterday': 'Gestern', + }, + 'days':[ + "Montag", + "Dienstag", + "Mittwoch", + "Donnerstag", + "Freitag", + "Samstag", + "Sonntag", + ], + 'months':[ + 'Januar', + 'Februar', + 'März', + 'April', + 'Mai', + 'Juni', + 'Juli', + 'August', + 'September', + 'Oktober', + 'November', + 'Dezember', + ] + }, + 'da':{ + '_language': 'Dansk', + 'and': 'og', + 'in': 'om', + 'ago': 'siden', + 'now': 'nu', + 'lose': 'mister', + 'gain': 'tilføjer', + 'time':{ + 'format': '24-hr', + 'year': [ + 'Å', + 'år', + 'år', + ], + 'week': [ + 'u', + 'uge', + 'uger', + ], + 'day': [ + 'd', + 'dag', + 'dage', + ], + 'hour': [ + 't', + 'time', + 'timer', + ], + 'minute': [ + 'min', + 'minut', + 'minutter', + ], + 'second': [ + 'sek', + 'sekund', + 'sekunder', + ], + }, + 'delta':{ + 'today': 'i dag', + 'tomorrow': 'i morgen', + 'yesterday': 'i går', + }, + 'days':[ + "mandag", + "tirsdag", + "onsdag", + "torsdag", + "fredag", + "lørdag", + "søndag", + ], + 'months':[ + 'januar', + 'februar', + 'marts', + 'april', + 'maj', + 'juni', + 'juli', + 'august', + 'september', + 'oktober', + 'november', + 'december', + ] + }, + 'nb':{ + '_language': 'Norsk (Bokmål)', + 'and': 'og', + 'in': 'om', + 'ago': 'siden', + 'now': 'nå', + 'lose': 'mister', + 'gain': 'får', + 'time':{ + 'format': '24-hr', + 'year': [ + 'å', + 'år', + 'år', + ], + 'week': [ + 'u', + 'uke', + 'uker', + ], + 'day': [ + 'd', + 'dag', + 'dager', + ], + 'hour': [ + 't', + 'time', + 'timer', + ], + 'minute': [ + 'min', + 'minutt', + 'minutter', + ], + 'second': [ + 'sek', + 'sekund', + 'sekunder', + ], + }, + 'delta':{ + 'today': 'i dag', + 'tomorrow': 'i morgen', + 'yesterday': 'i går', + }, + 'days':[ + "mandag", + "tirsdag", + "onsdag", + "torsdag", + "fredag", + "lørdag", + "søndag", + ], + 'months':[ + 'januar', + 'februar', + 'mars', + 'april', + 'mai', + 'juni', + 'juli', + 'august', + 'september', + 'oktober', + 'november', + 'desember', + ] + }, + 'nn':{ + '_language': 'Norsk (Nynorsk)', + 'and': 'og', + 'in': 'om', + 'ago': 'sia', + 'now': 'nå', + 'lose': 'mister', + 'gain': 'får', + 'time':{ + 'format': '24-hr', + 'year': [ + 'å', + 'år', + 'år', + ], + 'week': [ + 'v', + 'veke', + 'veker', + ], + 'day': [ + 'd', + 'dag', + 'dagar', + ], + 'hour': [ + 't', + 'time', + 'timar', + ], + 'minute': [ + 'min', + 'minutt', + 'minutt', + ], + 'second': [ + 'sek', + 'sekund', + 'sekund', + ], + }, + 'delta':{ + 'today': 'i dag', + 'tomorrow': 'i morgon', + 'yesterday': 'i går', + }, + 'days':[ + "måndag", + "tysdag", + "onsdag", + "torsdag", + "fredag", + "laurdag", + "søndag", + ], + 'months':[ + 'januar', + 'februar', + 'mars', + 'april', + 'mai', + 'juni', + 'juli', + 'august', + 'september', + 'oktober', + 'november', + 'desember', + ] + }, + 'fr':{ + '_language': 'Français', + 'and': 'et', + 'in': 'dans', + 'ago': 'il y a %s', + 'now': 'maintenant', + 'lose': 'perdre', + 'gain': 'gagner', + 'time':{ + 'format': '24-hr', + 'year': [ + 'an', + 'an', + 'ans', + ], + 'week': [ + 'sem.', + 'semaine', + 'semaines', + ], + 'day': [ + 'j', + 'jour', + 'jours', + ], + 'hour': [ + 'h', + 'heure', + 'heures', + ], + 'minute': [ + 'min', + 'minute', + 'minutes', + ], + 'second': [ + 's', + 'seconde', + 'secondes', + ], + }, + 'delta':{ + 'today': "aujourd'hui", + 'tomorrow': 'demain', + 'yesterday': 'hier', + }, + 'days':[ + "lundi", + "mardi", + "mercredi", + "jeudi", + "vendredi", + "samedi", + "dimanche", + ], + 'months':[ + 'janvier', + 'février', + 'mars', + 'avril', + 'mai', + 'juin', + 'juillet', + 'août', + 'septembre', + 'octobre', + 'novembre', + 'décembre', + ] + }, + 'es':{ + '_language': 'Español', + 'and': 'y', + 'in': 'en', + 'ago': 'hace', + 'now': 'ahora', + 'lose': 'perder', + 'gain': 'ganar', + 'time':{ + 'format': '24-hr', + 'year': [ + 'a', + 'año', + 'años', + ], + 'week': [ + 'sem.', + 'semana', + 'semanas', + ], + 'day': [ + 'd', + 'día', + 'días', + ], + 'hour': [ + 'h', + 'hora', + 'horas', + ], + 'minute': [ + 'm', + 'minuto', + 'minutos', + ], + 'second': [ + 's', + 'segundo', + 'segundos', + ], + }, + 'delta':{ + 'today': 'hoy', + 'tomorrow': 'mañana', + 'yesterday': 'ayer', + 'next': 'el próximo', + 'last': 'el pasado', + }, + 'days':[ + 'lunes', + 'martes', + 'miércoles', + 'jueves', + 'viernes', + 'sábado', + 'domingo' + ], + 'months':[ + 'enero', + 'febrero', + 'marzo', + 'abril', + 'mayo', + 'junio', + 'julio', + 'agosto', + 'septiembre', + 'octubre', + 'noviembre', + 'diciembre' + ], + 'time_of_hour':{ + 0: '{hour} en punto', + 1: '{hour} y un minuto', + 15: '{hour} y quarto', + 30: '{hour} y media', + 45: '{hour} menos quarto', + 59: '{hour} menos uno', + 'past_hour': '{hour} y {minute}', + 'to_hour': '{hour} menos {minute}', + }, + 'time_of_day':{ + 'midnight': 'medianoche', + 'noon': 'mediodía', + }, + }, + 'it':{ + '_language': 'Italiano', + 'and': 'e', + 'in': 'in', + 'ago': 'fa', + 'now': 'ora', + 'lose': 'perdita', + 'gain': 'guadagno', + 'time':{ + 'format': '24-hr', + 'year': [ + 'a.', + 'anno', + 'anni', + ], + 'week': [ + 'set.', + 'settimana', + 'settimane', + ], + 'day': [ + 'g', + 'giorno', + 'giorni', + ], + 'hour': [ + 'h', + 'ora', + 'ore', + ], + 'minute': [ + 'min', + 'minuto', + 'minuti', + ], + 'second': [ + 's', + 'secondo', + 'secondi', + ], + }, + 'delta':{ + 'today': 'oggi', + 'tomorrow': 'domani', + 'yesterday': 'ieri', + }, + 'days':[ + "lunedì", + "martedì", + "mercoledì", + "giovedì", + "venerdì", + "sabato", + "domenica", + ], + 'months':[ + 'gennaio', + 'febbraio', + 'marzo', + 'aprile', + 'maggio', + 'giugno', + 'luglio', + 'agosto', + 'settembre', + 'ottobre', + 'novembre', + 'dicembre', + ] + }, + 'pt':{ + '_language': 'Português', + 'and': 'e', + 'in': 'em', + 'ago': 'antes', + 'now': 'agora', + 'lose': 'perde', + 'gain': 'ganha', + 'time':{ + 'format': '24-hr', + 'year': [ + 'aa', + 'ano', + 'anos', + ], + 'week': [ + 'sem', + 'semana', + 'semanas', + ], + 'day': [ + 'd', + 'dia', + 'dias', + ], + 'hour': [ + 'h', + 'hora', + 'horas', + ], + 'minute': [ + 'min', + 'minuto', + 'minutos', + ], + 'second': [ + 'seg', + 'segundo', + 'segundos', + ], + }, + 'delta':{ + 'today': 'hoje', + 'tomorrow': 'amanhã', + 'yesterday': 'ontem', + 'next': 'seguinte', + 'last': 'anterior', + }, + 'days':[ + "Segunda", + "Terça", + "Quarta", + "Quinta", + "Sexta", + "Sábado", + "Domingo", + ], + 'months':[ + 'Janeiro', + 'Fevereiro', + 'Março', + 'Abril', + 'Maio', + 'Junho', + 'Julho', + 'Agosto', + 'Setembro', + 'Outubro', + 'Novembro', + 'Dezembro', + ] + }, + 'hr':{ + '_language': 'Hrvatski', + 'and': 'i', + 'in': 'u', + 'ago': 'prije', + 'now': 'sada', + 'lose': 'gubiš', + 'gain': 'dobivaš', + 'time':{ + 'format': '24-hr', + 'year': [ + 'g', + 'godina', + 'godine', + ], + 'week': [ + 'tj', + 'tjedan', + 'tjedana', + ], + 'day': [ + 'd', + 'dan', + 'dana', + ], + 'hour': [ + 'h', + 'sat', + 'sati', + ], + 'minute': [ + 'm', + 'minuta', + 'minuta', + ], + 'second': [ + 's', + 'sekunda', + 'sekundi', + ], + }, + 'delta':{ + 'today': 'danas', + 'tomorrow': 'sutra', + 'yesterday': 'jučer', + 'next': 'sljedeći', + 'last': 'protekli', + }, + 'days':[ + "Ponedjeljak", + "Utorak", + "Srijeda", + "Četvrtak", + "Petak", + "Subota", + "Nedjelja", + ], + 'months':[ + 'Siječanj', + 'Veljača', + 'Ožujak', + 'Travanj', + 'Svibanj', + 'Lipanj', + 'Srpanj', + 'Kolovoz', + 'Rujan', + 'Listopad', + 'Studeni', + 'Prosinac', + ] + }, + 'pl':{ + '_language': 'Polski', + 'and': 'i', + 'in': 'w', + 'ago': 'temu', + 'now': 'teraz', + 'lose': 'straciłeś', + 'gain': 'zyskałeś', + 'time':{ + 'format': '24-godz', + 'year': [ + 'r', + 'rok', + 'lata', + ], + 'week': [ + 'tyg', + 'tydzień', + 'tygodnie', + ], + 'day': [ + 'd', + 'dzień', + 'dni', + ], + 'hour': [ + 'godz', + 'godzina', + 'godziny', + ], + 'minute': [ + 'min', + 'minuta', + 'minuty', + ], + 'second': [ + 's', + 'sekunda', + 'sekundy', + ], + }, + 'delta':{ + 'today': 'dzisiaj', + 'tomorrow': 'jutro', + 'yesterday': 'wczoraj', + 'next': 'następny', + 'last': 'poprzedni', + }, + 'days':[ + "Poniedziałek", + "Wtorek", + "Środa", + "Czwartek", + "Piątek", + "Sobota", + "Niedziela", + ], + 'months':[ + 'Styczeń', + 'Luty', + 'Marzec', + 'Kwiecień', + 'Maj', + 'Czerwiec', + 'Lipiec', + 'Sierpień', + 'Wrzesień', + 'Październik', + 'Listopad', + 'Grudzień', + ] + }, + 'ru':{ + '_language': 'Русский', + 'and': 'и', + 'in': 'в', + 'ago': 'назад', + 'now': 'сейчас', + 'lose': 'уменьшение', + 'gain': 'увеличение', + 'time':{ + 'format': '24-hr', + 'year': [ + 'г', + 'год', + 'лет', + ], + 'week': [ + 'нед', + 'неделя', + 'недель', + ], + 'day': [ + 'д', + 'день', + 'дней', + ], + 'hour': [ + 'ч', + 'час', + 'часов', + ], + 'minute': [ + 'мин', + 'минута', + 'минут', + ], + 'second': [ + 'сек', + 'секунда', + 'секунд', + ], + }, + 'delta':{ + 'today': 'сегодня', + 'tomorrow': 'завтра', + 'yesterday': 'вчера', + 'next': 'следующий', + 'last': 'последний', + }, + 'days':[ + "Понедельник", + "Вторник", + "Среда", + "Четверг", + "Пятница", + "Суббота", + "Воскресенье", + ], + 'months':[ + 'Январь', + 'Февраль', + 'Март', + 'Апрель', + 'Май', + 'Июнь', + 'Июль', + 'Август', + 'Сентябрь', + 'Октябрь', + 'Ноябрь', + 'Декабрь', + ], + 'time_of_hour':{ + 0: '{hour} часов ровно', + 1: '{hour} и 1 минута', + 15: '{hour} с четвертью', + 30: '{hour} с половиной', + 45: 'без четверти {hour}', + 59: 'без минуты {hour}', + 'past_hour': '{hour} и {minute} минут', + 'to_hour': 'без {minute} минут {hour}', + }, + 'time_of_day':{ + 'midnight': 'полночь', + 'noon': 'полдень', + }, + } +} %} + +{# DO NOT MODIFY BELOW THIS LINE #} +{% set valid_entity_id_pattern = '^(?!.+__)(?!_)[\\da-z_]+(? 0 or raw else '' -}} +{% endmacro %} + +{%- macro _time_dict(uptime_seconds) %} +{%- set ns = namespace(ret=[]) %} +{%- for item in _default_values %} + {%- set ns.ret = ns.ret + [(item, _get_period_value(item, uptime_seconds) | int)] %} +{%- endfor %} +{{- dict.from_keys(ns.ret) | to_json }} +{%- endmacro %} + +{# macro to generate a friendly phrase #} +{%- macro _just_time(seconds, language, values, biggest, raw=False, short=False, floor=False) %} +{%- if seconds < 1 %} + {{- translate('now', language=language) }} +{%- else %} + {#- this used to be a macro, was slow because it converted to/from json #} + {%- set ns = namespace(ret=[]) %} + {#- ensure we have a list of values #} + {%- set values = [ values ] if values is string else values %} + {#- filter values to only have items in _default_values #} + {%- set values = values | select('in', _default_values) | list %} + {#- this should be a good list of values if the previous 2 filters didn't remove anything #} + {%- set values = _default_values | select('in', values) | list if values else _default_values %} + {%- set index = values.index(values | first | default) %} + {%- for item in values[index:] %} + {%- set duration = _durations.get(item, 1) %} + {%- set period = _periods.get(item, 1) %} + {%- set value = ((seconds // duration) % (period if period else duration)) | int %} + {%- if value > 0 or raw %} + {%- if ns.ret | length == 0 %} + {%- set chosen = (seconds / duration) | round if biggest and not floor else seconds // duration %} + {%- else %} + {%- set chosen = value %} + {%- endif %} + {%- set chosen = chosen | int %} + {%- if short %} + {%- set units = translate('time', item, index=0, language=language) %} + {%- else %} + {%- set units = translate('time', item, index=2, language=language) if chosen != 1 else translate('time', item, index=1, language=language) %} + {%- set units = ' %s' % units %} + {%- endif %} + {%- set ns.ret = ns.ret + [ '%s%s' % (chosen, units) ] %} + {%- if biggest and ns.ret | length == 1 %} + {%- break %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- set phrases = ns.ret %} + {#- add our langauges to the phrases #} + {%- if phrases | length > 0 %} + {%- set word_for_and = ' ' if short else ' %s ' % translate('and', language=language) %} + {{- phrases[:-1] | join(', ') ~ word_for_and ~ phrases[-1] if phrases | length > 1 else phrases | first | default }} + {%- else %} + {{- _just_time(seconds, language, values, biggest, True, short, floor) }} + {%- endif %} +{%- endif %} +{%- endmacro %} + +{# macro to generate a friendly time phrase #} +{%- macro _time(input, attribute, language, values, biggest, utc, short=False, floor=False) %} +{%- set duration_sensor = _check_for_duration_sensor(input) %} +{%- if duration_sensor %} + {%- set seconds = as_timedelta(duration_sensor).total_seconds() %} + {{- _just_time(seconds, language, values, biggest, short=short, floor=floor) }} +{%- else %} + {%- set uptime = _to_datetime(input, attribute, utc) | as_datetime %} + {%- if uptime %} + {%- set value = _delta_seconds(now(), uptime) | int %} + {%- set seconds = value | abs %} + {{- _just_time(seconds, language, values, biggest, short=short, floor=floor) }} + {%- else %} + {{- _bad_value }} + {%- endif %} +{%- endif %} +{%- endmacro %} + +{%- macro _time_between(func, input1, attr1, utc1, input2, attr2, utc2) -%} +{%- set t1 = _to_datetime(input1, attr1, utc1) | as_datetime -%} +{%- set t2 = _to_datetime(input2, attr2, utc2) | as_datetime -%} +{%- if t1 is not none and t2 is not none -%} + {{- func(t1, t2) -}} +{%- else -%} + {{- None -}} +{%- endif -%} +{%- endmacro -%} + +{# Returns the most significant time. e.g. 3 hours #} +{%- macro easy_time(uptime, attribute=None, language=default_language, utc=False, max_period='year', short=False, floor=False) %} +{%- set values = _default_values[_default_values.index(max_period):] if max_period in _default_values else _default_values %} +{{- _time(uptime, attribute, language, values, True, utc, short, floor) }} +{%- endmacro %} + +{# Returns a large time phrase without missing any detail. e.g. 3 hours, 4 minutes and 1 second #} +{%- macro big_time(uptime, attribute=None, language=default_language, utc=False, max_period='year', short=False) %} +{%- set values = _default_values[_default_values.index(max_period):] if max_period in _default_values else _default_values %} +{{- _time(uptime, attribute, language, values, False, utc, short) }} +{%- endmacro %} + +{# Returns a time phrase with only the details you care about most of the time. e.g. 3 hours and 4 minutes #} +{%- macro custom_time(uptime, values='', language=default_language, utc=False, short=False) %} +{%- set args = values.replace(' ','').split(',') | list if values is string else [] %} +{%- if args %} + {{- _time(uptime, None, language, args, False, utc, short) }} +{%- else %} + {{- _time(uptime, attribute, language, _default_values, False, utc, short) }} +{%- endif %} +{%- endmacro %} + +{%- macro custom_time_attr(uptime, attribute, values='', language=default_language, utc=False, short=False) %} +{%- set args = values.replace(' ','').split(',') | list if values is string else [] %} +{%- if args %} + {{- _time(uptime, attribute, language, args, False, utc, short) }} +{%- else %} + {{- _time(uptime, attribute, language, _default_values, False, utc, short) }} +{%- endif %} +{%- endmacro %} + +{%- macro easy_time_between(t1, t2, attr1=None, attr2=None, language=default_language, utc1=False, utc2=False, max_period='year', short=False, floor=False) %} +{%- set values = _default_values[_default_values.index(max_period):] if max_period in _default_values else _default_values %} +{%- set seconds = _time_between(_delta_seconds, t1, attr1, utc1, t2, attr2, utc2) | float | abs %} +{{- _just_time(seconds, language, values, True, short=short, floor=floor) }} +{%- endmacro %} + +{%- macro big_time_between(t1, t2, attr1=None, attr2=None, language=default_language, utc1=False, utc2=False, max_period='year', short=False) %} +{%- set values = _default_values[_default_values.index(max_period):] if max_period in _default_values else _default_values %} +{%- set seconds = _time_between(_delta_seconds, t1, attr1, utc1, t2, attr2, utc2) | float | abs %} +{{- _just_time(seconds, language, values, False, short=short) }} +{%- endmacro %} + +{%- macro custom_time_between(t1, t2, values='', attr1=None, attr2=None, language=default_language, utc1=False, utc2=False, max_period='year', short=False) %} +{%- set values = values.replace(' ','').split(',') | list if values is string else [] %} +{%- set seconds = _time_between(_delta_seconds, t1, attr1, utc1, t2, attr2, utc2) | float | abs %} +{{- _just_time(seconds, language, values, False, short=short) }} +{%- endmacro %} + +{%- macro time_between(t1, t2, attr1=None, attr2=None, utc1=False, utc2=False) %} +{{- _time_between(_delta_timedelta, t1, attr1, utc1, t2, attr2, utc2) }} +{%- endmacro %} + +{# macro to generate a friendly relative time phrase #} +{%- macro _relative_time(input, attribute, language, values, biggest, utc, short=False, floor=False) %} +{%- set uptime = _to_datetime(input, attribute, utc) | as_datetime %} +{%- if uptime %} + {%- set value = _delta_seconds(now(), uptime) | int %} + {%- set seconds = value | abs %} + {%- set current = value == 0 %} + {%- set future = not current and value / seconds > 0 %} + {%- set items = _just_time(seconds, language, values, biggest, short=short, floor=floor) %} + {%- if current %} + {{- items }} + {%- elif future %} + {{- translate('in', language=language) }} {{ items }} + {%- else %} + {%- set t = translate('ago', language=language) %} + {%- if '%s' in t %} + {{ t % items }} + {%- else %} + {{- items }} {{ translate('ago', language=language) }} + {%- endif %} + {%- endif %} +{%- else %} + {{- _bad_value }} +{%- endif %} +{%- endmacro %} + +{# Returns the most significant time. e.g. in 3 hours #} +{%- macro easy_relative_time(uptime, attribute=None, language=None, utc=False, max_period='year', short=False, floor=False) %} +{%- set values = _default_values[_default_values.index(max_period):] if max_period in _default_values else _default_values %} +{{- _relative_time(uptime, attribute, language, values, True, utc, short, floor) }} +{%- endmacro %} + +{# Returns a large time phrase without missing any detail. e.g. in 3 hours, 4 minutes and 1 second #} +{%- macro big_relative_time(uptime, attribute=None, language=None, utc=False, max_period='year', short=False) %} +{%- set values = _default_values[_default_values.index(max_period):] if max_period in _default_values else _default_values %} +{{- _relative_time(uptime, attribute, language, values, False, utc, short) }} +{%- endmacro %} + +{# Returns a time phrase with only the details you care about most of the time. e.g. in 3 hours and 4 minutes #} +{%- macro custom_relative_time(uptime, values='', language=None, utc=False, short=False) %} +{%- set args = values.replace(' ','').split(',') | list if values is string else [] %} +{%- if args %} + {{- _relative_time(uptime, None, language, args, False, utc, short) }} +{%- else %} + {{- _relative_time(uptime, attribute, language, _default_values, False, utc, short) }} +{%- endif %} +{%- endmacro %} + +{%- macro custom_relative_time_attr(uptime, attribute, values='', language=None, utc=False, short=False) %} +{%- set args = values.replace(' ','').split(',') | list if values is string else [] %} +{%- if args %} + {{- _relative_time(uptime, attribute, language, args, False, utc, short) }} +{%- else %} + {{- _relative_time(uptime, attribute, language, _default_values, False, utc, short) }} +{%- endif %} +{%- endmacro %} + +{# create an iso timestamp from month number, week number, day number #} +{# Thanksgiving is 11, 4, 3 #} +{%- macro month_week_day(month, week, weekday) -%} +{%- set today = today_at() %} +{%- set temp = today.replace(month=month, day=1) %} +{%- set adjust = (weekday - temp.isoweekday()) % 7 %} +{%- set temp = temp + timedelta(days=adjust) -%} +{{ (temp + timedelta(weeks = week - 1)).isoformat() }} +{%- endmacro %} + +{# create an iso timestamp from month number, day number #} +{%- macro month_day(month, day) -%} +{{ today_at().replace(month=month, day=day).isoformat() }} +{%- endmacro %} + +{# create an iso timestamp on the last day of month number #} +{%- macro last_day_in_month(month, weekday) -%} +{%- set today = today_at() %} +{%- set temp = today.replace(month=month, day=1) + timedelta(days=31) %} +{%- set temp = temp.replace(day=1) - timedelta(days=7) %} +{%- set adjust = (weekday - temp.isoweekday()) % 7 %} +{%- set temp = temp + timedelta(days=adjust) -%} +{{- (temp).isoformat() }} +{%- endmacro %} + +{%- macro _next_weekday(weekday, offset) %} +{%- set wd = (weekday - 1) % 7 %} +{%- set t = today_at() %} +{{- t + timedelta(days=(wd - t.weekday()) + offset) }} +{%- endmacro %} + +{%- macro next_weekday(weekday) %} +{{- _next_weekday(weekday, 7) }} +{%- endmacro %} + +{%- macro this_weekday(weekday) %} +{{- _next_weekday(weekday, 0) }} +{%- endmacro %} + +{%- macro last_weekday(weekday) %} +{{- _next_weekday(weekday, -7) }} +{%- endmacro %} + +{%- macro days_in_month(month=None) %} +{%- set today = today_at() %} +{%- set input = month if month is not none else today.month %} +{%- set input = (input - 1) % 12 + 1 %} +{%- set t = today.replace(day=1, month=input) %} +{%- set inc = t.month + 1 %} +{%- set next_month = inc if inc <= 12 else 1 %} +{%- set next_year = t.year + 1 if inc > 12 else t.year %} +{%- set next = t.replace(month=next_month, year=next_year) %} +{{- (next - t).days }} +{%- endmacro %} + +{%- macro _days_offset_month(offset) %} +{{- days_in_month(today_at().month + offset) }} +{%- endmacro %} + +{%- macro days_next_month(offset=1) %} +{{- _days_offset_month(offset) }} +{%- endmacro %} + +{%- macro days_last_month(offset=1) %} +{{- _days_offset_month(-1 * offset) }} +{%- endmacro %} + +{# easter day as an iso timestamp #} +{%- macro easter() %} +{%- set year = now().year %} +{%- set special_years = ['1954', '1981', '2049', '2076'] %} +{%- set special_year_sub = 7 %} +{%- set a = year % 19 %} +{%- set b = year % 4 %} +{%- set c = year % 7 %} +{%- set d = (19 * a + 24) % 30 %} +{%- set e = ((2 * b) + (4 * c) + (6 * d) + 5) % 7 %} +{%- set day = (22 + d + e) - special_year_sub if year in special_years else 22 + d + e %} +{%- set month = 4 if day > 31 else 3 %} +{%- set day = day - 31 if day > 31 else day -%} +{{ today_at().replace(month=month, day=day).isoformat() }} +{%- endmacro %} + +{%- macro _hms(t) %} +{%- set dststr = t.dst() | string if t.dst() is not none else "00:00:00" %} +{%- set h, m, s = dststr.split(':') | map('int') %} +{{- h * 60 * 60 + m * 60 + s }} +{%- endmacro %} + +{%- macro _is_dst(t) %} +{{- _hms(t) | int != 0 }} +{%- endmacro %} + +{%- macro _finddst(t, kwarg, rng) %} +{%- set ns = namespace(previous=_is_dst(t), found=none) %} +{%- for i in range(rng) %} + {%- set ts = t + timedelta(**{kwarg:i}) %} + {%- if ns.previous != _is_dst(ts) and ns.found is none %} + {%- set ns.found = i %} + {%- endif %} +{%- endfor %} +{{- ns.found }} +{%- endmacro %} + +{# next daylight savings time #} +{%- macro next_dst() %} +{%- set t = now().replace(hour=0, minute=0, second=0, microsecond=0) %} +{%- set d = _finddst(t, 'days', 366) | int - 1 %} +{%- set h = _finddst(t + timedelta(days=d), 'hours', 25) | int - 1 %} +{%- set m = _finddst(t + timedelta(days=d, hours=h), 'minutes', 61) | int %} +{{- (t + timedelta(days=d, hours=h, minutes=m)).isoformat() }} +{%- endmacro%} + +{%- macro _find_delta(t, kwarg, rng) %} +{%- set ns = namespace(previous=_hms(t), found=none) %} +{%- for i in range(rng) %} + {%- set ts = t + timedelta(**{kwarg:i}) %} + {%- if ns.previous != _hms(ts) and ns.found is none %} + {%- set before = _hms(ts - timedelta(days=1)) | int %} + {%- set after = _hms(ts) | int %} + {%- set ns.found = after - before %} + {%- endif %} +{%- endfor %} +{{- ns.found }} +{%- endmacro %} + +{# What will happen next dst? #} +{% macro next_dst_phrase(language=None) %} +{%- set t = now().replace(hour=0, minute=0, second=0, microsecond=0) %} +{%- set delta = _find_delta(t, 'days', 365) | int %} +{%- if delta > 0 %} + {{- translate('lose', language=language) }} {{ easy_time_between(0, delta | abs) }} +{%- else %} + {{- translate('gain', language=language) }} {{ easy_time_between(0, delta | abs) }} +{%- endif %} +{%- endmacro %} + +{# days until next dst #} +{%- macro days_until_dst() %} +{%- set next = next_dst() | as_datetime %} +{{- (next - today_at()).days if next is not none else 0 }} +{%- endmacro %} + +{%- macro clock(fmat=None, language=None) %} +{{- now().strftime(_get_language_time_format(fmat, language)) }} +{%- endmacro %} + +{%- set _clock_icon = ['twelve','one','two','three','four','five','six','seven','eight','nine','ten','eleven'] %} + +{%- macro clock_icon(hour=None) -%} +{%- if hour is none or hour is not integer -%} + {%- set t = now() -%} + {%- set h = (t.hour + t.minute // 30) % 12 %} + {{- 'mdi:clock-time-' ~ _clock_icon[h] -}} +{%- else -%} + {{- 'mdi:clock-time-' ~ _clock_icon[hour % 12] -}} +{%- endif -%} +{%- endmacro -%} + +{%- macro month(month=None, language=None) %} +{%- if month is datetime %} +{%- set idx = month.month - 1 %} +{%- elif month is integer and month > 0 %} +{%- set idx = (month - 1) % 12 %} +{%- elif month | regex_match(valid_entity_id_pattern) %} +{%- set idx = (states(month) | as_datetime | as_local).month - 1 %} +{%- else %} +{%- set idx = now().month - 1 %} +{%- endif %} +{{- translate('months', index=idx, language=language) }} +{%- endmacro %} + +{%- macro weekday(weekday=None, language=None) %} +{%- if weekday is datetime %} +{%- set idx = weekday.weekday() %} +{%- elif weekday is integer and weekday > 0 %} +{%- set idx = (weekday - 1) % 7 %} +{%- elif weekday | regex_match(valid_entity_id_pattern) %} +{%- set idx = (states(weekday) | as_datetime | as_local).weekday() %} +{%- else %} +{%- set idx = now().weekday() %} +{%- endif %} +{{- translate('days', index=idx, language=language) }} +{%- endmacro %} + +{%- macro count_the_days(input, attr, utc=False) %} +{%- set input = _to_datetime(input, attr, utc) | as_datetime %} +{%- set midnight = today_at() %} +{{- (input - midnight).days }} +{%- endmacro %} + +{%- macro speak_the_days(input, attr, language=None, utc=False) %} +{%- set _days = {-1: translate('delta', 'yesterday', language=language), 0: translate('delta', 'today', language=language), 1: translate('delta', 'tomorrow', language=language)} %} +{%- set midnight = today_at() %} +{%- set ns = namespace(days=[]) %} +{%- for i in range(-7, 14) %} + {%- set prefix = translate('delta', 'last', language=language) ~ ' ' if i < -1 else translate('delta', 'next', language=language) ~ ' ' if i > 6 else '' %} + {%- set ns.days = ns.days + [ (i | string, prefix ~ _days.get(i, weekday(midnight.weekday() + (i % 7) + 1, language))) ] %} +{%- endfor %} +{%- set collection = dict.from_keys(ns.days) %} +{%- set days = count_the_days(input, attr, utc) %} +{%- if days in collection %} + {{- collection.get(days) }} +{%- else %} + {%- set days = days | int %} + {%- set ret = _phrase('day', days | abs * 86400, language, True, True) %} + {%- if days > 0 %} + {{- translate('in', language=language) }} {{ ret }} + {%- else %} + {%- set t = translate('ago', language=language) %} + {%- if '%s' in t %} + {{- t % ret }} + {%- else %} + {{- ret }} {{ translate('ago', language=language) }} + {%- endif %} + {%- endif %} +{%- endif %} +{%- endmacro %} + +{%- macro hour(hour, language=None) %} +{%- if hour is datetime %} + {%- set hour = hour.hour %} +{%- elif hour | regex_match(valid_entity_id_pattern) %} + {%- set hour = (states(hour) | as_datetime | as_local).hour %} +{%- endif %} +{%- set _12 = not (hour % 12) %} +{%- set _24 = not (hour % 24) %} +{%- set _12hr = translate('time','format') == '12-hr' %} +{%- if _12 and _24 and _12hr %} + {{- translate('time_of_day', 'midnight', language=language) }} +{%- elif _12 and _12hr %} + {{- translate('time_of_day', 'noon', language=language) }} +{%- else %} + {{- hour % 12 if _12hr else hour }} +{%- endif %} +{%- endmacro %} + +{%- macro clock_phrase(input=None, attr=None, utc=False, language=None) %} +{%- if input is none %} + {%- set dt = now() %} +{%- elif input is datetime %} + {%- set dt = input %} +{%- else %} + {%- set dt = _to_datetime(input, attr, utc) | as_datetime %} +{%- endif %} +{%- set this_hour = dt.hour %} +{%- set this_minute = dt.minute %} +{%- if this_minute > 30 %} + {%- set hour_phrase = hour(this_hour + 1, language=language) %} + {%- set minute_calc = 60 - this_minute %} + {%- set minute_phrase = _phrase('minute', 60 * minute_calc, language, True, True) if this_minute % 5 else minute_calc | string %} +{%- else %} + {%- set hour_phrase = hour(this_hour, language=language) %} + {%- set minute_phrase = _phrase('minute', 60 * this_minute, language, True, True) if this_minute % 5 else this_minute | string %} +{%- endif %} +{%- if this_minute in [0, 1, 15, 30, 45, 59] %} + {%- if hour_phrase in ['noon', 'midnight'] and this_minute == 0 %} + {%- set fmat = '{hour}' %} + {%- else %} + {%- set fmat = translate('time_of_hour', this_minute, language=language) %} + {%- endif %} +{%- elif this_minute > 30 %} + {%- set fmat = translate('time_of_hour', 'to_hour', language=language) %} +{%- else %} + {%- set fmat = translate('time_of_hour', 'past_hour', language=language) %} +{%- endif %} +{{- fmat.format(hour=hour_phrase, minute=minute_phrase) -}} +{%- endmacro %} diff --git a/custom_templates/variables.jinja b/custom_templates/variables.jinja index 0f1d3348..bdd47297 100644 --- a/custom_templates/variables.jinja +++ b/custom_templates/variables.jinja @@ -97,3 +97,183 @@ "off": "Off" } | to_json }} {% endmacro %} + +{# + Holiday light colors +#} +{%- set holiday_colors = + { + "no_holiday": { + "match": [ + 255, + 199, + 125, + 245 + ] + }, + "patriotic": { + "red": [ + 255, + 0, + 0, + 0 + ], + "blue": [ + 0, + 0, + 255, + 0 + ], + "white": { + "color_temp": 260 + } + }, + "valentines": { + "red": [ + 255, + 0, + 0, + 0 + ], + "light_pink": [ + 228, + 131, + 151, + 0 + ] + }, + "st_patricks_day": { + "green": [ + 9, + 148, + 65, + 0 + ], + "gold": [ + 217, + 223, + 29, + 0 + ] + }, + "easter": { + "pink": [ + 255, + 0, + 192, + 0 + ], + "purple": [ + 192, + 3, + 255, + 0 + ], + "teal": [ + 0, + 255, + 254, + 0 + ] + }, + "memorial_day": { + "red": [ + 255, + 0, + 0, + 0 + ], + "blue": [ + 0, + 0, + 255, + 0 + ], + "white": { + "color_temp": 260 + } + }, + "independence_day": { + "red": [ + 255, + 0, + 0, + 0 + ], + "blue": [ + 0, + 0, + 255, + 0 + ], + "white": { + "color_temp": 260 + } + }, + "halloween": { + "orange": [ + 247, + 95, + 28, + 0 + ], + "purple": [ + 136, + 30, + 228, + 0 + ] + }, + "veterans_day": { + "red": [ + 255, + 0, + 0, + 0 + ], + "blue": [ + 0, + 0, + 255, + 0 + ], + "white": { + "color_temp": 260 + } + }, + "christmas": { + "red": [ + 179, + 0, + 12, + 0 + ], + "green": [ + 0, + 179, + 44, + 0 + ] + }, + "thanksgiving": { + "yellow": [ + 241, + 185, + 48, + 0 + ], + "autumn": [ + 181, + 71, + 48, + 0 + ], + "lime": [ + 138, + 151, + 72, + 0 + ] + } + } +%} diff --git a/entities/input_select/holiday_override.yaml b/entities/input_select/holiday_override.yaml new file mode 100644 index 00000000..909f455a --- /dev/null +++ b/entities/input_select/holiday_override.yaml @@ -0,0 +1,20 @@ +--- +# +# source: https://github.com/Petro31/home-assistant-config +# +holiday_override: + name: Holiday Override + initial: automatic + options: + - automatic + - no_holiday + - patriotic + - valentines + - st_patricks_day + - easter + - memorial_day + - independence_day + - halloween + - veterans_day + - thanksgiving + - christmas diff --git a/entities/template/sensor/holiday_lighting.yaml b/entities/template/sensor/holiday_lighting.yaml new file mode 100644 index 00000000..4a521de6 --- /dev/null +++ b/entities/template/sensor/holiday_lighting.yaml @@ -0,0 +1,148 @@ +--- +# The template platform supports sensors which get their values from other +# entities. +# +# source: https://github.com/Petro31/home-assistant-config +# +trigger: + - platform: time + at: "00:00:00" + - platform: homeassistant + event: start + # If you end up here to copy this, it relies on an automation in config\automation\events + # named "Events - Forward Reload Templates" + - platform: event + event_type: templates_reloaded + - platform: state + entity_id: input_select.holiday_override +action: + - variables: + holidays: + # These holidays are meant to be used with easy_time.jinja + # start, end, and event are all dictionaries that contain macro and kwargs. + # macro is the macro used from easy_time.jina. + # kwargs are the arguments used by name, e.g. if the macro uses month, day as inputs + # kwargs will be set to month: #, day: #. + + valentines: + event: + macro: month_day + kwargs: + month: 2 + day: 14 + before: + days: 14 + after: + days: 1 + + st_patricks_day: + event: + macro: month_day + kwargs: + month: 3 + day: 17 + before: + days: 6 + after: + days: 1 + + easter: + event: + macro: easter + before: + days: 6 + after: + days: 1 + + memorial_day: + event: + macro: last_day_in_month + kwargs: + month: 5 + weekday: 0 + before: + days: 6 + after: + days: 1 + + independence_day: + event: + macro: month_day + kwargs: + month: 7 + day: 4 + before: + days: 6 + after: + days: 1 + + halloween: + start: + macro: month_day + kwargs: + month: 10 + day: 1 + end: + macro: month_day + kwargs: + month: 11 + day: 1 + + veterans_day: + event: + macro: month_day + kwargs: + month: 11 + day: 11 + before: + days: 6 + after: + days: 1 + + christmas: + start: + macro: month_week_day + kwargs: + month: 11 + week: 4 + weekday: 7 + end: + macro: month_day + kwargs: + month: 1 + day: 7 + event: > + {%- set override = states('input_select.holiday_override') %} + {%- if override == 'automatic' %} + {%- import 'easy_time.jinja' as easy_time %} + {%- set dflt = {'minutes': 0 } %} + {%- set ns = namespace(events=[], found='no_holiday') %} + {%- for holiday, items in holidays.items() %} + {%- set event = items.get('event') %} + {%- set start = items.get('start') %} + {%- set end = items.get('end') %} + {%- if event %} + {%- set e = easy_time[event['macro']](**event.get('kwargs', {})) | as_datetime | as_local %} + {%- set b = timedelta(**items.get('before', dflt)) %} + {%- set a = timedelta(**items.get('after', dflt)) %} + {%- set ns.events = ns.events + [ (holiday, e - b), ('no_holiday', e + a) ] %} + {%- elif start and end %} + {%- set s = easy_time[start['macro']](**start.get('kwargs', {})) | as_datetime | as_local %} + {%- set e = easy_time[end['macro']](**end.get('kwargs', {})) | as_datetime | as_local %} + {%- set ns.events = ns.events + [ (holiday, s), ('no_holiday', e) ] %} + {%- endif %} + {%- endfor %} + + {%- for event, dt in ns.events | sort(attribute='1') %} + {%- if dt.date() <= now().date() %} + {%- set ns.found = event %} + {%- endif %} + {%- endfor %} + {{ ns.found }} + {%- else %} + {{ override }} + {%- endif %} +sensor: + - unique_id: holiday_lighting + name: Holiday Lighting + state: "{{ event }}" diff --git a/entities/template/sensor/seasonal_lights.yaml b/entities/template/sensor/seasonal_lights.yaml new file mode 100644 index 00000000..4ead7a31 --- /dev/null +++ b/entities/template/sensor/seasonal_lights.yaml @@ -0,0 +1,23 @@ +--- +# The template platform supports sensors which get their values from other +# entities. +# +# source: https://github.com/Petro31/home-assistant-config +# +sensor: + - unique_id: seasonal_lights + name: Seasonal Lights + state: > + {%- set scenes = dict( + christmas='scene.holiday_bulbs_christmas', + easter='scene.holiday_bulbs_easter', + halloween='scene.holiday_bulbs_halloween', + independence_day='scene.holiday_bulbs_patriotic', + veterans_day='scene.holiday_bulbs_patriotic', + memorial_day='scene.holiday_bulbs_patriotic', + st_patricks_day='scene.holiday_bulbs_st_patricks_day', + thanksgiving='scene.holiday_bulbs_thanksgiving', + valentines='scene.holiday_bulbs_valentines_day', + ) %} + {%- set holiday = states('sensor.holiday_lighting') %} + {{ scenes.get(holiday, 'scene.holiday_bulbs_daylight') }} diff --git a/scenes.yaml b/scenes.yaml index 8cf592f1..655e2333 100644 --- a/scenes.yaml +++ b/scenes.yaml @@ -1,3 +1,198 @@ ---- -# This file is used by the scenes editor in the Home Assistant frontend. -[] +- id: '1734639571989' + name: Sunrise Bulbs + icon: mdi:weather-sunset-up + metadata: {} + entities: + light.outside_entry_1: + state: 'off' + light.outside_entry_2: + state: 'off' + light.outside_garage_1: + state: 'off' + light.outside_garage_2: + state: 'off' +- id: '1734639577875' + name: Holiday Bulbs Soft White + icon: mdi:weather-sunset + metadata: {} + entities: + light.outside_entry_1: + state: 'on' + brightness: 255 + color_temp: 370 + light.outside_entry_2: + state: 'on' + brightness: 255 + color_temp: 370 + light.outside_garage_1: + state: 'on' + brightness: 255 + color_temp: 370 + light.outside_garage_2: + state: 'on' + brightness: 255 + color_temp: 370 +- id: '1734639585036' + name: Holiday Bulbs DayLight + icon: mdi:white-balance-sunny + metadata: {} + entities: + light.outside_entry_1: + state: 'on' + brightness: 255 + color_temp: 153 + light.outside_entry_2: + state: 'on' + brightness: 255 + color_temp: 153 + light.outside_garage_1: + state: 'on' + brightness: 255 + color_temp: 153 + light.outside_garage_2: + state: 'on' + brightness: 255 + color_temp: 153 +- id: '1734639591532' + name: Holiday Bulbs Valentines Day + icon: mdi:heart-multiple + metadata: {} + entities: + light.outside_entry_1: + state: 'on' + brightness: 255 + rgb_color: [ 94, 8, 30] + light.outside_entry_2: + state: 'on' + brightness: 255 + rgb_color: [228, 131, 151] + light.outside_garage_1: + state: 'on' + brightness: 255 + rgb_color: [228, 131, 151] + light.outside_garage_2: + state: 'on' + brightness: 255 + rgb_color: [ 94, 8, 30] +- id: '1734639597917' + name: Holiday Bulbs St Patricks Day + icon: mdi:clover + metadata: {} + entities: + light.outside_entry_1: + state: 'on' + brightness: 255 + rgb_color: [ 9, 148, 65] + light.outside_entry_2: + state: 'on' + brightness: 255 + rgb_color: [217, 223, 29] + light.outside_garage_1: + state: 'on' + brightness: 255 + rgb_color: [217, 223, 29] + light.outside_garage_2: + state: 'on' + brightness: 255 + rgb_color: [ 9, 148, 65] +- id: '1734639616965' + name: Holiday Bulbs Easter + icon: mdi:rabbit + metadata: {} + entities: + light.outside_entry_1: + state: 'on' + rgb_color: [255, 0, 192] + light.outside_entry_2: + state: 'on' + rgb_color: [192, 3, 255] + light.outside_garage_1: + state: 'on' + rgb_color: [192, 3, 255] + light.outside_garage_2: + state: 'on' + rgb_color: [255, 0, 192] +- id: '1734639623395' + name: Holiday Bulbs Patriotic + icon: mdi:flag-variant + metadata: {} + entities: + light.outside_entry_1: + state: 'on' + brightness: 255 + rgb_color: [ 255, 0, 0] + light.outside_entry_2: + state: 'on' + brightness: 255 + rgb_color: [0, 0, 255] + light.outside_garage_1: + state: 'on' + brightness: 255 + rgb_color: [ 255, 0, 0] + light.outside_garage_2: + state: 'on' + brightness: 255 + rgb_color: [0, 0, 255] +- id: '1734639628892' + name: Holiday Bulbs Halloween + icon: mdi:halloween + metadata: {} + entities: + light.outside_entry_1: + state: 'on' + brightness: 255 + rgb_color: [247,95,28] + light.outside_entry_2: + state: 'on' + brightness: 255 + rgb_color: [136, 30, 228] + light.outside_garage_1: + state: 'on' + brightness: 255 + rgb_color: [136, 30, 228] + light.outside_garage_2: + state: 'on' + brightness: 255 + rgb_color: [247,95,28] +- id: '1734639634203' + name: Holiday Bulbs Thanksgiving + icon: mdi:turkey + metadata: {} + entities: + light.outside_entry_1: + state: 'on' + brightness: 255 + rgb_color: [108, 47, 0] + light.outside_entry_2: + state: 'on' + brightness: 255 + rgb_color: [158, 104, 42] + light.outside_garage_1: + state: 'on' + brightness: 255 + rgb_color: [181, 71, 48] + light.outside_garage_2: + state: 'on' + brightness: 255 + rgb_color: [138, 151, 72] +- id: '1734639640002' + name: Holiday Bulbs Christmas + icon: mdi:string-lights + metadata: {} + entities: + light.outside_entry_1: + state: 'on' + brightness: 255 + rgb_color: [179, 0, 12] + light.outside_entry_2: + state: 'on' + brightness: 255 + rgb_color: [ 0, 179, 44] + light.outside_garage_1: + state: 'on' + brightness: 255 + rgb_color: [ 0, 179, 44] + light.outside_garage_2: + state: 'on' + brightness: 255 + rgb_color: [179, 0, 12]