Compare commits

...

20 Commits

Author SHA1 Message Date
a1b68f80b6 Changes for new version of Bubble Cards 2025-05-08 21:35:45 -04:00
adc4bc9b42 Update .HA_VERSION 2025-05-08 21:35:08 -04:00
1500151c12 Handle Tina's meds resetting when she wakes up #243 2025-05-07 11:48:56 -04:00
67d1d3d43e Fix #241 2025-04-29 18:11:36 -04:00
1c5ccbb926 Update time macros 2025-04-29 18:06:31 -04:00
5d4457c198 Adjust MBR climate scheduling 2025-04-29 01:54:06 -04:00
d16a0f8353 Update scheduled reset for wife's night meds 2025-04-29 01:53:40 -04:00
c8242c2fea Update .HA_VERSION 2025-04-29 01:52:52 -04:00
713ddb9f75 Fix Emma's climate scheduling using old logic 2025-04-28 21:33:49 -04:00
10d7ec5e03 Account for overtime in sports reports 2025-04-28 21:33:33 -04:00
95ffb38b7e Exclude RSSI sensors from recorder 2025-04-28 21:32:50 -04:00
b5c295a19d Add config stuff for new default theme 2025-04-24 01:51:11 -04:00
bd9dde2455 Remove eco mode sensors for aircons as they are no longer needed 2025-04-24 01:32:52 -04:00
857870e0b1 Add a few more lights to monitor for unintended switching 2025-04-19 22:50:35 -04:00
003fe6614d Update .HA_VERSION 2025-04-19 22:19:38 -04:00
364c81e8b1 Use night volumes if people are sleeping
#238
2025-04-19 14:37:47 -04:00
0d42142a07 Simplify default speaker volume settings
#238
2025-04-19 14:30:41 -04:00
7d6d72c6ef Update eco mode sensors to reflect new Midea integration in use 2025-04-19 13:58:08 -04:00
41228c1304 Gotta actually CALL an entity to run a service on it...fix #216 2025-04-18 17:49:48 -04:00
b4f4d06d6c Fix scenes using deprecated Hue effect "None" 2025-04-18 17:32:20 -04:00
14 changed files with 1173 additions and 453 deletions

View File

@ -1 +1 @@
2025.4.2 2025.5.0

View File

@ -530,127 +530,126 @@
- id: '1667341156218' - id: '1667341156218'
alias: White Noise alias: White Noise
description: '' description: ''
trigger: triggers:
- platform: state - entity_id:
entity_id:
- input_boolean.white_noise_emma_bedroom - input_boolean.white_noise_emma_bedroom
to: 'on' to: 'on'
from: 'off' from: 'off'
id: emma-on id: emma-on
alias: Emma On alias: Emma On
- platform: state trigger: state
entity_id: - entity_id:
- input_boolean.white_noise_basement - input_boolean.white_noise_basement
to: 'on' to: 'on'
from: 'off' from: 'off'
id: basement-on id: basement-on
alias: Basement On alias: Basement On
- platform: state trigger: state
entity_id: - entity_id:
- input_boolean.white_noise_kallen_bedroom - input_boolean.white_noise_kallen_bedroom
to: 'on' to: 'on'
from: 'off' from: 'off'
id: kallen-on id: kallen-on
alias: Kallen On alias: Kallen On
- platform: state trigger: state
entity_id: - entity_id:
- input_boolean.white_noise_emma_bedroom - input_boolean.white_noise_emma_bedroom
from: 'on' from: 'on'
to: 'off' to: 'off'
id: emma-off id: emma-off
alias: Emma Off alias: Emma Off
- platform: state trigger: state
entity_id: - entity_id:
- input_boolean.white_noise_basement - input_boolean.white_noise_basement
from: 'on' from: 'on'
to: 'off' to: 'off'
id: basement-off id: basement-off
alias: Basement Off alias: Basement Off
- platform: state trigger: state
entity_id: - entity_id:
- input_boolean.white_noise_kallen_bedroom - input_boolean.white_noise_kallen_bedroom
from: 'on' from: 'on'
to: 'off' to: 'off'
id: kallen-off id: kallen-off
alias: Kallen Off alias: Kallen Off
trigger: state
- alias: Emma Timeout - alias: Emma Timeout
platform: state
id: emma-timeout id: emma-timeout
entity_id: entity_id:
- media_player.emma_bedroom_google_speaker - media_player.emma_bedroom_google_speaker
to: 'off' to: 'off'
trigger: state
- alias: Basement Timeout - alias: Basement Timeout
platform: state
id: basement-timeout id: basement-timeout
entity_id: entity_id:
- media_player.basement_google_speaker - media_player.basement_google_speaker
to: 'off' to: 'off'
trigger: state
- alias: Kallen Timeout - alias: Kallen Timeout
platform: state
id: kallen-timeout id: kallen-timeout
entity_id: entity_id:
- media_player.kallen_bedroom_google_speaker - media_player.kallen_bedroom_google_speaker
to: 'off' to: 'off'
condition: [] trigger: state
action: conditions: []
actions:
- choose: - choose:
- conditions: - conditions:
- condition: trigger - condition: trigger
id: emma-on id: emma-on
sequence: sequence:
- alias: Start river sounds - alias: Start river sounds
service: google_assistant_sdk.send_text_command
data: data:
command: give me river noise on emma bedroom speaker command: give me river noise on emma bedroom speaker
- service: media_player.volume_set action: google_assistant_sdk.send_text_command
data: - data:
volume_level: '{{ states(''input_number.emma_bedroom_google_speaker_night_volume'') volume_level: '{{ states(''sensor.emma_bedroom_google_speaker_volume'')
}}' }}'
target: target:
entity_id: media_player.emma_bedroom_google_speaker entity_id: media_player.emma_bedroom_google_speaker
alias: Set volume alias: Set volume
action: media_player.volume_set
alias: Emma On alias: Emma On
- conditions: - conditions:
- condition: trigger - condition: trigger
id: basement-on id: basement-on
sequence: sequence:
- service: google_assistant_sdk.send_text_command - data:
data:
command: give me thunderstorm sounds on basement studio speaker command: give me thunderstorm sounds on basement studio speaker
alias: Start thunderstorm sounds alias: Start thunderstorm sounds
- service: media_player.volume_set action: google_assistant_sdk.send_text_command
data: - data:
volume_level: '{{ states(''input_number.basement_google_speaker_night_volume'') volume_level: '{{ states(''sensor.basement_google_speaker_volume'') }}'
}}'
target: target:
entity_id: media_player.basement_google_speaker entity_id: media_player.basement_google_speaker
alias: Set volume alias: Set volume
action: media_player.volume_set
alias: Basement On alias: Basement On
- conditions: - conditions:
- condition: trigger - condition: trigger
id: kallen-on id: kallen-on
sequence: sequence:
- alias: Start river sounds - alias: Start river sounds
service: google_assistant_sdk.send_text_command
data: data:
command: give me river noise on kallen bedroom speaker command: give me river noise on kallen bedroom speaker
- service: media_player.volume_set action: google_assistant_sdk.send_text_command
data: - data:
volume_level: '{{ states(''input_number.kallen_bedroom_google_speaker_night_volume'') volume_level: '{{ states(''sensor.kallen_bedroom_google_speaker_volume'')
}}' }}'
target: target:
entity_id: media_player.kallen_bedroom_google_speaker entity_id: media_player.kallen_bedroom_google_speaker
alias: Set volume alias: Set volume
action: media_player.volume_set
alias: Kallen On alias: Kallen On
- conditions: - conditions:
- condition: trigger - condition: trigger
id: emma-off id: emma-off
sequence: sequence:
- service: media_player.turn_off - data: {}
data: {}
target: target:
entity_id: media_player.emma_bedroom_google_speaker entity_id: media_player.emma_bedroom_google_speaker
alias: Turn off speaker alias: Turn off speaker
action: media_player.turn_off
- alias: If Emma is awake, reset volume - alias: If Emma is awake, reset volume
if: if:
- condition: state - condition: state
@ -662,49 +661,44 @@
minutes: 0 minutes: 0
seconds: 5 seconds: 5
milliseconds: 0 milliseconds: 0
- service: media_player.volume_set - data:
data: volume_level: '{{ states(''sensor.emma_bedroom_google_speaker_volume'')
volume_level: "{% if is_state('input_boolean.give_me_darkness','on') %}\n }}'
\ {{ states('input_number.emma_bedroom_google_speaker_night_volume')
}}\n{% else %}\n {{ states('input_number.emma_bedroom_google_speaker_day_volume')
}}\n{% endif %}\n"
target: target:
entity_id: media_player.emma_bedroom_google_speaker entity_id: media_player.emma_bedroom_google_speaker
alias: Reset volume alias: Reset volume
action: media_player.volume_set
alias: Emma Off alias: Emma Off
- conditions: - conditions:
- condition: trigger - condition: trigger
id: basement-off id: basement-off
sequence: sequence:
- service: media_player.turn_off - data: {}
data: {}
target: target:
entity_id: media_player.basement_google_speaker entity_id: media_player.basement_google_speaker
alias: Turn off speaker alias: Turn off speaker
action: media_player.turn_off
- delay: - delay:
hours: 0 hours: 0
minutes: 0 minutes: 0
seconds: 5 seconds: 5
milliseconds: 0 milliseconds: 0
- service: media_player.volume_set - data:
data: volume_level: '{{ states(''sensor.basement_google_speaker_volume'') }}'
volume_level: "{% if is_state('input_boolean.give_me_darkness','on') %}\n
{{ states('input_number.basement_google_speaker_night_volume') }}\n{%
else %}\n {{ states('input_number.basement_google_speaker_day_volume')
}}\n{% endif %}\n"
target: target:
entity_id: media_player.basement_google_speaker entity_id: media_player.basement_google_speaker
alias: Reset volume alias: Reset volume
action: media_player.volume_set
alias: Basement Off alias: Basement Off
- conditions: - conditions:
- condition: trigger - condition: trigger
id: kallen-off id: kallen-off
sequence: sequence:
- service: media_player.turn_off - data: {}
data: {}
target: target:
entity_id: media_player.kallen_bedroom_google_speaker entity_id: media_player.kallen_bedroom_google_speaker
alias: Turn off speaker alias: Turn off speaker
action: media_player.turn_off
- alias: If Kallen is awake, reset volume - alias: If Kallen is awake, reset volume
if: if:
- condition: and - condition: and
@ -721,15 +715,13 @@
minutes: 0 minutes: 0
seconds: 5 seconds: 5
milliseconds: 0 milliseconds: 0
- service: media_player.volume_set - data:
data: volume_level: '{{ states(''sensor.kallen_bedroom_google_speaker_volume'')
volume_level: "{% if is_state('input_boolean.give_me_darkness','on') %}\n }}'
\ {{ states('input_number.kallen_bedroom_google_speaker_night_volume')
}}\n{% else %}\n {{ states('input_number.kallen_bedroom_google_speaker_day_volume')
}}\n{% endif %}\n"
target: target:
entity_id: media_player.kallen_bedroom_google_speaker entity_id: media_player.kallen_bedroom_google_speaker
alias: Reset volume alias: Reset volume
action: media_player.volume_set
alias: Kallen Off alias: Kallen Off
- conditions: - conditions:
- condition: trigger - condition: trigger
@ -749,16 +741,16 @@
seconds: 5 seconds: 5
milliseconds: 0 milliseconds: 0
- alias: Start river sounds - alias: Start river sounds
service: google_assistant_sdk.send_text_command
data: data:
command: give me river noise on emma bedroom speaker command: give me river noise on emma bedroom speaker
- service: media_player.volume_set action: google_assistant_sdk.send_text_command
data: - data:
volume_level: '{{ states(''input_number.emma_bedroom_google_speaker_night_volume'') volume_level: '{{ states(''sensor.emma_bedroom_google_speaker_volume'')
}}' }}'
target: target:
entity_id: media_player.emma_bedroom_google_speaker entity_id: media_player.emma_bedroom_google_speaker
alias: Set volume alias: Set volume
action: media_player.volume_set
alias: Emma Timeout alias: Emma Timeout
- conditions: - conditions:
- condition: trigger - condition: trigger
@ -778,16 +770,15 @@
seconds: 5 seconds: 5
milliseconds: 0 milliseconds: 0
- alias: Start thunderstorm sounds - alias: Start thunderstorm sounds
service: google_assistant_sdk.send_text_command
data: data:
command: give me thunderstorm sounds on basement studio speaker command: give me thunderstorm sounds on basement studio speaker
- service: media_player.volume_set action: google_assistant_sdk.send_text_command
data: - data:
volume_level: '{{ states(''input_number.basement_google_speaker_night_volume'') volume_level: '{{ states(''sensor.basement_google_speaker_volume'') }}'
}}'
target: target:
entity_id: media_player.basement_google_speaker entity_id: media_player.basement_google_speaker
alias: Set volume alias: Set volume
action: media_player.volume_set
alias: Basement Timeout alias: Basement Timeout
- conditions: - conditions:
- condition: trigger - condition: trigger
@ -807,16 +798,16 @@
seconds: 5 seconds: 5
milliseconds: 0 milliseconds: 0
- alias: Start river sounds - alias: Start river sounds
service: google_assistant_sdk.send_text_command
data: data:
command: give me river noise on kallen bedroom speaker command: give me river noise on kallen bedroom speaker
- service: media_player.volume_set action: google_assistant_sdk.send_text_command
data: - data:
volume_level: '{{ states(''input_number.kallen_bedroom_google_speaker_night_volume'') volume_level: '{{ states(''sensor.kallen_bedroom_google_speaker_volume'')
}}' }}'
target: target:
entity_id: media_player.kallen_bedroom_google_speaker entity_id: media_player.kallen_bedroom_google_speaker
alias: Set volume alias: Set volume
action: media_player.volume_set
alias: Kallen Timeout alias: Kallen Timeout
mode: parallel mode: parallel
max: 20 max: 20
@ -2641,100 +2632,100 @@
- id: '1696356974829' - id: '1696356974829'
alias: Scheduled Reset alias: Scheduled Reset
description: Reset all context entities for the next day at the appropriate times description: Reset all context entities for the next day at the appropriate times
trigger: triggers:
- platform: time - at: 00:00:00
at: 00:00:00
id: midnight id: midnight
- platform: time trigger: time
at: input_datetime.audible_notification_on - at: input_datetime.audible_notification_on
id: audible-on id: audible-on
- platform: time trigger: time
at: input_datetime.kallen_school_day_end - at: input_datetime.kallen_school_day_end
id: school-end id: school-end
- platform: state trigger: time
entity_id: sensor.twitch_ironnerd24 - entity_id: sensor.twitch_ironnerd24
from: streaming from: streaming
to: offline to: offline
id: stream-offline id: stream-offline
- platform: time trigger: state
at: 04:00:00 - at: 04:00:00
id: 4am id: 4am
- platform: time trigger: time
at: '16:00:00' - at: '12:00:00'
id: 4pm id: noon
- platform: time trigger: time
at: 06:00:00 - at: 06:00:00
id: 6am id: 6am
condition: [] trigger: time
action: conditions: []
actions:
- choose: - choose:
- conditions: - conditions:
- condition: trigger - condition: trigger
id: midnight id: midnight
sequence: sequence:
- service: script.scheduling_reset - data: {}
data: {} action: script.scheduling_reset
- service: script.kallen_school_reset_late - data: {}
data: {} action: script.kallen_school_reset_late
- service: automation.turn_on - target:
target:
entity_id: entity_id:
- automation.scheduled_alarm_rearm - automation.scheduled_alarm_rearm
- automation.scheduled_alarm_disarm - automation.scheduled_alarm_disarm
data: {} data: {}
- service: input_boolean.turn_off action: automation.turn_on
target: - target:
entity_id: entity_id:
- input_boolean.skip_disarm - input_boolean.skip_disarm
- input_boolean.skip_rearm - input_boolean.skip_rearm
data: {} data: {}
- service: counter.reset action: input_boolean.turn_off
target: - target:
entity_id: entity_id:
- counter.back_door_opened_today - counter.back_door_opened_today
- counter.front_door_opened_today - counter.front_door_opened_today
- counter.basement_studio_door_opened_today - counter.basement_studio_door_opened_today
- counter.basement_led_strip_resets - counter.basement_led_strip_resets
data: {} data: {}
action: counter.reset
- conditions: - conditions:
- condition: trigger - condition: trigger
id: id:
- audible-on - audible-on
sequence: sequence:
- service: script.reset_annc_switches - data: {}
data: {} action: script.reset_annc_switches
- conditions: - conditions:
- condition: trigger - condition: trigger
id: school-end id: school-end
sequence: sequence:
- service: script.kallen_school_reset - data: {}
data: {} action: script.kallen_school_reset
- conditions: - conditions:
- condition: trigger - condition: trigger
id: stream-offline id: stream-offline
sequence: sequence:
- service: input_boolean.turn_off - target:
target:
entity_id: input_boolean.tony_streaming_today entity_id: input_boolean.tony_streaming_today
data: {} data: {}
action: input_boolean.turn_off
- conditions: - conditions:
- condition: trigger - condition: trigger
id: 4am id: 4am
sequence: sequence:
- service: input_boolean.turn_off - target:
target:
entity_id: entity_id:
- input_boolean.kallen_morning_meds_taken - input_boolean.kallen_morning_meds_taken
- input_boolean.kallen_night_meds_taken - input_boolean.kallen_night_meds_taken
- input_boolean.tina_morning_meds_taken - input_boolean.tina_morning_meds_taken
- input_boolean.emma_scheduling_evening_ran - input_boolean.emma_scheduling_evening_ran
data: {} data: {}
- service: counter.reset action: input_boolean.turn_off
target: - target:
entity_id: entity_id:
- counter.tony_morning_meds_reminder_count - counter.tony_morning_meds_reminder_count
- counter.tony_afternoon_meds_reminder_count - counter.tony_afternoon_meds_reminder_count
data: {} data: {}
action: counter.reset
- conditions: - conditions:
- condition: trigger - condition: trigger
id: 6am id: 6am
@ -2744,19 +2735,16 @@
entity_id: sensor.twitch_ironnerd24 entity_id: sensor.twitch_ironnerd24
state: offline state: offline
then: then:
- service: input_boolean.turn_off - target:
target:
entity_id: input_boolean.tony_streaming_today entity_id: input_boolean.tony_streaming_today
data: {} data: {}
action: input_boolean.turn_off
- conditions: - conditions:
- condition: trigger - condition: trigger
id: 4pm id:
- noon
sequence: sequence:
- service: input_boolean.turn_off - stop: No current actions scheduled at noon, remove this action if this changes
target:
entity_id:
- input_boolean.tina_night_meds_taken
data: {}
mode: restart mode: restart
- id: '1696361494561' - id: '1696361494561'
alias: Turn On Audible Notifications alias: Turn On Audible Notifications
@ -6121,3 +6109,67 @@
entity_id: input_boolean.emma_awake entity_id: input_boolean.emma_awake
alias: Turn on Emma Awake alias: Turn on Emma Awake
mode: restart mode: restart
- id: '1746632520108'
alias: Tina Sleep Handling
description: Awareness of when Tina is asleep or wakes up
triggers:
- alias: Leave Home
entity_id: person.christina_stork
zone: zone.home
event: leave
id: wake-leave
trigger: zone
- alias: Sentence
command:
- Tina is awake
- Christina is awake
id: wake-sentence
trigger: conversation
- alias: Focus off
entity_id:
- binary_sensor.tinas_iphone_focus
from: 'on'
to: 'off'
for:
hours: 0
minutes: 0
seconds: 30
id: wake-focus
trigger: state
conditions: []
actions:
- alias: Routing
choose:
- conditions:
- condition: and
conditions:
- alias: Wakeup
condition: trigger
id:
- wake-sentence
- wake-focus
- wake-leave
- condition: state
entity_id: input_boolean.tina_awake
state: 'off'
alias: Wakeup Trigger
sequence:
- delay:
hours: 0
minutes: 0
seconds: 5
milliseconds: 0
- alias: Set context that Tina is awake
data: {}
action: input_boolean.turn_on
target:
entity_id: input_boolean.tina_awake
- action: input_boolean.turn_off
metadata: {}
data: {}
target:
entity_id:
- input_boolean.tina_morning_meds_taken
- input_boolean.tina_night_meds_taken
alias: Reset Tina meds taken switches
mode: restart

