Compare commits

...

35 Commits

Author SHA1 Message Date
150c0cec8a Starting to dig into Speech Engine...annnnnd holy shit 2024-08-08 22:46:28 -04:00
734b39f88b More variable scripts 2024-08-08 22:46:28 -04:00
e13d3879c6 Figuring out a way to still use notify groups for this rewrite 2024-08-08 22:46:27 -04:00
67086b340c "get_room_lights" script 2024-08-08 22:46:26 -04:00
c7456cad29 Start adding routing to speech engine. Not functional yet. 2024-08-08 22:46:25 -04:00
3fc4e91b68 "get room services" script 2024-08-08 22:46:24 -04:00
bcfc6405ce Add scheduling automations for sports notifications
Signed-off-by: Tony Stork <tm24fan8@gmail.com>
2024-08-08 22:30:52 -04:00
1028f2d053 Fix typo for wife's name 2024-08-08 22:30:52 -04:00
e40785a382 Use time_from_calendar macro for K scheduling for two hour delays 2024-08-08 22:30:51 -04:00
d88f89475b Fix scheduling for wife's morning meds reminder
#205
2024-08-08 22:30:51 -04:00
4b3cfbc1df Add new macro for setting time AND date from calendars 2024-08-08 22:30:50 -04:00
1d537036c4 Change template condition to "or" condition for my meds cleanup
#205
2024-08-08 22:30:50 -04:00
f3b17dfd5e Change template condition to "or" condition for wife meds cleanup
#205
2024-08-08 22:30:49 -04:00
95d0a20e3d Implement new trackers for K
#205
2024-08-08 22:30:49 -04:00
3eb5f3a7cc Implement new trackers for wife
#205
2024-08-08 22:30:48 -04:00
6ee087ab56 We need to START the med scripts by incrementing the counter
Doing it at the end means things that should happen on the third reminder will not actually happen until the fourth.

#205
2024-08-08 22:30:48 -04:00
476cbac212 Rewrite Tony meds scripts to simply handle sending the reminders
#205
2024-08-08 22:30:48 -04:00
c8671a1b38 Add Tony Meds Cleanup automation
#205
2024-08-08 22:30:47 -04:00
b7424a0d74 Rewrite Tony Meds Handler automation
#205
2024-08-08 22:30:47 -04:00
7ea640c947 Switch from template sensors to input booleans for reminders
#205
2024-08-08 22:30:46 -04:00
404adcb60a Change logic for setting and resetting notification times
#205
2024-08-08 22:30:46 -04:00
3543e43672 Add triggers to help with reboot survival
#205
2024-08-08 22:30:45 -04:00
29b310fe5b Fix UUIDs
#205
2024-08-08 22:30:45 -04:00
cc69a937eb Initial notification framework for meds rework 2024-08-08 22:30:44 -04:00
faef1d02b2 Add bug report issue template
(cherry picked from commit 94cbb81be1)
2024-08-08 22:29:56 -04:00
46df823c24 Add min/max/average temp and lux sensors to database 2024-07-30 18:00:25 -04:00
707c03804d Update to latest relative_time_plus.jinja 2024-07-24 15:58:55 -04:00
9fea293c23 Add med reminder counts for K 2024-07-24 15:55:35 -04:00
703fed14c3 Move wife's med tracker to UI, add reminder counts 2024-07-23 21:54:39 -04:00
37a6f31a1e Add night meds reminder count, reset reminder counts when meds are taken 2024-07-23 21:54:15 -04:00
8411488ab3 Make E's actual wakeup time actually update properly 2024-07-23 21:52:49 -04:00
bda6fc97ba Move Minnesota Twins to first spot for baseball teams 2024-07-23 15:25:07 -04:00
261913371f Updated readme 2024-07-22 22:54:28 -04:00
b718ad2de2 Add text notifications for shower mode window alert #204 2024-07-22 22:29:39 -04:00
2c559ec2c4 Shower mode window alert, close #204 2024-07-22 21:56:53 -04:00
16 changed files with 2205 additions and 1043 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -312,6 +312,12 @@ influxdb:
- sensor.bypassed_sensors
- input_boolean.shower_mode
- sensor.services_down
- sensor.average_room_temperature
- sensor.average_room_illuminance
- sensor.brightest_room
- sensor.dimmest_room
- sensor.warmest_room_temperature
- sensor.coldest_room_temperature
logbook:
include:
@@ -480,3 +486,9 @@ prometheus:
- sensor.bypassed_sensors
- input_boolean.shower_mode
- sensor.services_down
- sensor.average_room_temperature
- sensor.average_room_illuminance
- sensor.brightest_room
- sensor.dimmest_room
- sensor.warmest_room_temperature
- sensor.coldest_room_temperature

View File

@@ -4,243 +4,417 @@
combine contains the text to combine the last time fraction, and error the text to display on wrong date input
#}
{%- set _time_period_phrases = [
{
'language': 'en',
'phrases':
{
'year': ['year', 'years', 'yr'],
'month': ['month', 'months', 'mth'],
'week': ['week', 'weeks', 'wk'],
'day': ['day', 'days', 'day'],
'hour': ['hour', 'hours', 'hr'],
'minute': ['minute', 'minutes', 'min'],
'second': ['second', 'seconds', 'sec'],
'millisecond': ['millisecond', 'milliseconds', 'ms'],
'combine': 'and',
'error': 'Invalid date'
}
},
{
'language': 'pl',
'phrases':
{
'year': ['rok', 'lat', 'r'],
'month': ['miesiąc', 'miesięcy', 'msc'],
'week': ['tydzi', 'tygodni', 'tyg'],
'day': ['dzień', 'dni', 'dzień'],
'hour': ['godzina', 'godzin', 'godz'],
'minute': ['minuta', 'minut', 'min'],
'second': ['sekunda', 'sekund', 'sek'],
'millisecond': ['milisekunda', 'milisekund', 'ms'],
'combine': 'i',
'error': 'Niepoprawna data'
}
},
{
'language': 'fr',
'phrases':
{
'year': ['année', 'années', 'an'],
'month': ['mois', 'mois', 'mois'],
'week': ['semaine', 'semaines', 'sem'],
'day': ['jour', 'jours', 'j'],
'hour': ['heure', 'heures', 'h'],
'minute': ['minute', 'minutes', 'min'],
'second': ['seconde', 'secondes', 'sec'],
'millisecond': ['milliseconde', 'millisecondes', 'ms'],
'combine': 'et',
'error': 'Date non valide'
}
},
{
'language': 'it',
'phrases':
{
'year': ['anno', 'anni', 'aa'],
'month': ['mese', 'mesi', 'mm'],
'week': ['settimana', 'settimane', 'set'],
'day': ['giorno', 'giorni', 'gg'],
'hour': ['ora', 'ore', 'h'],
'minute': ['minuto', 'minuti', 'min'],
'second': ['secondo', 'secondi', 'sec'],
'millisecond': ['millisecondo', 'millisecondi', 'ms'],
'combine': 'e',
'error': 'Data non valida'
}
},
{
'language': 'nl',
'phrases':
{
'year': ['jaar', 'jaar', 'jr'],
'month': ['maand', 'maanden', 'mnd'],
'week': ['week', 'weken', 'wk'],
'day': ['dag', 'dagen', 'dg'],
'hour': ['uur', 'uur', 'u'],
'minute': ['minuut', 'minuten', 'min'],
'second': ['seconde', 'seconden', 'sec'],
'millisecond': ['milliseconde', 'milliseconden', 'ms'],
'combine': 'en',
'error': 'Ongeldige datum'
}
},
{
'language': 'de',
'phrases':
{
'year': ['Jahr', 'Jahre', 'J.'],
'month': ['Monat', 'Monate', 'M.'],
'week': ['Woche', 'Wochen', 'Wo.'],
'day': ['Tag', 'Tage', 'Tg.'],
'hour': ['Stunde', 'Stunden', 'Std.'],
'minute': ['Minute', 'Minuten', 'Min.'],
'second': ['Sekunde', 'Sekunden', 'Sek.'],
'millisecond': ['Milliseconde', 'Milliseconden', 'ms'],
'combine': 'und',
'error': 'Falsches Datum'
}
},
{
'language': 'pt',
'phrases':
{
'year': ['ano', 'anos', 'aa'],
'month': ['mês', 'meses', 'mm'],
'week': ['semana', 'semanas', 'sem'],
'day': ['dia', 'dias', 'd'],
'hour': ['hora', 'horas', 'h'],
'minute': ['minuto', 'minutos', 'min'],
'second': ['segundo', 'segundos', 'seg'],
'millisecond': ['millissegundo', 'millissegundos', 'ms'],
'combine': 'e',
'error': 'Data Inválida'
}
},
{
'language': 'dk',
'phrases':
{
'year': ['år', 'år', 'år'],
'month': ['måned', 'måneder', 'mnd'],
'week': ['uge', 'uger', 'uge'],
'day': ['dag', 'dage', 'dag'],
'hour': ['time', 'timer', 't.'],
'minute': ['minut', 'minuter', 'min.'],
'second': ['sekund', 'sekunder', 'sek.'],
'millisecond': ['millisekund', 'millisekunder', 'ms.'],
'combine': 'og',
'error': 'Ugyldig dato'
}
}
]
%}
{
'language': 'en',
'phrases': {
'year': ['year', 'years', 'yr'],
'month': ['month', 'months', 'mth'],
'week': ['week', 'weeks', 'wk'],
'day': ['day', 'days', 'day'],
'hour': ['hour', 'hours', 'hr'],
'minute': ['minute', 'minutes', 'min'],
'second': ['second', 'seconds', 'sec'],
'millisecond': ['millisecond', 'milliseconds', 'ms'],
'combine': 'and',
'error': 'Invalid date',
}
},
{
'language': 'pl',
'phrases': {
'year': ['rok', 'lat', 'r'],
'month': ['miesiąc', 'miesięcy', 'msc'],
'week': ['tydzień', 'tygodni', 'tyg'],
'day': ['dzień', 'dni', 'dzień'],
'hour': ['godzina', 'godzin', 'godz'],
'minute': ['minuta', 'minut', 'min'],
'second': ['sekunda', 'sekund', 'sek'],
'millisecond': ['milisekunda', 'milisekund', 'ms'],
'combine': 'i',
'error': 'Niepoprawna data',
}
},
{
'language': 'fr',
'phrases': {
'year': ['année', 'années', 'an'],
'month': ['mois', 'mois', 'mois'],
'week': ['semaine', 'semaines', 'sem'],
'day': ['jour', 'jours', 'j'],
'hour': ['heure', 'heures', 'h'],
'minute': ['minute', 'minutes', 'min'],
'second': ['seconde', 'secondes', 'sec'],
'millisecond': ['milliseconde', 'millisecondes', 'ms'],
'combine': 'et',
'error': 'Date non valide',
}
},
{
'language': 'it',
'phrases': {
'year': ['anno', 'anni', 'aa'],
'month': ['mese', 'mesi', 'mm'],
'week': ['settimana', 'settimane', 'set'],
'day': ['giorno', 'giorni', 'gg'],
'hour': ['ora', 'ore', 'h'],
'minute': ['minuto', 'minuti', 'min'],
'second': ['secondo', 'secondi', 'sec'],
'millisecond': ['millisecondo', 'millisecondi', 'ms'],
'combine': 'e',
'error': 'Data non valida',
}
},
{
'language': 'nb',
'phrases': {
'year': ['år', 'år', 'år'],
'month': ['måned', 'måneder', 'mnd'],
'week': ['uke', 'uker', 'u'],
'day': ['dag', 'dager', 'd'],
'hour': ['time', 'timer', 't'],
'minute': ['minutt', 'minutter', 'min'],
'second': ['sekund', 'sekunder', 'sek'],
'millisecond': ['millisekund', 'millisekunder', 'ms'],
'combine': 'og',
'error': 'Ugyldig dato',
}
},
{
'language': 'nl',
'phrases': {
'year': ['jaar', 'jaar', 'jr'],
'month': ['maand', 'maanden', 'mnd'],
'week': ['week', 'weken', 'wk'],
'day': ['dag', 'dagen', 'dg'],
'hour': ['uur', 'uur', 'u'],
'minute': ['minuut', 'minuten', 'min'],
'second': ['seconde', 'seconden', 'sec'],
'millisecond': ['milliseconde', 'milliseconden', 'ms'],
'combine': 'en',
'error': 'Ongeldige datum',
}
},
{
'language': 'nn',
'phrases': {
'year': ['år', 'år', 'år'],
'month': ['månad', 'månader', 'mnd'],
'week': ['veke', 'veker', 'v'],
'day': ['dag', 'dagar', 'd'],
'hour': ['time', 'timar', 't'],
'minute': ['minutt', 'minutt', 'min'],
'second': ['sekund', 'sekund', 'sek'],
'millisecond': ['millisekund', 'millisekund', 'ms'],
'combine': 'og',
'error': 'Ugyldig dato',
}
},
{
'language': 'de',
'phrases': {
'year': ['Jahr', 'Jahre', 'J.'],
'month': ['Monat', 'Monate', 'M.'],
'week': ['Woche', 'Wochen', 'Wo.'],
'day': ['Tag', 'Tage', 'Tg.'],
'hour': ['Stunde', 'Stunden', 'Std.'],
'minute': ['Minute', 'Minuten', 'Min.'],
'second': ['Sekunde', 'Sekunden', 'Sek.'],
'millisecond': ['Millisekunde', 'Millisekunden', 'ms'],
'combine': 'und',
'error': 'Falsches Datum',
}
},
{
'language': 'pt',
'phrases': {
'year': ['ano', 'anos', 'aa'],
'month': ['mês', 'meses', 'mm'],
'week': ['semana', 'semanas', 'sem'],
'day': ['dia', 'dias', 'd'],
'hour': ['hora', 'horas', 'h'],
'minute': ['minuto', 'minutos', 'min'],
'second': ['segundo', 'segundos', 'seg'],
'millisecond': ['millissegundo', 'millissegundos', 'ms'],
'combine': 'e',
'error': 'Data Inválida',
}
},
{
'language': 'dk',
'phrases': {
'year': ['år', 'år', 'år'],
'month': ['måned', 'måneder', 'mnd'],
'week': ['uge', 'uger', 'uge'],
'day': ['dag', 'dage', 'dag'],
'hour': ['time', 'timer', 't.'],
'minute': ['minut', 'minuter', 'min.'],
'second': ['sekund', 'sekunder', 'sek.'],
'millisecond': ['millisekund', 'millisekunder', 'ms.'],
'combine': 'og',
'error': 'Ugyldig dato',
}
},
{
'language': 'sv',
'phrases': {
'year': ['år', 'år', 'år'],
'month': ['månad', 'månader', 'mån'],
'week': ['vecka', 'veckor', 'v'],
'day': ['dag', 'dagar', 'dag'],
'hour': ['timme', 'timmar', 'tim'],
'minute': ['minut', 'minuter', 'min'],
'second': ['sekund', 'sekunder', 'sek'],
'millisecond': ['millisekund', 'millisekunder', 'ms'],
'combine': 'och',
'error': 'Ogiltigt datum',
}
},
{
'language': 'cs',
'phrases': {
'year': ['rok', 'roky', 'rok'],
'month': ['měsíc', 'měsíce', 'měs'],
'week': ['týden', 'týdny', 'týd'],
'day': ['den', 'dny', 'd'],
'hour': ['hodina', 'hodiny', 'hod'],
'minute': ['minuta', 'minuty', 'min'],
'second': ['sekunda', 'sekundy', 'sek'],
'millisecond': ['millisekunda', 'millisekundy', 'ms'],
'combine': 'a',
'error': 'špatný datum'
}
},
{
'language': 'fi',
'phrases': {
'year': ['vuosi', 'vuotta', 'v'],
'month': ['kuukausi', 'kuukautta', 'kk'],
'week': ['viikko', 'viikkoa', 'vk'],
'day': ['päivä', 'päivää', 'pv'],
'hour': ['tunti', 'tuntia', 't'],
'minute': ['minuutti', 'minuuttia', 'min'],
'second': ['sekunti', 'sekuntia', 's'],
'millisecond': ['millisekunti', 'millisekuntia', 'ms'],
'combine': 'ja',
'error': 'Väärä päivämäärä',
}
},
{
'language': 'ru',
'phrases': {
'year': ['год', 'года', 'г'],
'month': ['месяц', 'месяцы', 'м'],
'week': ['неделя', 'недели', 'н'],
'day': ['день', 'дни', 'д'],
'hour': ['час', 'часы', 'ч'],
'minute': ['минута', 'минут', 'м'],
'second': ['секунд', 'секунды', 'с'],
'millisecond': ['милисекунд', 'милисекунды', 'мс'],
'combine': 'и',
'error': 'Неверная дата',
}
},
{
'language': 'uk',
'phrases': {
'year': ['рік', 'років', 'р'],
'month': ['місяць', 'місяців', 'м'],
'week': ['тиждень', 'тижнів', 'тижд'],
'day': ['день', 'днів', 'дн'],
'hour': ['годину', 'годин', 'год'],
'minute': ['хвилину', 'хвилин', 'хв'],
'second': ['секунду', 'секунд', 'сек'],
'millisecond': ['мілісекунду', 'мілісекунд', 'мсек'],
'combine': 'та',
'error': 'Недійсна дата',
}
},
] -%}
{# macro to convert the abbreviated input for the not_use and always_show lists to the full time part names #}
{%- macro _abbr_to_full(input) -%}
{# determine not_use list #}
{%- set abbr_to_full = dict(yr='year', mth='month', wk='week', day='day', hr='hour', min='minute', sec='second', ms='millisecond') -%}
{%- set list = input if input is list else (input | replace(' ', '')).split(',') -%}
{%- if list | select('in', abbr_to_full) | list | count > 0 -%}
{%- set ns = namespace(output=[]) -%}
{%- for i in list -%}
{%- set ns.output = ns.output + [abbr_to_full[i] | default(i)] -%}
{%- endfor -%}
{%- set list = ns.output -%}
{%- endif -%}
{{- list | select('in', abbr_to_full.values()) | list | to_json -}}
{%- endmacro -%}
{#
macro to split a timedelta in years, months, weeks, days, hours, minutes, seconds
macro to split a timedelta in years, months, weeks, days, hours, minutes, seconds and milliseconds
used by the relative time plus macro, set up as a seperate macro so it can be reused
#}
{%- macro time_split(date, compare_date=now(), time=true, not_use=[]) -%}
{# set defaults for variables #}
{%- set date = date | as_local if time else date.date()-%}
{%- macro time_split(date, parts=8, compare_date=now(), not_use=[], always_show=['all'], time=true, round_mode='floor') -%}
{#- set defaults for input if not entered #}
{%- set date = date if date is datetime else date | as_datetime('invalid') -%}
{%- set compare_date = compare_date if compare_date is datetime else compare_date | as_datetime('invalid') -%}
{%- set time = time | bool(true) -%}
{%- set comp_date = compare_date if time else compare_date.date() -%}
{%- set date_max = [comp_date, date] | max -%}
{%- set date_min = [comp_date, date] | min -%}
{#- set time periods in seconds #}
{%- set m, h, d, w = 60, 3600, 86400, 604800 -%}
{#- set numer of years, and set lowest date using this number of years #}
{%- set yrs = date_max.year - date_min.year - (1 if date_max.replace(year=date_min.year) < date_min else 0) -%}
{%- set date_max = date_max.replace(year=date_max.year - yrs) -%}
{#- set numer of months, and set lowest date using this number of months #}
{%- if 'month' not in not_use -%}
{%- set mth = (date_max.month - date_min.month - (1 if date_max.day < date_min.day else 0) + 12) % 12 -%}
{%- set month_new = (((date_max.month - mth) + 12) % 12) | default(12, true) -%}
{%- set day_max = ((date_max.replace(day=1, month=month_new) + timedelta(days=31)).replace(day=1) - timedelta(days=1)).day -%}
{%- set extra_days = [0, date_max.day - day_max] | max -%}
{%- set date_temp = date_max.replace(month=month_new, day=[date_max.day, day_max]|min) -%}
{%- set date_max = date_temp if date_temp <= date_max else date_temp.replace(year=date_max.year-1) -%}
{%- set mth = mth + yrs * 12 if 'year' in not_use else mth -%}
{%- endif -%}
{%- set date_max = date_max.replace(year=date_max.year + yrs) if 'year' in not_use and 'month' in not_use else date_max -%}
{%- set yrs = 0 if 'year' in not_use else yrs -%}
{#- set other time period variables #}
{%- set s = (date_max - date_min).total_seconds() + extra_days | default(0) * 86400 -%}
{%- set wks = 0 if 'week' in not_use else (s // w) | int -%}
{%- set day = 0 if 'day' in not_use else ((s - wks * w) // d) | int -%}
{%- set hrs = 0 if 'hour' in not_use else ((s - wks * w - day * d) // h) | int -%}
{%- set min = 0 if 'minute' in not_use else ((s - wks * w - day * d - hrs * h) // m) | int -%}
{%- set sec = 0 if 'second' in not_use else (s - wks * w - day * d - hrs * h - min * m) | int -%}
{%- set ms = (s % 1 * 1000) | round | int -%}
{# output result #}
{%- set output = dict(year=yrs, month=mth | default(0), week=wks, day=day, hour=hrs, minute=min, second=sec, millisecond=ms) %}
{{- dict(output.items() | rejectattr('0', 'in', not_use)) | to_json -}}
{%- set parts = [parts | int(1), always_show | count] | max -%}
{# 1: check if date input is correct #}
{%- if date is datetime and compare_date is datetime -%}
{# convert date input to local or date only #}
{%- set date = date | as_local if time else (date | as_local).date() -%}
{%- set compare_date = compare_date | as_local if time else (compare_date | as_local).date() -%}
{# determine highest and lowest date #}
{%- set date_max = [compare_date, date] | max -%}
{%- set date_min = [compare_date, date] | min -%}
{#- set time periods in seconds #}
{%- set days_year = 365 + (1 if (compare_date.replace(month=3, day=1) - timedelta(days=1)).day == 29 else 0) -%}
{%- set days_month = ((compare_date.replace(day=20) + timedelta(days=20)).replace(day=1) - timedelta(days=1)).day -%}
{%- set dur = dict(
year=days_year * 86400000,
month=days_month * 86400000,
week=604800000,
day=86400000,
hour=3600000,
minute=60000,
second=1000,
millisecond=1,
)
-%}
{# make sure input for not_use and always_show is correct #}
{%- if not not_use in [['millisecond'], []] -%}
{%- set not_use = _abbr_to_full(not_use) | from_json -%}
{%- endif -%}
{%- set not_use = not_use + ['hour', 'minute', 'second', 'millisecond' ] if not time else not_use -%}
{%- if always_show in [['all'], 'all'] -%}
{%- set always_show = dur.keys() | list -%}
{%- elif always_show != [] -%}
{%- set always_show = _abbr_to_full(always_show) | from_json | reject('in' , not_use) | list -%}
{%- endif -%}
{%- set always_show = always_show | reject('in', not_use) | list -%}
{%- set do_use = dur.keys() | reject('in', not_use) | list -%}
{# determine number of milliseconds #}
{%- set ms = ((date_max - date_min).total_seconds() * 1000) | round(0, 'ceil')-%}
{# 2: Check if the number of milliseconds is more then the duration of the last time part to output #}
{%- if do_use and ms < dur[do_use|last] -%}
{{- {do_use | last: (ms / dur[do_use|last]) | round(0, round_mode)} | to_json -}}
{%- else -%}
{# check if it is needed to determine years #}
{%- if ms >= dur.day * 365 -%}
{#- set numer of years, and set highest date using this number of years #}
{%- set yrs = date_max.year - date_min.year - (1 if date_max.replace(year=date_min.year) < date_min else 0) -%}
{%- set date_max = date_max.replace(year=date_max.year - yrs) -%}
{%- set ms = (date_max - date_min).total_seconds() * 1000 -%}
{%- set ms_yrs = ms -%}
{%- endif -%}
{%- set yrs = yrs | default(0) -%}
{# check if it is needed to determine months #}
{%- set check_mth =
ms >= dur.day * 28
and 'month' in do_use
-%}
{%- if check_mth -%}
{#- set numer of months, and set highest date using this number of months #}
{%- set ns = namespace(dm=date_max, mth=0) -%}
{%- set dmd = ns.dm.day -%}
{%- for m in range(1, 12) -%}
{%- set dmm, dmy = ns.dm.month, ns.dm.year -%}
{%- set day_max = (ns.dm.replace(day=1) - timedelta(days=1)).day -%}
{%- set dm = ns.dm.replace(
month=12 if dmm == 1 else dmm - 1,
year=dmy - 1 if dmm == 1 else dmy,
day= [dmd, day_max] | min
)
-%}
{%- if dm < date_min -%}
{%- break -%}
{%- else -%}
{%- set ns.mth = ns.mth + 1 -%}
{%- set ns.dm = dm -%}
{%- endif -%}
{%- endfor -%}
{%- set date_max, mth = ns.dm, ns.mth -%}
{%- set mth = mth + yrs * 12 if 'year' in not_use else mth -%}
{%- set ms = (date_max - date_min).total_seconds() * 1000 -%}
{%- endif -%}
{%- set mth = mth | default(0) -%}
{# prepare for other time parts #}
{%- set date_max = date_max.replace(year=date_max.year + yrs) if 'year' in not_use and 'month' in not_use else date_max -%}
{#- set other time period variables #}
{%- set ms = ((date_max - date_min).total_seconds() * 1000 + extra_days | default(0) * dur.day) | round(0) -%}
{%- set wks = (ms // dur.week) | int -%}
{%- set days = ((ms % dur.week // dur.day) + (wks * dur.week / dur.day if 'week' in not_use else 0)) | int -%}
{%- set hrs = ((ms % dur.day // dur.hour) + (days * dur.day / dur.hour if 'day' in not_use else 0)) | int -%}
{%- set min = ((ms % dur.hour // dur.minute) + (hrs * dur.hour / dur.minute if 'hour' in not_use else 0)) | int -%}
{%- set sec = ((ms % dur.minute // dur.second) + (min * dur.minute / dur.second if 'minute' in not_use else 0)) | int -%}
{%- set mis = ((ms % dur.second) | round + (sec * dur.second if 'second' in not_use else 0)) | int -%}
{# prepare dict with ouput #}
{%- set output = dict(year=yrs, month=mth | default(0), week=wks, day=days, hour=hrs, minute=min, second=sec, millisecond=mis) -%}
{%- set output = dict(output.items() | selectattr('0', 'in', do_use)) -%}
{%- set keys = output.keys() | list -%}
{%- set with_value = output.items() | rejectattr('1', 'eq', 0) | map(attribute='0') | list -%}
{%- set first = with_value | first | default('millisecond') -%}
{%- set first = keys | select('in', always_show | default([], true) + [first]) | first -%}
{%- set to_use = keys[keys.index(first):] -%}
{%- set to_output = to_use[:parts] -%}
{%- set last = to_output | last |default('millisecond') -%}
{# 3: check if there is anything left to use #}
{%- if to_use -%}
{%- set to_output = to_use[:parts] -%}
{%- set always_return = to_output | last -%}
{# check if all values for always_show are included #}
{%- set as_check = always_show | reject('in', to_output) | list | count -%}
{%- if always_show and as_check > 0 -%}
{%- set to_reject = to_use | reject('in', to_output) | reject('in', always_show) | list -%}
{%- set not_use = not_use + to_output[as_check*-1:] + to_reject -%}
{%- set to_output = to_output | reject('in', not_use) | list + always_show -%}
{%- set to_output = keys | select('in', to_output) | list -%}
{%- set output = time_split(date, parts, compare_date, not_use, always_show, time, round_mode) | from_json -%}
{%- endif -%}
{# apply round if needed #}
{%- if round_mode in ['common', 'ceil'] and last != 'millisecond' -%}
{# determine first and last item with data #}
{%- set ms = ms_yrs if last == 'year' else ms -%}
{%- set remain = ms % dur[last] -%}
{%- set remain_part = remain / dur[last] -%}
{%- set to_round = 1 if remain_part >= 0.5 and round_mode == 'common' else remain_part | round(0, round_mode) -%}
{%- set sec_to_add = ((dur[last] + (dur.day if last in ['year', 'month'] else 1) - remain) | round(0, 'ceil') * to_round) / 1000 -%}
{%- set round_mode = 'floor' -%}
{%- set date_max = [compare_date, date] | max + timedelta(seconds=sec_to_add) -%}
{%- set date_min = [compare_date, date] | min -%}
{%- set output = time_split(date_max, parts, date_min, not_use, always_show, time, round_mode) | from_json -%}
{%- endif -%}
{# output result #}
{%- set zero_values = output.items() | selectattr('1', 'eq', 0) | map(attribute='0') | list -%}
{%- set reject_list = zero_values | reject('in', always_show) | list -%}
{{- dict(output.items() | selectattr('0', 'in', to_output) | rejectattr('0', 'in', reject_list)) | default({always_return: 0}, true) | to_json -}}
{%- else -%} {{- dict(error='No time parts left to output') | to_json -}}
{%- endif -%} {# 3 #}
{%- endif -%} {# 2 #}
{%- else -%} {{- dict(error='Invalid date input') | to_json -}}
{%- endif -%} {# 1 #}
{%- endmacro -%}
{# macro to output a timedelta in a readable format #}
{%- macro relative_time_plus(date, parts=1, abbr=false, verbose=false, language='en', compare_date=now(), month=none, week=none, millisecond=none, not_use=['millisecond'], always_show=[], time=true) -%}
{#- set defaults for input if not entered #}
{%- set date = date if date is datetime else date | as_datetime -%}
{%- set compare_date = compare_date if compare_date is datetime else compare_date | as_datetime -%}
{%- macro relative_time_plus(date, parts=1, abbr=false, language='en', compare_date=now(), not_use=['millisecond'], always_show=[], time=true, round_mode='floor') -%}
{#- select correct phrases bases on language input #}
{%- set phrases = _time_period_phrases -%}
{%- set languages = phrases | map(attribute='language') | list -%}
{%- set language = iif(language in languages, language, 'en') -%}
{%- set phr = phrases | selectattr('language', 'eq', language) | map(attribute='phrases') | list | first -%}
{#- perform smart stuff #}
{%- if date is datetime and compare_date is datetime -%}
{# determine not_use list #}
{%- set abbr_to_full = dict(yr='year', mth='month', wk='week', hr='hour', min='minute', sec='second', ms='millisecond') -%}
{%- set add = [('month', month),('week',week),('millisecond',millisecond)] | selectattr('1', 'eq', false) | map(attribute='0') | list -%}
{%- set not_use = not_use if not_use is list else (not_use | replace(' ', '')).split(',') -%}
{%- set not_use = (not_use + add) | unique | list -%}
{%- if not_use | select('in', abbr_to_full) | list | count > 0 -%}
{%- set ns = namespace(not_use=[]) -%}
{%- for i in not_use -%}
{%- set ns.not_use = ns.not_use + [abbr_to_full[i] | default(i)] -%}
{%- endfor -%}
{%- set not_use = ns.not_use | unique | list -%}
{%- endif -%}
{# set variables #}
{%- set date, compare_date = date | as_local, compare_date | as_local -%}
{%- set parts = parts | int(1) -%}
{%- set time = time | bool(true) -%}
{%- set abbr = abbr | bool(false) or verbose | bool(false) -%}
{# split timedelta #}
{%- set time_parts = time_split(date, compare_date, time, not_use) | from_json -%}
{#- find first non zero time period #}
{%- set time_periods = ['year', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'] -%}
{%- set do_use = time_periods | reject('in', not_use) | list -%}
{# continue if there are still time periods to use #}
{%- if do_use | count > 0 -%}
{%- set always_return = do_use | last -%}
{%- set always_show = always_show if always_show is list else (always_show | replace(' ', '')).split(',') -%}
{%- if always_show | select('in', abbr_to_full) | list | count > 0 -%}
{%- set ns = namespace(always_show=[]) -%}
{%- for i in always_show -%}
{%- set ns.always_show = ns.always_show + [abbr_to_full[i] | default(i)] -%}
{%- endfor -%}
{%- set always_show = ns.always_show | unique | list -%}
{%- endif -%}
{%- set parts = [parts, always_show | count] | max -%}
{%- set to_show = (time_parts.items() | selectattr('1') | map(attribute='0') | list + always_show) | unique | list | default([always_return], true) -%}
{%- set first = do_use | select('in', to_show) | first -%}
{#-select itemw to show based on input #}
{%- set index_first = (time_parts.keys() | list).index(first) -%}
{%- set items = (time_parts.keys() | list)[index_first:index_first + parts] -%}
{# convert to phrases #}
{%- set ns = namespace(phrases=[]) -%}
{%- for i in items if i in to_show or i == first -%}
{%- set phr_abbr = phr[i][2] -%}
{%- set phr_verb = phr[i][1] if time_parts[i] != 1 else phr[i][0] -%}
{%- set phrase = '{} {}'.format(time_parts[i], phr_abbr if abbr else phr_verb) -%}
{%- set ns.phrases = ns.phrases + [phrase] -%}
{%- endfor -%}
{#- join phrases in a string, using phr.combine for the last item #}
{{- '{} {} {}'.format(ns.phrases[:-1] | join(', '), phr.combine, ns.phrases[-1]) if ns.phrases | count > 1 else ns.phrases | first -}}
{%- else -%}
All time periods are excluded
{%- endif -%}
{%- set abbr = abbr | bool(false) -%}
{# split timedelta #}
{%- set time_parts = time_split(date, parts, compare_date, not_use, always_show, time, round_mode) | from_json -%}
{# check for error #}
{%- if 'error' in time_parts -%}
{{- time_parts['error'] -}}
{%- else -%}
{{- phr.error -}}
{# convert to phrases #}
{%- set ns = namespace(phrases=[]) -%}
{%- for i in time_parts.keys() -%}
{%- set phr_abbr = phr[i][2] -%}
{%- set phr_verb = phr[i][1] if time_parts[i] != 1 else phr[i][0] -%}
{%- set phrase = '{} {}'.format(time_parts[i], phr_abbr if abbr else phr_verb) -%}
{%- set ns.phrases = ns.phrases + [phrase] -%}
{%- endfor -%}
{#- join phrases in a string, using phr.combine for the last item #}
{{- '{} {} {}'.format(ns.phrases[:-1] | join(', '), phr.combine, ns.phrases[-1]) if ns.phrases | count > 1 else ns.phrases | first -}}
{%- endif -%}
{%- endmacro -%}
{%- endmacro -%}

View File

@@ -107,12 +107,12 @@
{% if is_state('binary_sensor.san_francisco_49ers_inhibit','off') %}
{{ sports_pregame('sensor.san_francisco_49ers') }}
{% endif %}
{% if is_state('binary_sensor.cleveland_guardians_inhibit','off') %}
{{ sports_pregame('sensor.cleveland_guardians') }}
{% endif %}
{% if is_state('binary_sensor.minnesota_twins_inhibit','off') %}
{{ sports_pregame('sensor.minnesota_twins') }}
{% endif %}
{% if is_state('binary_sensor.cleveland_guardians_inhibit','off') %}
{{ sports_pregame('sensor.cleveland_guardians') }}
{% endif %}
{% if is_state('binary_sensor.los_angeles_dodgers_inhibit','off') %}
{{ sports_pregame('sensor.los_angeles_dodgers') }}
{% endif %}
@@ -135,12 +135,12 @@
{% if is_state('binary_sensor.san_francisco_49ers_inhibit','off') %}
{{ sports_main('sensor.san_francisco_49ers') }}
{% endif %}
{% if is_state('binary_sensor.cleveland_guardians_inhibit','off') %}
{{ sports_main('sensor.cleveland_guardians') }}
{% endif %}
{% if is_state('binary_sensor.minnesota_twins_inhibit','off') %}
{{ sports_main('sensor.minnesota_twins') }}
{% endif %}
{% if is_state('binary_sensor.cleveland_guardians_inhibit','off') %}
{{ sports_main('sensor.cleveland_guardians') }}
{% endif %}
{% if is_state('binary_sensor.los_angeles_dodgers_inhibit','off') %}
{{ sports_main('sensor.los_angeles_dodgers') }}
{% endif %}
@@ -152,4 +152,6 @@
{{ cleanup(data()) }}
{% endmacro %}
{{ sports_updates('pregame') }}
{% macro sports_datetime(team) %}
{{ as_timestamp(state_attr(team,'date')) | timestamp_custom('%Y-%m-%d %H:%M:%S') }}
{% endmacro%}

View File

@@ -68,6 +68,31 @@
{% endif %}
{% endmacro %}
{% macro datetime_from_calendar(calendar,start_or_end,action,operator,days,hours,minutes) %}
{% set base = as_timestamp(strptime(state_attr(calendar,start_or_end), '%Y-%m-%d %H:%M:%S')) | int %}
{% if minutes is defined %}
{% set mod = ((((days * 24) * 60) * 60) + (hours* 60) * 60) + (minutes * 60) | int %}
{% elif hours is defined %}
{% set mod = (((days * 24) * 60) * 60) + (hours* 60) * 60 | int %}
{% elif days is defined %}
{% set mod = ((days * 24) * 60) * 60 | int %}
{% endif %}
{% if action == 'set' %}
{% set ts = "%Y-%m-%d %H:%M:%S" %}
{% elif action == 'read' %}
{% set ts = "%Y-%m-%d %-I:%M %p" %}
{% endif %}
{% if operator is defined %}
{% if operator == 'add' %}
{{ (base + mod) | timestamp_custom(ts) }}
{% elif operator == 'subtract' %}
{{ (base - mod) | timestamp_custom(ts) }}
{% endif %}
{% else %}
{{ base | timestamp_custom(ts) }}
{% endif %}
{% endmacro %}
{% macro set_datetime(hours,minutes,seconds) %}
{% if seconds is defined %}
{{ (as_timestamp(now()) + (((hours * 60) * 60) + (minutes * 60)) + seconds) | int | timestamp_custom('%Y-%m-%d %H:%M:%S') }}

View File

@@ -0,0 +1,22 @@
name: Bug Report
about: Report a bug that you have found
title: "[Bug]: "
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
- type: markdown
attributes:
value: |
This issue was created by an issue **template**
visible: [content]
- type: textarea
id: what-happened
attributes:
label: What happened?
description: Also, what were you expecting to happen?
placeholder: Tell me what you saw!
value: "A bug happened!"
validations:
required: true

View File

@@ -987,8 +987,9 @@ script:
type: normal
message: Emma has awoken, so it is time to make your way upstairs now
- if:
- condition: template
value_template: "{{ is_state('binary_sensor.morning','on') or is_state('binary_sensor.midday','on') }}"
- condition: time
before: "18:00:00"
after: "07:00:00"
then:
- service: input_datetime.set_datetime
target:

View File

@@ -16,9 +16,15 @@ input_boolean:
kallen_late_bedtime:
name: Kallen Late Bedtime
icon: mdi:weather-night
kallen_morning_meds_reminder:
name: Kallen Morning Meds Reminder
icon: mdi:medication
kallen_morning_meds_taken:
name: Kallen Morning Meds Taken
icon: mdi:medication
kallen_night_meds_reminder:
name: Kallen Night Meds Reminder
icon: mdi:medication
kallen_night_meds_taken:
name: Kallen Night Meds Taken
icon: mdi:medication
@@ -67,12 +73,12 @@ input_datetime:
icon: mdi:medication
kallen_morning_meds_notify:
name: Kallen Morning Meds Notify
has_date: false
has_date: true
has_time: true
icon: mdi:medication
kallen_night_meds_notify:
name: Kallen Night Meds Notify
has_date: false
has_date: true
has_time: true
icon: mdi:medication
kallen_alarm_clock:

View File

@@ -984,7 +984,33 @@ script:
- critical
variables:
voice: "{{ states('input_select.jarvis_voice') }}"
groupname: >-
{% if who == 'kids_bedrooms' %}
kids_bedroom_speakers
{% elif who == 'all_bedrooms' %}
all_bedroom_speakers
{% elif who == 'basement' and is_state('input_boolean.studio_quiet','on') %}
alexa_no_basement
{% else %}
{{ who }}
{% endif %}
sequence:
- service: script.get_room_speakers
data:
room: "{{ who }}"
response_variable: "get_room_speakers"
- choose:
- conditions: "{{ who in ['everywhere','Everywhere'] }}"
sequence:
- service: script.get_all_speakers
response_variable: "get_all_speakers"
- conditions: "{{ get_room_speakers.jarvis_tts == 'group' }}"
sequence:
- service: script.get_group_speakers
data:
group: "{{ who }}"
response_variable: "get_group_speakers"
# Need to figure out whether to do this part here, or in alexa/jarvis voice scripts, or both
- service: mqtt.publish
data:
topic: 'house/polly/lastmsg'
@@ -1028,44 +1054,13 @@ script:
- service: >-
{% if voice == 'nabu' %}
script.nabu_voice
{% elif who in ['living_room_echo_dot', 'media_player.living_room_echo_dot','living_room','Living Room Echo Dot','Living Room'] %}
script.alexa_voice
{% elif who in ['kallen_bedroom','Kallen Bedroom'] %}
{% if is_state('input_boolean.kallen_sleeping','on') and type not in ['critical','Critical'] %}
script.alexa_voice
{% else %}
script.jarvis_voice
{% endif %}
{% elif who in ['emma_bedroom','Emma Bedroom'] %}
{% if is_state('input_boolean.emma_sleeping','on') and type not in ['critical','Critical'] %}
script.alexa_voice
{% else %}
script.jarvis_voice
{% endif %}
{% elif who in ['master_bedroom','master_bedroom_echo_dot','media_player.master_bedroom_echo_dot','Master Bedroom Echo Dot','Master Bedroom'] %}
script.alexa_voice
{% elif who in ['kids_bedrooms','Kids Bedrooms'] %}
script.jarvis_voice
{% elif who in ['all_bedrooms','All Bedrooms'] %}
script.alexa_voice
{% elif who in ['Basement','basement','basement_echo_dot','media_player.basement_echo_dot','Basement Echo Dot'] %}
script.alexa_voice
{% elif who in ['Basement Google','basement_google'] %}
{% if is_state('input_boolean.studio_quiet','on') %}
script.alexa_voice
{% else %}
script.jarvis_voice
{% endif %}
{% elif who in ['Common Areas','common','common_areas'] %}
script.alexa_voice
{% elif who in ['alexa_everywhere','Alexa Everywhere'] %}
script.alexa_voice
{% elif who in ['Everywhere','everywhere'] %}
{% elif get_room_services.jarvis_tts in ['group','alexa'] %}
script.alexa_voice
{% else %}
script.alexa_voice
script.jarvis_voice
{% endif %}
data:
# Work on where this redirect logic should go
who: >
{% if who in ['living_room_echo_dot', 'media_player.living_room_echo_dot','living_room','Living Room Echo Dot','Living Room'] %}
living_room
@@ -1142,7 +1137,7 @@ script:
type: '{{ type }}'
- if:
- condition: template
value_template: "{{ who in ['Everywhere','everywhere','all_bedrooms','All Bedrooms','kids_bedrooms','Kids Bedrooms'] }}"
value_template: "{{ get_room_speakers.jarvis_tts == 'group' and get_group_speakers.google is defined }}"
then:
- service: script.jarvis_voice
data:
@@ -1786,6 +1781,15 @@ script:
] | random }}
{%- endmacro -%}
{%- macro snark_shower_mode_window() -%}
{{ [
'Now that you have finished showering, you may want to consider shutting the upstairs bathroom window.',
'As there is no screen in the upstairs bathroom window, you should shut it to prevent bugs and other unwanted creatures from getting into the house.',
'Hey, you left the upstairs bathroom window open after your shower. Do something about that ASAP.',
'The second floor already has enough trouble maintaining temperature, please close the upstairs bathroom window after your shower.'
] | random }}
{%- endmacro -%}
{%- macro school_pickup_reminder() -%}
{{ [
'It is almost time to head to school ',
@@ -1943,7 +1947,11 @@ script:
{% endif %}
{% if call_snark_door_closed == 1 %}
{{ snark_door_closed () }}
{{ snark_door_closed() }}
{% endif %}
{% if call_snark_shower_mode_window == 1 %}
{{ snark_shower_mode_window() }}
{% endif %}
{% if call_school_pickup_reminder == 1 %}

View File

@@ -164,7 +164,7 @@ script:
time: >
{% from 'time.jinja' import time_from_calendar %}
{% if is_state('input_boolean.two_hour_delay','on') %}
10:00
{{ time_from_calendar('calendar.kallen_school_days','start_time','set','add',2)}}
{% else %}
{{ time_from_calendar('calendar.kallen_school_days','start_time','set') }}
{% endif %}
@@ -587,8 +587,9 @@ script:
entity_id: input_datetime.tina_morning_meds_notify
data:
time: >
{% from 'time.jinja' import datetime_from_calendar %}
{% if is_state('input_boolean.work_today','on') %}
{{ (state_attr('input_datetime.tina_workday_start','timestamp') | int - 1800) | timestamp_custom('%H:%M', false) }}
{{ datetime_from_calendar('calendar.family_tinawork','start_time','set','subtract',0,0,30) }}
{% else %}
{{ states('input_datetime.master_bedroom_wakeup') }}
{% endif %}

View File

@@ -3,6 +3,53 @@ input_boolean:
name: Sports Updates
icon: mdi:strategy
input_datetime:
michigan_wolverines_start:
name: Michigan Wolverines Start
has_date: true
has_time: true
icon: mdi:football
ohio_state_buckeyes_start:
name: Ohio State Buckeyes Start
has_date: true
has_time: true
icon: mdi:football
toledo_rockets_start:
name: Toledo Rockets Start
has_date: true
has_time: true
icon: mdi:football
minnesota_vikings_start:
name: Minnesota Vikings Start
has_date: true
has_time: true
icon: mdi:football
san_francisco_49ers_start:
name: San Francisco 49ers Start
has_date: true
has_time: true
icon: mdi:football
minnesota_twins_start:
name: Minnesota Twins Start
has_date: true
has_time: true
icon: mdi:baseball
cleveland_guardians_start:
name: Cleveland Guardians Start
has_date: true
has_time: true
icon: mdi:baseball
los_angeles_dodgers_start:
name: Los Angeles Dodgers Start
has_date: true
has_time: true
icon: mdi:baseball
minnesota_wild_start:
name: Minnesota Wild Start
has_date: true
has_time: true
icon: mdi:hockey-puck
template:
- binary_sensor:
- name: Michigan Wolverines Inhibit
@@ -55,16 +102,6 @@ template:
state: >
{% from 'sports.jinja' import sports_today %}
{{ sports_today('sensor.san_francisco_49ers') }}
- name: Cleveland Guardians Inhibit
unique_id: b0980d47-d762-4f23-97b1-9e88da729d8f
state: >
{% from 'sports.jinja' import sports_inhibit %}
{{ sports_inhibit('sensor.cleveland_guardians') }}
- name: Cleveland Guardians Event Today
unique_id: 985a7b2c-9ebd-4a2e-8ee2-2ab5359310e0
state: >
{% from 'sports.jinja' import sports_today %}
{{ sports_today('sensor.cleveland_guardians') }}
- name: Minnesota Twins Inhibit
unique_id: 2987ae95-f55d-4994-b9dd-018278d2f5ad
state: >
@@ -75,6 +112,16 @@ template:
state: >
{% from 'sports.jinja' import sports_today %}
{{ sports_today('sensor.minnesota_twins') }}
- name: Cleveland Guardians Inhibit
unique_id: b0980d47-d762-4f23-97b1-9e88da729d8f
state: >
{% from 'sports.jinja' import sports_inhibit %}
{{ sports_inhibit('sensor.cleveland_guardians') }}
- name: Cleveland Guardians Event Today
unique_id: 985a7b2c-9ebd-4a2e-8ee2-2ab5359310e0
state: >
{% from 'sports.jinja' import sports_today %}
{{ sports_today('sensor.cleveland_guardians') }}
- name: Los Angeles Dodgers Inhibit
unique_id: 2c6aae6e-eff6-46e5-bee9-311f9bbc0c0e
state: >

View File

@@ -7,9 +7,15 @@ input_boolean:
work_today_extended:
name: Work Today Extended
icon: mdi:briefcase-plus
tina_morning_meds_reminder:
name: Tina Morning Meds Reminder
icon: mdi:medication
tina_morning_meds_taken:
name: Tina Morning Meds Taken
icon: mdi:medication
tina_night_meds_reminder:
name: Tina Night Meds Reminder
icon: mdi:medication
tina_night_meds_taken:
name: Tina Night Meds Taken
icon: mdi:medication
@@ -35,7 +41,7 @@ input_datetime:
icon: mdi:medication
tina_morning_meds_notify:
name: Tina Morning Meds Notify
has_date: false
has_date: true
has_time: true
icon: mdi:medication
tina_night_meds_taken:
@@ -45,7 +51,7 @@ input_datetime:
icon: mdi:medication
tina_night_meds_notify:
name: Tina Night Meds Notify
has_date: false
has_date: true
has_time: true
icon: mdi:medication
@@ -103,78 +109,6 @@ automation:
data:
reason: "{{ reason }}"
- id: 513e33b8-a236-474b-a9cc-e40af36a052d
alias: Tina Meds Handler
description: Make sure Tina has taken her meds in the morning and at night
mode: parallel
max: 4
trigger:
- platform: time
at: input_datetime.tina_morning_meds_notify
id: wakeup
- platform: state
entity_id: input_boolean.tina_morning_meds_taken
to: 'on'
id: boolean-morning
- platform: time
at: input_datetime.tina_night_meds_notify
id: sleep
- platform: state
entity_id: input_boolean.tina_night_meds_taken
to: 'on'
id: boolean-night
action:
- choose:
- conditions:
- condition: and
conditions:
- condition: trigger
id: wakeup
- condition: state
entity_id: input_boolean.tina_morning_meds_taken
state: 'off'
sequence:
- service: script.turn_on
target:
entity_id: script.tina_morning_meds
- conditions:
- condition: trigger
id: boolean-morning
sequence:
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.tina_morning_meds_taken
data:
datetime: >
{% from 'time.jinja' import current_time %}
{{ current_time('datetime',24) }}
- conditions:
- condition: and
conditions:
- condition: trigger
id: sleep
- condition: state
entity_id: input_boolean.tina_night_meds_taken
state: 'off'
- condition: state
entity_id: input_boolean.master_bedroom_sleeping
state: 'off'
sequence:
- service: script.turn_on
target:
entity_id: script.tina_night_meds
- conditions:
- condition: trigger
id: boolean-night
sequence:
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.tina_night_meds_taken
data:
datetime: >
{% from 'time.jinja' import current_time %}
{{ current_time('datetime',24) }}
script:
tina_work_today:
alias: 'Tina Work Today'
@@ -263,165 +197,3 @@ script:
- service: script.master_bedroom_scheduling_evening
- service: script.emma_bedroom_scheduling_evening
- service: script.security_scheduling
tina_morning_meds:
alias: 'Tina Morning Meds'
icon: mdi:medication
mode: restart
sequence:
- service: script.text_notify
data:
who: tina
type: alert
title: Morning Meds
message: You need to take your morning meds
tag: tina-morning-meds
actions:
- action: "TINA_MORNING_MEDS_TAKEN"
title: Taken
- action: "TINA_MORNING_MEDS_SKIPPED"
title: Skip
- action: "TINA_MORNING_MEDS_ASK_LATER"
title: Ask Later
- wait_for_trigger:
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: "TINA_MORNING_MEDS_TAKEN"
id: taken
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: "TINA_MORNING_MEDS_SKIPPED"
id: skipped
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: "TINA_MORNING_MEDS_ASK_LATER"
id: ask-later
- platform: state
entity_id: person.christina_stork
from: 'home'
id: left
- platform: state
entity_id: input_boolean.tina_morning_meds_taken
to: 'on'
id: manual
timeout: "00:30:00"
continue_on_timeout: true
- choose:
- conditions: "{{ wait.trigger.id in ['taken','manual'] }}"
sequence:
- service: input_boolean.turn_on
target:
entity_id: input_boolean.tina_morning_meds_taken
- conditions: "{{ wait.trigger.id == 'ask-later' }}"
sequence:
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.tina_morning_meds_notify
data:
datetime: >
{% from 'time.jinja' import set_datetime %}
{{ set_datetime(0,30) }}
- conditions: "{{ wait.trigger.id == 'left' }}"
sequence:
- service: script.text_notify
data:
who: tina
type: alert
title: HEY DUMBASS
message: YOU FORGOT TO TAKE YOUR MORNING MEDS!!!!!
- conditions: "{{ wait.trigger == 'none' or wait.trigger.idx is undefined }}"
sequence:
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.tina_morning_meds_notify
data:
datetime: >
{% from 'time.jinja' import set_datetime %}
{{ set_datetime(0,1) }}
- service: script.text_notify
data:
type: alert
who: tina
message: clear_notification
tag: tina-morning-meds
tina_night_meds:
alias: 'Tina Night Meds'
icon: mdi:medication
mode: restart
sequence:
- service: script.text_notify
data:
who: tina
type: alert
title: Night Meds
message: You need to take your night meds
tag: tina-night-meds
actions:
- action: "TINA_NIGHT_MEDS_TAKEN"
title: Taken
- action: "TINA_NIGHT_MEDS_SKIPPED"
title: Skip
- action: "TINA_NIGHT_MEDS_ASK_LATER"
title: Ask Later
- wait_for_trigger:
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: "TINA_NIGHT_MEDS_TAKEN"
id: taken
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: "TINA_NIGHT_MEDS_SKIPPED"
id: skipped
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: "TINA_NIGHT_MEDS_ASK_LATER"
id: ask-later
- platform: state
entity_id: input_boolean.tina_night_meds_taken
to: 'on'
id: manual
- platform: state
entity_id:
- input_boolean.master_bedroom_sleeping
- input_boolean.goodnight
to: 'on'
id: sleeping
timeout: "00:30:00"
continue_on_timeout: true
- choose:
- conditions: "{{ wait.trigger.id in ['taken','manual'] }}"
sequence:
- service: input_boolean.turn_on
target:
entity_id: input_boolean.tina_night_meds_taken
- conditions: "{{ wait.trigger.id == 'ask-later' }}"
sequence:
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.tina_night_meds_notify
data:
datetime: >
{% from 'time.jinja' import set_datetime %}
{{ set_datetime(0,30) }}
- conditions: "{{ wait.trigger == 'none' or wait.trigger.idx is undefined }}"
sequence:
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.tina_night_meds_notify
data:
datetime: >
{% from 'time.jinja' import set_datetime %}
{{ set_datetime(0,1) }}
- service: script.text_notify
data:
type: alert
who: tina
message: clear_notification
tag: tina-night-meds

View File

@@ -4,12 +4,21 @@ input_boolean:
tony_streaming_today:
name: Tony Streaming Today
icon: mdi:twitch
tony_morning_meds_reminder:
name: Tony Morning Meds Reminder
icon: mdi:medication
tony_morning_meds_taken:
name: Tony Morning Meds Taken
icon: mdi:medication
tony_afternoon_meds_reminder:
name: Tony Afternoon Meds Reminder
icon: mdi:medication
tony_afternoon_meds_taken:
name: Tony Afternoon Meds Taken
icon: mdi:medication
tony_night_meds_reminder:
name: Tony Night Meds Reminder
icon: mdi:medication
tony_night_meds_taken:
name: Tony Night Meds Taken
icon: mdi:medication
@@ -64,17 +73,17 @@ input_datetime:
icon: mdi:medication
tony_morning_meds_notify:
name: Tony Morning Meds Notify
has_date: false
has_date: true
has_time: true
icon: mdi:medication
tony_afternoon_meds_notify:
name: Tony Afternoon Meds Notify
has_date: false
has_date: true
has_time: true
icon: mdi:medication
tony_night_meds_notify:
name: Tony Night Meds Notify
has_date: false
has_date: true
has_time: true
icon: mdi:medication
tony_custom_meds_taken_p1:
@@ -84,7 +93,7 @@ input_datetime:
icon: mdi:medication
tony_custom_meds_notify_p1:
name: Tony Custom Meds Notify P1
has_date: false
has_date: true
has_time: true
icon: mdi:medication
tony_custom_meds_taken_p2:
@@ -94,7 +103,7 @@ input_datetime:
icon: mdi:medication
tony_custom_meds_notify_p2:
name: Tony Custom Meds Notify P2
has_date: false
has_date: true
has_time: true
icon: mdi:medication
tony_ibuprofen_taken:
@@ -104,7 +113,7 @@ input_datetime:
icon: mdi:medication
tony_ibuprofen_notify:
name: Tony Ibuprofen Notify
has_date: false
has_date: true
has_time: true
icon: mdi:medication
tony_tylenol_taken:
@@ -114,7 +123,7 @@ input_datetime:
icon: mdi:medication
tony_tylenol_notify:
name: Tony Tylenol Notify
has_date: false
has_date: true
has_time: true
icon: mdi:medication
@@ -178,4 +187,34 @@ sensor:
json_attributes:
- project
- items
scan_interval: 30
scan_interval: 30
# template:
# - binary_sensor:
# - name: Tony Morning Meds Needed
# unique_id: 32f2f158-8c59-486e-bf85-f14909375ff7
# state: >
# {% set ct = as_timestamp(now()) %}
# {% set notify = state_attr('input_datetime.tony_morning_meds_notify','timestamp') %}
# {{ (ct >= notify) and is_state('input_boolean.tony_morning_meds_taken','off') }}
# attributes:
# reminder_time: "{{ states('input_datetime.tony_morning_meds_notify') }}"
# icon: mdi:medication
# - name: Tony Afternoon Meds Needed
# unique_id: 363b5ea0-3ad7-4e98-b0b0-5ff67bbef2f4
# state: >
# {% set ct = as_timestamp(now()) %}
# {% set notify = state_attr('input_datetime.tony_afternoon_meds_notify','timestamp') %}
# {{ (ct >= notify) and is_state('input_boolean.tony_afternoon_meds_taken','off') }}
# attributes:
# reminder_time: "{{ states('input_datetime.tony_afternoon_meds_notify') }}"
# icon: mdi:medication
# - name: Tony Night Meds Needed
# unique_id: b927b5a4-27a7-42aa-af4e-fa37a7036d25
# state: >
# {% set ct = as_timestamp(now()) %}
# {% set notify = state_attr('input_datetime.tony_night_meds_notify','timestamp') %}
# {{ (ct >= notify) and is_state('input_boolean.tony_night_meds_taken','off') }}
# attributes:
# reminder_time: "{{ states('input_datetime.tony_night_meds_notify') }}"
# icon: mdi:medication

126
packages/variables.yaml Normal file
View File

@@ -0,0 +1,126 @@
script:
get_room_speakers:
alias: Get Room Speakers
sequence:
- variables:
room_services: >-
{% if room in areas() %}
{% set alexa_speaker = states.media_player |
selectattr('entity_id', 'in', area_entities(room)) |
rejectattr('attributes.last_called', 'undefined') |
selectattr('entity_id', 'search', 'echo_dot') |
map(attribute='entity_id') |
list | first %}
{% set google_speaker = states.media_player |
selectattr('entity_id', 'in', area_entities(room)) |
rejectattr('attributes.device_class', 'undefined') |
selectattr('attributes.device_class', 'search', '(speaker)') |
selectattr('entity_id', 'search', 'google') |
map(attribute='entity_id') |
list | first %}
{% set tts = "alexa" if alexa_speaker is defined else "google" %}
{% else %}
{% set tts = "group" %}
{% endif %}
{"area":"{{room}}","alexa_speaker":"{{alexa_speaker|default({}) }}","jarvis_tts":"{{tts|default("google") }}","google_speaker":"{{google_speaker|default({}) }}"}
- stop: "Services acquired"
response_variable: "get_room_speakers"
get_group_speakers:
alias: Get Group Speakers
sequence:
- variables:
get_group_speakers: >-
{% set speakers = expand('group.' + group) | map(attribute='entity_id') | list | join(',') %}
{% set alexa_speakers = expand('group.' + group) |
rejectattr('attributes.last_called', 'undefined') |
selectattr('entity_id', 'search', 'echo_dot') |
map(attribute='entity_id') |
list | join(',') %}
{% set google_speakers = expand('group.' + group) |
rejectattr('attributes.device_class', 'undefined') |
selectattr('attributes.device_class', 'search', '(speaker)') |
selectattr('entity_id', 'search', 'google') |
map(attribute='entity_id') |
list | join(',') %}
{"alexa":"{{alexa_speakers|default({})}}","google":"{{google_speakers|default({})}}"}
- stop: "Speakers acquired"
response_variable: "get_group_speakers"
get_echo_dots:
alias: Get Echo Dots
sequence:
- variables:
get_echo_dots: >-
{% if group is defined %}
{% set speakers = expand('group.' + group) %}
{% else %}
{% set speakers = states.media_player %}
{% endif %}
{% set echo_dots = speakers |
rejectattr('attributes.last_called', 'undefined') |
selectattr('entity_id', 'search', 'echo_dot') |
map(attribute='entity_id') |
list | join(',') %}
{"speakers":"{{echo_dots}}"}
- stop: "Echo Dots acquired"
response_variable: "get_echo_dots"
get_google_speakers:
alias: Get Google Speakers
sequnce:
- variables:
get_google_speakers: >-
{% if group is defined %}
{% set speakers = expand('group.' + group) %}
{% else %}
{% set speakers = states.media_player %}
{% endif %}
{% set google_speaker = speakers |
rejectattr('attributes.device_class', 'undefined') |
selectattr('attributes.device_class', 'search', '(speaker)') |
selectattr('entity_id', 'search', 'google') |
map(attribute='entity_id') |
list | join(',') %}
{"speakers":"{{google_speaker}}"}
- stop: "Google speakers acquired"
response_variable: "get_google_speakers"
get_all_speakers:
alias: Get All Speakers
sequence:
- variables: >-
get_speakers:
{% set alexa_speaker = states.media_player |
rejectattr('attributes.last_called', 'undefined') |
selectattr('entity_id', 'search', 'echo_dot') |
map(attribute='entity_id')
%}
{% set google_speaker = states.media_player |
rejectattr('attributes.device_class', 'undefined') |
selectattr('attributes.device_class', 'search', '(speaker)') |
selectattr('entity_id', 'search', 'google') |
map(attribute='entity_id')
%}
{% set alexa_list = alexa_speaker | list | join(',') %}
{% set google_list = google_speaker | list | join(',') %}
{% set all_speakers = alexa_list + ',' + google_list %}
{"all_speakers":"{{all_speakers}}"}
get_room_lights:
alias: Get Room Lights
sequence:
- variables:
area: >
{{ room }}
entities: >
{% set lights = states.light |
selectattr('entity_id', 'in', area_entities(area)) |
map(attribute='entity_id') |
list | join(',') %}
{"lights":"{{lights}}"}
- stop: "Lights acquired"
response_variable: "entities"

View File

@@ -67,6 +67,9 @@ ## HACS Lovelace Cards
<details>
<summary>Click here</summary>
- [Bubble Card](https://github.com/Clooos/Bubble-Card)
- [Config Template Card](https://github.com/iantrich/config-template-card)
- [Decluttering Card](https://github.com/custom-cards/decluttering-card)
- [Card Tools](https://github.com/thomasloven/lovelace-card-tools) (required for various other cards)
- [Layout Card](https://github.com/thomasloven/lovelace-layout-card)
- [Scheduler Card](https://github.com/nielsfaber/scheduler-card) (required for Scheduler component)
@@ -79,22 +82,17 @@ ## HACS Lovelace Cards
- [Atomic Calendar Revive](https://github.com/totaldebug/atomic-calendar-revive)
- [Plotly Graph Card](https://github.com/dbuezas/lovelace-plotly-graph-card)
- [Mushroom](https://github.com/piitaya/lovelace-mushroom)
- [Todoist Card](https://github.com/tm24fan8/todoist-card)
- [Apexcharts Card](https://github.com/RomRider/apexcharts-card)
- [Auto Entities Card](https://github.com/thomasloven/lovelace-auto-entities)
- [Header Cards](https://github.com/gadgetchnnel/lovelace-header-cards)
- [Plex Meets Home Assistant](https://github.com/JurajNyiri/PlexMeetsHomeAssistant)
- [Slider Button Card](https://github.com/custom-cards/slider-button-card)
- [Weather Radar Card](https://github.com/Makin-Things/weather-radar-card)
- [Platinum Weather Card](https://github.com/Makin-Things/platinum-weather-card) (Not currently in use, but VERY nicely done)
- [Stack In Card](https://github.com/custom-cards/stack-in-card)
- [Canary](https://github.com/jcwillox/lovelace-canary)
- [Paper Buttons Row](https://github.com/jcwillox/lovelace-paper-buttons-row)
- [State Switch](https://github.com/thomasloven/lovelace-state-switch)
- [Multiple Entity Row](https://github.com/benct/lovelace-multiple-entity-row)
- [Weather Card](https://github.com/bramkragten/weather-card)
- [Template Entity Row](https://github.com/thomasloven/lovelace-template-entity-row)
- [Config Template Card](https://github.com/iantrich/config-template-card)
- [Canvas Gauge Card](https://github.com/custom-cards/canvas-gauge-card)
- [Datetime Card](https://github.com/a-p-z/datetime-card)
- [Waze Travel Time](https://github.com/r-renato/ha-card-waze-travel-time)
@@ -122,9 +120,7 @@ ## HACS Lovelace Cards
- [Windrose Card](https://github.com/aukedejong/lovelace-windrose-card)
- [Swipe Card](https://github.com/bramkragten/swipe-card)
- [Meteoalarm Card](https://github.com/MrBartusek/MeteoalarmCard)
- [Bubble Card](https://github.com/Clooos/Bubble-Card)
- [Weather Chart Card](https://github.com/mlamberts78/weather-chart-card)
- [Twitch Followed Live Streams Card](https://github.com/stefmde/HomeAssistant-TwitchFollowedLiveStreamsCard)
- [Comfortable Environment Card](https://github.com/argaar/comfortable-environment-card)
</details>

View File

@@ -1647,19 +1647,28 @@ tony_morning_meds:
icon: mdi:medication
mode: restart
sequence:
- parallel:
- if:
- condition: numeric_state
entity_id: counter.tony_morning_meds_reminder_count
above: 2
then:
- service: script.speech_engine
data:
who: common_areas
type: alert
message: Tony, you need to take your morning meds. This is reminder number
{{ states('counter.tony_morning_meds_reminder_count') }} for today.
- service: script.text_notify
- service: counter.increment
metadata: {}
data: {}
target:
entity_id: counter.tony_morning_meds_reminder_count
alias: Increment morning reminder counter
- service: script.text_notify
data:
type: alert
who: tony
message: clear_notification
tag: tony-morning-meds
alias: Clear previous morning notification
- delay:
hours: 0
minutes: 0
seconds: 5
milliseconds: 0
- alias: Send morning notifications via text, and TTS if needed
parallel:
- alias: Send text notification
service: script.text_notify
data:
who: tony
type: alert
@@ -1671,99 +1680,45 @@ tony_morning_meds:
title: Taken
- action: TONY_MORNING_MEDS_SKIPPED
title: Skip
- action: TONY_MORNING_MEDS_ASK_LATER
title: Ask Later
- wait_for_trigger:
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: TONY_MORNING_MEDS_TAKEN
id: taken
alias: Taken
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: TONY_MORNING_MEDS_SKIPPED
id: skipped
alias: Skipped
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: TONY_MORNING_MEDS_ASK_LATER
id: ask-later
alias: Ask Later
- platform: state
entity_id: person.tony_stork
from: home
id: left
alias: Left
- platform: state
entity_id: input_boolean.tony_morning_meds_taken
to: 'on'
id: manual
alias: Manual
timeout: 00:30:00
continue_on_timeout: true
- choose:
- conditions:
- condition: template
value_template: '{{ wait.trigger.id in [''taken'',''manual''] }}'
alias: Taken, Manual
sequence:
- service: input_boolean.turn_on
target:
entity_id: input_boolean.tony_morning_meds_taken
data: {}
- conditions:
- condition: template
value_template: '{{ wait.trigger.id == ''ask-later'' }}'
alias: Ask Later
sequence:
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.tony_morning_meds_notify
- alias: Send TTS if reminders > 2
if:
- condition: numeric_state
entity_id: counter.tony_morning_meds_reminder_count
above: 2
alias: When reminder count > 2
then:
- service: script.speech_engine
data:
datetime: '{% from ''time.jinja'' import set_datetime %} {{ set_datetime(0,30)
}}
'
- conditions:
- condition: template
value_template: '{{ wait.trigger.id == ''left'' }}'
alias: Left
sequence:
- service: script.text_notify
data:
who: tony
type: critical
title: HEY DUMBASS
message: YOU FORGOT TO TAKE YOUR MORNING MEDS!!!!!
- conditions:
- condition: template
value_template: '{{ wait.trigger == ''none'' or wait.trigger.idx is undefined
}}'
alias: None or undefined
sequence:
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.tony_morning_meds_notify
data:
datetime: '{% from ''time.jinja'' import set_datetime %} {{ set_datetime(0,1)
}}
'
- service: script.text_notify
data:
type: alert
who: tony
message: clear_notification
tag: tony-morning-meds
who: common_areas
type: alert
message: Tony, you need to take your morning meds. This is reminder number
{{ states('counter.tony_morning_meds_reminder_count') }} for today.
alias: Send TTS notification
tony_night_meds:
alias: Tony Night Meds
icon: mdi:medication
mode: restart
sequence:
- service: counter.increment
metadata: {}
data: {}
target:
entity_id: counter.tony_night_meds_reminder_count
alias: Increment night reminder counter
- service: script.text_notify
data:
type: alert
who: tony
message: clear_notification
tag: tony-night-meds
alias: Clear previous night notification
- delay:
hours: 0
minutes: 0
seconds: 5
milliseconds: 0
- alias: Send text notification
service: script.text_notify
data:
who: tony
type: alert
@@ -1775,87 +1730,6 @@ tony_night_meds:
title: Taken
- action: TONY_NIGHT_MEDS_SKIPPED
title: Skip
- action: TONY_NIGHT_MEDS_ASK_LATER
title: Ask Later
- wait_for_trigger:
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: TONY_NIGHT_MEDS_TAKEN
id: taken
alias: Taken
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: TONY_NIGHT_MEDS_SKIPPED
id: skipped
alias: Skipped
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: TONY_NIGHT_MEDS_ASK_LATER
id: ask-later
alias: Ask Later
- platform: state
entity_id: input_boolean.tony_night_meds_taken
to: 'on'
id: manual
alias: Manual
timeout: 00:30:00
continue_on_timeout: true
- choose:
- conditions:
- condition: template
value_template: '{{ wait.trigger.id in [''taken'',''manual''] }}'
alias: Taken, Manual
sequence:
- service: input_boolean.turn_on
target:
entity_id: input_boolean.tony_night_meds_taken
data: {}
- conditions:
- condition: template
value_template: '{{ wait.trigger.id == ''ask-later'' }}'
alias: Ask Later
sequence:
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.tony_night_meds_notify
data:
datetime: '{% from ''time.jinja'' import set_datetime %} {{ set_datetime(0,30)
}}
'
- conditions:
- condition: template
value_template: '{{ wait.trigger == ''none'' or wait.trigger.idx is undefined
}}'
alias: None or undefined
sequence:
- if:
- condition: and
conditions:
- condition: state
entity_id: person.tony_stork
state: home
- condition: state
entity_id: binary_sensor.morning
state: 'off'
then:
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.tony_night_meds_notify
data:
datetime: '{% from ''time.jinja'' import set_datetime %} {{ set_datetime(0,1)
}}
'
- service: script.text_notify
data:
type: alert
who: tony
message: clear_notification
tag: tony-night-meds
tony_stream_today:
alias: Tony Stream Today
sequence:
@@ -2004,20 +1878,31 @@ tony_custom_meds:
mode: parallel
tony_afternoon_meds:
alias: Tony Afternoon Meds
icon: mdi:medication
mode: restart
sequence:
- parallel:
- if:
- condition: numeric_state
entity_id: counter.tony_afternoon_meds_reminder_count
above: 2
then:
- service: script.speech_engine
data:
who: common_areas
type: alert
message: Tony, you need to take your afternoon meds. This is reminder number
{{ states('counter.tony_afternoon_meds_reminder_count') }} for today.
- service: script.text_notify
- service: counter.increment
metadata: {}
data: {}
target:
entity_id: counter.tony_afternoon_meds_reminder_count
alias: Increment afternoon reminder counter
- service: script.text_notify
data:
type: alert
who: tony
message: clear_notification
tag: tony-afternoon-meds
alias: Clear previous afternoon notification
- delay:
hours: 0
minutes: 0
seconds: 5
milliseconds: 0
- alias: Send afternoon notifications via text, and TTS if needed
parallel:
- alias: Send text notification
service: script.text_notify
data:
who: tony
type: alert
@@ -2029,97 +1914,20 @@ tony_afternoon_meds:
title: Taken
- action: TONY_AFTERNOON_MEDS_SKIPPED
title: Skip
- action: TONY_AFTERNOON_MEDS_ASK_LATER
title: Ask Later
- wait_for_trigger:
- alias: Taken
platform: event
event_type: ios.notification_action_fired
event_data:
actionName: TONY_AFTERNOON_MEDS_TAKEN
id: taken
- alias: Skipped
platform: event
event_type: ios.notification_action_fired
event_data:
actionName: TONY_AFTERNOON_MEDS_SKIPPED
id: skipped
- alias: Ask Later
platform: event
event_type: ios.notification_action_fired
event_data:
actionName: TONY_AFTERNOON_MEDS_ASK_LATER
id: ask-later
- platform: state
entity_id: person.tony_stork
from: home
id: left
alias: Left
- alias: Manual
platform: state
entity_id:
- input_boolean.tony_afternoon_meds_taken
to: 'on'
id: manual
from: 'off'
timeout: 00:30:00
continue_on_timeout: true
- choose:
- conditions:
- condition: template
value_template: '{{ wait.trigger.id in [''taken'',''manual''] }}'
alias: Taken, Manual
sequence:
- service: input_boolean.turn_on
data: {}
target:
entity_id: input_boolean.tony_afternoon_meds_taken
- conditions:
- condition: template
value_template: '{{ wait.trigger.id == ''ask-later'' }}'
alias: Ask Later
sequence:
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.tony_afternoon_meds_notify
- alias: Send TTS if reminders > 2
if:
- condition: numeric_state
entity_id: counter.tony_afternoon_meds_reminder_count
above: 2
alias: When reminder count > 2
then:
- service: script.speech_engine
data:
datetime: '{% from ''time.jinja'' import set_datetime %} {{ set_datetime(0,30)
}}
'
- conditions:
- condition: template
value_template: '{{ wait.trigger.id == ''left'' }}'
alias: Left
sequence:
- service: script.text_notify
data:
who: tony
type: critical
title: HEY DUMBASS
message: YOU FORGOT TO TAKE YOUR AFTERNOON MEDS!!!!!
- conditions:
- condition: template
value_template: '{{ wait.trigger == ''none'' or wait.trigger.idx is undefined
}}'
alias: None or undefined
sequence:
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.tony_afternoon_meds_notify
data:
datetime: '{% from ''time.jinja'' import set_datetime %} {{ set_datetime(0,1)
}}
'
- service: script.text_notify
data:
type: alert
who: tony
message: clear_notification
tag: tony-afternoon-meds
icon: mdi:medication
mode: restart
who: common_areas
type: alert
message: Tony, you need to take your afternoon meds. This is reminder number
{{ states('counter.tony_afternoon_meds_reminder_count') }} for today.
alias: Send TTS notification
tony_ibuprofen:
alias: Tony Ibuprofen
sequence:
@@ -2480,203 +2288,109 @@ tony_tylenol:
mode: queued
icon: mdi:medication
max: 10
'1710612011154':
kallen_morning_meds:
alias: Kallen Morning Meds
sequence:
- service: script.text_notify
data:
who: kallen
type: alert
title: Morning Meds
message: You need to take your morning meds. Go to mom or dad to confirm.
tag: kallen-morning-meds-self
- service: script.text_notify
data:
who: parents
type: alert
title: Morning Meds
message: Kallen needs to take his morning meds
tag: kallen-morning-meds-parents
actions:
- action: KALLEN_MORNING_MEDS_TAKEN
title: Taken
- action: KALLEN_MORNING_MEDS_SKIPPED
title: Skip
- action: KALLEN_MORNING_MEDS_ASK_LATER
title: Ask Later
- wait_for_trigger:
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: KALLEN_MORNING_MEDS_TAKEN
id: taken
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: KALLEN_MORNING_MEDS_SKIPPED
id: skipped
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: KALLEN_MORNING_MEDS_ASK_LATER
id: ask-later
- platform: state
entity_id: person.kallen_stork
from: home
id: left
- platform: state
entity_id: input_boolean.kallen_morning_meds_taken
to: 'on'
id: manual
timeout: 00:10:00
continue_on_timeout: true
- choose:
- conditions:
- condition: template
value_template: '{{ wait.trigger.id in [''taken'',''manual''] }}'
sequence:
- service: input_boolean.turn_on
target:
entity_id: input_boolean.kallen_morning_meds_taken
data: {}
- conditions:
- condition: template
value_template: '{{ wait.trigger.id == ''ask-later'' }}'
sequence:
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.kallen_morning_meds_notify
data:
datetime: '{% from ''time.jinja'' import set_datetime %} {{ set_datetime(0,5)
}}
'
- conditions:
- condition: template
value_template: '{{ wait.trigger.id == ''left'' or wait.trigger == ''none''
or wait.trigger.idx is undefined }}'
sequence:
- if:
- condition: state
entity_id: person.kallen_stork
state: home
then:
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.kallen_morning_meds_notify
data:
datetime: '{% from ''time.jinja'' import set_datetime %} {{ set_datetime(0,1)
}}
'
- service: script.text_notify
data:
type: alert
who: kallen
message: clear_notification
tag: kallen-morning-meds-parents
- service: script.text_notify
data:
type: alert
who: kallen
message: clear_notification
tag: kallen-morning-meds-self
- service: counter.increment
metadata: {}
data: {}
target:
entity_id: counter.kallen_morning_meds_reminder_count
alias: Increment morning reminder counter
- alias: Clear previous morning notifications
parallel:
- service: script.text_notify
data:
type: alert
who: parents
message: clear_notification
tag: kallen-morning-meds-parents
alias: Clear for parents
- service: script.text_notify
data:
type: alert
who: kallen
message: clear_notification
tag: kallen-morning-meds-self
alias: Clear for Kallen
- delay:
hours: 0
minutes: 0
seconds: 5
milliseconds: 0
- alias: Send text notifications
parallel:
- alias: Send to parents
service: script.text_notify
data:
who: parents
type: alert
title: Morning Meds
message: Kallen needs to take his morning meds
tag: kallen-morning-meds-parents
actions:
- action: KALLEN_MORNING_MEDS_TAKEN
title: Taken
- action: KALLEN_MORNING_MEDS_SKIPPED
title: Skip
- service: script.text_notify
data:
who: kallen
type: alert
title: Morning Meds
message: You need to take your morning meds. Go to mom or dad to confirm.
tag: kallen-morning-meds-self
alias: Send to Kallen
icon: mdi:medication
mode: restart
'1710612164315':
kallen_night_meds:
alias: Kallen Night Meds
sequence:
- service: script.text_notify
data:
who: kallen
type: alert
title: Night Meds
message: You need to take your night meds (melatonin)
tag: kallen-night-meds
actions:
- action: KALLEN_NIGHT_MEDS_TAKEN
title: Taken
- action: KALLEN_NIGHT_MEDS_SKIPPED
title: Skip
- action: KALLEN_NIGHT_MEDS_ASK_LATER
title: Ask Later
- service: script.text_notify
data:
who: "{% if states('person.christina_stork') in ['Bob Evans','BobEvans'] %}\n
\ tony\n{% else %}\n parents\n{% endif %}\n"
type: alert
title: Night Meds
message: Kallen needs to take his night meds (melatonin)
tag: kallen-night-meds
actions:
- action: KALLEN_NIGHT_MEDS_TAKEN
title: Taken
- action: KALLEN_NIGHT_MEDS_SKIPPED
title: Skip
- action: KALLEN_NIGHT_MEDS_ASK_LATER
title: Ask Later
- wait_for_trigger:
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: KALLEN_NIGHT_MEDS_TAKEN
id: taken
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: KALLEN_NIGHT_MEDS_SKIPPED
id: skipped
- platform: event
event_type: ios.notification_action_fired
event_data:
actionName: KALLEN_NIGHT_MEDS_ASK_LATER
id: ask-later
- platform: state
entity_id: input_boolean.kallen_night_meds_taken
to: 'on'
id: manual
timeout: 00:05:00
continue_on_timeout: true
- choose:
- conditions:
- condition: template
value_template: '{{ wait.trigger.id in [''taken'',''manual''] }}'
sequence:
- service: input_boolean.turn_on
target:
entity_id: input_boolean.kallen_night_meds_taken
data: {}
- conditions:
- condition: template
value_template: '{{ wait.trigger.id == ''ask-later'' }}'
sequence:
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.kallen_night_meds_notify
data:
datetime: '{% from ''time.jinja'' import set_datetime %} {{ set_datetime(0,15)
}}
'
- conditions:
- condition: template
value_template: '{{ wait.trigger == ''none'' or wait.trigger.idx is undefined
}}'
sequence:
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.kallen_night_meds_notify
data:
datetime: '{% from ''time.jinja'' import set_datetime %} {{ set_datetime(0,1)
}}
'
- service: counter.increment
metadata: {}
data: {}
alias: Increment night reminder counter
- service: script.text_notify
data:
type: alert
who: all
message: clear_notification
tag: kallen-night-meds
alias: Clear previous night notification
- delay:
hours: 0
minutes: 0
seconds: 5
milliseconds: 0
- parallel:
- service: script.text_notify
data:
who: "{% if states('person.christina_stork') in ['Bob Evans','BobEvans'] %}\n
\ tony\n{% else %}\n parents\n{% endif %}\n"
type: alert
title: Night Meds
message: Kallen needs to take his night meds (melatonin)
tag: kallen-night-meds
actions:
- action: KALLEN_NIGHT_MEDS_TAKEN
title: Taken
- action: KALLEN_NIGHT_MEDS_SKIPPED
title: Skip
alias: Send to parents
- alias: Send to Kallen
service: script.text_notify
data:
who: kallen
type: alert
title: Night Meds
message: You need to take your night meds (melatonin)
tag: kallen-night-meds
actions:
- action: KALLEN_NIGHT_MEDS_TAKEN
title: Taken
- action: KALLEN_NIGHT_MEDS_SKIPPED
title: Skip
alias: Send text notifications
icon: mdi:medication
mode: restart
reset_annc_switches:
@@ -3260,3 +2974,77 @@ emma_sleep:
alias: Turn on white noise
icon: mdi:lightbulb-night
mode: restart
tina_morning_meds:
alias: Tina Morning Meds
icon: mdi:medication
mode: restart
sequence:
- service: counter.increment
metadata: {}
data: {}
target:
entity_id: counter.tina_morning_meds_reminder_count
alias: Increment morning reminder counter
- service: script.text_notify
data:
type: alert
who: tina
message: clear_notification
tag: tina-morning-meds
alias: Clear previous morning notification
- delay:
hours: 0
minutes: 0
seconds: 5
milliseconds: 0
- alias: Send text notification
service: script.text_notify
data:
who: tina
type: alert
title: Morning Meds
message: You need to take your morning meds
tag: tina-morning-meds
actions:
- action: TINA_MORNING_MEDS_TAKEN
title: Taken
- action: TINA_MORNING_MEDS_SKIPPED
title: Skip
description: ''
tina_night_meds:
alias: Tina Night Meds
icon: mdi:medication
mode: restart
sequence:
- service: counter.increment
metadata: {}
data: {}
target:
entity_id: counter.tina_night_meds_reminder_count
alias: Increment night reminder counter
- service: script.text_notify
data:
type: alert
who: tina
message: clear_notification
tag: tina-night-meds
alias: Clear previous night notification
- delay:
hours: 0
minutes: 0
seconds: 5
milliseconds: 0
- alias: Send text notification
service: script.text_notify
data:
who: tina
type: alert
title: Night Meds
message: You need to take your night meds
tag: tina-night-meds
actions:
- action: TINA_NIGHT_MEDS_TAKEN
title: Taken
- action: TINA_NIGHT_MEDS_SKIPPED
title: Skip
description: ''