View File

@ -32,8 +32,16 @@ frontend:
extra_module_url: extra_module_url:
- /hacsfiles/hass-hue-icons/hass-hue-icons.js - /hacsfiles/hass-hue-icons/hass-hue-icons.js
- /hacsfiles/hass-bha-icons/hass-bha-icons.js - /hacsfiles/hass-bha-icons/hass-bha-icons.js
- /hacsfiles/material-you-utilities/material-you-utilities.min.js
javascript_version: latest javascript_version: latest
panel_custom:
- name: material-you-panel
url_path: material-you-configuration
sidebar_title: Material You Utilities
sidebar_icon: mdi:material-design
module_url: /hacsfiles/material-you-utilities/material-you-utilities.min.js
http: http:
use_x_forwarded_for: true use_x_forwarded_for: true
trusted_proxies: trusted_proxies:
@ -107,6 +115,7 @@ recorder:
- sensor.*gpu_core_load - sensor.*gpu_core_load
- sensor.portainer* - sensor.portainer*
- sensor.mosquitto* - sensor.mosquitto*
- sensor.*_rssi
entities: entities:
- sensor.avg_ping - sensor.avg_ping
- sensor.max_ping - sensor.max_ping

View File

@ -79,7 +79,7 @@
45: 'quarter to {hour}', 45: 'quarter to {hour}',
59: 'a minute to {hour}', 59: 'a minute to {hour}',
'past_hour': '{minute} past {hour}', 'past_hour': '{minute} past {hour}',
'to_hour': '{minute} to {hour}', 'to_hour': '{minute} to {hour}',
}, },
'time_of_day':{ 'time_of_day':{
'midnight': 'midnight', 'midnight': 'midnight',
@ -157,7 +157,7 @@
'November', 'November',
'December', 'December',
] ]
}, },
'nl':{ 'nl':{
'_language': 'Nederlands', '_language': 'Nederlands',
'and': 'en', 'and': 'en',
@ -203,6 +203,8 @@
'today': 'vandaag', 'today': 'vandaag',
'tomorrow': 'morgen', 'tomorrow': 'morgen',
'yesterday': 'gisteren', 'yesterday': 'gisteren',
'next': 'volgende',
'last': 'afgelopen',
}, },
'days':[ 'days':[
"maandag", "maandag",
@ -226,12 +228,30 @@
'oktober', 'oktober',
'november', 'november',
'december', 'december',
] ],
'time_of_hour':{
0: '{hour} uur',
1: '1 over {hour}',
15: 'kwart over {hour}',
30: 'half {hour}',
45: 'kwart voor {hour}',
59: '1 voor {hour}',
'past_hour': '{minute} over {hour}',
'to_hour': '{minute} voor {hour}',
'to_half_hour': '{minute} voor half {hour}',
'past_half_hour': '{minute} over half {hour}',
'half_hour': 'half {hour}',
'use_twelve': true,
},
'time_of_day':{
'midnight': 'middernacht',
'noon': 'middag',
},
}, },
'sv':{ 'sv':{
'_language': 'Svenska', '_language': 'Svenska',
'and': 'och', 'and': 'och',
'in': 'i', 'in': 'om',
'ago': 'sedan', 'ago': 'sedan',
'now': 'nu', 'now': 'nu',
'lose': 'förlora', 'lose': 'förlora',
@ -273,6 +293,7 @@
'today': 'idag', 'today': 'idag',
'tomorrow': 'imorgon', 'tomorrow': 'imorgon',
'yesterday': 'igår', 'yesterday': 'igår',
'next': 'nästa',
}, },
'days':[ 'days':[
"måndag", "måndag",
@ -302,7 +323,7 @@
'_language': 'Deutsch', '_language': 'Deutsch',
'and': 'und', 'and': 'und',
'in': 'in', 'in': 'in',
'ago': 'vor', 'ago': 'vor %s',
'now': 'jetzt', 'now': 'jetzt',
'lose': 'Du verlierst', 'lose': 'Du verlierst',
'gain': 'Du gewinnst', 'gain': 'Du gewinnst',
@ -363,7 +384,7 @@
'Juli', 'Juli',
'August', 'August',
'September', 'September',
'October', 'Oktober',
'November', 'November',
'Dezember', 'Dezember',
] ]
@ -623,6 +644,8 @@
'today': "aujourd'hui", 'today': "aujourd'hui",
'tomorrow': 'demain', 'tomorrow': 'demain',
'yesterday': 'hier', 'yesterday': 'hier',
'next': 'prochain',
'last': 'dernier',
}, },
'days':[ 'days':[
"lundi", "lundi",
@ -693,6 +716,8 @@
'today': 'hoy', 'today': 'hoy',
'tomorrow': 'mañana', 'tomorrow': 'mañana',
'yesterday': 'ayer', 'yesterday': 'ayer',
'next': 'el próximo',
'last': 'el pasado',
}, },
'days':[ 'days':[
'lunes', 'lunes',
@ -711,12 +736,26 @@
'mayo', 'mayo',
'junio', 'junio',
'julio', 'julio',
'agosto' 'agosto',
'septiembre', 'septiembre',
'octubre', 'octubre',
'noviembre', 'noviembre',
'diciembre' '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':{ 'it':{
'_language': 'Italiano', '_language': 'Italiano',
@ -865,9 +904,9 @@
'and': 'i', 'and': 'i',
'in': 'u', 'in': 'u',
'ago': 'prije', 'ago': 'prije',
'now': 'sad', 'now': 'sada',
'lose': 'gubiš', 'lose': 'gubiš',
'gain': 'dobijaš', 'gain': 'dobivaš',
'time':{ 'time':{
'format': '24-hr', 'format': '24-hr',
'year': [ 'year': [
@ -905,8 +944,8 @@
'today': 'danas', 'today': 'danas',
'tomorrow': 'sutra', 'tomorrow': 'sutra',
'yesterday': 'jučer', 'yesterday': 'jučer',
'next': 'slijedeći', 'next': 'sljedeći',
'last': 'prošli', 'last': 'protekli',
}, },
'days':[ 'days':[
"Ponedjeljak", "Ponedjeljak",
@ -1003,11 +1042,421 @@
'Listopad', 'Listopad',
'Grudzień', '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': 'полдень',
},
},
'uk':{
'_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} годин(а) одна хвилина',
15: 'чверть на {hour}',
30: 'пів на {hour}',
45: 'за чверть {hour}',
59: 'за хвилину {hour}',
'past_hour': '{hour} та {minute} хвилин',
'to_hour': 'за {minute} хвилин {hour}',
},
'time_of_day':{
'midnight': 'опівночі',
'noon': 'опівдні',
},
},
'zh-Hans':{
'_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_day':{
'midnight': '午夜',
'noon': '正午',
},
},
'ko':{
'_language':'Korean',
'and':'',
'in':'후',
'ago':'전',
'now':'지금',
'lose':'감소',
'gain':'증가',
'time':{
'format':'24-hr',
'year':[
'년',
'년',
'년',
],
'week':[
'주',
'주',
'주',
],
'day':[
'일',
'일',
'일',
],
'hour':[
'시',
'시간',
'시간',
],
'minute':[
'분',
'분',
'분',
],
'second':[
'초',
'초',
'초',
],
},
'delta':{
'today':'오늘',
'tomorrow':'내일',
'yesterday':'어제',
'next':'다음',
'last':'지난',
},
'days':[
'월요일',
'화요일',
'수요일',
'목요일',
'금요일',
'토요일',
'일요일',
],
'months':[
'1월',
'2월',
'3월',
'4월',
'5월',
'6월',
'7월',
'8월',
'9월',
'10월',
'11월',
'12월',
],
'time_of_day':{
'midnight':'자정',
'noon':'정오',
},
},
'cs': {
'_language': 'Čeština',
'and': 'a',
'in': 'za',
'ago': 'před %s',
'now': 'nyní',
'lose': 'ztratit',
'gain': 'získat',
'time': {
'format': '12-hodin',
'year': [
'rok',
'rok',
'roky'
],
'week': [
'týd',
'týden',
'týdny'
],
'day': [
'd',
'den',
'dny'
],
'hour': [
'hod',
'hodina',
'hodiny'
],
'minute': [
'min',
'minuta',
'minuty'
],
'second': [
'sek',
'sekunda',
'sekundy'
]
},
'delta': {
'today': 'dnes',
'tomorrow': 'zítra',
'yesterday': 'včera',
'next': 'příští',
'last': 'poslední'
},
'days': [
'Pondělí',
'Úterý',
'Středa',
'Čtvrtek',
'Pátek',
'Sobota',
'Neděle'
],
'months': [
'Leden',
'Únor',
'Březen',
'Duben',
'Květen',
'Červen',
'Červenec',
'Srpen',
'Září',
'Říjen',
'Listopad',
'Prosinec'
],
'time_of_hour': {
0: '{hour} hodin',
1: 'minuta po {hour}',
15: 'čtvrt na {hour}',
30: 'půl {hour}',
45: 'tři čtvrtě na {hour}',
59: 'minuta do {hour}',
'past_hour': '{minute} po {hour}',
'to_hour': '{minute} do {hour}'
},
'time_of_day': {
'midnight': 'půlnoc',
'noon': 'poledne'
}
} }
} %} } %}
{# DO NOT MODIFY BELOW THIS LINE #} {# DO NOT MODIFY BELOW THIS LINE #}
{% set valid_entity_id_pattern = '^(?!.+__)(?!_)[\\da-z_]+(?<!_)\\.(?!_)[\\da-z_]+(?<!_)$' %}
{% set _bad_value = '?' %} {% set _bad_value = '?' %}
{% set _durations = { {% set _durations = {
'year': 31536000, 'year': 31536000,
@ -1091,10 +1540,10 @@
{%- endmacro -%} {%- endmacro -%}
{%- macro _check_for_duration_sensor(input) %} {%- macro _check_for_duration_sensor(input) %}
{%- if input is string and input | regex_search('^(?!.+__)(?!_)[\da-z_]+(?<!_)\.(?!_)[\da-z_]+(?<!_)$') and input.startswith('sensor') and states[input] is not none and states[input].attributes.device_class is defined and states[input].attributes.unit_of_measurement is defined -%} {%- if input is string and input | regex_search(valid_entity_id_pattern) and input.startswith('sensor') and states[input] is not none and states[input].attributes.device_class is defined and states[input].attributes.unit_of_measurement is defined -%}
{%- set obj = states[input] -%} {%- set obj = states[input] -%}
{%- set divisor = _duration_sensor.get(obj.attributes.unit_of_measurement) -%} {%- set multiplier = _duration_sensor.get(obj.attributes.unit_of_measurement) -%}
{{- (obj.state | float / divisor) | string | as_timedelta -}} {{- (obj.state | float * multiplier) | string | as_timedelta -}}
{%- else %} {%- else %}
{{- '' -}} {{- '' -}}
{%- endif -%} {%- endif -%}
@ -1116,7 +1565,7 @@
{#- assume time as string or entity_id -#} {#- assume time as string or entity_id -#}
{%- elif input is string and input not in ['', 'None'] -%} {%- elif input is string and input not in ['', 'None'] -%}
{#- if entity_id -#} {#- if entity_id -#}
{%- if input | regex_search('^(?!.+__)(?!_)[\da-z_]+(?<!_)\.(?!_)[\da-z_]+(?<!_)$') -%} {%- if input | regex_search(valid_entity_id_pattern) -%}
{%- if attribute is not none and attribute is string -%} {%- if attribute is not none and attribute is string -%}
{{- _to_datetime(state_attr(input, attribute), None) -}} {{- _to_datetime(state_attr(input, attribute), None) -}}
{%- elif input.startswith('input_datetime') and is_state_attr(input, 'has_date', False) -%} {%- elif input.startswith('input_datetime') and is_state_attr(input, 'has_date', False) -%}
@ -1201,7 +1650,7 @@
{%- set index = values.index(values | first | default) %} {%- set index = values.index(values | first | default) %}
{%- for item in values[index:] %} {%- for item in values[index:] %}
{%- set duration = _durations.get(item, 1) %} {%- set duration = _durations.get(item, 1) %}
{%- set period = _periods.get(item, 1) %} {%- set period = _periods.get(item, 0) %}
{%- set value = ((seconds // duration) % (period if period else duration)) | int %} {%- set value = ((seconds // duration) % (period if period else duration)) | int %}
{%- if value > 0 or raw %} {%- if value > 0 or raw %}
{%- if ns.ret | length == 0 %} {%- if ns.ret | length == 0 %}
@ -1252,8 +1701,8 @@
{%- endmacro %} {%- endmacro %}
{%- macro _time_between(func, input1, attr1, utc1, input2, attr2, utc2) -%} {%- macro _time_between(func, input1, attr1, utc1, input2, attr2, utc2) -%}
{%- set t1 = _to_datetime(input1, attr1, utc1) | as_datetime -%} {%- set t1 = _to_datetime(input1, attr1, utc1) | as_datetime | as_local -%}
{%- set t2 = _to_datetime(input2, attr2, utc2) | as_datetime -%} {%- set t2 = _to_datetime(input2, attr2, utc2) | as_datetime | as_local -%}
{%- if t1 is not none and t2 is not none -%} {%- if t1 is not none and t2 is not none -%}
{{- func(t1, t2) -}} {{- func(t1, t2) -}}
{%- else -%} {%- else -%}
@ -1320,9 +1769,12 @@
{%- if uptime %} {%- if uptime %}
{%- set value = _delta_seconds(now(), uptime) | int %} {%- set value = _delta_seconds(now(), uptime) | int %}
{%- set seconds = value | abs %} {%- set seconds = value | abs %}
{%- set future = value / seconds > 0 %} {%- set current = value == 0 %}
{%- set future = not current and value / seconds > 0 %}
{%- set items = _just_time(seconds, language, values, biggest, short=short, floor=floor) %} {%- set items = _just_time(seconds, language, values, biggest, short=short, floor=floor) %}
{%- if future %} {%- if current %}
{{- items }}
{%- elif future %}
{{- translate('in', language=language) }} {{ items }} {{- translate('in', language=language) }} {{ items }}
{%- else %} {%- else %}
{%- set t = translate('ago', language=language) %} {%- set t = translate('ago', language=language) %}
@ -1411,6 +1863,16 @@
{{- _next_weekday(weekday, -7) }} {{- _next_weekday(weekday, -7) }}
{%- endmacro %} {%- endmacro %}
{%- macro nearest_day(weekday) %}
{%- set today_timestamp = as_timestamp(today_at())|int %}
{%- set this_weekday_timestamp = as_timestamp(this_weekday(weekday))|int %}
{%- if today_timestamp < this_weekday_timestamp %}
{{- _next_weekday(weekday, 0) }}
{%- else %}
{{- _next_weekday(weekday, 7) }}
{%- endif %}
{%- endmacro %}
{%- macro days_in_month(month=None) %} {%- macro days_in_month(month=None) %}
{%- set today = today_at() %} {%- set today = today_at() %}
{%- set input = month if month is not none else today.month %} {%- set input = month if month is not none else today.month %}
@ -1527,30 +1989,36 @@
{%- endif -%} {%- endif -%}
{%- endmacro -%} {%- endmacro -%}
{%- macro month(month=None, language=None) %} {%- macro month(month=None, language=None, short=False) %}
{%- if month is datetime %} {%- if month is datetime %}
{%- set idx = month.month - 1 %} {%- set idx = month.month - 1 %}
{%- elif month is integer and month > 0 %} {%- elif month is integer and month > 0 %}
{%- set idx = (month - 1) % 12 %} {%- set idx = (month - 1) % 12 %}
{%- elif month | regex_match(valid_entity_id_pattern) %}
{%- set idx = (states(month) | as_datetime | as_local).month - 1 %}
{%- else %} {%- else %}
{%- set idx = now().month - 1 %} {%- set idx = now().month - 1 %}
{%- endif %} {%- endif %}
{{- translate('months', index=idx, language=language) }} {%- set ret = translate('months', index=idx, language=language) %}
{{- ret[:3] if short else ret }}
{%- endmacro %} {%- endmacro %}
{%- macro weekday(weekday=None, language=None) %} {%- macro weekday(weekday=None, language=None, short=False) %}
{%- if weekday is datetime %} {%- if weekday is datetime %}
{%- set idx = weekday.weekday() %} {%- set idx = weekday.weekday() %}
{%- elif weekday is integer and weekday > 0 %} {%- elif weekday is integer and weekday > 0 %}
{%- set idx = (weekday - 1) % 7 %} {%- set idx = (weekday - 1) % 7 %}
{%- elif weekday | regex_match(valid_entity_id_pattern) %}
{%- set idx = (states(weekday) | as_datetime | as_local).weekday() %}
{%- else %} {%- else %}
{%- set idx = now().weekday() %} {%- set idx = now().weekday() %}
{%- endif %} {%- endif %}
{{- translate('days', index=idx, language=language) }} {%- set ret = translate('days', index=idx, language=language) %}
{{- ret[:3] if short else ret }}
{%- endmacro %} {%- endmacro %}
{%- macro count_the_days(input, attr, utc=False) %} {%- macro count_the_days(input, attr, utc=False) %}
{%- set input = _to_datetime(input, attr, utc) | as_datetime %} {%- set input = _to_datetime(input, attr, utc) | as_datetime | as_local %}
{%- set midnight = today_at() %} {%- set midnight = today_at() %}
{{- (input - midnight).days }} {{- (input - midnight).days }}
{%- endmacro %} {%- endmacro %}
@ -1561,7 +2029,7 @@
{%- set ns = namespace(days=[]) %} {%- set ns = namespace(days=[]) %}
{%- for i in range(-7, 14) %} {%- 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 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 + 1, language))) ] %} {%- set ns.days = ns.days + [ (i | string, prefix ~ _days.get(i, weekday(midnight.weekday() + (i % 7) + 1, language))) ] %}
{%- endfor %} {%- endfor %}
{%- set collection = dict.from_keys(ns.days) %} {%- set collection = dict.from_keys(ns.days) %}
{%- set days = count_the_days(input, attr, utc) %} {%- set days = count_the_days(input, attr, utc) %}
@ -1586,16 +2054,20 @@
{%- macro hour(hour, language=None) %} {%- macro hour(hour, language=None) %}
{%- if hour is datetime %} {%- if hour is datetime %}
{%- set hour = hour.hour %} {%- set hour = hour.hour %}
{%- elif hour | regex_match(valid_entity_id_pattern) %}
{%- set hour = (states(hour) | as_datetime | as_local).hour %}
{%- endif %} {%- endif %}
{%- set _12 = not (hour % 12) %} {%- set _12 = not (hour % 12) %}
{%- set _24 = not (hour % 24) %} {%- set _24 = not (hour % 24) %}
{%- set _12hr = translate('time','format') == '12-hr' %} {%- set use_twelve = translate('time_of_day', 'use_twelve', language=language, fallback=false) %}
{%- if _12 and _24 and _12hr %} {%- set _12hr = translate('time','format', language=language) == '12-hr' %}
{%- if _12 and _24 and _12hr and not use_twelve %}
{{- translate('time_of_day', 'midnight', language=language) }} {{- translate('time_of_day', 'midnight', language=language) }}
{%- elif _12 and _12hr %} {%- elif _12 and _12hr and not use_twelve %}
{{- translate('time_of_day', 'noon', language=language) }} {{- translate('time_of_day', 'noon', language=language) }}
{%- else %} {%- else %}
{{- hour % 12 if _12hr else hour }} {%- set ret = hour % 12 if _12hr else hour %}
{{- 12 if ret == 0 and use_twelve else ret }}
{%- endif %} {%- endif %}
{%- endmacro %} {%- endmacro %}
@ -1617,7 +2089,22 @@
{%- set hour_phrase = hour(this_hour, language=language) %} {%- 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 %} {%- set minute_phrase = _phrase('minute', 60 * this_minute, language, True, True) if this_minute % 5 else this_minute | string %}
{%- endif %} {%- endif %}
{%- if this_minute in [0, 1, 15, 30, 45, 59] %} {%- set this_config = translate('time_of_hour', language=language) %}
{%- if (16 <= this_minute <= 29 and 'to_half_hour' in this_config) or (31 <= this_minute <= 44 and 'past_half_hour' in this_config) or (this_minute == 30 and 'half_hour' in this_config) %}
{%- set hour_phrase = hour(this_hour + 1, language=language) %}
{%- if 16 <= this_minute <= 29 %}
{%- set minute_calc = 30 - this_minute %}
{%- set fmat = translate('time_of_hour', 'to_half_hour', language=language) %}
{%- set minute_phrase = _phrase('minute', 60 * minute_calc, language, True, True) if this_minute % 5 else minute_calc | string %}
{%- elif 31 <= this_minute <= 44 %}
{%- set minute_calc = this_minute - 30 %}
{%- set fmat = translate('time_of_hour', 'past_half_hour', language=language) %}
{%- set minute_phrase = _phrase('minute', 60 * minute_calc, language, True, True) if this_minute % 5 else minute_calc | string %}
{%- else %}
{%- set minute_calc = None %}
{%- set fmat = translate('time_of_hour', 'half_hour', language=language) %}
{%- endif %}
{%- elif this_minute in [0, 1, 15, 30, 45, 59] %}
{%- if hour_phrase in ['noon', 'midnight'] and this_minute == 0 %} {%- if hour_phrase in ['noon', 'midnight'] and this_minute == 0 %}
{%- set fmat = '{hour}' %} {%- set fmat = '{hour}' %}
{%- else %} {%- else %}

View File

@ -1,234 +1,342 @@
{# {#
set phrases to be used in the relative_time_period macro set phrases to be used in the relative_time_period macro
one list item per language, each time fraction contains a list with the singular, plural and abbriviated phrase one list item per language, each time fraction contains a list with the short and several long forms of time units
combine contains the text to combine the last time fraction, and error the text to display on wrong date input combine contains the text to combine the last time fraction, and error the text to display on wrong date input
Plural forms for languages: https://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms
asian: ja, vi, ko
english: en, de, nl, sv, da, no, nb, nn, fo, es, pt, it, bg, el, fi, et, he, eo, hu, tr, ca
french: pt_BR, fr
latvian: lv
irish: ga
romanian: ro
lithuanian: lv
russian: ru, uk, be, sr, hr
slovak: cs, sk
polish: pl
slovenian: sl
arabic: ar
#} #}
{%- set _time_period_phrases = [ {%- set _time_period_phrases = [
{ {
'language': 'en', 'language': 'en',
'plural_form': 'english',
'phrases': { 'phrases': {
'year': ['year', 'years', 'yr'], 'year': ['yr', 'year', 'years'],
'month': ['month', 'months', 'mth'], 'month': ['mth', 'month', 'months'],
'week': ['week', 'weeks', 'wk'], 'week': ['wk', 'week', 'weeks'],
'day': ['day', 'days', 'day'], 'day': ['day', 'day', 'days'],
'hour': ['hour', 'hours', 'hr'], 'hour': ['hr', 'hour', 'hours'],
'minute': ['minute', 'minutes', 'min'], 'minute': ['min', 'minute', 'minutes'],
'second': ['second', 'seconds', 'sec'], 'second': ['sec', 'second', 'seconds'],
'millisecond': ['millisecond', 'milliseconds', 'ms'], 'millisecond': ['ms', 'millisecond', 'milliseconds'],
'combine': 'and', 'combine': 'and',
'error': 'Invalid date', 'error': 'Invalid date',
} }
}, },
{ {
'language': 'pl', 'language': 'pl',
'plural_form': 'polish',
'phrases': { 'phrases': {
'year': ['rok', 'lat', 'r'], 'year': ['r', 'rok', 'lata', 'lat'],
'month': ['miesiąc', 'miesięcy', 'msc'], 'month': ['msc', 'miesiąc', 'miesiące', 'miesięcy'],
'week': ['tydzień', 'tygodni', 'tyg'], 'week': ['tyg', 'tydzień', 'tygodnie', 'tygodni'],
'day': ['dzień', 'dni', 'dzień'], 'day': ['dzień', 'dzień', 'dni', 'dni'],
'hour': ['godzina', 'godzin', 'godz'], 'hour': ['godz', 'godzina', 'godziny', 'godzin'],
'minute': ['minuta', 'minut', 'min'], 'minute': ['min', 'minuta', 'minuty', 'minut'],
'second': ['sekunda', 'sekund', 'sek'], 'second': ['sek', 'sekunda', 'sekundy', 'sekund'],
'millisecond': ['milisekunda', 'milisekund', 'ms'], 'millisecond': ['ms', 'milisekunda', 'milisekundy', 'milisekund'],
'combine': 'i', 'combine': 'i',
'error': 'Niepoprawna data', 'error': 'Niepoprawna data',
} }
}, },
{ {
'language': 'fr', 'language': 'fr',
'plural_form': 'french',
'phrases': { 'phrases': {
'year': ['année', 'années', 'an'], 'year': ['an', 'année', 'années'],
'month': ['mois', 'mois', 'mois'], 'month': ['mois', 'mois', 'mois'],
'week': ['semaine', 'semaines', 'sem'], 'week': ['sem', 'semaine', 'semaines'],
'day': ['jour', 'jours', 'j'], 'day': ['j', 'jour', 'jours'],
'hour': ['heure', 'heures', 'h'], 'hour': ['h', 'heure', 'heures'],
'minute': ['minute', 'minutes', 'min'], 'minute': ['min', 'minute', 'minutes'],
'second': ['seconde', 'secondes', 'sec'], 'second': ['sec', 'seconde', 'secondes'],
'millisecond': ['milliseconde', 'millisecondes', 'ms'], 'millisecond': ['ms', 'milliseconde', 'millisecondes'],
'combine': 'et', 'combine': 'et',
'error': 'Date non valide', 'error': 'Date non valide',
} }
}, },
{ {
'language': 'it', 'language': 'it',
'plural_form': 'english',
'phrases': { 'phrases': {
'year': ['anno', 'anni', 'aa'], 'year': ['aa', 'anno', 'anni'],
'month': ['mese', 'mesi', 'mm'], 'month': ['mm', 'mese', 'mesi'],
'week': ['settimana', 'settimane', 'set'], 'week': ['set', 'settimana', 'settimane'],
'day': ['giorno', 'giorni', 'gg'], 'day': ['gg', 'giorno', 'giorni'],
'hour': ['ora', 'ore', 'h'], 'hour': ['h', 'ora', 'ore'],
'minute': ['minuto', 'minuti', 'min'], 'minute': ['min', 'minuto', 'minuti'],
'second': ['secondo', 'secondi', 'sec'], 'second': ['sec', 'secondo', 'secondi'],
'millisecond': ['millisecondo', 'millisecondi', 'ms'], 'millisecond': ['ms', 'millisecondo', 'millisecondi'],
'combine': 'e', 'combine': 'e',
'error': 'Data non valida', 'error': 'Data non valida',
} }
}, },
{ {
'language': 'nb', 'language': 'nb',
'plural_form': 'english',
'phrases': { 'phrases': {
'year': ['år', 'år', 'år'], 'year': ['år', 'år', 'år'],
'month': ['måned', 'måneder', 'mnd'], 'month': ['mnd', 'måned', 'måneder'],
'week': ['uke', 'uker', 'u'], 'week': ['u', 'uke', 'uker'],
'day': ['dag', 'dager', 'd'], 'day': ['d', 'dag', 'dager'],
'hour': ['time', 'timer', 't'], 'hour': ['t', 'time', 'timer'],
'minute': ['minutt', 'minutter', 'min'], 'minute': ['min', 'minutt', 'minutter'],
'second': ['sekund', 'sekunder', 'sek'], 'second': ['sek', 'sekund', 'sekunder'],
'millisecond': ['millisekund', 'millisekunder', 'ms'], 'millisecond': ['ms', 'millisekund', 'millisekunder'],
'combine': 'og', 'combine': 'og',
'error': 'Ugyldig dato', 'error': 'Ugyldig dato',
} }
}, },
{ {
'language': 'nl', 'language': 'nl',
'plural_form': 'english',
'phrases': { 'phrases': {
'year': ['jaar', 'jaar', 'jr'], 'year': ['jr', 'jaar', 'jaar'],
'month': ['maand', 'maanden', 'mnd'], 'month': ['mnd', 'maand', 'maanden'],
'week': ['week', 'weken', 'wk'], 'week': ['wk', 'week', 'weken'],
'day': ['dag', 'dagen', 'dg'], 'day': ['dg', 'dag', 'dagen'],
'hour': ['uur', 'uur', 'u'], 'hour': ['u', 'uur', 'uur'],
'minute': ['minuut', 'minuten', 'min'], 'minute': ['min', 'minuut', 'minuten'],
'second': ['seconde', 'seconden', 'sec'], 'second': ['sec', 'seconde', 'seconden'],
'millisecond': ['milliseconde', 'milliseconden', 'ms'], 'millisecond': ['ms', 'milliseconde', 'milliseconden'],
'combine': 'en', 'combine': 'en',
'error': 'Ongeldige datum', 'error': 'Ongeldige datum',
} }
}, },
{ {
'language': 'nn', 'language': 'nn',
'plural_form': 'english',
'phrases': { 'phrases': {
'year': ['år', 'år', 'år'], 'year': ['år', 'år', 'år'],
'month': ['månad', 'månader', 'mnd'], 'month': ['mnd', 'månad', 'månader'],
'week': ['veke', 'veker', 'v'], 'week': ['v', 'veke', 'veker'],
'day': ['dag', 'dagar', 'd'], 'day': ['d', 'dag', 'dagar'],
'hour': ['time', 'timar', 't'], 'hour': ['t', 'time', 'timar'],
'minute': ['minutt', 'minutt', 'min'], 'minute': ['min', 'minutt', 'minutt'],
'second': ['sekund', 'sekund', 'sek'], 'second': ['sek', 'sekund', 'sekund'],
'millisecond': ['millisekund', 'millisekund', 'ms'], 'millisecond': ['ms', 'millisekund', 'millisekund'],
'combine': 'og', 'combine': 'og',
'error': 'Ugyldig dato', 'error': 'Ugyldig dato',
} }
}, },
{ {
'language': 'de', 'language': 'de',
'plural_form': 'english',
'phrases': { 'phrases': {
'year': ['Jahr', 'Jahre', 'J.'], 'year': ['J.', 'Jahr', 'Jahre'],
'month': ['Monat', 'Monate', 'M.'], 'month': ['M.', 'Monat', 'Monate'],
'week': ['Woche', 'Wochen', 'Wo.'], 'week': ['Wo.', 'Woche', 'Wochen'],
'day': ['Tag', 'Tage', 'Tg.'], 'day': ['Tg.', 'Tag', 'Tage'],
'hour': ['Stunde', 'Stunden', 'Std.'], 'hour': ['Std.', 'Stunde', 'Stunden'],
'minute': ['Minute', 'Minuten', 'Min.'], 'minute': ['Min.', 'Minute', 'Minuten'],
'second': ['Sekunde', 'Sekunden', 'Sek.'], 'second': ['Sek.', 'Sekunde', 'Sekunden'],
'millisecond': ['Millisekunde', 'Millisekunden', 'ms'], 'millisecond': ['ms', 'Millisekunde', 'Millisekunden'],
'combine': 'und', 'combine': 'und',
'error': 'Falsches Datum', 'error': 'Falsches Datum',
} }
}, },
{ {
'language': 'pt', 'language': 'pt',
'plural_form': 'english',
'phrases': { 'phrases': {
'year': ['ano', 'anos', 'aa'], 'year': ['aa', 'ano', 'anos'],
'month': ['mês', 'meses', 'mm'], 'month': ['mm', 'mês', 'meses'],
'week': ['semana', 'semanas', 'sem'], 'week': ['sem', 'semana', 'semanas'],
'day': ['dia', 'dias', 'd'], 'day': ['d', 'dia', 'dias'],
'hour': ['hora', 'horas', 'h'], 'hour': ['h', 'hora', 'horas'],
'minute': ['minuto', 'minutos', 'min'], 'minute': ['min', 'minuto', 'minutos'],
'second': ['segundo', 'segundos', 'seg'], 'second': ['seg', 'segundo', 'segundos'],
'millisecond': ['millissegundo', 'millissegundos', 'ms'], 'millisecond': ['ms', 'millissegundo', 'millissegundos'],
'combine': 'e', 'combine': 'e',
'error': 'Data Inválida', 'error': 'Data Inválida',
} }
}, },
{ {
'language': 'dk', 'language': 'dk',
'plural_form': 'english',
'phrases': { 'phrases': {
'year': ['år', 'år', 'år'], 'year': ['år', 'år', 'år'],
'month': ['måned', 'måneder', 'mnd'], 'month': ['mnd', 'måned', 'måneder'],
'week': ['uge', 'uger', 'uge'], 'week': ['uge', 'uge', 'uger'],
'day': ['dag', 'dage', 'dag'], 'day': ['dag', 'dag', 'dage'],
'hour': ['time', 'timer', 't.'], 'hour': ['t.', 'time', 'timer'],
'minute': ['minut', 'minuter', 'min.'], 'minute': ['min.', 'minut', 'minuter'],
'second': ['sekund', 'sekunder', 'sek.'], 'second': ['sek.', 'sekund', 'sekunder'],
'millisecond': ['millisekund', 'millisekunder', 'ms.'], 'millisecond': ['ms.', 'millisekund', 'millisekunder'],
'combine': 'og', 'combine': 'og',
'error': 'Ugyldig dato', 'error': 'Ugyldig dato',
} }
}, },
{ {
'language': 'sv', 'language': 'sv',
'plural_form': 'english',
'phrases': { 'phrases': {
'year': ['år', 'år', 'år'], 'year': ['år', 'år', 'år'],
'month': ['månad', 'månader', 'mån'], 'month': ['mån', 'månad', 'månader'],
'week': ['vecka', 'veckor', 'v'], 'week': ['v', 'vecka', 'veckor'],
'day': ['dag', 'dagar', 'dag'], 'day': ['dag', 'dag', 'dagar'],
'hour': ['timme', 'timmar', 'tim'], 'hour': ['tim', 'timme', 'timmar'],
'minute': ['minut', 'minuter', 'min'], 'minute': ['min', 'minut', 'minuter'],
'second': ['sekund', 'sekunder', 'sek'], 'second': ['sek', 'sekund', 'sekunder'],
'millisecond': ['millisekund', 'millisekunder', 'ms'], 'millisecond': ['ms', 'millisekund', 'millisekunder'],
'combine': 'och', 'combine': 'och',
'error': 'Ogiltigt datum', 'error': 'Ogiltigt datum',
} }
}, },
{ {
'language': 'cs', 'language': 'cs',
'plural_form': 'slovak',
'phrases': { 'phrases': {
'year': ['rok', 'roky', 'rok'], 'year': ['rok', 'rok', 'roky', 'let'],
'month': ['měsíc', 'měsíce', 'měs'], 'month': ['měs', 'měsíc', 'měsíce', 'měsíců'],
'week': ['týden', 'týdny', 'týd'], 'week': ['týd', 'týden', 'týdny', 'týd'],
'day': ['den', 'dny', 'd'], 'day': ['d', 'den', 'dny', 'd'],
'hour': ['hodina', 'hodiny', 'hod'], 'hour': ['hod', 'hodina', 'hodiny', 'hodin'],
'minute': ['minuta', 'minuty', 'min'], 'minute': ['min', 'minuta', 'minuty', 'minut'],
'second': ['sekunda', 'sekundy', 'sek'], 'second': ['sek', 'sekunda', 'sekundy', 'sekund'],
'millisecond': ['millisekunda', 'millisekundy', 'ms'], 'millisecond': ['ms', 'millisekunda', 'millisekundy', 'millisekund'],
'combine': 'a', 'combine': 'a',
'error': 'špatný datum' 'error': 'špatné datum'
} }
}, },
{ {
'language': 'fi', 'language': 'fi',
'plural_form': 'english',
'phrases': { 'phrases': {
'year': ['vuosi', 'vuotta', 'v'], 'year': ['v', 'vuosi', 'vuotta'],
'month': ['kuukausi', 'kuukautta', 'kk'], 'month': ['kk', 'kuukausi', 'kuukautta'],
'week': ['viikko', 'viikkoa', 'vk'], 'week': ['vk', 'viikko', 'viikkoa'],
'day': ['päivä', 'päivää', 'pv'], 'day': ['pv', 'päivä', 'päivää'],
'hour': ['tunti', 'tuntia', 't'], 'hour': ['t', 'tunti', 'tuntia'],
'minute': ['minuutti', 'minuuttia', 'min'], 'minute': ['min', 'minuutti', 'minuuttia'],
'second': ['sekunti', 'sekuntia', 's'], 'second': ['s', 'sekunti', 'sekuntia'],
'millisecond': ['millisekunti', 'millisekuntia', 'ms'], 'millisecond': ['ms', 'millisekunti', 'millisekuntia'],
'combine': 'ja', 'combine': 'ja',
'error': 'Väärä päivämäärä', 'error': 'Väärä päivämäärä',
} }
}, },
{ {
'language': 'ru', 'language': 'ru',
'plural_form': 'russian',
'phrases': { 'phrases': {
'year': ['год', 'года', 'г'], 'year': ['г', 'год', 'года', 'лет'],
'month': ['месяц', 'месяцы', 'м'], 'month': ['м', 'месяц', 'месяца', 'месяцев'],
'week': ['неделя', 'недели', 'н'], 'week': ['н', 'неделя', 'недели', 'недель'],
'day': ['день', 'дни', 'д'], 'day': ['д', 'день', 'дня', 'дней'],
'hour': ['час', 'часы', 'ч'], 'hour': ['ч', 'час', 'часа', 'часов'],
'minute': ['минута', 'минут', 'м'], 'minute': ['м', 'минута', 'минуты', 'минут'],
'second': ['секунд', 'секунды', 'с'], 'second': ['с', 'секунда', 'секунды', 'секунд'],
'millisecond': ['милисекунд', 'милисекунды', 'мс'], 'millisecond': ['мс', 'милисекунда', 'милисекунды', 'милисекунд'],
'combine': 'и', 'combine': 'и',
'error': 'Неверная дата', 'error': 'Неверная дата',
} }
}, },
{ {
'language': 'uk', 'language': 'uk',
'plural_form': 'russian',
'phrases': { 'phrases': {
'year': ['рік', 'років', 'р'], 'year': ['р', 'рік', 'роки', 'років'],
'month': ['місяць', 'місяців', 'м'], 'month': ['м', 'місяць', 'місяці', 'місяців'],
'week': ['тиждень', 'тижнів', 'тижд'], 'week': ['тижд', 'тиждень', 'тижні', 'тижнів'],
'day': ['день', 'днів', 'дн'], 'day': ['дн', 'день', 'дні', 'днів'],
'hour': ['годину', 'годин', 'год'], 'hour': ['год', 'година', 'години', 'годин'],
'minute': ['хвилину', 'хвилин', 'хв'], 'minute': ['хв', 'хвилина', 'хвилини', 'хвилин'],
'second': ['секунду', 'секунд', 'сек'], 'second': ['сек', 'секунда', 'секунди', 'секунд'],
'millisecond': ['мілісекунду', 'мілісекунд', 'мсек'], 'millisecond': ['мсек', 'мілісекунда', 'мілісекунди', 'мілісекунд'],
'combine': 'та', 'combine': 'та',
'error': 'Недійсна дата', 'error': 'Недійсна дата',
} }
}, },
{
'language': 'bg',
'plural_form': 'english',
'phrases': {
'year': ['г', 'година', 'години'],
'month': ['м', 'месец', 'месеца'],
'week': ['седм', 'седмица', 'седмици'],
'day': ['д', 'ден', 'дни'],
'hour': ['ч', 'час', 'часа'],
'minute': ['м', 'минута', 'минути'],
'second': ['с', 'секунда', 'секунди'],
'millisecond': ['мс', 'милисекунда', 'милисекунди'],
'combine': 'и',
'error': 'Невалидна дата',
}
},
{
'language': 'vi',
'plural_form': 'asian',
'phrases': {
'year': ['y', 'năm'],
'month': ['m', 'tháng'],
'week': ['w', 'tuần'],
'day': ['d', 'ngày'],
'hour': ['h', 'giờ'],
'minute': ['m', 'phút', 'phút'],
'second': ['s', 'giây'],
'millisecond': ['ms', 'mili giây'],
'combine': 'và',
'error': 'Ngày không hợp lệ',
}
},
{
'language': 'es',
'plural_form': 'english',
'phrases': {
'year': ['a', 'año', 'años'],
'month': ['m', 'mes', 'meses'],
'week': ['sem', 'semana', 'semanas'],
'day': ['d', 'día', 'días'],
'hour': ['h', 'hora', 'horas'],
'minute': ['min', 'minuto', 'minutos'],
'second': ['s', 'segundo', 'segundos'],
'millisecond': ['ms', 'milisegundo', 'milisegundos'],
'combine': 'y',
'error': 'Fecha inválida',
}
},
{
'language': 'he',
'plural_form': 'english',
'phrases': {
'year': ['שנה', 'שנה', 'שנים'],
'month': ['חודש', 'חודש', 'חודשים'],
'week': ['שבוע', 'שבוע', 'שבועות'],
'day': ['יום', 'יום', 'ימים'],
'hour': ['שעה', 'שעה', 'שעות'],
'minute': ['דקה', 'דקה', 'דקות'],
'second': ['שניה', 'שניה', 'שניות'],
'millisecond': ['מילי', 'מילישניה', 'מילישניות'],
'combine': 'ו',
'error': 'תאריך לא חוקי',
}
},
{
'language': 'hu',
'plural_form': 'english',
'phrases': {
'year': ['é', 'év', 'év'],
'month': ['hó', 'hónap', 'hónap'],
'week': ['hét', 'hét', 'hét'],
'day': ['n', 'nap', 'nap'],
'hour': ['ó', 'óra', 'óra'],
'minute': ['p', 'perc', 'perc'],
'second': ['mp', 'másodperc', 'másodperc'],
'millisecond': ['ms', 'ezredmásodperc', 'ezredmásodperc'],
'combine': 'és',
'error': 'Érvénytelen dátum',
}
},
] -%} ] -%}
{# macro to convert the abbreviated input for the not_use and always_show lists to the full time part names #} {# macro to convert the abbreviated input for the not_use and always_show lists to the full time part names #}
@ -255,12 +363,14 @@
{%- set date = date if date is datetime else date | as_datetime('invalid') -%} {%- 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 compare_date = compare_date if compare_date is datetime else compare_date | as_datetime('invalid') -%}
{%- set time = time | bool(true) -%} {%- set time = time | bool(true) -%}
{%- set parts = [parts | int(1), always_show | count] | max -%} {%- set parts = [parts | int(1), always_show | count] | max -%}
{# create namespace to store debug data #}
{%- set debug = namespace(debug="") -%}
{# 1: check if date input is correct #} {# 1: check if date input is correct #}
{%- if date is datetime and compare_date is datetime -%} {%- if date is datetime and compare_date is datetime -%}
{# convert date input to local or date only #} {# convert date input to local or date only #}
{%- set date = date | as_local if time else (date | as_local).date() -%} {%- 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() -%} {%- set compare_date = compare_date | as_local if time else (compare_date | as_local).date() -%}
{# determine highest and lowest date #} {# determine highest and lowest date #}
{%- set date_max = [compare_date, date] | max -%} {%- set date_max = [compare_date, date] | max -%}
{%- set date_min = [compare_date, date] | min -%} {%- set date_min = [compare_date, date] | min -%}
@ -282,7 +392,7 @@
{%- if not not_use in [['millisecond'], []] -%} {%- if not not_use in [['millisecond'], []] -%}
{%- set not_use = _abbr_to_full(not_use) | from_json -%} {%- set not_use = _abbr_to_full(not_use) | from_json -%}
{%- endif -%} {%- endif -%}
{%- set not_use = not_use + ['hour', 'minute', 'second', 'millisecond' ] if not time else not_use -%} {%- set not_use = not_use + ['hour', 'minute', 'second', 'millisecond' ] if not time else not_use -%}
{%- if always_show in [['all'], 'all'] -%} {%- if always_show in [['all'], 'all'] -%}
{%- set always_show = dur.keys() | list -%} {%- set always_show = dur.keys() | list -%}
{%- elif always_show != [] -%} {%- elif always_show != [] -%}
@ -296,7 +406,7 @@
{%- if do_use and ms < dur[do_use|last] -%} {%- if do_use and ms < dur[do_use|last] -%}
{{- {do_use | last: (ms / dur[do_use|last]) | round(0, round_mode)} | to_json -}} {{- {do_use | last: (ms / dur[do_use|last]) | round(0, round_mode)} | to_json -}}
{%- else -%} {%- else -%}
{# check if it is needed to determine years #} {# check if it is needed to determine years #}
{%- if ms >= dur.day * 365 -%} {%- if ms >= dur.day * 365 -%}
{#- set numer of years, and set highest date using this number of years #} {#- 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 yrs = date_max.year - date_min.year - (1 if date_max.replace(year=date_min.year) < date_min else 0) -%}
@ -305,7 +415,7 @@
{%- set ms_yrs = ms -%} {%- set ms_yrs = ms -%}
{%- endif -%} {%- endif -%}
{%- set yrs = yrs | default(0) -%} {%- set yrs = yrs | default(0) -%}
{# check if it is needed to determine months #} {# check if it is needed to determine months #}
{%- set check_mth = {%- set check_mth =
ms >= dur.day * 28 ms >= dur.day * 28
and 'month' in do_use and 'month' in do_use
@ -354,7 +464,7 @@
{%- set first = keys | select('in', always_show | default([], true) + [first]) | first -%} {%- set first = keys | select('in', always_show | default([], true) + [first]) | first -%}
{%- set to_use = keys[keys.index(first):] -%} {%- set to_use = keys[keys.index(first):] -%}
{%- set to_output = to_use[:parts] -%} {%- set to_output = to_use[:parts] -%}
{%- set last = to_output | last |default('millisecond') -%} {%- set last = dur.items() | selectattr('0', 'in', to_output) | map(attribute='0') | list | last | default('millisecond') -%}
{# 3: check if there is anything left to use #} {# 3: check if there is anything left to use #}
{%- if to_use -%} {%- if to_use -%}
{%- set to_output = to_use[:parts] -%} {%- set to_output = to_use[:parts] -%}
@ -365,9 +475,10 @@
{%- set to_reject = to_use | reject('in', to_output) | reject('in', always_show) | list -%} {%- 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 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 = to_output | reject('in', not_use) | list + always_show -%}
{%- set to_output = keys | select('in', to_output) | list -%} {%- set to_output = keys | select('in', to_output) | list + ['extra']-%}
{%- set output = time_split(date, parts, compare_date, not_use, always_show, time, round_mode) | from_json -%} {%- set output = time_split(date, parts, compare_date, not_use, always_show, time, round_mode) | from_json -%}
{%- endif -%} {%- endif -%}
{# apply round if needed #} {# apply round if needed #}
{%- if round_mode in ['common', 'ceil'] and last != 'millisecond' -%} {%- if round_mode in ['common', 'ceil'] and last != 'millisecond' -%}
{# determine first and last item with data #} {# determine first and last item with data #}
@ -376,22 +487,59 @@
{%- set remain_part = remain / 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 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 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_max = [compare_date, date] | max + timedelta(seconds=sec_to_add) -%}
{%- set date_min = [compare_date, date] | min -%} {%- 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 -%} {%- set output = time_split(date_max, parts, date_min, not_use, always_show, time, 'floor') | from_json -%}
{%- 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] -%}
{%- endif -%} {%- endif -%}
{# output result #} {# output result #}
{%- set zero_values = output.items() | selectattr('1', 'eq', 0) | map(attribute='0') | list -%} {%- set zero_values = output.items() | selectattr('1', 'eq', 0) | map(attribute='0') | list -%}
{%- set reject_list = zero_values | reject('in', always_show) | 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 -}} {{- dict(output.items() | selectattr('0', 'in', to_output) | rejectattr('0', 'in', reject_list), **dict(debug=debug.debug) if debug.debug else dict()) | default({always_return: 0}, true) | to_json-}}
{%- else -%} {{- dict(error='No time parts left to output') | to_json -}} {%- else -%} {{- dict(error='No time parts left to output') -}}
{%- endif -%} {# 3 #} {%- endif -%} {# 3 #}
{%- endif -%} {# 2 #} {%- endif -%} {# 2 #}
{%- else -%} {{- dict(error='Invalid date input') | to_json -}} {%- else -%} {{- dict(error='Invalid date input')-}}
{%- endif -%} {# 1 #} {%- endif -%} {# 1 #}
{%- endmacro -%} {%- endmacro -%}
{# macro for determining the time unit variant depending on the language #}
{%- macro plural(number=0, rule='english') -%}
{%- set mod100 = number % 100 -%}
{%- set mod10 = number % 10 -%}
{%- set form = 1 -%}
{%- if rule == 'english' -%}
{%- set form = 1 if number == 1 else 2 -%}
{%- elif rule == 'french' -%}
{%- set form = 1 if number <= 1 else 2 -%}
{%- elif rule == 'latvian' -%}
{%- set form = 1 if (mod10 == 1 and mod100 != 11) else 2 if number != 0 else 3 -%}
{%- elif rule == 'irish' -%}
{%- set form = 1 if number == 1 else 2 if number == 2 else 3 -%}
{%- elif rule == 'romanian' -%}
{%- set form = 1 if number == 1 else 2 if (number == 0 or (mod100 > 0 and mod100 < 20 )) else 3 -%}
{%- elif rule == 'lithuanian' -%}
{%- set form = 1 if (mod10 == 1 and mod100 != 11) else 2 if (mod10 >= 2 and (mod100 < 10 or mod100 >= 20)) else 3 -%}
{%- elif rule == 'russian' -%}
{%- set form = 1 if (mod10 == 1 and mod100 != 11) else 2 if (mod10 >= 2 and mod10 <= 4 and (mod100 < 10 or mod100 >= 20)) else 3 -%}
{%- elif rule == 'slovak' -%}
{%- set form = 1 if number == 1 else 2 if (number >= 2 and number <= 4) else 3 -%}
{%- elif rule == 'polish' -%}
{%- set form = 1 if number == 1 else 2 if (mod10 >= 2 and mod10 <= 4 and (mod100 < 10 or mod100 >= 20)) else 3 -%}
{%- elif rule == 'slovenian' -%}
{%- set form = 1 if mod100 == 1 else 2 if mod100 == 2 else 3 if (mod100 == 3 or mod100 == 4) else 4 -%}
{%- elif rule == 'arabic' -%}
{%- set form = 1 if number == 0 else 2 if number == 1 else 3 if number == 2 else 4 if (mod100 >= 3 and mod100 <= 10) else 5 if mod100 >= 11 else 6 -%}
{%- endif -%}
{{- form -}}
{%- endmacro -%}
{# macro to output a timedelta in a readable format #} {# macro to output a timedelta in a readable format #}
{%- macro relative_time_plus(date, parts=1, abbr=false, language='en', compare_date=now(), not_use=['millisecond'], always_show=[], time=true, round_mode='floor') -%} {%- 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 #} {#- select correct phrases bases on language input #}
@ -399,6 +547,7 @@
{%- set languages = phrases | map(attribute='language') | list -%} {%- set languages = phrases | map(attribute='language') | list -%}
{%- set language = iif(language in languages, language, 'en') -%} {%- set language = iif(language in languages, language, 'en') -%}
{%- set phr = phrases | selectattr('language', 'eq', language) | map(attribute='phrases') | list | first -%} {%- set phr = phrases | selectattr('language', 'eq', language) | map(attribute='phrases') | list | first -%}
{%- set plural_form = phrases | selectattr('language', 'eq', language) | map(attribute='plural_form') | list | first -%}
{%- set abbr = abbr | bool(false) -%} {%- set abbr = abbr | bool(false) -%}
{# split timedelta #} {# split timedelta #}
{%- set time_parts = time_split(date, parts, compare_date, not_use, always_show, time, round_mode) | from_json -%} {%- set time_parts = time_split(date, parts, compare_date, not_use, always_show, time, round_mode) | from_json -%}
@ -409,9 +558,9 @@
{# convert to phrases #} {# convert to phrases #}
{%- set ns = namespace(phrases=[]) -%} {%- set ns = namespace(phrases=[]) -%}
{%- for i in time_parts.keys() -%} {%- for i in time_parts.keys() -%}
{%- set phr_abbr = phr[i][2] -%} {%- set plural_variant = plural(time_parts[i], plural_form) | int -%}
{%- set phr_verb = phr[i][1] if time_parts[i] != 1 else phr[i][0] -%} {%- set phr_form = phr[i][0] if abbr else phr[i][plural_variant] -%}
{%- set phrase = '{} {}'.format(time_parts[i], phr_abbr if abbr else phr_verb) -%} {%- set phrase = '{} {}'.format(time_parts[i], phr_form) -%}
{%- set ns.phrases = ns.phrases + [phrase] -%} {%- set ns.phrases = ns.phrases + [phrase] -%}
{%- endfor -%} {%- endfor -%}
{#- join phrases in a string, using phr.combine for the last item #} {#- join phrases in a string, using phr.combine for the last item #}

View File

@ -32,9 +32,11 @@
{% else %} {% else %}
{% if ' - ' in game_clock %} {% if ' - ' in game_clock %}
{% set clock_time, quarter = game_clock.split(' - ') %} {% set clock_time, quarter = game_clock.split(' - ') %}
with {{ clock_time ~ ' remaining in the ' ~ quarter ~ ' ' ~ period_str }} {% if quarter == 'ot' %}
{% else %} with {{ clock_time ~ ' remaining in overtime' }}
with {{ game_clock ~ ' remaining in the ' ~ period_str }} {% else %}
with {{ clock_time ~ ' remaining in the ' ~ quarter ~ ' ' ~ period_str }}
{% endif %}
{% endif %} {% endif %}
{% endif %} {% endif %}
{% endmacro %} {% endmacro %}

View File

@ -116,16 +116,6 @@ template:
unique_id: 2ce31844-b115-42b8-8213-feccf24e236c unique_id: 2ce31844-b115-42b8-8213-feccf24e236c
state: "{{ state_attr('climate.master_bedroom_aircon','temperature') | float }}" state: "{{ state_attr('climate.master_bedroom_aircon','temperature') | float }}"
availability: "{{ states('climate.master_bedroom_aircon') not in ['unavailable','unknown'] }}" availability: "{{ states('climate.master_bedroom_aircon') not in ['unavailable','unknown'] }}"
- name: "Master Bedroom Eco Mode"
unique_id: edf36e23-adcf-4506-80eb-a14f4ea2fce0
state: "{{ is_state_attr('climate.master_bedroom_aircon','preset_mode','eco') }}"
icon: >-
{% if is_state_attr('climate.master_bedroom_aircon','preset_mode','eco') %}
mdi:home-lightning-bolt
{% else %}
mdi:home-lightning-bolt-outline
{% endif %}
availability: "{{ states('climate.master_bedroom_aircon') not in ['unavailable','unknown'] }}"
- name: "Master Bedroom Aircon Fan Mode" - name: "Master Bedroom Aircon Fan Mode"
unique_id: c0e4f9ba-0c6c-4673-9a75-13f253f2f2e8 unique_id: c0e4f9ba-0c6c-4673-9a75-13f253f2f2e8
state: "{{ state_attr('climate.master_bedroom_aircon','fan_mode') }}" state: "{{ state_attr('climate.master_bedroom_aircon','fan_mode') }}"
@ -146,16 +136,6 @@ template:
unique_id: b81152a1-d4d9-4e3e-8a78-6039de2884ad unique_id: b81152a1-d4d9-4e3e-8a78-6039de2884ad
state: "{{ state_attr('climate.emma_bedroom_aircon','temperature') | float }}" state: "{{ state_attr('climate.emma_bedroom_aircon','temperature') | float }}"
availability: "{{ states('climate.emma_bedroom_aircon') not in ['unavailable','unknown'] }}" availability: "{{ states('climate.emma_bedroom_aircon') not in ['unavailable','unknown'] }}"
- name: "Emma Bedroom Eco Mode"
unique_id: 4b6fc8fc-4152-4d8b-ad8d-80f97fcabe44
state: "{{ is_state_attr('climate.emma_bedroom_aircon','preset_mode','eco') }}"
icon: >-
{% if is_state_attr('climate.emma_bedroom_aircon','preset_mode','eco') %}
mdi:home-lightning-bolt
{% else %}
mdi:home-lightning-bolt-outline
{% endif %}
availability: "{{ states('climate.emma_bedroom_aircon') not in ['unavailable','unknown'] }}"
- name: "Emma Bedroom Aircon Fan Mode" - name: "Emma Bedroom Aircon Fan Mode"
unique_id: d678eb2e-be5b-4626-913d-fc1e32941ead unique_id: d678eb2e-be5b-4626-913d-fc1e32941ead
state: "{{ state_attr('climate.emma_bedroom_aircon','fan_mode') }}" state: "{{ state_attr('climate.emma_bedroom_aircon','fan_mode') }}"

11
packages/dashboards.yaml Normal file
View File

@ -0,0 +1,11 @@
template:
- trigger:
- trigger: event
event_type: bubble_card_update_modules
sensor:
- name: "Bubble Card Modules"
state: "saved"
icon: "mdi:puzzle"
attributes:
modules: "{{ trigger.event.data.modules }}"
last_updated: "{{ trigger.event.data.last_updated }}"

View File

@ -659,14 +659,18 @@ template:
state: > state: >
{% set lights = states.light.upstairs_bathroom_lights, {% set lights = states.light.upstairs_bathroom_lights,
states.light.hallway_overhead, states.light.hallway_overhead,
states.light.downstairs_bathroom_lights %} states.light.downstairs_bathroom_lights,
states.light.living_room_lights,
states.light.front_porch_light %}
{% set issues = lights | selectattr('state','eq','unavailable') | list | count %} {% set issues = lights | selectattr('state','eq','unavailable') | list | count %}
{{ issues > 0 }} {{ issues > 0 }}
attributes: attributes:
issues: > issues: >
{% set lights = states.light.upstairs_bathroom_lights, {% set lights = states.light.upstairs_bathroom_lights,
states.light.hallway_overhead, states.light.hallway_overhead,
states.light.downstairs_bathroom_lights %} states.light.downstairs_bathroom_lights,
states.light.living_room_lights,
states.light.front_porch_light %}
{% set ids = lights | selectattr('state','eq','unavailable') | map(attribute='attributes.friendly_name') | list %} {% set ids = lights | selectattr('state','eq','unavailable') | map(attribute='attributes.friendly_name') | list %}
{{ ids | join(', ') }} {{ ids | join(', ') }}
- sensor: - sensor:

View File

@ -198,6 +198,57 @@ input_number:
step: 0.05 step: 0.05
icon: mdi:knob icon: mdi:knob
template:
- sensor:
- name: "Basement Echo Dot Volume"
state: >
{% if is_state('input_boolean.give_me_darkness','on') %}
{{ states('input_number.basement_echo_dot_night_volume') }}
{% else %}
{{ states('input_number.basement_echo_dot_day_volume') }}
{% endif %}
icon: mdi:volume-high
- name: "Basement Google Speaker Volume"
state: >
{% if is_state('input_boolean.give_me_darkness','on') %}
{{ states('input_number.basement_google_speaker_night_volume') }}
{% else %}
{{ states('input_number.basement_google_speaker_day_volume') }}
{% endif %}
icon: mdi:volume-high
- name: "Living Room Echo Dot Volume"
state: >
{% if is_state('input_boolean.give_me_darkness','on') %}
{{ states('input_number.living_room_echo_dot_night_volume') }}
{% else %}
{{ states('input_number.living_room_echo_dot_day_volume') }}
{% endif %}
icon: mdi:volume-high
- name: "Master Bedroom Echo Dot Volume"
state: >
{% if is_state('input_boolean.give_me_darkness','on') or is_state('binary_sensor.people_sleeping','on') %}
{{ states('input_number.master_bedroom_echo_dot_night_volume') }}
{% else %}
{{ states('input_number.master_bedroom_echo_dot_day_volume') }}
{% endif %}
icon: mdi:volume-high
- name: "Kallen Bedroom Google Speaker Volume"
state: >
{% if is_state('input_boolean.give_me_darkness','on') or is_state('input_boolean.kallen_sleeping','on') %}
{{ states('input_number.kallen_bedroom_google_speaker_night_volume') }}
{% else %}
{{ states('input_number.kallen_bedroom_google_speaker_day_volume') }}
{% endif %}
icon: mdi:volume-high
- name: "Emma Bedroom Google Speaker Volume"
state: >
{% if is_state('input_boolean.give_me_darkness','on') or is_state('input_boolean.emma_sleeping','on') %}
{{ states('input_number.emma_bedroom_google_speaker_night_volume') }}
{% else %}
{{ states('input_number.emma_bedroom_google_speaker_day_volume') }}
{% endif %}
icon: mdi:volume-high
# Amazon Polly Sensors to see last message and location of audible notification # Amazon Polly Sensors to see last message and location of audible notification
mqtt: mqtt:
sensor: sensor:
@ -325,24 +376,14 @@ script:
- condition: template - condition: template
value_template: > value_template: >
{% set current = state_attr('media_player.basement_echo_dot','volume_level') | float %} {% set current = state_attr('media_player.basement_echo_dot','volume_level') | float %}
{% set night = states('input_number.basement_echo_dot_night_volume') | float %} {% set expected = states('sensor.basement_echo_dot_volume') | float %}
{% set day = states('input_number.basement_echo_dot_day_volume') | float %} {{ current != expected }}
{% if is_state('input_boolean.give_me_darkness','on') %}
{{ current != night }}
{% else %}
{{ current != day }}
{% endif %}
then: then:
- service: media_player.volume_set - service: media_player.volume_set
target: target:
entity_id: media_player.basement_echo_dot entity_id: media_player.basement_echo_dot
data: data:
volume_level: > volume_level: "{{ states('sensor.basement_echo_dot_volume') }}"
{% if is_state('input_boolean.give_me_darkness','on') %}
{{ states('input_number.basement_echo_dot_night_volume') }}
{% else %}
{{ states('input_number.basement_echo_dot_day_volume') }}
{% endif %}
# Basement Google Speaker # Basement Google Speaker
- if: - if:
- condition: and - condition: and
@ -373,24 +414,14 @@ script:
- condition: template - condition: template
value_template: > value_template: >
{% set current = state_attr('media_player.basement_google_speaker','volume_level') | float %} {% set current = state_attr('media_player.basement_google_speaker','volume_level') | float %}
{% set night = states('input_number.basement_google_speaker_night_volume') | float %} {% set expected = states('sensor.basement_google_speaker_volume') | float %}
{% set day = states('input_number.basement_google_speaker_day_volume') | float %} {{ current != expected }}
{% if is_state('input_boolean.give_me_darkness','on') %}
{{ current != night }}
{% else %}
{{ current != day }}
{% endif %}
then: then:
- service: media_player.volume_set - service: media_player.volume_set
target: target:
entity_id: media_player.basement_google_speaker entity_id: media_player.basement_google_speaker
data: data:
volume_level: > volume_level: "{{ states('sensor.basement_google_speaker_volume') }}"
{% if is_state('input_boolean.give_me_darkness','on') %}
{{ states('input_number.basement_google_speaker_night_volume') }}
{% else %}
{{ states('input_number.basement_google_speaker_day_volume') }}
{% endif %}
- service: media_player.volume_mute - service: media_player.volume_mute
target: target:
entity_id: media_player.basement_google_speaker entity_id: media_player.basement_google_speaker
@ -405,24 +436,14 @@ script:
- condition: template - condition: template
value_template: > value_template: >
{% set current = state_attr('media_player.living_room_echo_dot','volume_level') | float %} {% set current = state_attr('media_player.living_room_echo_dot','volume_level') | float %}
{% set night = states('input_number.living_room_echo_dot_night_volume') | float %} {% set expected = states('sensor.living_room_echo_dot_volume') | float %}
{% set day = states('input_number.living_room_echo_dot_day_volume') | float %} {{ current != expected }}
{% if is_state('input_boolean.give_me_darkness','on') %}
{{ current != night }}
{% else %}
{{ current != day }}
{% endif %}
then: then:
- service: media_player.volume_set - service: media_player.volume_set
target: target:
entity_id: media_player.living_room_echo_dot entity_id: media_player.living_room_echo_dot
data: data:
volume_level: > volume_level: "{{ states('sensor.living_room_echo_dot_volume') }}"
{% if is_state('input_boolean.give_me_darkness','on') %}
{{ states('input_number.living_room_echo_dot_night_volume') }}
{% else %}
{{ states('input_number.living_room_echo_dot_day_volume') }}
{% endif %}
# Master Bedroom Echo Dot # Master Bedroom Echo Dot
- if: - if:
- condition: state - condition: state
@ -435,24 +456,14 @@ script:
- condition: template - condition: template
value_template: > value_template: >
{% set current = state_attr('media_player.master_bedroom_echo_dot','volume_level') | float %} {% set current = state_attr('media_player.master_bedroom_echo_dot','volume_level') | float %}
{% set night = states('input_number.master_bedroom_echo_dot_night_volume') | float %} {% set expected = states('sensor.master_bedroom_echo_dot_volume') | float %}
{% set day = states('input_number.master_bedroom_echo_dot_day_volume') | float %} {{ current != expected }}
{% if is_state('input_boolean.give_me_darkness','on') %}
{{ current != night }}
{% else %}
{{ current != day }}
{% endif %}
then: then:
- service: media_player.volume_set - service: media_player.volume_set
target: target:
entity_id: media_player.master_bedroom_echo_dot entity_id: media_player.master_bedroom_echo_dot
data: data:
volume_level: > volume_level: "{{ states('sensor.master_bedroom_echo_dot_volume') }}"
{% if is_state('input_boolean.give_me_darkness','on') %}
{{ states('input_number.master_bedroom_echo_dot_night_volume') }}
{% else %}
{{ states('input_number.master_bedroom_echo_dot_day_volume') }}
{% endif %}
# Kallen Bedroom Speaker # Kallen Bedroom Speaker
- if: - if:
- condition: and - condition: and
@ -483,24 +494,14 @@ script:
- condition: template - condition: template
value_template: > value_template: >
{% set current = state_attr('media_player.kallen_bedroom_google_speaker','volume_level') | float %} {% set current = state_attr('media_player.kallen_bedroom_google_speaker','volume_level') | float %}
{% set night = states('input_number.kallen_bedroom_google_speaker_night_volume') | float %} {% set expected = states('sensor.kallen_bedroom_google_speaker_volume') | float %}
{% set day = states('input_number.kallen_bedroom_google_speaker_day_volume') | float %} {{ current != expected }}
{% if is_state('input_boolean.give_me_darkness','on') %}
{{ current != night }}
{% else %}
{{ current != day }}
{% endif %}
then: then:
- service: media_player.volume_set - service: media_player.volume_set
target: target:
entity_id: media_player.kallen_bedroom_google_speaker entity_id: media_player.kallen_bedroom_google_speaker
data: data:
volume_level: > volume_level: "{{ states('sensor.kallen_bedroom_google_speaker_volume') }}"
{% if is_state('input_boolean.give_me_darkness','on') %}
{{ states('input_number.kallen_bedroom_google_speaker_night_volume') }}
{% else %}
{{ states('input_number.kallen_bedroom_google_speaker_day_volume') }}
{% endif %}
- service: media_player.volume_mute - service: media_player.volume_mute
target: target:
entity_id: media_player.kallen_bedroom_google_speaker entity_id: media_player.kallen_bedroom_google_speaker
@ -536,24 +537,14 @@ script:
- condition: template - condition: template
value_template: > value_template: >
{% set current = state_attr('media_player.emma_bedroom_google_speaker','volume_level') | float %} {% set current = state_attr('media_player.emma_bedroom_google_speaker','volume_level') | float %}
{% set night = states('input_number.emma_bedroom_google_speaker_night_volume') | float %} {% set expected = states('sensor.emma_bedroom_google_speaker_volume') | float %}
{% set day = states('input_number.emma_bedroom_google_speaker_day_volume') | float %} {{ current != expected }}
{% if is_state('input_boolean.give_me_darkness','on') %}
{{ current != night }}
{% else %}
{{ current != day }}
{% endif %}
then: then:
- service: media_player.volume_set - service: media_player.volume_set
target: target:
entity_id: media_player.emma_bedroom_google_speaker entity_id: media_player.emma_bedroom_google_speaker
data: data:
volume_level: > volume_level: "{{ states('sensor.kallen_bedroom_google_speaker_volume') }}"
{% if is_state('input_boolean.give_me_darkness','on') %}
{{ states('input_number.emma_bedroom_google_speaker_night_volume') }}
{% else %}
{{ states('input_number.emma_bedroom_google_speaker_day_volume') }}
{% endif %}
- service: media_player.volume_mute - service: media_player.volume_mute
target: target:
entity_id: media_player.emma_bedroom_google_speaker entity_id: media_player.emma_bedroom_google_speaker
@ -1326,53 +1317,34 @@ script:
media_player.basement_google_speaker media_player.basement_google_speaker
{% endif %} {% endif %}
volume_level: >- volume_level: >-
{% set numbers_night = [ {% set numbers = [
states.input_number.emma_bedroom_google_speaker_night_volume.state, states.sensor.emma_bedroom_google_speaker_volume.state,
states.input_number.kallen_bedroom_google_speaker_night_volume.state states.sensor.kallen_bedroom_google_speaker_volume.state
] %} ] %}
{% set numbers_day = [ {% set kidsgroup = numbers | list | min | float %}
states.input_number.emma_bedroom_google_speaker_day_volume.state,
states.input_number.kallen_bedroom_google_speaker_day_volume.state
] %}
{% set kidsgroup_night = numbers_night | list | min | float %}
{% set kidsgroup_day = numbers_day | list | max | float %}
{% if type in ['critical'] %} {% if type in ['critical'] %}
1.0 1.0
{% elif is_state('input_boolean.give_me_darkness','on') %}
{% if who in ['Everywhere','everywhere','kids_bedrooms','all_bedrooms'] %}
{% if is_state('input_boolean.emma_sleeping','on') and is_state('input_boolean.kallen_sleeping','off') %}
{{ states('input_number.kallen_bedroom_google_speaker_night_volume') }}
{% elif is_state('input_boolean.kallen_sleeping','on') and is_state('input_boolean.emma_sleeping','off') %}
{{ states('input_number.emma_bedroom_google_speaker_night_volume') }}
{% else %}
{{ kidsgroup_night }}
{% endif %}
{% elif who in ['kallen_bedroom','media_player.kallen_bedroom_google_speaker'] %}
{{ states('input_number.kallen_bedroom_google_speaker_night_volume') }}
{% elif who in ['emma_bedroom','media_player.emma_bedroom_google_speaker'] %}
{{ states('input_number.emma_bedroom_google_speaker_night_volume') }}
{% elif who in ['Basement Google','basement_google'] %}
{{ states('input_number.basement_google_speaker_night_volume') }}
{% else %}
0.3
{% endif %}
{% else %} {% else %}
{% if who in ['Everywhere','everywhere','kids_bedrooms','all_bedrooms'] %} {% if who in ['Everywhere','everywhere','kids_bedrooms','all_bedrooms'] %}
{% if is_state('input_boolean.emma_sleeping','on') and is_state('input_boolean.kallen_sleeping','off') %} {% if is_state('input_boolean.emma_sleeping','on') and is_state('input_boolean.kallen_sleeping','off') %}
{{ states('input_number.kallen_bedroom_google_speaker_day_volume') }} {{ states('sensor.kallen_bedroom_google_speaker_volume') }}
{% elif is_state('input_boolean.kallen_sleeping','on') and is_state('input_boolean.emma_sleeping','off') %} {% elif is_state('input_boolean.kallen_sleeping','on') and is_state('input_boolean.emma_sleeping','off') %}
{{ states('input_number.emma_bedroom_google_speaker_day_volume') }} {{ states('sensor.emma_bedroom_google_speaker_volume') }}
{% else %} {% else %}
{{ kidsgroup_day }} {{ kidsgroup }}
{% endif %} {% endif %}
{% elif who in ['kallen_bedroom','media_player.kallen_bedroom_google_speaker'] %} {% elif who in ['kallen_bedroom','media_player.kallen_bedroom_google_speaker'] %}
{{ states('input_number.kallen_bedroom_google_speaker_day_volume') }} {{ states('sensor.kallen_bedroom_google_speaker_volume') }}
{% elif who in ['emma_bedroom','media_player.emma_bedroom_google_speaker'] %} {% elif who in ['emma_bedroom','media_player.emma_bedroom_google_speaker'] %}
{{ states('input_number.emma_bedroom_google_speaker_day_volume') }} {{ states('sensor.emma_bedroom_google_speaker_volume') }}
{% elif who in ['Basement Google','basement_google'] %} {% elif who in ['Basement Google','basement_google'] %}
{{ states('input_number.basement_google_speaker_day_volume') }} {{ states('sensor.basement_google_speaker_volume') }}
{% else %} {% else %}
0.6 {% if is_state('input_boolean.give_me_darkness','on') %}
0.3
{% else %}
0.6
{% endif %}
{% endif %} {% endif %}
{% endif %} {% endif %}
- service: tts.amazon_polly_say - service: tts.amazon_polly_say

View File

@ -600,20 +600,25 @@ script:
data: data:
time: > time: >
{% set low = states('sensor.overnight_lowest_temperature') | int %} {% set low = states('sensor.overnight_lowest_temperature') | int %}
{% set high = states('sensor.todays_high_temp') | int %}
{% set kallen_bedtime = state_attr('input_datetime.kallen_bedtime','timestamp') | int %} {% set kallen_bedtime = state_attr('input_datetime.kallen_bedtime','timestamp') | int %}
{% set cutoff = 81000 %} {% set cutoff = 81000 %} {# Cutoff time is 22:30 #}
{% if is_state('input_boolean.hot_day','on') and is_state('binary_sensor.kallen_school_tomorrow','on') %} {% if is_state('binary_sensor.kallen_school_tomorrow','on') %}
{{ (kallen_bedtime - 3600) | timestamp_custom('%H:%M',false) }} {% if is_state('input_boolean.hot_day','on') %}
{% elif is_state('input_boolean.hot_day','on') and is_state('binary_sensor.kallen_school_tomorrow','off') %} {{ (kallen_bedtime - 3600) | timestamp_custom('%H:%M',false) }}
{{ kallen_bedtime | timestamp_custom('%H:%M',false) }} {% elif low >= 56 or high >= 75 %}
{% elif 56 <= low <= 60 %} {{ (kallen_bedtime - 1800) | timestamp_custom('%H:%M',false) }}
22:30 {% else %}
{% elif low > 60 %} {{ kallen_bedtime | timestamp_custom('%H:%M',false) }}
{% endif %}
{% elif low > 60 or high > 74 %}
{% if kallen_bedtime < cutoff %} {% if kallen_bedtime < cutoff %}
{{ kallen_bedtime | timestamp_custom('%H:%M',false) }} {{ kallen_bedtime | timestamp_custom('%H:%M',false) }}
{% else %} {% else %}
21:30 22:00
{% endif %} {% endif %}
{% elif 56 <= low <= 60 %}
22:30
{% else %} {% else %}
00:00 00:00
{% endif %} {% endif %}
@ -624,11 +629,11 @@ script:
{% set low = states('sensor.overnight_lowest_temperature') | int %} {% set low = states('sensor.overnight_lowest_temperature') | int %}
{% set high = states('sensor.todays_high_temp') | int %} {% set high = states('sensor.todays_high_temp') | int %}
{% if low > 60 or is_state('input_boolean.hot_day','on') %} {% if low > 60 or is_state('input_boolean.hot_day','on') %}
00:00
{% elif 50 <= low <= 60 %}
01:00 01:00
{% elif low >= states('input_number.master_bedroom_fan_threshold') | int and high > 60 %} {% elif 50 <= low <= 60 %}
02:00 02:00
{% elif low >= states('input_number.master_bedroom_fan_threshold') | int and high > 60 %}
03:00
{% else %} {% else %}
06:00 06:00
{% endif %} {% endif %}
@ -714,11 +719,16 @@ script:
entity_id: input_select.scheduled_climate_mode_emma_bedroom entity_id: input_select.scheduled_climate_mode_emma_bedroom
data: data:
option: > option: >
{% if is_state('input_boolean.emma_bedroom_aircon_installed','on') %} {% set low = states('sensor.overnight_lowest_temperature') | int %}
{% if (states('sensor.overnight_lowest_temperature') | int) >= (states('input_number.emma_aircon_threshold') | int) %} {% set run_threshold = states('input_number.emma_bedroom_aircon_run_threshold') | int %}
{% set mode_threshold = states('input_number.emma_bedroom_aircon_mode_threshold') | int %}
{% if is_state('input_boolean.emma_bedroom_aircon_installed','off') %}
White Noise
{% elif low >= run_threshold %}
{% if low >= mode_threshold %}
AC AC
{% else %} {% else %}
White Noise Fan
{% endif %} {% endif %}
{% else %} {% else %}
White Noise White Noise

View File

@ -1210,14 +1210,23 @@
min_mireds: 153 min_mireds: 153
max_mireds: 500 max_mireds: 500
effect_list: effect_list:
- None - 'off'
- candle - candle
- fire - fire
- prism - prism
- sparkle
- opal
- glisten
- underwater
- cosmos
- sunbeam
- enchant
- sunrise
- sunset
supported_color_modes: supported_color_modes:
- color_temp - color_temp
- xy - xy
effect: None effect: 'off'
color_mode: xy color_mode: xy
brightness: 179 brightness: 179
color_temp_kelvin: color_temp_kelvin:
@ -1244,14 +1253,23 @@
min_mireds: 153 min_mireds: 153
max_mireds: 500 max_mireds: 500
effect_list: effect_list:
- None - 'off'
- candle - candle
- fire - fire
- prism - prism
- sparkle
- opal
- glisten
- underwater
- cosmos
- sunbeam
- enchant
- sunrise
- sunset
supported_color_modes: supported_color_modes:
- color_temp - color_temp
- xy - xy
effect: None effect: 'off'
color_mode: xy color_mode: xy
brightness: 255 brightness: 255
color_temp_kelvin: color_temp_kelvin:
@ -1278,10 +1296,13 @@
min_mireds: 153 min_mireds: 153
max_mireds: 500 max_mireds: 500
effect_list: effect_list:
- None - 'off'
- candle - candle
- fire - fire
- prism - prism
- sparkle
- opal
- glisten
supported_color_modes: supported_color_modes:
- color_temp - color_temp
- xy - xy
@ -1342,14 +1363,23 @@
min_mireds: 153 min_mireds: 153
max_mireds: 500 max_mireds: 500
effect_list: effect_list:
- None - 'off'
- candle - candle
- fire - fire
- prism - prism
- sparkle
- opal
- glisten
- underwater
- cosmos
- sunbeam
- enchant
- sunrise
- sunset
supported_color_modes: supported_color_modes:
- color_temp - color_temp
- xy - xy
effect: None effect: 'off'
color_mode: xy color_mode: xy
brightness: 255 brightness: 255
color_temp_kelvin: color_temp_kelvin:
@ -1376,14 +1406,23 @@
min_mireds: 153 min_mireds: 153
max_mireds: 500 max_mireds: 500
effect_list: effect_list:
- None - 'off'
- candle - candle
- fire - fire
- prism - prism
- sparkle
- opal
- glisten
- underwater
- cosmos
- sunbeam
- enchant
- sunrise
- sunset
supported_color_modes: supported_color_modes:
- color_temp - color_temp
- xy - xy
effect: None effect: 'off'
color_mode: xy color_mode: xy
brightness: 255 brightness: 255
color_temp_kelvin: color_temp_kelvin:
@ -1441,14 +1480,17 @@
min_mireds: 153 min_mireds: 153
max_mireds: 500 max_mireds: 500
effect_list: effect_list:
- None - 'off'
- candle - candle
- fire - fire
- prism - prism
- sparkle
- opal
- glisten
supported_color_modes: supported_color_modes:
- color_temp - color_temp
- xy - xy
effect: None effect: 'off'
color_mode: xy color_mode: xy
brightness: 204 brightness: 204
color_temp_kelvin: color_temp_kelvin:

View File

@ -2481,25 +2481,26 @@ kallen_morning_meds:
kallen_night_meds: kallen_night_meds:
alias: Kallen Night Meds alias: Kallen Night Meds
sequence: sequence:
- service: counter.increment - alias: Increment night reminder counter
metadata: {} metadata: {}
data: {} data: {}
alias: Increment night reminder counter action: counter.increment
- service: script.text_notify target:
data: entity_id: counter.kallen_night_meds_reminder_count
- data:
type: alert type: alert
who: all who: all
message: clear_notification message: clear_notification
tag: kallen-night-meds tag: kallen-night-meds
alias: Clear previous night notification alias: Clear previous night notification
action: script.text_notify
- delay: - delay:
hours: 0 hours: 0
minutes: 0 minutes: 0
seconds: 5 seconds: 5
milliseconds: 0 milliseconds: 0
- parallel: - parallel:
- service: script.text_notify - data:
data:
who: "{% if states('person.christina_stork') in ['Bob Evans','BobEvans'] %}\n who: "{% if states('person.christina_stork') in ['Bob Evans','BobEvans'] %}\n
\ tony\n{% else %}\n parents\n{% endif %}\n" \ tony\n{% else %}\n parents\n{% endif %}\n"
type: alert type: alert
@ -2512,8 +2513,8 @@ kallen_night_meds:
- action: KALLEN_NIGHT_MEDS_SKIPPED - action: KALLEN_NIGHT_MEDS_SKIPPED
title: Skip title: Skip
alias: Send to parents alias: Send to parents
action: script.text_notify
- alias: Send to Kallen - alias: Send to Kallen
service: script.text_notify
data: data:
who: kallen who: kallen
type: alert type: alert
@ -2525,6 +2526,7 @@ kallen_night_meds:
title: Taken title: Taken
- action: KALLEN_NIGHT_MEDS_SKIPPED - action: KALLEN_NIGHT_MEDS_SKIPPED
title: Skip title: Skip
action: script.text_notify
alias: Send text notifications alias: Send text notifications
icon: mdi:medication icon: mdi:medication
mode: restart mode: restart