5963 lines
218 KiB
YAML
5963 lines
218 KiB
YAML
- id: a86036e6-5023-4298-b809-defcbb4d6df9
|
|
alias: LIDL button play area
|
|
mode: restart
|
|
triggers:
|
|
- alias: Play area LIDL button pressed
|
|
trigger: state
|
|
entity_id: event.knop_speelhoek_action
|
|
not_from: unavailable
|
|
variables:
|
|
event: '{{ trigger.to_state.attributes.event_type | default(''unknown'', true)
|
|
}}'
|
|
actions:
|
|
- alias: Which click type
|
|
choose:
|
|
- conditions:
|
|
- alias: Short
|
|
condition: template
|
|
value_template: '{{ event == ''on'' }}'
|
|
sequence:
|
|
- alias: toggle light
|
|
action: light.toggle
|
|
target:
|
|
entity_id: light.groep_speelhoek
|
|
- conditions:
|
|
- alias: Double
|
|
condition: template
|
|
value_template: '{{ event == ''off'' }}'
|
|
sequence:
|
|
- alias: Toggle bookcase light
|
|
action: light.toggle
|
|
target:
|
|
entity_id: light.boekenkast
|
|
- id: 3b350cdb-4a8e-4ce9-b239-fc2e329f931d
|
|
alias: Activate Guest Mode when Guest Wifi is used
|
|
triggers:
|
|
- trigger: state
|
|
entity_id: sensor.guest_wifi_active
|
|
to: null
|
|
id: 'on'
|
|
- trigger: state
|
|
entity_id: sensor.guest_wifi_active
|
|
to: '0'
|
|
for:
|
|
hours: 2
|
|
id: 'off'
|
|
conditions:
|
|
- "{{\n trigger.id == 'off'\n or\n (\n trigger.to_state.state | is_number\n\
|
|
\ and trigger.from_state.state | is_number\n and trigger.to_state.state\
|
|
\ > trigger.from_state.state\n )\n}}\n"
|
|
actions:
|
|
- alias: Toggle guest mode input boolean
|
|
action: input_boolean.turn_{{ trigger.id }}
|
|
target:
|
|
entity_id: input_boolean.gast
|
|
- if: '{{ trigger.id == ''on'' }}'
|
|
then:
|
|
- variables:
|
|
added: "{{\n trigger.to_state.attributes.names\n | reject('in', trigger.from_state.attributes.names)\n\
|
|
\ | list\n}}\n"
|
|
- alias: Notify about new guests
|
|
repeat:
|
|
for_each: ' {{ added }}'
|
|
sequence:
|
|
- alias: Trigger guest mode notification
|
|
action: script.turn_on
|
|
target:
|
|
entity_id: script.guest_mode_sensor
|
|
data:
|
|
variables:
|
|
guest: ' {{ repeat.item }}'
|
|
- id: '1718219154509'
|
|
alias: Luchtreiniger Slaapkamer
|
|
triggers:
|
|
- trigger: time
|
|
at: '21:30:00'
|
|
id: time
|
|
- trigger: state
|
|
entity_id:
|
|
- sensor.house_mode
|
|
to: Slapen
|
|
id: sleep_time
|
|
- trigger: state
|
|
entity_id:
|
|
- sensor.house_mode
|
|
from: Slapen
|
|
id: no_more_sleep_time
|
|
- trigger: state
|
|
entity_id:
|
|
- sensor.luchtreiniger_slaapkamer_air_quality
|
|
not_to:
|
|
- excellent
|
|
- unknown
|
|
id: air_quality
|
|
- trigger: state
|
|
entity_id:
|
|
- sensor.luchtreiniger_slaapkamer_air_quality
|
|
to: excellent
|
|
id: air_quality
|
|
for:
|
|
minutes: 5
|
|
- trigger: time_pattern
|
|
hours: /1
|
|
id: quality_check
|
|
actions:
|
|
- choose:
|
|
- conditions:
|
|
- condition: trigger
|
|
id:
|
|
- air_quality
|
|
- sleep_time
|
|
- quality_check
|
|
- condition: state
|
|
entity_id: sensor.house_mode
|
|
state: Slapen
|
|
- condition: not
|
|
conditions:
|
|
- condition: state
|
|
entity_id: sensor.luchtreiniger_slaapkamer_air_quality
|
|
state: excellent
|
|
sequence:
|
|
- alias: Turn on bedroom air purifier at low speed for sleep mode
|
|
action: fan.turn_on
|
|
data:
|
|
percentage: 11
|
|
target:
|
|
entity_id: fan.luchtreiniger_slaapkamer
|
|
- alias: Turn off bedroom air purifier LED for sleep
|
|
action: switch.turn_off
|
|
target:
|
|
entity_id: switch.luchtreiniger_slaapkamer_led_enable
|
|
- conditions:
|
|
- condition: trigger
|
|
id:
|
|
- time
|
|
- air_quality
|
|
- condition: time
|
|
after: '21:30'
|
|
- condition: not
|
|
conditions:
|
|
- condition: state
|
|
entity_id: sensor.luchtreiniger_slaapkamer_air_quality
|
|
state: excellent
|
|
- condition: numeric_state
|
|
entity_id: zone.home
|
|
above: 0
|
|
sequence:
|
|
- alias: Turn on bedroom air purifier in auto mode
|
|
action: fan.turn_on
|
|
data:
|
|
preset_mode: auto
|
|
target:
|
|
entity_id: fan.luchtreiniger_slaapkamer
|
|
- conditions:
|
|
- condition: trigger
|
|
id:
|
|
- air_quality
|
|
- sleep_time
|
|
- no_more_sleep_time
|
|
- condition: or
|
|
conditions:
|
|
- condition: trigger
|
|
id:
|
|
- no_more_sleep_time
|
|
- condition: and
|
|
conditions:
|
|
- condition: state
|
|
entity_id: sensor.house_mode
|
|
state: Slapen
|
|
- condition: state
|
|
entity_id: sensor.luchtreiniger_slaapkamer_air_quality
|
|
state: excellent
|
|
for:
|
|
minutes: 5
|
|
sequence:
|
|
- alias: Turn off bedroom air purifier when air quality is excellent
|
|
action: fan.turn_off
|
|
target:
|
|
entity_id: fan.luchtreiniger_slaapkamer
|
|
- alias: Turn on bedroom air purifier LED when stopping
|
|
action: switch.turn_on
|
|
target:
|
|
entity_id: switch.luchtreiniger_slaapkamer_led_enable
|
|
- id: 06666ef4-abec-4f74-8282-1cf575c64c8f
|
|
alias: Turn on light based on trapdoor attic
|
|
triggers:
|
|
- trigger: state
|
|
entity_id: binary_sensor.vlieringluik_contact
|
|
from:
|
|
- 'on'
|
|
- 'off'
|
|
to:
|
|
- 'on'
|
|
- 'off'
|
|
actions:
|
|
- alias: Turn on light
|
|
action: light.turn_{{ trigger.to_state.state }}
|
|
target:
|
|
entity_id: light.vliering_led
|
|
- id: c9be7372-de6f-4763-b0d0-23665b7f1e9b
|
|
alias: Christmass lights
|
|
mode: parallel
|
|
triggers:
|
|
- trigger: state
|
|
entity_id: light.tuinlampjes
|
|
to:
|
|
- 'on'
|
|
- 'off'
|
|
from:
|
|
- 'on'
|
|
- 'off'
|
|
id: icicles
|
|
- trigger: state
|
|
entity_id: light.eettafel
|
|
to: 'on'
|
|
id: tree_star
|
|
- trigger: state
|
|
entity_id: light.tv_lamp
|
|
to:
|
|
- 'on'
|
|
- 'off'
|
|
from:
|
|
- 'on'
|
|
- 'off'
|
|
id: lantarn
|
|
- trigger: state
|
|
entity_id: event.shelly1_eettafel_shelly1_eettafel
|
|
not_from: unavailable
|
|
id: to_bed
|
|
conditions:
|
|
- alias: Check for long press event on Eettaffel button
|
|
condition: template
|
|
value_template: '{{ trigger.id != to_bed or trigger.to_state.attributes.event_type
|
|
== ''long_press'' }}'
|
|
- alias: It's Chirstmas time
|
|
condition: state
|
|
entity_id: input_boolean.christmas_time
|
|
state: 'on'
|
|
actions:
|
|
- alias: Which action?
|
|
choose:
|
|
- conditions: '{{ trigger.id == ''icicles''}}'
|
|
sequence:
|
|
- alias: Turn icicles on or off
|
|
action: switch.turn_{{ trigger.to_state.state }}
|
|
target:
|
|
entity_id: '{{ ''switch.ijspegels'' }}'
|
|
- conditions: '{{ trigger.id == ''lantarn''}}'
|
|
sequence:
|
|
- alias: Wait until lantarn is available
|
|
wait_template: '{{ states(''switch.kerstlantaarn'') not in [ ''unavailable'',
|
|
''unknown''] }}'
|
|
- alias: lantarn schakelen met tvlamp
|
|
action: switch.turn_{{ trigger.to_state.state }}
|
|
target:
|
|
entity_id: '{{ ''switch.kerstlantaarn'' }}'
|
|
- conditions: '{{ trigger.id == ''tree_star''}}'
|
|
sequence:
|
|
- alias: Turn christmas tree and star on
|
|
action: switch.turn_on
|
|
target:
|
|
entity_id: '{{[''switch.kerstboom'', ''switch.kerstster'', ''switch.kerstbal'']
|
|
}}'
|
|
- conditions: '{{ trigger.id == ''to_bed''}}'
|
|
sequence:
|
|
- alias: Turn christmas tree and star off
|
|
action: switch.turn_off
|
|
target:
|
|
entity_id: '{{[''switch.kerstboom'', ''switch.kerstster'', ''switch.kerstsbal'']
|
|
}}'
|
|
- id: f540e546-ae22-4535-958f-35693ba636e5
|
|
alias: Disable and eneable Christmas integrations
|
|
triggers:
|
|
- trigger: state
|
|
entity_id: input_boolean.christmas_time
|
|
to:
|
|
- 'on'
|
|
- 'off'
|
|
actions:
|
|
- action: homeassistant.{{ 'disable' if trigger.to_state.state == 'off' else 'enable'
|
|
}}_config_entry
|
|
data:
|
|
config_entry_id:
|
|
- 48b8951b1855b53bba5a91888055fa5f
|
|
- 924ced5da4fa886ac83bcfdab71dddb6
|
|
- 9118fe1fd50a9108740ac05c000f4f04
|
|
- 29e8c93c5cfff4b86c1e87698d4efe61
|
|
- 082d600e428cc075a9f6575c05ac535a
|
|
- template:
|
|
- triggers:
|
|
- alias: Update combined weather forecast every 5 minutes at 30 seconds past the
|
|
minute
|
|
trigger: time_pattern
|
|
minutes: /5
|
|
seconds: '30'
|
|
- alias: Update combined weather forecast on Home Assistant startup
|
|
trigger: homeassistant
|
|
event: start
|
|
- alias: Update combined weather forecast on manual trigger event
|
|
trigger: event
|
|
event_type: update_combined_forecast
|
|
actions:
|
|
- alias: Define weights for different weather integrations
|
|
variables:
|
|
debug: false
|
|
weight:
|
|
- entity_id: weather.knmi
|
|
current: 3
|
|
daily: 3
|
|
hourly: 4
|
|
- entity_id: weather.buienradar
|
|
current: 2
|
|
daily: 2
|
|
forecast_all:
|
|
- attr: condition
|
|
- attr: wind_bearing
|
|
round: 2
|
|
- attr: cloud_coverage
|
|
round: 0
|
|
- attr: temperature
|
|
round: 1
|
|
- attr: wind_speed
|
|
round: 2
|
|
- attr: precipitation
|
|
round: 2
|
|
- attr: precipitation_probability
|
|
round: 0
|
|
- attr: dew_point
|
|
round: 1
|
|
- attr: uv_index
|
|
round: 2
|
|
- attr: apparent_temperature
|
|
round: 1
|
|
- attr: pressure
|
|
round: 2
|
|
- attr: humidity
|
|
round: 0
|
|
forecast_daily:
|
|
- attr: templow
|
|
round: 2
|
|
- attr: wind_gust_speed
|
|
round: 0
|
|
forecast_twice_daily:
|
|
- attr: is_daytime
|
|
- alias: Set right forecast type
|
|
variables:
|
|
type: hourly
|
|
supported:
|
|
- 2
|
|
- 3
|
|
- 6
|
|
- 7
|
|
- alias: Get the forecast data from the entities
|
|
sequence: &id001
|
|
- alias: Get all entities which support the forecast type
|
|
variables:
|
|
weather_entities: "{{\n states.weather \n | selectattr('attributes.supported_features',\
|
|
\ 'defined')\n | selectattr('attributes.supported_features', 'in',\
|
|
\ supported)\n | map(attribute='entity_id') \n | reject('in', integration_entities('template'))\n\
|
|
\ | select('has_value')\n | list\n}}\n"
|
|
- alias: Get forecasts in case there are entities
|
|
if: '{{ weather_entities | count > 0 }}'
|
|
then:
|
|
- alias: Set forecast available flag when entities found
|
|
variables:
|
|
forecast_available: true
|
|
- alias: Get hourly forecast data out of selected entities
|
|
action: weather.get_forecasts
|
|
data:
|
|
type: '{{ type }}'
|
|
target:
|
|
entity_id: '{{ weather_entities }}'
|
|
response_variable: forecast
|
|
else:
|
|
- alias: Set forecast unavailable flag when no entities found
|
|
variables:
|
|
forecast_available: false
|
|
- alias: Combine the forecasts in one
|
|
variables:
|
|
hourly_entities: '{{ weather_entities }}'
|
|
hourly: "{# set number of days to use for forecasts #}\n {% set forecast_days\
|
|
\ = 3 if type == 'hourly' else 10 %}\n{# define valid forecast attributes\
|
|
\ and precision for rounding #}\n {% set forecast_attr = forecast_all if\
|
|
\ type == 'hourly' else forecast_all + forecast_daily if type == 'daily'\
|
|
\ else forecast_all + forecast_twice_daily %}\n{# check if forecast is retreived\
|
|
\ #}\n {% if forecast_available %}\n {# combine all forecasts in one list\
|
|
\ #}\n {% if weight is defined\n and weight is list\n and\
|
|
\ weight | count > 0\n and weight[0] is mapping\n %}\n {%\
|
|
\ set ns = namespace(all=[]) %}\n {% for k, v in forecast.items() %}\n\
|
|
\ {% set w = weight \n | selectattr('entity_id',\
|
|
\ 'eq', k)\n | map(attribute=type)\n \
|
|
\ | first\n | default(1) %}\n {% set ns.all\
|
|
\ = ns.all + v.forecast * w %}\n {% endfor %}\n {% set all = ns.all\
|
|
\ %}\n {% else %}\n {% set all = forecast.values() | map(attribute='forecast')\
|
|
\ | sum(start=[]) %}\n {% endif %}\n {# make sure no old forecasts are\
|
|
\ included, and only 3 days for hourly forecasts, and 10 days for daily\
|
|
\ #}\n {% set compare_start = today_at() if type == 'daily' else now()\
|
|
\ - timedelta(hours=1) %}\n {% set compare_end = now() + timedelta(days=forecast_days)\
|
|
\ %}\n {# align datetimes so they all use local timezone, and the same\
|
|
\ start time for daily forecasts #}\n {% set ns = namespace(aligned=[],\
|
|
\ forecast=[]) %}\n {% for item in all if compare_start <= as_datetime(item.datetime)\
|
|
\ | as_local <= compare_end %}\n {% set new_dt = item.datetime | as_datetime(item.datetime)\
|
|
\ | as_local %}\n {% set new_dt = new_dt.isoformat() if type in ['hourly',\
|
|
\ 'twice_daily'] else new_dt.replace(hour=0, minute=0).isoformat() %}\n\
|
|
\ {% set ns.aligned = ns.aligned + [dict(item, datetime=new_dt)] %}\n\
|
|
\ {% endfor %}\n {# set list of unique datetime #}\n {% set dt_list\
|
|
\ = ns.aligned | map(attribute='datetime') | unique | sort | list %}\n \
|
|
\ {# create forecast list item for each datetime #}\n {% for dt in dt_list\
|
|
\ %}\n {% set forecasts = ns.aligned | selectattr('datetime', 'eq',\
|
|
\ dt) | list %}\n {% set dt_ns = namespace(keys=[], forecast=dict(datetime=dt))\
|
|
\ %}\n {# find forecast available forecast items #}\n {% for\
|
|
\ item in forecasts %}\n {% set dt_ns.keys = dt_ns.keys + item.keys()\
|
|
\ | list %}\n {% endfor %}\n {# remove unsupported types for\
|
|
\ template weather #}\n {% set allowed_keys = forecast_attr | map(attribute='attr')\
|
|
\ | list %}\n {% set keys_list = dt_ns.keys | unique | select('in',\
|
|
\ allowed_keys) %}\n {# find value for each forecast item #}\n \
|
|
\ {% for key in keys_list %}\n {% set key_items = forecasts\
|
|
\ | selectattr(key, 'defined') | map(attribute=key) | list %}\n \
|
|
\ {# find most frequent item for condition #}\n {% if key ==\
|
|
\ 'condition' %}\n {% if 'clear-night' in key_items %}\n \
|
|
\ {% set key_items = key_items | map('replace', 'sunny', 'clear-night')\
|
|
\ | list %}\n {% endif %}\n {% set add_dict =\
|
|
\ dict(condition=statistical_mode(key_items, none)) %}\n {%\
|
|
\ set dt_ns.forecast = dict(dt_ns.forecast, **add_dict) %}\n \
|
|
\ {% elif key == 'is_daytime' %}\n {% set add_dict = dict(is_daytime=key_items[0])\
|
|
\ %}\n {% set dt_ns.forecast = dict(dt_ns.forecast, **add_dict)\
|
|
\ %} \n {# find median for other (numeric)\
|
|
\ forecast types #}\n {% else %}\n {# filter out\
|
|
\ non numeric values #}\n {% set values = key_items | map('replace',\
|
|
\ none, 0) | select('is_number') | map('float') | list | sort %}\n \
|
|
\ {% if values | count > 0 %}\n {# add forecast\
|
|
\ item to forecast #}\n {% set round = forecast_attr\
|
|
\ | selectattr('attr', 'eq', key) | map(attribute='round') | list | first\
|
|
\ %}\n {% set add_dict = {key: median(values)|round(round)}\
|
|
\ %}\n {% set dt_ns.forecast = dict(dt_ns.forecast, **add_dict)\
|
|
\ %} \n {% endif %}\n {% endif %}\n {%\
|
|
\ endfor %}\n {# combine forecast for each datetime in one list #}\n\
|
|
\ {% set ns.forecast = ns.forecast + [dt_ns.forecast] %}\n {%\
|
|
\ endfor %}\n {# output the forecast #}\n {{ ns.forecast }}\n{# create\
|
|
\ twice daily forecast based on hourly forecast if not provided normally\
|
|
\ #} {% elif type == 'twice_daily' and hourly | count > 0 %}\n {% set times\
|
|
\ = hourly | selectattr('datetime', 'search', 'T09:00|T18:00') | map(attribute='datetime')\
|
|
\ | list %}\n {% set ns = namespace(forecast=[], item={}) %}\n {% for\
|
|
\ t in times %}\n {% set day = t is search 'T09:00' %}\n {% set dates\
|
|
\ = hourly | map(attribute='datetime') | list %}\n {% set index = dates.index(t)\
|
|
\ %}\n {% set data = hourly[index:index+(9 if day else 13)] %}\n {%\
|
|
\ set key_list = data[0].keys() | list %}\n {% set ns.item = {'datetime':\
|
|
\ t, 'is_daytime': day} %}\n {% for key in key_list %}\n {% set\
|
|
\ key_items = data | selectattr(key, 'defined') | map(attribute=key) | list\
|
|
\ %}\n {% if key_items[0] is string %}\n {% set ns.item = dict(ns.item,\
|
|
\ **{key: key_items | statistical_mode}) %}\n {% elif key == 'temperature'\
|
|
\ %}\n {% set ns.item = dict(ns.item, **{key: key_items | max, 'templow':\
|
|
\ key_items | min}) %}\n {% elif key_items[0] | is_number %}\n \
|
|
\ {% set r = forecast_attr | selectattr('attr', 'eq', key) | map(attribute='round')\
|
|
\ | first | default(1) %}\n {% set ns.item = dict(ns.item, **{key:\
|
|
\ key_items | average | round(r)}) %}\n {% endif %}\n {% endfor\
|
|
\ %}\n {% set ns.forecast = ns.forecast + [ns.item] %}\n {% endfor %}\n\
|
|
\ {{ ns.forecast }}\n{% else %}\n []\n{% endif %}\n"
|
|
- alias: Set right forecast type
|
|
variables:
|
|
type: daily
|
|
supported:
|
|
- 1
|
|
- 3
|
|
- 5
|
|
- 7
|
|
- alias: Get the forecast data from the entities
|
|
sequence: *id001
|
|
- alias: Combine the forecasts in one
|
|
variables:
|
|
daily_entities: '{{ weather_entities }}'
|
|
daily: "{# set number of days to use for forecasts #}\n {% set forecast_days\
|
|
\ = 3 if type == 'hourly' else 10 %}\n{# define valid forecast attributes\
|
|
\ and precision for rounding #}\n {% set forecast_attr = forecast_all if\
|
|
\ type == 'hourly' else forecast_all + forecast_daily if type == 'daily'\
|
|
\ else forecast_all + forecast_twice_daily %}\n{# check if forecast is retreived\
|
|
\ #}\n {% if forecast_available %}\n {# combine all forecasts in one list\
|
|
\ #}\n {% if weight is defined\n and weight is list\n and\
|
|
\ weight | count > 0\n and weight[0] is mapping\n %}\n {%\
|
|
\ set ns = namespace(all=[]) %}\n {% for k, v in forecast.items() %}\n\
|
|
\ {% set w = weight \n | selectattr('entity_id',\
|
|
\ 'eq', k)\n | map(attribute=type)\n \
|
|
\ | first\n | default(1) %}\n {% set ns.all\
|
|
\ = ns.all + v.forecast * w %}\n {% endfor %}\n {% set all = ns.all\
|
|
\ %}\n {% else %}\n {% set all = forecast.values() | map(attribute='forecast')\
|
|
\ | sum(start=[]) %}\n {% endif %}\n {# make sure no old forecasts are\
|
|
\ included, and only 3 days for hourly forecasts, and 10 days for daily\
|
|
\ #}\n {% set compare_start = today_at() if type == 'daily' else now()\
|
|
\ - timedelta(hours=1) %}\n {% set compare_end = now() + timedelta(days=forecast_days)\
|
|
\ %}\n {# align datetimes so they all use local timezone, and the same\
|
|
\ start time for daily forecasts #}\n {% set ns = namespace(aligned=[],\
|
|
\ forecast=[]) %}\n {% for item in all if compare_start <= as_datetime(item.datetime)\
|
|
\ | as_local <= compare_end %}\n {% set new_dt = item.datetime | as_datetime(item.datetime)\
|
|
\ | as_local %}\n {% set new_dt = new_dt.isoformat() if type in ['hourly',\
|
|
\ 'twice_daily'] else new_dt.replace(hour=0, minute=0).isoformat() %}\n\
|
|
\ {% set ns.aligned = ns.aligned + [dict(item, datetime=new_dt)] %}\n\
|
|
\ {% endfor %}\n {# set list of unique datetime #}\n {% set dt_list\
|
|
\ = ns.aligned | map(attribute='datetime') | unique | sort | list %}\n \
|
|
\ {# create forecast list item for each datetime #}\n {% for dt in dt_list\
|
|
\ %}\n {% set forecasts = ns.aligned | selectattr('datetime', 'eq',\
|
|
\ dt) | list %}\n {% set dt_ns = namespace(keys=[], forecast=dict(datetime=dt))\
|
|
\ %}\n {# find forecast available forecast items #}\n {% for\
|
|
\ item in forecasts %}\n {% set dt_ns.keys = dt_ns.keys + item.keys()\
|
|
\ | list %}\n {% endfor %}\n {# remove unsupported types for\
|
|
\ template weather #}\n {% set allowed_keys = forecast_attr | map(attribute='attr')\
|
|
\ | list %}\n {% set keys_list = dt_ns.keys | unique | select('in',\
|
|
\ allowed_keys) %}\n {# find value for each forecast item #}\n \
|
|
\ {% for key in keys_list %}\n {% set key_items = forecasts\
|
|
\ | selectattr(key, 'defined') | map(attribute=key) | list %}\n \
|
|
\ {# find most frequent item for condition #}\n {% if key ==\
|
|
\ 'condition' %}\n {% if 'clear-night' in key_items %}\n \
|
|
\ {% set key_items = key_items | map('replace', 'sunny', 'clear-night')\
|
|
\ | list %}\n {% endif %}\n {% set add_dict =\
|
|
\ dict(condition=statistical_mode(key_items, none)) %}\n {%\
|
|
\ set dt_ns.forecast = dict(dt_ns.forecast, **add_dict) %}\n \
|
|
\ {% elif key == 'is_daytime' %}\n {% set add_dict = dict(is_daytime=key_items[0])\
|
|
\ %}\n {% set dt_ns.forecast = dict(dt_ns.forecast, **add_dict)\
|
|
\ %} \n {# find median for other (numeric)\
|
|
\ forecast types #}\n {% else %}\n {# filter out\
|
|
\ non numeric values #}\n {% set values = key_items | map('replace',\
|
|
\ none, 0) | select('is_number') | map('float') | list | sort %}\n \
|
|
\ {% if values | count > 0 %}\n {# add forecast\
|
|
\ item to forecast #}\n {% set round = forecast_attr\
|
|
\ | selectattr('attr', 'eq', key) | map(attribute='round') | list | first\
|
|
\ %}\n {% set add_dict = {key: median(values)|round(round)}\
|
|
\ %}\n {% set dt_ns.forecast = dict(dt_ns.forecast, **add_dict)\
|
|
\ %} \n {% endif %}\n {% endif %}\n {%\
|
|
\ endfor %}\n {# combine forecast for each datetime in one list #}\n\
|
|
\ {% set ns.forecast = ns.forecast + [dt_ns.forecast] %}\n {%\
|
|
\ endfor %}\n {# output the forecast #}\n {{ ns.forecast }}\n{# create\
|
|
\ twice daily forecast based on hourly forecast if not provided normally\
|
|
\ #} {% elif type == 'twice_daily' and hourly | count > 0 %}\n {% set times\
|
|
\ = hourly | selectattr('datetime', 'search', 'T09:00|T18:00') | map(attribute='datetime')\
|
|
\ | list %}\n {% set ns = namespace(forecast=[], item={}) %}\n {% for\
|
|
\ t in times %}\n {% set day = t is search 'T09:00' %}\n {% set dates\
|
|
\ = hourly | map(attribute='datetime') | list %}\n {% set index = dates.index(t)\
|
|
\ %}\n {% set data = hourly[index:index+(9 if day else 13)] %}\n {%\
|
|
\ set key_list = data[0].keys() | list %}\n {% set ns.item = {'datetime':\
|
|
\ t, 'is_daytime': day} %}\n {% for key in key_list %}\n {% set\
|
|
\ key_items = data | selectattr(key, 'defined') | map(attribute=key) | list\
|
|
\ %}\n {% if key_items[0] is string %}\n {% set ns.item = dict(ns.item,\
|
|
\ **{key: key_items | statistical_mode}) %}\n {% elif key == 'temperature'\
|
|
\ %}\n {% set ns.item = dict(ns.item, **{key: key_items | max, 'templow':\
|
|
\ key_items | min}) %}\n {% elif key_items[0] | is_number %}\n \
|
|
\ {% set r = forecast_attr | selectattr('attr', 'eq', key) | map(attribute='round')\
|
|
\ | first | default(1) %}\n {% set ns.item = dict(ns.item, **{key:\
|
|
\ key_items | average | round(r)}) %}\n {% endif %}\n {% endfor\
|
|
\ %}\n {% set ns.forecast = ns.forecast + [ns.item] %}\n {% endfor %}\n\
|
|
\ {{ ns.forecast }}\n{% else %}\n []\n{% endif %}\n"
|
|
- alias: Set right forecast type
|
|
variables:
|
|
type: twice_daily
|
|
supported:
|
|
- 4
|
|
- 5
|
|
- 6
|
|
- 7
|
|
- alias: Get the forecast data from the entities
|
|
sequence: *id001
|
|
- alias: Combine the forecasts in one
|
|
variables:
|
|
twice_daily_entities: '{{ weather_entities }}'
|
|
twice_daily: "{# set number of days to use for forecasts #}\n {% set forecast_days\
|
|
\ = 3 if type == 'hourly' else 10 %}\n{# define valid forecast attributes\
|
|
\ and precision for rounding #}\n {% set forecast_attr = forecast_all if\
|
|
\ type == 'hourly' else forecast_all + forecast_daily if type == 'daily'\
|
|
\ else forecast_all + forecast_twice_daily %}\n{# check if forecast is retreived\
|
|
\ #}\n {% if forecast_available %}\n {# combine all forecasts in one list\
|
|
\ #}\n {% if weight is defined\n and weight is list\n and\
|
|
\ weight | count > 0\n and weight[0] is mapping\n %}\n {%\
|
|
\ set ns = namespace(all=[]) %}\n {% for k, v in forecast.items() %}\n\
|
|
\ {% set w = weight \n | selectattr('entity_id',\
|
|
\ 'eq', k)\n | map(attribute=type)\n \
|
|
\ | first\n | default(1) %}\n {% set ns.all\
|
|
\ = ns.all + v.forecast * w %}\n {% endfor %}\n {% set all = ns.all\
|
|
\ %}\n {% else %}\n {% set all = forecast.values() | map(attribute='forecast')\
|
|
\ | sum(start=[]) %}\n {% endif %}\n {# make sure no old forecasts are\
|
|
\ included, and only 3 days for hourly forecasts, and 10 days for daily\
|
|
\ #}\n {% set compare_start = today_at() if type == 'daily' else now()\
|
|
\ - timedelta(hours=1) %}\n {% set compare_end = now() + timedelta(days=forecast_days)\
|
|
\ %}\n {# align datetimes so they all use local timezone, and the same\
|
|
\ start time for daily forecasts #}\n {% set ns = namespace(aligned=[],\
|
|
\ forecast=[]) %}\n {% for item in all if compare_start <= as_datetime(item.datetime)\
|
|
\ | as_local <= compare_end %}\n {% set new_dt = item.datetime | as_datetime(item.datetime)\
|
|
\ | as_local %}\n {% set new_dt = new_dt.isoformat() if type in ['hourly',\
|
|
\ 'twice_daily'] else new_dt.replace(hour=0, minute=0).isoformat() %}\n\
|
|
\ {% set ns.aligned = ns.aligned + [dict(item, datetime=new_dt)] %}\n\
|
|
\ {% endfor %}\n {# set list of unique datetime #}\n {% set dt_list\
|
|
\ = ns.aligned | map(attribute='datetime') | unique | sort | list %}\n \
|
|
\ {# create forecast list item for each datetime #}\n {% for dt in dt_list\
|
|
\ %}\n {% set forecasts = ns.aligned | selectattr('datetime', 'eq',\
|
|
\ dt) | list %}\n {% set dt_ns = namespace(keys=[], forecast=dict(datetime=dt))\
|
|
\ %}\n {# find forecast available forecast items #}\n {% for\
|
|
\ item in forecasts %}\n {% set dt_ns.keys = dt_ns.keys + item.keys()\
|
|
\ | list %}\n {% endfor %}\n {# remove unsupported types for\
|
|
\ template weather #}\n {% set allowed_keys = forecast_attr | map(attribute='attr')\
|
|
\ | list %}\n {% set keys_list = dt_ns.keys | unique | select('in',\
|
|
\ allowed_keys) %}\n {# find value for each forecast item #}\n \
|
|
\ {% for key in keys_list %}\n {% set key_items = forecasts\
|
|
\ | selectattr(key, 'defined') | map(attribute=key) | list %}\n \
|
|
\ {# find most frequent item for condition #}\n {% if key ==\
|
|
\ 'condition' %}\n {% if 'clear-night' in key_items %}\n \
|
|
\ {% set key_items = key_items | map('replace', 'sunny', 'clear-night')\
|
|
\ | list %}\n {% endif %}\n {% set add_dict =\
|
|
\ dict(condition=statistical_mode(key_items, none)) %}\n {%\
|
|
\ set dt_ns.forecast = dict(dt_ns.forecast, **add_dict) %}\n \
|
|
\ {% elif key == 'is_daytime' %}\n {% set add_dict = dict(is_daytime=key_items[0])\
|
|
\ %}\n {% set dt_ns.forecast = dict(dt_ns.forecast, **add_dict)\
|
|
\ %} \n {# find median for other (numeric)\
|
|
\ forecast types #}\n {% else %}\n {# filter out\
|
|
\ non numeric values #}\n {% set values = key_items | map('replace',\
|
|
\ none, 0) | select('is_number') | map('float') | list | sort %}\n \
|
|
\ {% if values | count > 0 %}\n {# add forecast\
|
|
\ item to forecast #}\n {% set round = forecast_attr\
|
|
\ | selectattr('attr', 'eq', key) | map(attribute='round') | list | first\
|
|
\ %}\n {% set add_dict = {key: median(values)|round(round)}\
|
|
\ %}\n {% set dt_ns.forecast = dict(dt_ns.forecast, **add_dict)\
|
|
\ %} \n {% endif %}\n {% endif %}\n {%\
|
|
\ endfor %}\n {# combine forecast for each datetime in one list #}\n\
|
|
\ {% set ns.forecast = ns.forecast + [dt_ns.forecast] %}\n {%\
|
|
\ endfor %}\n {# output the forecast #}\n {{ ns.forecast }}\n{# create\
|
|
\ twice daily forecast based on hourly forecast if not provided normally\
|
|
\ #} {% elif type == 'twice_daily' and hourly | count > 0 %}\n {% set times\
|
|
\ = hourly | selectattr('datetime', 'search', 'T09:00|T18:00') | map(attribute='datetime')\
|
|
\ | list %}\n {% set ns = namespace(forecast=[], item={}) %}\n {% for\
|
|
\ t in times %}\n {% set day = t is search 'T09:00' %}\n {% set dates\
|
|
\ = hourly | map(attribute='datetime') | list %}\n {% set index = dates.index(t)\
|
|
\ %}\n {% set data = hourly[index:index+(9 if day else 13)] %}\n {%\
|
|
\ set key_list = data[0].keys() | list %}\n {% set ns.item = {'datetime':\
|
|
\ t, 'is_daytime': day} %}\n {% for key in key_list %}\n {% set\
|
|
\ key_items = data | selectattr(key, 'defined') | map(attribute=key) | list\
|
|
\ %}\n {% if key_items[0] is string %}\n {% set ns.item = dict(ns.item,\
|
|
\ **{key: key_items | statistical_mode}) %}\n {% elif key == 'temperature'\
|
|
\ %}\n {% set ns.item = dict(ns.item, **{key: key_items | max, 'templow':\
|
|
\ key_items | min}) %}\n {% elif key_items[0] | is_number %}\n \
|
|
\ {% set r = forecast_attr | selectattr('attr', 'eq', key) | map(attribute='round')\
|
|
\ | first | default(1) %}\n {% set ns.item = dict(ns.item, **{key:\
|
|
\ key_items | average | round(r)}) %}\n {% endif %}\n {% endfor\
|
|
\ %}\n {% set ns.forecast = ns.forecast + [ns.item] %}\n {% endfor %}\n\
|
|
\ {{ ns.forecast }}\n{% else %}\n []\n{% endif %}\n"
|
|
- alias: Set variable for weather entities for attributes
|
|
variables:
|
|
weather_entities: "{{\n states.weather\n | map(attribute='entity_id')\n\
|
|
\ | reject('in', integration_entities('template'))\n | select('has_value')\n\
|
|
\ | list\n}}\n"
|
|
current_values: "{% set attr_all = forecast_all + forecast_daily %} {% set\
|
|
\ ns = namespace(attributes=['condition'], values={}) %} {% for e in weather_entities\
|
|
\ %}\n {% set ns.attributes = ns.attributes + states[e].attributes.items()\
|
|
\ | selectattr('1', 'is_number') | map(attribute='0') | reject('eq', 'supported_features')\
|
|
\ | list %}\n{% endfor %} {% set attributes = ns.attributes | unique | list\
|
|
\ %} {% for a in attributes %}\n {% if weight is defined and weight is\
|
|
\ list and weight[0] is mapping %}\n {% set ns.weight = [] %}\n {%\
|
|
\ for e in weather_entities %}\n {% set w = weight | selectattr('entity_id',\
|
|
\ 'eq', e) | map(attribute='current') | first | default(1) %}\n {%\
|
|
\ set ns.weight = ns.weight + [states(e) if a == 'condition' else state_attr(e,\
|
|
\ a)] * w %}\n {% endfor %}\n {% set values = ns.weight | reject('none')\
|
|
\ | list %}\n {% else %}\n {% if a == 'condition' %}\n {% set values\
|
|
\ = weather_entities | map('states') | list %}\n {% else %}\n {%\
|
|
\ set values = weather_entities | map('state_attr', a) | select('is_number')\
|
|
\ | list %}\n {% endif %}\n {% endif %}\n {% set r = attr_all | selectattr('attr',\
|
|
\ 'eq', a) | map(attribute='round') | first | default(1) %}\n {% set value\
|
|
\ = values | statistical_mode if a == 'condition' else values | median(none)\
|
|
\ | round(r, default=none) %}\n {% set ns.values = dict(ns.values, **{a:\
|
|
\ value}) %}\n{% endfor %} {{ ns.values }}\n"
|
|
- alias: Send debug notification if debug mode is enabled
|
|
if: '{{ debug | default(false) | bool(false) }}'
|
|
then:
|
|
- alias: Send notification with some debug date
|
|
action: persistent_notification.create
|
|
data:
|
|
title: Weather Combined debug
|
|
message: 'hourly: {{ hourly | count }} items
|
|
|
|
hourly_entities: "{{ hourly_entities | join('', '') }}"
|
|
|
|
daily: {{ daily | count }} items
|
|
|
|
daily_entities: {{ daily_entities | join('', '') }}
|
|
|
|
twice_daily: {{ twice_daily | count }} items
|
|
|
|
twice_daily_entities: {{ twice_daily_entities | join('', '') }}
|
|
|
|
current_values: {{ current_values }}
|
|
|
|
'
|
|
weather:
|
|
- name: Combined
|
|
unique_id: 97b3c060-3146-41dd-91d9-0765d2e15e16
|
|
condition_template: '{{ current_values.get(''condition'', none) }}'
|
|
temperature_template: '{{ current_values.get(''temperature'', none) }}'
|
|
apparent_temperature_template: '{{ current_values.get(''apparent_temperature'',
|
|
none) }}'
|
|
pressure_template: '{{ current_values.get(''pressure'', none) }}'
|
|
wind_speed_template: '{{ current_values.get(''wind_speed'', none) }}'
|
|
wind_gust_speed_template: '{{ current_values.get(''wind_gust_speed'', none)
|
|
}}'
|
|
visibility_template: '{{ current_values.get(''visibility'', none) }}'
|
|
humidity_template: '{{ current_values.get(''humidity'', none) }}'
|
|
wind_bearing_template: '{{ current_values.get(''wind_bearing'', none) }}'
|
|
ozone_template: '{{ current_values.get(''ozone'', none) }}'
|
|
cloud_coverage_template: '{{ current_values.get(''cloud_coverage'', none) }}'
|
|
dew_point_template: '{{ current_values.get(''dew_point'', none) }}'
|
|
temperature_unit: °C
|
|
pressure_unit: hPa
|
|
wind_speed_unit: km/h
|
|
visibility_unit: km
|
|
precipitation_unit: mm
|
|
forecast_hourly_template: '{{ hourly }}'
|
|
forecast_daily_template: '{{ daily }}'
|
|
forecast_twice_daily_template: '{{ twice_daily | default([], true) }}'
|
|
sensor:
|
|
- device_class: temperature
|
|
state_class: measurement
|
|
unit_of_measurement: °C
|
|
availability: "{{\n daily is defined\n and daily is list\n and daily | selectattr('datetime',\
|
|
\ 'search', now().date() | string) | list | count > 0\n}}\n"
|
|
unique_id: 7b190917-6d93-4c01-8854-4a1b7bf9d886
|
|
name: Weather Combined Max Temp Today
|
|
state: "{{\n daily\n | selectattr('datetime', 'search', now().date()| string)\n\
|
|
\ | map(attribute='temperature')\n | list\n | first\n}}\n"
|
|
- device_class: temperature
|
|
state_class: measurement
|
|
unit_of_measurement: °C
|
|
availability: "{{\n daily is defined\n and daily is list\n and daily | selectattr('datetime',\
|
|
\ 'search', now().date() | string) | list | count > 0\n}}\n"
|
|
unique_id: e61acc80-7348-45ed-b83c-070109cd4fe1
|
|
name: Weather Combined Max Temp Tomorrow
|
|
state: "{{\n daily\n | selectattr('datetime', 'search', (now() + timedelta(days=1)).date()\n\
|
|
\ | string)\n | map(attribute='temperature')\n | list\n | first\n\
|
|
}}\n"
|
|
- unique_id: 3098ef4f-aa24-4c27-ae00-514b699a1bfa
|
|
name: Weather Combined daily condition
|
|
state: '{{ daily[0].condition }}'
|
|
icon: "{% set icon = {\n \"clear-night\": \"mdi:weather-night\",\n \"\
|
|
cloudy\": \"mdi:weather-cloudy\",\n \"exceptional\": \"mdi:alert-circle-outline\"\
|
|
,\n \"fog\": \"mdi:weather-fog\",\n \"hail\": \"mdi:weather-hail\",\n\
|
|
\ \"lightning\": \"mdi:weather-lightning\",\n \"lightning-rainy\": \"\
|
|
mdi:weather-lightning-rainy\",\n \"pouring\": \"mdi:weather-pouring\",\n\
|
|
\ \"rainy\": \"mdi:weather-rainy\",\n \"snowy\": \"mdi:weather-snowy\"\
|
|
,\n \"snowy-rainy\": \"mdi:weather-snowy-rainy\",\n \"sunny\": \"mdi:weather-sunny\"\
|
|
,\n \"windy\": \"mdi:weather-windy\",\n \"windy-variant\": \"mdi:weather-windy-variant\"\
|
|
,\n \"partlycloudy\": \"mdi:weather-partly-cloudy\"\n }\n%} {{ icon.get(daily[0].condition,\
|
|
\ 'mdi:cloud-alert') }}\n"
|
|
availability: '{{ daily is defined and daily is list and daily | count > 0 }}'
|
|
binary_sensor:
|
|
- unique_id: 5e88168e-bd66-4f98-8a12-e4cab0fb42c8
|
|
name: Weather combined sun in next hours
|
|
state: '{% set next_hours = hourly[:3] | map(attribute=''condition'') | list
|
|
%} {{ next_hours | select(''in'', [''partlycloudy'', ''sunny'']) | list |
|
|
count > 0 }}
|
|
|
|
'
|
|
icon: "{% set icon = {\n \"clear-night\": \"mdi:weather-night\",\n \"\
|
|
cloudy\": \"mdi:weather-cloudy\",\n \"exceptional\": \"mdi:alert-circle-outline\"\
|
|
,\n \"fog\": \"mdi:weather-fog\",\n \"hail\": \"mdi:weather-hail\",\n\
|
|
\ \"lightning\": \"mdi:weather-lightning\",\n \"lightning-rainy\": \"\
|
|
mdi:weather-lightning-rainy\",\n \"pouring\": \"mdi:weather-pouring\",\n\
|
|
\ \"rainy\": \"mdi:weather-rainy\",\n \"snowy\": \"mdi:weather-snowy\"\
|
|
,\n \"snowy-rainy\": \"mdi:weather-snowy-rainy\",\n \"sunny\": \"mdi:weather-sunny\"\
|
|
,\n \"windy\": \"mdi:weather-windy\",\n \"windy-variant\": \"mdi:weather-windy-variant\"\
|
|
,\n \"partlycloudy\": \"mdi:weather-partly-cloudy\"\n }\n%} {% set next_hours\
|
|
\ = hourly[:3] | map(attribute='condition') | list %} {{ icon.get(statistical_mode(next_hours),\
|
|
\ 'mdi:cloud-alert') }}\n"
|
|
availability: '{{ hourly is defined and hourly is list and hourly | count >=
|
|
3 }}'
|
|
- id: 3d938c95-1b47-4ee3-93ca-56753feb6e94
|
|
alias: Computer Martijn notification actions
|
|
mode: single
|
|
max_exceeded: silent
|
|
triggers:
|
|
- trigger: event
|
|
id: computer_off
|
|
event_type: mobile_app_notification_action
|
|
event_data:
|
|
action: computer_martijn_off
|
|
- trigger: event
|
|
id: computer_on
|
|
event_type: mobile_app_notification_action
|
|
event_data:
|
|
action: computer_martijn_on
|
|
- trigger: time
|
|
id: alert_on
|
|
at: 08:00:00
|
|
actions:
|
|
- alias: Actions computer Martijn alert
|
|
choose:
|
|
- conditions:
|
|
condition: trigger
|
|
id: computer_off
|
|
sequence:
|
|
- alias: Turn off computer after user confirms
|
|
action: switch.turn_off
|
|
target:
|
|
entity_id: switch.computer_zolder
|
|
- conditions:
|
|
condition: trigger
|
|
id: computer_on
|
|
sequence:
|
|
- alias: Turn off computer alert after user says keep on
|
|
action: alert.turn_off
|
|
target:
|
|
entity_id: alert.computer_martijn
|
|
- conditions:
|
|
condition: trigger
|
|
id: alert_on
|
|
sequence:
|
|
- alias: Turn on computer alert at 8 AM
|
|
action: alert.turn_on
|
|
target:
|
|
entity_id: alert.computer_martijn
|
|
- id: 3152abda-e95c-4d49-8314-b6b6a803cc16
|
|
alias: Send notification for corrupted database
|
|
triggers:
|
|
- alias: Check if oldest date matches expected date
|
|
trigger: template
|
|
value_template: "{{\n 'sensor.oldest_statistics_date' | has_value\n and states('sensor.oldest_statistics_date')\
|
|
\ != '2021-07-07'\n}}\n"
|
|
actions:
|
|
- alias: Send notification
|
|
action: notify.mobile_app_pixel_10_pro
|
|
data:
|
|
title: 🚨 Database waarschuwing 🚨
|
|
message: De Home Assistant database is mogelijk corrupt! Controleer de database.
|
|
data:
|
|
channel: Database Warning
|
|
ttl: 0
|
|
priority: high
|
|
notification_icon: mdi:database
|
|
- id: 341786d9-1a4e-4328-be86-1e3d68d5744c
|
|
alias: Dishwasher notification
|
|
mode: single
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: Dishwasher finished running
|
|
trigger: state
|
|
entity_id: binary_sensor.dishwasher_active
|
|
from: 'on'
|
|
to: 'off'
|
|
id: finished
|
|
actions:
|
|
- alias: Reset dishwasher program to Eco
|
|
action: input_select.select_option
|
|
target:
|
|
entity_id: input_select.dishwasher_program
|
|
data:
|
|
option: Eco
|
|
- alias: Reset dishwasher extra setting to Normal
|
|
action: input_select.select_option
|
|
target:
|
|
entity_id: input_select.dishwasher_program_extra
|
|
data:
|
|
option: Normaal
|
|
- alias: Clear dishwasher delayed start timer
|
|
action: input_number.set_value
|
|
target:
|
|
entity_id: input_number.dishwasher_delayed_start
|
|
data:
|
|
value: 0
|
|
- alias: Notification
|
|
action: notify.all_phones
|
|
data:
|
|
title: 💦 De vaatwasser is klaar
|
|
message: Doe hem snel open zodat hij kan uitwasemen
|
|
data:
|
|
channel: Dishwasher
|
|
ttl: 0
|
|
priority: high
|
|
notification_icon: mdi:dishwasher-alert
|
|
- id: afcf34ca-7a3e-4f49-a332-9313d2a2eca5
|
|
alias: Actions based on doorbell
|
|
triggers:
|
|
- alias: Doorbell button pressed
|
|
trigger: state
|
|
entity_id: binary_sensor.smart_doorbell_button
|
|
to: 'on'
|
|
mode: restart
|
|
max_exceeded: silent
|
|
variables:
|
|
birthday:
|
|
- sensor.anniversary_floris
|
|
- sensor.anniversary_martijn
|
|
- sensor.anniversary_pepijn
|
|
- sensor.anniversary_martijn
|
|
holiday:
|
|
- sensor.anniversary_sinterklaas
|
|
birthday_today: "{% set m = state_attr('calendar.m_m', 'message') | lower %} {{\n\
|
|
\ '0' in birthday | map('states') | list\n or\n (\n is_state('calendar.m_m',\
|
|
\ 'on')\n and 'verjaardag' in m\n and m.split(' ')[1] in ['martijn', 'marleen',\
|
|
\ 'floris', 'pepijn']\n )\n}}\n"
|
|
conditions:
|
|
- alias: Prevent running too much
|
|
condition: template
|
|
value_template: '{{ now() - this.attributes.last_triggered | default(0 | as_datetime,
|
|
true) > timedelta(seconds=30) }}'
|
|
actions:
|
|
- alias: Notification for phones
|
|
action: notify.all_phones
|
|
data:
|
|
title: 🔔 Ding dong!
|
|
message: Er staat iemand aan de deur!
|
|
data:
|
|
channel: Deurbel
|
|
priority: high
|
|
ttl: 0
|
|
notification_icon: mdi:bell
|
|
- alias: Nvidia Shield active?
|
|
if:
|
|
- not:
|
|
- condition: state
|
|
entity_id: media_player.nvidia_shield
|
|
state: 'off'
|
|
then:
|
|
- alias: Pause Shield
|
|
action: media_player.media_pause
|
|
target:
|
|
entity_id: media_player.nvidia_shield
|
|
- alias: Chime off and someone home?
|
|
choose:
|
|
- conditions:
|
|
- alias: Chime off?
|
|
condition: state
|
|
entity_id: switch.smart_doorbell_chime_active
|
|
state: 'off'
|
|
- alias: Someone home?
|
|
condition: state
|
|
entity_id: sensor.house_mode
|
|
state: Thuis
|
|
sequence:
|
|
- parallel:
|
|
- sequence:
|
|
- variables:
|
|
light_state: '{{ states(''light.voordeur'') }}'
|
|
- alias: Blink front door light
|
|
repeat:
|
|
count: 8
|
|
sequence:
|
|
- action: light.toggle
|
|
target:
|
|
entity_id: light.voordeur
|
|
- delay: 1
|
|
- alias: Restore state
|
|
action: light.turn_{{ light_state }}
|
|
target:
|
|
entity_id: light.voordeur
|
|
- alias: Blink lights using script
|
|
action: script.turn_on
|
|
target:
|
|
entity_id: script.light_blink_alert
|
|
- conditions:
|
|
- alias: Chime not active
|
|
condition: state
|
|
entity_id: switch.smart_doorbell_chime_active
|
|
state: 'off'
|
|
- alias: Nobobdy home?
|
|
condition: state
|
|
entity_id: sensor.house_mode
|
|
state: Afwezig
|
|
sequence:
|
|
- alias: Blink front door light
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: light.voordeur
|
|
data:
|
|
effect: Slow Pulse
|
|
- conditions:
|
|
- alias: Chime active
|
|
condition: state
|
|
entity_id: switch.smart_doorbell_chime_active
|
|
state: 'on'
|
|
- alias: Someone home
|
|
condition: numeric_state
|
|
entity_id: zone.home
|
|
above: 0
|
|
sequence:
|
|
- variables:
|
|
name_a: "{{\n expand(birthday)\n | selectattr('state', 'eq', '0')\n\
|
|
\ | map(attribute='object_id')\n | map('replace', 'anniversary_',\
|
|
\ '')\n | join\n}}\n"
|
|
name_c: '{% set m = state_attr(''calendar.m_m'', ''message'') %} {{ m.split(''
|
|
'')[1:] | join('' '') }}
|
|
|
|
'
|
|
name: '{{ name_a or name_c }}'
|
|
sound: '{{ ''roltong.mp3'' if birthday_today else ''dingdong.mp3'' }}'
|
|
message: '{{ (''Is dit misschien visite voor '' ~ name ~ ''?!'') if birthday_today
|
|
else '' '' }}
|
|
|
|
'
|
|
sat_id: "{% set reject_list = ['assist_satellite.m5stack_atom_echo_d4e7f8_assist_satellite',\
|
|
\ 'assist_satellite.grandstream'] %} {% set reject_list = (reject_list\
|
|
\ + ['assist_satellite.pepijn']) if is_state('binary_sensor.pepijn_sleeping',\
|
|
\ 'on') else reject_list %} {% set reject_list = (reject_list + ['assist_satellite.floris'])\
|
|
\ if is_state('binary_sensor.floris_sleeping', 'on') else reject_list\
|
|
\ %} {{\n states.assist_satellite\n | map(attribute='entity_id')\n\
|
|
\ | reject('in', reject_list)\n | list\n}}\n"
|
|
- alias: Make sure soundbar is ready
|
|
if: '{{ ''assist_satellite.woonkamer'' in sat_id }}'
|
|
then:
|
|
- alias: Turn soundbar on in case it wasn't already
|
|
action: media_player.turn_on
|
|
target:
|
|
entity_id: media_player.samsung_soundbar
|
|
- alias: Make sure soundbar is on
|
|
wait_template: '{{ not ''media_player.samsung_soundbar'' | has_value or
|
|
state_attr(''media_player.samsung_soundbar'', ''volume_level'') is not
|
|
none }}'
|
|
- alias: Set soundbar to the correct source
|
|
action: media_player.select_source
|
|
data:
|
|
source: aux
|
|
target:
|
|
entity_id: media_player.samsung_soundbar
|
|
- alias: Store volume level
|
|
variables:
|
|
sb_vol: '{{ state_attr(''media_player.samsung_soundbar'', ''volume_level'')
|
|
| default(0.5, true) }}'
|
|
- alias: Set volume to at least 0.5
|
|
action: media_player.volume_set
|
|
target:
|
|
entity_id: media_player.samsung_soundbar
|
|
data:
|
|
volume_level: '{{ [0.5, sb_vol] | max }}'
|
|
- repeat:
|
|
for_each: '{{ sat_id }}'
|
|
sequence:
|
|
- alias: Use announcement script
|
|
action: script.turn_on
|
|
target:
|
|
entity_id: script.send_announcement_with_volume_setting
|
|
data:
|
|
variables:
|
|
satellite: '{{ repeat.item }}'
|
|
message: '{{ message }}'
|
|
pre_announce_sound: media-source://media_source/local/misc/{{ sound
|
|
}}
|
|
volume: 0.6
|
|
- alias: Restore volume soundbar
|
|
if: '{{ ''assist_satellite.woonkamer'' in sat_id }}'
|
|
then:
|
|
- alias: Set soundbar back to original volume
|
|
action: media_player.volume_set
|
|
target:
|
|
entity_id: media_player.samsung_soundbar
|
|
data:
|
|
volume_level: '{{ sb_vol }}'
|
|
- id: 86f3e0f1-cbaf-4897-a603-cb0e33f76793
|
|
alias: Turn doorbell sound on and off
|
|
mode: single
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: Home Assistant started
|
|
trigger: homeassistant
|
|
event: start
|
|
- alias: Doorbell chime became available
|
|
trigger: state
|
|
entity_id: switch.smart_doorbell_chime_active
|
|
from: unavailable
|
|
- alias: Schedule time for chime control
|
|
trigger: time
|
|
at:
|
|
- 07:00:00
|
|
- '19:00:00'
|
|
actions:
|
|
- alias: Bedtime children?
|
|
choose:
|
|
- conditions:
|
|
- alias: Evening or night?
|
|
condition: time
|
|
after: '19:00:00'
|
|
before: 07:00:00
|
|
sequence:
|
|
- alias: Turn chime off
|
|
action: switch.turn_off
|
|
data:
|
|
entity_id: switch.smart_doorbell_chime_active
|
|
- conditions:
|
|
- alias: Daytime?
|
|
condition: time
|
|
after: 07:00:00
|
|
before: '19:00:00'
|
|
sequence:
|
|
- alias: Turn chime on
|
|
action: switch.turn_on
|
|
data:
|
|
entity_id: switch.smart_doorbell_chime_active
|
|
- id: 3e12aad4-2ddb-46ce-af36-1dbcc14129d9
|
|
alias: Turn light stairs closet off and on
|
|
mode: restart
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: Stairs closet door state changed
|
|
trigger: state
|
|
entity_id: binary_sensor.deur_trapkast_contact
|
|
actions:
|
|
- alias: Open or closed?
|
|
choose:
|
|
- conditions:
|
|
- alias: Door open?
|
|
condition: state
|
|
entity_id: binary_sensor.deur_trapkast_contact
|
|
state: 'on'
|
|
sequence:
|
|
- alias: Turn stairs closet light on
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: light.trapkast_template
|
|
- alias: Wait 5 minutes before auto-off
|
|
delay:
|
|
minutes: 5
|
|
- alias: Turn stairs closet light off after delay
|
|
action: light.turn_off
|
|
target:
|
|
entity_id: light.trapkast_template
|
|
- conditions:
|
|
- alias: Door closed?
|
|
condition: state
|
|
entity_id: binary_sensor.deur_trapkast_contact
|
|
state: 'off'
|
|
sequence:
|
|
- alias: Turn stairs closet light off immediately
|
|
action: light.turn_off
|
|
target:
|
|
entity_id: light.trapkast_template
|
|
- id: dryer_finished_notification
|
|
alias: Dryer Finished Notification
|
|
description: Notify when dryer finishes based on power consumption below 20W for
|
|
3 minutes
|
|
triggers:
|
|
- trigger: numeric_state
|
|
alias: Power below threshold
|
|
entity_id: sensor.droger_power
|
|
below: 20
|
|
for:
|
|
minutes: 3
|
|
conditions:
|
|
- condition: template
|
|
alias: Valid power reading
|
|
value_template: '{{ trigger.from_state.state | is_number }}'
|
|
actions:
|
|
- action: rest_command.signal_send_message
|
|
alias: Send dryer finished notification
|
|
data:
|
|
message: 🧺 De droger is klaar!
|
|
mode: single
|
|
- id: e18beec6-b22c-4ac5-88da-05b7c05b9c33
|
|
alias: ECU reset with switch
|
|
triggers:
|
|
- alias: Solar energy output sensor not responding for 5 minutes
|
|
trigger: template
|
|
value_template: '{{ not states(''sensor.solar_total_lifetime_energy_output'')
|
|
| is_number }}'
|
|
for:
|
|
minutes: 5
|
|
id: 'off'
|
|
- alias: ECU reports lower value then current return to grid
|
|
trigger: template
|
|
value_template: "{{\n states('sensor.ecu_current_power') | float(0) <\n states('sensor.electricity_meter_energieproductie')\
|
|
\ | float(0)\n}}\n"
|
|
for:
|
|
minutes: 10
|
|
id: 'off'
|
|
- alias: ECU current power didn't change for 15 minutes
|
|
trigger: state
|
|
entity_id: sensor.ecu_current_power
|
|
to: null
|
|
for:
|
|
minutes: 15
|
|
id: stable
|
|
- alias: ECU reset switch turned off for 10 seconds
|
|
trigger: state
|
|
entity_id: switch.ecu_reset
|
|
to: 'off'
|
|
for:
|
|
seconds: 10
|
|
id: 'on'
|
|
- alias: Home Assistant started
|
|
trigger: homeassistant
|
|
event: start
|
|
id: 'on'
|
|
conditions:
|
|
- alias: Check if trigger is not stable or if sun is up with power output
|
|
condition: template
|
|
value_template: "{{\n trigger.id != 'stable'\n or\n (\n is_state('sun.sun',\
|
|
\ 'above_horizon')\n and trigger.to_state.state | int(0) > 0\n )\n}}\n"
|
|
actions:
|
|
- alias: Turn ECU reset switch on or off based on trigger
|
|
action: switch.turn_{{ 'off' if trigger.id == 'stable' else trigger.id }}
|
|
target:
|
|
entity_id: switch.ecu_reset
|
|
- id: 376b6b93-e8ed-43cf-89e3-1b915e5ff236
|
|
alias: Send notification when Martijn or Marleen leaves from work
|
|
mode: parallel
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: Marleen left work
|
|
trigger: state
|
|
entity_id: person.marleen
|
|
from: secret work_marleen
|
|
to: not_home
|
|
- alias: Martijn left work
|
|
trigger: state
|
|
entity_id: person.martijn
|
|
from: secret work_martijn
|
|
to: not_home
|
|
- alias: Person status changed (for reset)
|
|
trigger: state
|
|
entity_id:
|
|
- person.martijn
|
|
- person.marleen
|
|
to:
|
|
- home
|
|
- secret work_marleen
|
|
- secret work_martijn
|
|
id: reset
|
|
- alias: Cancel ETA notification for Martijn
|
|
trigger: event
|
|
id: reset
|
|
event_type: mobile_app_notification_action
|
|
event_data:
|
|
action: cancel_eta_martijn
|
|
variables:
|
|
name: martijn
|
|
- alias: Cancel ETA notification for Marleen
|
|
trigger: event
|
|
id: reset
|
|
event_type: mobile_app_notification_action
|
|
event_data:
|
|
action: cancel_eta_marleen
|
|
variables:
|
|
name: marleen
|
|
variables:
|
|
name: '{{ name if name is defined else states[trigger.entity_id].object_id }}'
|
|
notify: '{{ ''notify.mobile_app_pixel_8_marleen'' if name == ''martijn'' else
|
|
''notify.mobile_app_pixel_10_pro'' }}'
|
|
gender: '{{ ''hij'' if name == ''martijn'' else ''ze'' }}'
|
|
sensor: sensor.{{ name }}_naar_huis
|
|
vehicle: '{{ ''fiets'' if is_state(''input_boolean.martijn_fiets'', ''on'') and
|
|
is_state(''binary_sensor.pixel_10_pro_android_auto'', ''off'') and name == ''martijn''
|
|
else ''auto'' }}'
|
|
eta: '{%- set delta = 40 if vehicle == ''fiets'' else states(sensor) | float %}
|
|
{{ (now() + timedelta(minutes=delta)).strftime(''%H:%M'') }}
|
|
|
|
'
|
|
work:
|
|
martijn: secret work_martijn
|
|
marleen: secret work_marleen
|
|
actions:
|
|
- if: '{{ trigger.id == ''reset'' }}'
|
|
then:
|
|
- alias: Remove ETA variable
|
|
event: remove_variable
|
|
event_data:
|
|
key: eta_{{ name }}
|
|
else:
|
|
- alias: Update travel time sensor
|
|
action: homeassistant.update_entity
|
|
target:
|
|
entity_id: '{{ sensor }}'
|
|
- alias: Send notification to phone
|
|
action: '{{ notify }}'
|
|
data:
|
|
title: '{{ name | capitalize }} is onderweg {{ ('' met de '' ~ vehicle) if
|
|
name == ''martijn'' else ''''}}'
|
|
message: Als {{ gender }} meteen naar huis komt is {{ gender }} er om {{ eta
|
|
}}
|
|
data:
|
|
channel: ETA
|
|
tag: eta_{{ name }}
|
|
ttl: 0
|
|
priority: high
|
|
notification_icon: '{{ ''mdi:bike'' if vehicle == ''fiets'' else ''mdi:car''}}'
|
|
actions:
|
|
- action: cancel_eta_{{ name }}
|
|
title: Stop updates
|
|
- alias: Set ETA variable
|
|
event: set_variable
|
|
event_data:
|
|
key: eta_{{ name }}
|
|
value: '{{ eta }}'
|
|
set_timestamp: false
|
|
- if: '{{ vehicle == ''auto'' }}'
|
|
then:
|
|
- repeat:
|
|
until: "{{\n is_state(trigger.entity_id, [work[name], 'home'])\n or (state_attr('sensor.variables',\
|
|
\ 'variables') | default({}, true)).get('eta_'~name, none) is none\n}}\n"
|
|
sequence:
|
|
- alias: Update travel time sensor in loop
|
|
action: homeassistant.update_entity
|
|
target:
|
|
entity_id: '{{ sensor }}'
|
|
- alias: Calculate updated ETA time
|
|
variables:
|
|
eta: '{{ now() + timedelta(minutes=states(sensor)|float) }}'
|
|
- wait_for_trigger:
|
|
- alias: Person reached destination
|
|
trigger: template
|
|
value_template: '{{ is_state(trigger.entity_id, [work[name], ''home''])
|
|
}}'
|
|
- alias: ETA cancellation requested
|
|
trigger: event
|
|
event_type: mobile_app_notification_action
|
|
event_data:
|
|
action: cancel_eta_{{ name }}
|
|
- alias: ETA delay detected
|
|
trigger: template
|
|
value_template: "{{\n (now() + timedelta(minutes=states(sensor) | float))\
|
|
\ - as_datetime(eta) > timedelta(minutes=5)\n}}\n"
|
|
id: delay
|
|
- if: '{{ wait.trigger.id == ''delay'' }}'
|
|
then:
|
|
- alias: Calculate delayed ETA time
|
|
variables:
|
|
eta: '{{ (now() + timedelta(minutes=states(sensor) | float)).strftime(''%H:%M'')
|
|
}}'
|
|
- alias: Update ETA variable with new time
|
|
event: set_variable
|
|
event_data:
|
|
key: eta_{{ name }}
|
|
value: '{{ eta }}'
|
|
- alias: Send notification to phone
|
|
action: '{{ notify }}'
|
|
data:
|
|
title: '{{ name | capitalize }} is vertraagd'
|
|
message: '{{ gender | capitalize }} zou er nu rond {{ eta }} moeten
|
|
zijn'
|
|
data:
|
|
channel: ETA
|
|
tag: eta_{{ name }}
|
|
ttl: 0
|
|
priority: high
|
|
notification_icon: mdi:car
|
|
actions:
|
|
- action: cancel_eta_{{ name }}
|
|
title: Stop updates
|
|
- id: 6757b053-0f63-4c30-98bd-1038ab57700e
|
|
alias: Check if Martijn is on his bicycle for ETA calculation
|
|
mode: single
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: Martijn detected on bicycle
|
|
trigger: state
|
|
id: on_bike
|
|
entity_id: sensor.pixel_10_pro_detected_activity
|
|
to: on_bicycle
|
|
- alias: Martijn arrived home
|
|
trigger: state
|
|
id: back_home
|
|
entity_id: person.martijn
|
|
to: home
|
|
actions:
|
|
- alias: 🚲 of 🏡
|
|
choose:
|
|
- conditions:
|
|
- alias: 🚲
|
|
condition: trigger
|
|
id: on_bike
|
|
sequence:
|
|
- alias: Turn on input_boolean
|
|
action: input_boolean.turn_on
|
|
target:
|
|
entity_id: input_boolean.martijn_fiets
|
|
- conditions:
|
|
- alias: Martijn was on 🚲?
|
|
condition: state
|
|
entity_id: input_boolean.martijn_fiets
|
|
state: 'on'
|
|
- alias: Back 🏡
|
|
condition: trigger
|
|
id: back_home
|
|
sequence:
|
|
- alias: Turn off input_boolean
|
|
action: input_boolean.turn_off
|
|
target:
|
|
entity_id: input_boolean.martijn_fiets
|
|
- id: 2068227c-13b2-4bc3-bc1b-50afe8da2deb
|
|
alias: Marleen is almost home
|
|
mode: single
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: Marleen within 4km of home
|
|
trigger: numeric_state
|
|
entity_id: sensor.thuis_marleen_distance
|
|
below: 4000
|
|
conditions:
|
|
- alias: Richting huis?
|
|
condition: state
|
|
entity_id: sensor.thuis_marleen_direction_of_travel
|
|
state: towards
|
|
- alias: Marleen niet thuis?
|
|
condition: state
|
|
entity_id: person.marleen
|
|
state: not_home
|
|
- alias: Martijn wel thuis?
|
|
condition: state
|
|
entity_id: person.martijn
|
|
state: home
|
|
actions:
|
|
- alias: Message to phone Martijn
|
|
action: notify.mobile_app_pixel_10_pro
|
|
data:
|
|
title: Hoera
|
|
message: Marleen is bijna thuis
|
|
data:
|
|
channel: ETA
|
|
ttl: 0
|
|
priority: high
|
|
notification_icon: mdi:party-popper
|
|
- alias: Determine TTS target devices based on Martijn's activity
|
|
variables:
|
|
target: "{%- \n if is_state('media_player.martijn', 'playing')\n or is_state('sensor.location_phone_martijn',\
|
|
\ 'Zolder') \n%}\n [ 'assist_satellite.keuken', 'assist_satellite.martijn'\
|
|
\ ]\n{%- else %}\n [ 'assist_satellite.keuken' ]\n{%- endif %}\n"
|
|
- alias: Send TTS
|
|
action: assist_satellite.announce
|
|
target:
|
|
entity_id: '{{ target }}'
|
|
data:
|
|
message: Hoera Marleen is bijna thuis
|
|
- id: eb769e97-f6dd-471a-90ee-29d4666e0718
|
|
alias: Turn everything off when nobody is home
|
|
mode: single
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: House mode changed to away for 10 seconds
|
|
trigger: state
|
|
entity_id: sensor.house_mode
|
|
to: Afwezig
|
|
for:
|
|
seconds: 10
|
|
conditions:
|
|
- alias: Niemand thuis?
|
|
condition: state
|
|
entity_id: sensor.house_mode
|
|
state: Afwezig
|
|
actions:
|
|
- alias: TV on
|
|
choose:
|
|
- conditions: '{{ states(''sensor.tv_meubel_power'') | float(0) > 40 }}'
|
|
sequence:
|
|
- alias: Enable guest mode to avoid that they will be in the dark
|
|
action: input_boolean.turn_on
|
|
target:
|
|
entity_id: input_boolean.gast
|
|
default:
|
|
- alias: All lights off
|
|
action: light.turn_off
|
|
target:
|
|
entity_id: light.groep_huis
|
|
- alias: Turn off extractor hood if needed?
|
|
choose:
|
|
- conditions:
|
|
- alias: Extractor hood or light active?
|
|
condition: numeric_state
|
|
entity_id: sensor.afzuigkap_power
|
|
above: 1
|
|
sequence:
|
|
- alias: Turn off plug
|
|
action: switch.turn_off
|
|
target:
|
|
entity_id: switch.afzuigkap
|
|
- alias: Turn off desk Martijn if not active
|
|
choose:
|
|
- conditions:
|
|
- alias: Computer Martijn uit
|
|
condition: state
|
|
entity_id: binary_sensor.computer_zolder
|
|
state: 'off'
|
|
- alias: Laptop werkt uit
|
|
condition: state
|
|
entity_id: binary_sensor.laptop_werk_martijn_lan
|
|
state: 'off'
|
|
- alias: Laptop werkt uit
|
|
condition: state
|
|
entity_id: binary_sensor.laptop_werk_martijn_wifi
|
|
state: 'off'
|
|
sequence:
|
|
- alias: Bureau Martijn uit
|
|
action: switch.turn_off
|
|
target:
|
|
entity_id: switch.bureau_martijn_template
|
|
- id: 15bc9238-0a61-4448-92bc-854848521572
|
|
alias: Turn lights outside on and off
|
|
mode: single
|
|
max_exceeded: silent
|
|
triggers:
|
|
- trigger: homeassistant
|
|
event: start
|
|
- trigger: state
|
|
entity_id: sun.sun
|
|
to:
|
|
- above_horizon
|
|
- below_horizon
|
|
- trigger: time
|
|
at:
|
|
- 00:00
|
|
- 06:30
|
|
actions:
|
|
- alias: Midnight, morning or evening?
|
|
choose:
|
|
- conditions:
|
|
- alias: Midnight?
|
|
condition: time
|
|
before: ' 00:15:00'
|
|
sequence:
|
|
- alias: Lights in garden off
|
|
action: light.turn_off
|
|
target:
|
|
entity_id:
|
|
- light.tuinlampjes
|
|
- light.veranda
|
|
- conditions:
|
|
- alias: After sunrise?
|
|
condition: state
|
|
entity_id: sun.sun
|
|
state: above_horizon
|
|
sequence:
|
|
- alias: All outside lights off
|
|
action: light.turn_off
|
|
target:
|
|
entity_id:
|
|
- light.groep_buiten
|
|
- conditions:
|
|
- alias: After sunset
|
|
condition: state
|
|
entity_id: sun.sun
|
|
state: below_horizon
|
|
sequence:
|
|
- alias: Turn front door light and garden lights on
|
|
action: light.turn_on
|
|
target:
|
|
entity_id:
|
|
- light.tuinlampjes
|
|
- light.voordeur
|
|
- alias: Turn porch light on
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: light.veranda
|
|
data:
|
|
brightness: 10
|
|
- alias: Short delay
|
|
delay: 10
|
|
- alias: Another service call to be sure (sometimes it fails)
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: light.veranda
|
|
data:
|
|
brightness: 10
|
|
- id: f80d05dd-bdc4-49ec-b5c0-07c9bb3757a0
|
|
alias: Actions for garden sonoff
|
|
mode: parallel
|
|
max_exceeded: silent
|
|
triggers:
|
|
- trigger: state
|
|
entity_id: event.sonoff_tuin_sonoff_tuin
|
|
not_from: unavailable
|
|
actions:
|
|
- alias: Click type?
|
|
choose:
|
|
- conditions:
|
|
- alias: Short?
|
|
condition: template
|
|
value_template: '{{ trigger.to_state.attributes.event_type == ''single_press''
|
|
}}'
|
|
sequence:
|
|
- alias: Toggle light
|
|
action: light.toggle
|
|
target:
|
|
entity_id: light.groep_tuin
|
|
- conditions:
|
|
- alias: Double?
|
|
condition: template
|
|
value_template: '{{ trigger.to_state.attributes.event_type == ''double_press''
|
|
}}'
|
|
sequence:
|
|
- alias: Light on 100%
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: light.veranda
|
|
data:
|
|
brightness: 255
|
|
- conditions:
|
|
- alias: Long?
|
|
condition: template
|
|
value_template: '{{ trigger.to_state.attributes.event_type == ''long_press''
|
|
}}'
|
|
sequence:
|
|
- alias: Toggle veranda cover open/close
|
|
action: cover.{{ 'close' if is_state('cover.veranda', 'open') else 'open'
|
|
}}_cover
|
|
target:
|
|
entity_id: cover.veranda
|
|
- id: 36123179-ef70-4a84-be1a-ea1eb11cfc97
|
|
alias: Open sunshade when needed
|
|
mode: restart
|
|
triggers:
|
|
- alias: The temperature in the living room is rising
|
|
trigger: state
|
|
entity_id: binary_sensor.trend_woonkamer_temp
|
|
to: 'on'
|
|
- alias: The sun is above the horizon
|
|
trigger: state
|
|
entity_id: sun.sun
|
|
to: above_horizon
|
|
- alias: It will be over 18 degrees
|
|
trigger: numeric_state
|
|
entity_id: sensor.weather_combined_max_temp_today
|
|
above: 18
|
|
- alias: Sunny or partly cloudy outside
|
|
trigger: state
|
|
entity_id: weather.combined
|
|
to:
|
|
- sunny
|
|
- partycloudy
|
|
- alias: Currently not raining
|
|
trigger: state
|
|
entity_id: binary_sensor.rain
|
|
to: 'off'
|
|
- alias: Over 20 degrees inside
|
|
trigger: numeric_state
|
|
entity_id: sensor.woonkamer_multi_temperature
|
|
above: 20
|
|
- alias: Time is 16:00
|
|
trigger: time
|
|
at: '16:00:00'
|
|
id: close
|
|
conditions:
|
|
- condition: template
|
|
value_template: "{{\n (\n is_state('cover.veranda', 'open')\n and trigger.id\
|
|
\ == 'close'\n )\n or is_state('cover.veranda', 'closed')\n}}\n"
|
|
actions:
|
|
- alias: Check if sun is rising and cover not in manual mode
|
|
if: '{{ state_attr(''sun.sun'', ''rising'') and not is_state(''binary_sensor.screen_veranda_manual'',
|
|
''on'') }}'
|
|
then:
|
|
- alias: No rain
|
|
condition: state
|
|
entity_id: binary_sensor.rain
|
|
state: 'off'
|
|
- alias: Warm day
|
|
condition: template
|
|
value_template: '{% set temp = states(''sensor.weather_combined_max_temp_today'')
|
|
| float(0) %} {{ temp > 25 or (temp > 18 and now().month in range(4,9)) }}
|
|
|
|
'
|
|
- alias: Sunny or partly cloudy
|
|
condition: state
|
|
entity_id: weather.combined
|
|
state:
|
|
- sunny
|
|
- partlycloudy
|
|
- alias: Temperature rising
|
|
condition: state
|
|
entity_id: binary_sensor.trend_woonkamer_temp
|
|
state: 'on'
|
|
- alias: Warm inside
|
|
condition: template
|
|
value_template: '{% set temp = states(''sensor.woonkamer_multi_temperature'')
|
|
| float(0) %} {{ temp > 22 or (temp > 20 and now().month in range(4,9)) }}
|
|
|
|
'
|
|
- alias: Store the current state of the light
|
|
variables:
|
|
light_state: '{{ states(''light.veranda'') }}'
|
|
- alias: Open cover
|
|
action: cover.open_cover
|
|
target:
|
|
entity_id: cover.veranda
|
|
- alias: Wait if the light changes
|
|
wait_template: '{{ not is_state(''light.veranda'', light_state) }}'
|
|
timeout: 00:05:00
|
|
continue_on_timeout: false
|
|
- alias: Restore the light state
|
|
action: light.turn_{{ light_state }}
|
|
target:
|
|
entity_id: light.veranda
|
|
- alias: Check if this is the evening close trigger
|
|
if: '{{ trigger.id == ''close'' }}'
|
|
then:
|
|
- alias: Store the current state of the light
|
|
variables:
|
|
light_state: '{{ states(''light.veranda'') }}'
|
|
- alias: Close cover
|
|
action: cover.close_cover
|
|
target:
|
|
entity_id: cover.veranda
|
|
- alias: Restore the light state
|
|
action: light.turn_{{ light_state }}
|
|
target:
|
|
entity_id: light.veranda
|
|
- id: '1752267977360'
|
|
alias: Turn off awning light during daytime
|
|
triggers:
|
|
- alias: Veranda light turned on
|
|
trigger: state
|
|
entity_id:
|
|
- light.veranda
|
|
to: 'on'
|
|
conditions:
|
|
- alias: Sun is above horizon (daytime)
|
|
condition: state
|
|
entity_id: sun.sun
|
|
state: above_horizon
|
|
- alias: Light was turned on automatically (not by user)
|
|
condition: template
|
|
value_template: '{{ trigger.to_state.context.parent_id is none and trigger.to_state.context.user_id
|
|
is none }}'
|
|
actions:
|
|
- alias: Turn off veranda light
|
|
action: light.turn_off
|
|
target:
|
|
entity_id: light.veranda
|
|
mode: single
|
|
- template:
|
|
- triggers:
|
|
- alias: Home Assistant started
|
|
trigger: homeassistant
|
|
event: start
|
|
id: 'true'
|
|
- alias: Home Assistant shutting down
|
|
trigger: homeassistant
|
|
event: shutdown
|
|
id: 'false'
|
|
actions:
|
|
- alias: Check if Home Assistant started after reboot notification
|
|
if: "{{\n trigger.id | bool\n and (state_attr('sensor.variables', 'variables')\
|
|
\ | default(dict(reboot_from_notification=false))).reboot_from_notification\n\
|
|
}}\n"
|
|
then:
|
|
- alias: Send notification to phone
|
|
service: notify.mobile_app_pixel_10_pro
|
|
data:
|
|
title: Home Assistant is weer opgestart
|
|
message: Update is succesvol uitgevoerd
|
|
data:
|
|
tag: ha_update
|
|
channel: Home Assistant
|
|
ttl: 0
|
|
priority: high
|
|
- alias: Write variables to variables template sensor
|
|
event: set_variable
|
|
event_data:
|
|
key: reboot_from_notification
|
|
value: false
|
|
set_timestamp: false
|
|
binary_sensor:
|
|
- unique_id: binary_sensor_ha_started
|
|
name: HA started
|
|
state: '{{ trigger.id | bool }}'
|
|
device_class: running
|
|
- id: 6cdd3311-fb90-47ea-a796-f679091021f2
|
|
alias: Turn on holiday mode and send notification
|
|
mode: queued
|
|
max_exceeded: silent
|
|
triggers:
|
|
- trigger: state
|
|
entity_id: zone.home
|
|
to: '0'
|
|
for: '12:00:00'
|
|
id: boolean_on
|
|
- trigger: event
|
|
id: holiday_on
|
|
event_type: mobile_app_notification_action
|
|
event_data:
|
|
action: vakantie
|
|
- trigger: state
|
|
id: holiday_house
|
|
entity_id: sensor.house_mode
|
|
to: Vakantie
|
|
- trigger: event
|
|
id: no_holiday
|
|
event_type: mobile_app_notification_action
|
|
event_data:
|
|
action: no_holiday
|
|
- trigger: numeric_state
|
|
id: holiday_over
|
|
entity_id: sensor.thuis_martijn_distance
|
|
below: 10000
|
|
actions:
|
|
- alias: Actions holiday mode
|
|
choose:
|
|
- conditions:
|
|
condition: trigger
|
|
id: boolean_on
|
|
sequence:
|
|
- action: input_boolean.turn_on
|
|
target:
|
|
entity_id: input_boolean.op_vakantie
|
|
- conditions:
|
|
condition: trigger
|
|
id: holiday_on
|
|
sequence:
|
|
- action: input_boolean.turn_off
|
|
target:
|
|
entity_id: input_boolean.op_vakantie
|
|
- action: input_boolean.turn_on
|
|
target:
|
|
entity_id: input_boolean.vakantie
|
|
- action: notify.mobile_app_pixel_10_pro
|
|
data:
|
|
title: ☀️ Fijne vakantie! ☀️
|
|
message: Vakantiemodus is nu actief
|
|
data:
|
|
channel: Holiday
|
|
ttl: 0
|
|
priority: high
|
|
notification_icon: mdi:sunglasses
|
|
- conditions:
|
|
condition: trigger
|
|
id: holiday_house
|
|
sequence:
|
|
- alias: Placeholder to prevent empty sequence
|
|
delay: 0
|
|
- conditions:
|
|
condition: trigger
|
|
id: no_holiday
|
|
sequence:
|
|
- action: input_boolean.turn_off
|
|
target:
|
|
entity_id: input_boolean.op_vakantie
|
|
- conditions:
|
|
condition: trigger
|
|
id: holiday_over
|
|
sequence:
|
|
- action: input_boolean.turn_off
|
|
target:
|
|
entity_id: input_boolean.vakantie
|
|
- if:
|
|
- alias: No guest
|
|
condition: state
|
|
entity_id: input_boolean.gast
|
|
state: 'off'
|
|
then:
|
|
- variables:
|
|
switches: "{{\n integration_entities('esphome')\n | select('is_state',\
|
|
\ 'Detached')\n | map('replace', 'select', 'switch')\n | map('replace',\
|
|
\ '_button_type', '')\n | select('has_value')\n | list\n}}\n"
|
|
- action: switch.turn_on
|
|
target:
|
|
entity_id: '{{ switches }}'
|
|
- delay: 20
|
|
- variables:
|
|
lights: "{{\n switches\n | map('regex_replace', '^switch.shelly1_|^switch.sonoff_',\
|
|
\ 'light.')\n | select('has_value')\n | list\n}}\n"
|
|
- action: light.turn_off
|
|
target:
|
|
entity_id: '{{ lights }}'
|
|
- id: 6d6452d1-f65e-49c5-9ed6-3c6c8754911a
|
|
alias: Turn on/off lights in the morning during holidays
|
|
mode: single
|
|
max_exceeded: silent
|
|
triggers:
|
|
- trigger: time
|
|
at: 06:30
|
|
conditions:
|
|
- alias: Holiday mode on?
|
|
condition: state
|
|
entity_id: sensor.house_mode
|
|
state: Vakantie
|
|
- alias: Guest mode off
|
|
condition: state
|
|
entity_id: input_boolean.gast
|
|
state: 'off'
|
|
actions:
|
|
- variables:
|
|
light_list:
|
|
- light.floris_template
|
|
- light.pepijn_template
|
|
light_select: '{{ range(0,1) | random }}'
|
|
light_select2: '{{ range(0,1) | random }}'
|
|
- alias: Random delay before lights are turned on
|
|
delay:
|
|
minutes: '{{ range(0,60) | random }}'
|
|
- alias: Turn on light in master bedroom
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: light.slaapkamer_plafond_template
|
|
- alias: Another delay
|
|
delay:
|
|
minutes: '{{ range(3,8) | random }}'
|
|
- alias: Turn light in one of the children bedrooms on
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: '{{ light_list[light_select] }}'
|
|
- alias: Another delay
|
|
delay:
|
|
minutes: '{{ range(2,8) | random }}'
|
|
- alias: Turn on light in other bedroom
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: '{{ light_list[0 if light_select == 1 else 1] }}'
|
|
- alias: Even more delay
|
|
delay:
|
|
minutes: '{{ range(20,30) | random }}'
|
|
- alias: Run morning script
|
|
action: script.turn_on
|
|
target:
|
|
entity_id: script.good_morning_routine
|
|
- alias: Even more delay
|
|
delay:
|
|
minutes: '{{ range(10,25) | random }}'
|
|
- alias: Turn of light in one children bedroom
|
|
action: light.turn_off
|
|
target:
|
|
entity_id: '{{ light_list[light_select2] }}'
|
|
- alias: Delay.. again..
|
|
delay:
|
|
minutes: '{{ range(2,8) | random }}'
|
|
- alias: And turn off the other children bedroom's light
|
|
action: light.turn_off
|
|
target:
|
|
entity_id: '{{ light_list[0 if light_select2 == 1 else 1] }}'
|
|
- alias: STOP WITH THESE DELAYS!
|
|
delay:
|
|
minutes: '{{ range(3,8) | random }}'
|
|
- alias: Turn off master bedroom light
|
|
action: light.turn_off
|
|
target:
|
|
entity_id: light.slaapkamer_plafond_template
|
|
- id: 2a73c7ac-123a-4d5b-99dd-9a0bec93e125
|
|
alias: Turn lights on/off when it is time to go to bed during holidays
|
|
mode: single
|
|
max_exceeded: silent
|
|
triggers:
|
|
- trigger: time
|
|
at: '22:00'
|
|
conditions:
|
|
- alias: Holiday mode on?
|
|
condition: state
|
|
entity_id: sensor.house_mode
|
|
state: Vakantie
|
|
- alias: Guest mode off
|
|
condition: state
|
|
entity_id: input_boolean.gast
|
|
state: 'off'
|
|
actions:
|
|
- alias: Random delay to turn light on
|
|
delay:
|
|
minutes: '{{ range(0,30) | random }}'
|
|
- alias: Turn light bedroom on
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: light.slaapkamer_plafond_template
|
|
- alias: Random delay to turn light downstairs off
|
|
delay:
|
|
minutes: '{{ range(5,10) | random }}'
|
|
- alias: Turn lights downstairs off
|
|
action: light.turn_off
|
|
target:
|
|
entity_id: light.groep_beneden
|
|
- alias: Turn all lights off
|
|
delay:
|
|
minutes: '{{ range(15,20) | random }}'
|
|
- alias: Alle lampen uit
|
|
action: light.turn_off
|
|
target:
|
|
entity_id: light.groep_huis
|
|
- id: b2977df5-1481-4b19-b56a-ae79bbf9659d
|
|
alias: Lights bedrooms children during holidays
|
|
mode: parallel
|
|
max_exceeded: silent
|
|
triggers:
|
|
- trigger: time
|
|
id: floris_template
|
|
at: '19:00'
|
|
- trigger: time
|
|
id: pepijn_template
|
|
at: '19:15'
|
|
conditions:
|
|
- alias: Holiday mode on?
|
|
condition: state
|
|
entity_id: sensor.house_mode
|
|
state: Vakantie
|
|
- alias: Guest mode off
|
|
condition: state
|
|
entity_id: input_boolean.gast
|
|
state: 'off'
|
|
actions:
|
|
- alias: Random delay to turn light on
|
|
delay:
|
|
minutes: '{{ range(0,30) | random }}'
|
|
- alias: Turn light on
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: light.{{ trigger.id }}
|
|
- alias: Random delay to turn light off
|
|
delay:
|
|
minutes: '{{ range(20,40) | random }}'
|
|
- alias: Turn light off
|
|
action: light.turn_off
|
|
target:
|
|
entity_id: light.{{ trigger.id }}
|
|
- id: d4fa325e-c2b5-4ec8-8c51-e574fa105eca
|
|
alias: Sunshade outside during holidays
|
|
mode: single
|
|
max_exceeded: silent
|
|
triggers:
|
|
- trigger: time
|
|
id: screen_open
|
|
at: 06:30
|
|
- trigger: time
|
|
id: screen_close
|
|
at: '14:00'
|
|
conditions:
|
|
- alias: Holiday mode on?
|
|
condition: state
|
|
entity_id: sensor.house_mode
|
|
state: Vakantie
|
|
- alias: Guest mode off
|
|
condition: state
|
|
entity_id: input_boolean.gast
|
|
state: 'off'
|
|
actions:
|
|
- alias: In of uit?
|
|
choose:
|
|
- conditions:
|
|
- condition: trigger
|
|
id: screen_open
|
|
- alias: Warm day?
|
|
condition: template
|
|
value_template: '{{ states(''sensor.weather_combined_max_temp_today'') | float(25)
|
|
>= 22 }}'
|
|
- alias: Sunny day?
|
|
condition: template
|
|
value_template: '{{ states(''sensor.weather_combined_daily_condition'') in
|
|
[''partly_cloudy'', ''sunny'', ''unavailable'', ''unknown''] }}
|
|
|
|
'
|
|
sequence:
|
|
- alias: Random delay
|
|
delay:
|
|
minutes: '{{ range(0, 60) | random }}'
|
|
- alias: Open sunshade
|
|
action: cover.open_cover
|
|
target:
|
|
entity_id: cover.veranda
|
|
- conditions:
|
|
- condition: trigger
|
|
id: screen_close
|
|
sequence:
|
|
- alias: Random delay
|
|
delay:
|
|
minutes: '{{ range(0, 60) | random }}'
|
|
- alias: Close sunshade
|
|
action: cover.close_cover
|
|
target:
|
|
entity_id: cover.veranda
|
|
- id: b5652fa9-d044-40b8-b53e-62886309dca8
|
|
alias: Arrive home with guest mode on
|
|
triggers:
|
|
- trigger: state
|
|
entity_id: person.martijn
|
|
from: not_home
|
|
to: home
|
|
conditions:
|
|
- alias: Guest Mode on
|
|
condition: state
|
|
entity_id: input_boolean.gast
|
|
state: 'on'
|
|
actions:
|
|
- alias: Send guest mode notification
|
|
action: notify.mobile_app_pixel_10_pro
|
|
data:
|
|
title: 🏡 Welkom thuis
|
|
message: Mag de gastmodus uit?
|
|
data:
|
|
channel: Guest
|
|
ttl: 0
|
|
priority: high
|
|
notification_icon: mdi:home
|
|
tag: Guest
|
|
actions:
|
|
- action: guest_mode_off
|
|
title: Yep
|
|
- action: guest_mode_on
|
|
title: Nope
|
|
- alias: Wait for user response to guest mode question
|
|
wait_for_trigger:
|
|
- trigger: event
|
|
event_type: mobile_app_notification_action
|
|
event_data:
|
|
action: guest_mode_off
|
|
- trigger: event
|
|
event_type: mobile_app_notification_action
|
|
event_data:
|
|
action: guest_mode_on
|
|
- alias: Turn of guest mode if needed
|
|
choose:
|
|
- conditions: '{{ wait.trigger.event.data.action == ''guest_mode_off'' }}'
|
|
sequence:
|
|
- alias: Turn of guest mode
|
|
action: input_boolean.turn_off
|
|
target:
|
|
entity_id: input_boolean.gast
|
|
- id: 8efddd53-2d4d-461e-bc80-a630a5ca244c
|
|
alias: Apply correct settings for IKEA lights
|
|
mode: parallel
|
|
max: 50
|
|
max_exceeded: silent
|
|
triggers:
|
|
- trigger: event
|
|
event_type: call_service
|
|
event_data:
|
|
domain: light
|
|
service: turn_on
|
|
id: turn_on
|
|
- trigger: event
|
|
event_type: call_service
|
|
event_data:
|
|
domain: light
|
|
service: toggle
|
|
id: toggle
|
|
variables:
|
|
entity_test: '{{ trigger.event.data.service_data.entity_id }}'
|
|
entities: "{% set entities = trigger.event.data.service_data.entity_id %} {% set\
|
|
\ entities = entities if entities is list else [entities] %} {% set ns = namespace(ikea=[])\
|
|
\ %} {% for e in entities if device_id(e) in label_devices('ikea') %}\n {%\
|
|
\ set ns.ikea = ns.ikea + [e] %}\n{% endfor %} {{ (entities | select('in', label_entities('ikea'))\
|
|
\ | list + ns.ikea) | unique | list }}\n"
|
|
attr_data: '{{ trigger.event.data.service_data.keys() | reject(''in'', [''transition'',
|
|
''entity_id'']) | list }}'
|
|
toggle: '{{ trigger.event.data.service == ''toggle'' }}'
|
|
conditions:
|
|
- alias: Check if there is at least one IKEA light targeted, and multiple attributes
|
|
changed
|
|
condition: template
|
|
value_template: '{{ entities | count > 0 and attr_data | count > 1 }}'
|
|
actions:
|
|
- alias: Short delay in case the toggle service call was used to ensure the light
|
|
has time to turn off
|
|
if: '{{ toggle }}'
|
|
then:
|
|
- alias: Short delay
|
|
delay: 0.5
|
|
- alias: Repeat loop to set each attribute to the right value
|
|
repeat:
|
|
for_each: '{{ attr_data }}'
|
|
sequence:
|
|
- alias: Set attribute to variable because repeat.item var will be overwritten
|
|
variables:
|
|
attr: '{{ repeat.item }}'
|
|
- alias: Repeat loop for each light
|
|
repeat:
|
|
for_each: '{{ (entities | select(''is_state'', ''on'') | list) if toggle
|
|
else entities }}
|
|
|
|
'
|
|
sequence:
|
|
- alias: Check if attribute needs to be changed
|
|
if: '{{ state_attr(repeat.item, attr) != trigger.event.data.service_data[attr]
|
|
}}'
|
|
then:
|
|
- alias: Set light entity to correct attribute value
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: '{{ repeat.item }}'
|
|
data: "{% set other_attr = attr_data | reject('eq', attr) | list %}\
|
|
\ {{\n dict(\n trigger.event.data.service_data.items()\n \
|
|
\ | rejectattr('0', 'in', ['entity_id'] + other_attr)\n \
|
|
\ )\n}}\n"
|
|
- alias: Very short delay
|
|
delay:
|
|
seconds: 0.1
|
|
- id: ef97c1e3-8e09-4b7c-9973-cc5379d6239d
|
|
alias: Warn when not all Dutch intents are provided
|
|
triggers:
|
|
- trigger: state
|
|
entity_id: binary_sensor.all_intents_provided
|
|
to: 'off'
|
|
actions:
|
|
- alias: Send message
|
|
action: rest_command.signal_send_message
|
|
data:
|
|
message: '⭐ Nederlands heeft geen ster meer, er zijn dus nieuwe intents bij
|
|
gekomen. Check welke intents missen.
|
|
|
|
'
|
|
- id: 7680c082-f8f8-402d-ba9c-dc2064de40b4
|
|
alias: Turn on nightlight for Pepijn and Floris
|
|
triggers:
|
|
- alias: Pepijn's main light turned off
|
|
trigger: state
|
|
entity_id: light.pepijn_template
|
|
to: 'off'
|
|
id: pepijn
|
|
- alias: Pepijn's nightlight enabled
|
|
trigger: state
|
|
entity_id: input_boolean.nachtlampje_pepijn
|
|
to: 'on'
|
|
id: pepijn
|
|
- alias: Floris's main light turned off
|
|
trigger: state
|
|
entity_id: light.floris_template
|
|
to: 'off'
|
|
id: floris
|
|
- alias: Floris's nightlight enabled
|
|
trigger: state
|
|
entity_id: input_boolean.nachtlampje_floris
|
|
to: 'on'
|
|
id: floris
|
|
- alias: Trigger sentence
|
|
trigger: conversation
|
|
command:
|
|
- floris gaat slapen
|
|
id: floris
|
|
conditions:
|
|
- '{{ is_state(''input_boolean.nachtlampje_'' ~ trigger.id, ''on'') }}'
|
|
- '{{ is_state(''binary_sensor.'' ~ trigger.id ~ ''_sleeping'', ''on'') }}'
|
|
- '{{ is_state(''light.groep_'' ~ trigger.id, ''off'') }}'
|
|
actions:
|
|
- if: '{{ trigger.id == ''pepijn'' }}'
|
|
then:
|
|
- alias: Turn on night light Pepijn
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: "{% set area = 'slaapkamer_pepijn' %} {{ \n intersect(label_entities('night_light'),\
|
|
\ area_entities(area))\n | select('is_state', 'on')\n | list\n}}\n"
|
|
else:
|
|
- alias: Turn on night light Floris
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: "{% set area = 'slaapkamer_floris' %} {{ \n intersect(label_entities('night_light'),\
|
|
\ area_entities(area))\n | select('is_state', 'on')\n | list\n}}\n"
|
|
- id: d9126ef3-31ed-4058-a8d8-564f6faaf3c5
|
|
alias: Dim Reading light Floris when used as night light
|
|
triggers:
|
|
- alias: Night lights on, else off
|
|
trigger: state
|
|
entity_id: binary_sensor.dashboard_floris_slaapt
|
|
to: 'on'
|
|
variables:
|
|
target_brightness: 10
|
|
- alias: Parent bedtime
|
|
trigger: state
|
|
entity_id: sensor.house_mode
|
|
to:
|
|
- Slapen
|
|
- Tandenpoetsen
|
|
variables:
|
|
target_brightness: 3
|
|
conditions:
|
|
- alias: Reading light floris is on (as night light)
|
|
condition: state
|
|
entity_id: light.floris_leeslamp
|
|
state: 'on'
|
|
action:
|
|
- alias: Dim the reading light
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: light.floris_leeslamp
|
|
data:
|
|
brightness_pct: '{{ target_brightness }}'
|
|
- id: e03d310f-0611-4d9c-9781-0487993c4976
|
|
alias: Xiaomi button kitchen
|
|
triggers:
|
|
- alias: Kitchen button pressed
|
|
trigger: state
|
|
entity_id: event.knop_keuken_action
|
|
not_from: unavailable
|
|
variables:
|
|
event: '{{ trigger.to_state.attributes.event_type | default(''unknown'', true)
|
|
}}'
|
|
actions:
|
|
- alias: Which click type
|
|
choose:
|
|
- conditions: '{{ event == ''single'' }}'
|
|
sequence:
|
|
- alias: Toggle kitchen spots
|
|
action: light.toggle
|
|
data:
|
|
entity_id: light.keukenspotjes
|
|
- conditions: '{{ event == ''double'' }}'
|
|
sequence:
|
|
- alias: Toggle main kitchen light
|
|
action: light.toggle
|
|
target:
|
|
entity_id: light.keuken
|
|
- conditions: '{{ event == ''hold'' }}'
|
|
sequence: []
|
|
- conditions: '{{ event == ''release'' }}'
|
|
sequence: []
|
|
- id: fe09f19c-86eb-4bd8-be3f-096bed6308f1
|
|
alias: Espresso machine plug off
|
|
mode: restart
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: Espresso machine turned on
|
|
trigger: state
|
|
entity_id: switch.espresso
|
|
from: 'off'
|
|
to: 'on'
|
|
- alias: Home Assistant started
|
|
trigger: homeassistant
|
|
event: start
|
|
- alias: Automations reloaded
|
|
trigger: event
|
|
event_type: automation_reloaded
|
|
- alias: Espresso machine power above 25W
|
|
trigger: numeric_state
|
|
entity_id: sensor.espresso_power
|
|
above: 25
|
|
id: active
|
|
conditions:
|
|
- alias: Espressomachine on?
|
|
condition: state
|
|
entity_id: switch.espresso
|
|
state: 'on'
|
|
actions:
|
|
- alias: Trigger type
|
|
choose:
|
|
- conditions:
|
|
- condition: trigger
|
|
id: active
|
|
sequence:
|
|
- alias: Espresso machine inactive for 31 minutes
|
|
wait_for_trigger:
|
|
- alias: Power dropped below 25W for 31 minutes
|
|
trigger: numeric_state
|
|
entity_id: sensor.espresso_power
|
|
below: 25
|
|
for: 00:31:00
|
|
default:
|
|
- delay:
|
|
minutes: 31
|
|
- alias: Turn plug off
|
|
action: switch.turn_off
|
|
target:
|
|
entity_id: switch.espresso
|
|
- id: b776ef0d-e5f7-42d1-8bf8-744fe2b7127b
|
|
alias: Extractor hood back on in the morning
|
|
mode: single
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: Ground floor lights turned on
|
|
trigger: state
|
|
entity_id: light.groep_beneden
|
|
to: 'on'
|
|
conditions:
|
|
- alias: Extractor hood off?
|
|
condition: state
|
|
entity_id: switch.afzuigkap
|
|
state: 'off'
|
|
- alias: Daytime
|
|
condition: time
|
|
after: ' 06:00:00'
|
|
before: ' 21:00:00'
|
|
actions:
|
|
- alias: Turn plug back on
|
|
action: switch.turn_on
|
|
target:
|
|
entity_id: switch.afzuigkap
|
|
- alias: Power usage kitchen
|
|
id: 0a454b0d-156e-4938-945e-d2bfb9b3cbd7
|
|
mode: single
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: Fridge power high for 10 minutes
|
|
trigger: numeric_state
|
|
entity_id: sensor.koelkast_power
|
|
above: 80
|
|
for: 00:10:00
|
|
conditions:
|
|
- alias: 'Rate limit: only send notification once per hour'
|
|
condition: template
|
|
value_template: '{{ as_timestamp(now()) - as_timestamp(state_attr(''automation.power_usage_kitchen'',
|
|
''last_triggered''), 0) > 3600 }}
|
|
|
|
'
|
|
actions:
|
|
- alias: Send fridge power warning notification
|
|
action: notify.mobile_app_pixel_10_pro
|
|
data:
|
|
title: Stroomverbruik koelkast
|
|
message: De koelkast verbruikt verdacht veel stroom, check of hij niet open
|
|
staat
|
|
data:
|
|
channel: Fridge
|
|
ttl: 0
|
|
priority: high
|
|
tag: fridge_alert
|
|
notification_icon: mdi:fridge-alert
|
|
- id: d826bab6-6791-425b-90b6-cae882317c5f
|
|
alias: Water kettle plug off
|
|
mode: restart
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: Water kettle turned on
|
|
trigger: state
|
|
entity_id: switch.waterkoker
|
|
from: 'off'
|
|
to: 'on'
|
|
- alias: Home Assistant started
|
|
trigger: homeassistant
|
|
event: start
|
|
- alias: Water kettle power above 25W
|
|
trigger: numeric_state
|
|
entity_id: sensor.waterkoker_power
|
|
above: 25
|
|
id: active
|
|
conditions:
|
|
- alias: Kettle on?
|
|
condition: state
|
|
entity_id: switch.waterkoker
|
|
state: 'on'
|
|
actions:
|
|
- alias: Trigger type
|
|
choose:
|
|
- conditions:
|
|
- condition: trigger
|
|
id: active
|
|
sequence:
|
|
- alias: Kettle inactive for 10 minutes
|
|
wait_for_trigger:
|
|
- alias: Power dropped below 25W for 10 minutes
|
|
trigger: numeric_state
|
|
entity_id: sensor.waterkoker_power
|
|
below: 25
|
|
for: 00:10:00
|
|
default:
|
|
- delay:
|
|
minutes: 10
|
|
- alias: Turn plug off
|
|
action: switch.turn_off
|
|
target:
|
|
entity_id: switch.waterkoker
|
|
- id: f0fc0c8c-662d-4477-9002-5ec4b49da7ba
|
|
alias: Change color temperature of lights based on brightness
|
|
mode: parallel
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: Light brightness changed
|
|
trigger: state
|
|
entity_id:
|
|
- light.eettafel
|
|
- light.pepijn
|
|
- light.floris
|
|
- light.tv_lamp
|
|
- light.speelhoek
|
|
- light.bedside_lamp
|
|
attribute: brightness
|
|
variables:
|
|
name: '{{ trigger.to_state.object_id }}'
|
|
overrides:
|
|
example_light:
|
|
min_ct: 2000
|
|
max_ct: 6500
|
|
eettafel:
|
|
min_br: 37
|
|
pepijn:
|
|
min_br: 37
|
|
floris:
|
|
min_br: 37
|
|
tv_lamp:
|
|
min_br: 37
|
|
speelhoek:
|
|
min_br: 37
|
|
input_boolean_dimmed: '{{ ''input_boolean.dimmed_'' + name }}'
|
|
light: '{{ trigger.entity_id }}'
|
|
max_ct: '{{ overrides.get(name, {}).get(''max_ct'') | default(state_attr(light,
|
|
''max_color_temp_kelvin''), true) }}'
|
|
min_ct: '{{ overrides.get(name, {}).get(''min_ct'') | default(state_attr(light,
|
|
''min_color_temp_kelvin''), true) }}'
|
|
min_br: '{{ overrides.get(name, {}).get(''min_br'') | default(1, true) }}'
|
|
max_br: '{{ overrides.get(name, {}).get(''max_br'') | default(255, true) }}'
|
|
br: '{{ state_attr(trigger.entity_id, ''brightness'') }}'
|
|
color_mode: '{{ state_attr(light, ''color_mode'') | default(''color_temp'', true)
|
|
}}'
|
|
conditions:
|
|
- alias: Light on?
|
|
condition: template
|
|
value_template: '{{ trigger.to_state.state == ''on'' and trigger.from_state.state
|
|
== ''on'' }}'
|
|
- alias: Already dimmed before?
|
|
condition: template
|
|
value_template: '{{ not is_state(input_boolean_dimmed, ''off'') }}'
|
|
- alias: Light on color_temp mode?
|
|
condition: template
|
|
value_template: '{{ color_mode == ''color_temp'' }}'
|
|
- alias: No transition active
|
|
condition: template
|
|
value_template: '{{ state_attr(''group.transition_active'', ''entity_id'') | default([],
|
|
true) | select(''search'', light | replace(''_template'', '''')) | list | count
|
|
== 0 }}'
|
|
actions:
|
|
- alias: Set color temperature based on brightness
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: '{{ light }}'
|
|
data:
|
|
color_temp_kelvin: '{{ [max_ct, min_ct + ((br-min_br) * (max_ct - min_ct) /
|
|
(max_br-min_br)) | int] | min }}
|
|
|
|
'
|
|
- id: 5f532453-807b-4170-9a1c-eff2857f73e8
|
|
alias: Lights off based on lux sensor
|
|
mode: single
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: Light level above 100 lux
|
|
trigger: numeric_state
|
|
entity_id: sensor.woonkamer_lux_illuminance_lux
|
|
id: light
|
|
above: 100
|
|
- alias: Light level above 400 lux (very bright)
|
|
trigger: numeric_state
|
|
entity_id: sensor.woonkamer_lux_illuminance_lux
|
|
id: very_light
|
|
above: 400
|
|
conditions:
|
|
- alias: Check if it's daytime (before sunset with offset)
|
|
condition: sun
|
|
before: sunset
|
|
before_offset: 03:00:00
|
|
actions:
|
|
- alias: Light or very light?
|
|
choose:
|
|
- conditions:
|
|
- condition: trigger
|
|
id: light
|
|
sequence:
|
|
- alias: Turn of some lights
|
|
action: light.turn_off
|
|
target:
|
|
entity_id:
|
|
- light.groep_woonkamer
|
|
- light.groep_speelhoek
|
|
- light.keuken
|
|
default:
|
|
- alias: Turn off all lights
|
|
action: light.turn_off
|
|
target:
|
|
entity_id: light.groep_beneden
|
|
- id: 3fd99480-be86-44d6-a3dd-678c832d6366
|
|
alias: Restroom light on and off
|
|
mode: single
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: Motion detected in restroom
|
|
trigger: state
|
|
entity_id: binary_sensor.wc_motion_occupancy
|
|
to: 'on'
|
|
from: 'off'
|
|
actions:
|
|
- alias: Turn light on
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: light.wc
|
|
- repeat:
|
|
sequence:
|
|
- alias: Wait until motion sensor triggers again
|
|
wait_for_trigger:
|
|
- alias: Motion detected again
|
|
trigger: state
|
|
entity_id: binary_sensor.wc_motion_occupancy
|
|
to: 'on'
|
|
- alias: Light turned off manually
|
|
trigger: state
|
|
entity_id: light.wc
|
|
to: 'off'
|
|
timeout: 00:06:00
|
|
- if: '{{ wait.trigger is none }}'
|
|
then:
|
|
- alias: Turn light off after timeout
|
|
action: light.turn_off
|
|
target:
|
|
entity_id: light.wc
|
|
until:
|
|
- alias: Check if light is off
|
|
condition: state
|
|
entity_id: light.wc
|
|
state: 'off'
|
|
- id: 089a1b6a-4dfa-490e-bda3-675de31e1807
|
|
alias: LIDL button livingroom
|
|
triggers:
|
|
- alias: LIDL button pressed
|
|
trigger: state
|
|
entity_id: event.knop_tv_hoek_action
|
|
not_from: unavailable
|
|
variables:
|
|
event: '{{ trigger.to_state.attributes.event_type | default(''unknown'', true)
|
|
}}'
|
|
actions:
|
|
- alias: Which click type
|
|
choose:
|
|
- conditions:
|
|
- alias: Short
|
|
condition: template
|
|
value_template: '{{ event == ''on'' }}'
|
|
sequence:
|
|
- alias: toggle led light
|
|
action: light.toggle
|
|
target:
|
|
entity_id: light.tv_lamp
|
|
- conditions:
|
|
- alias: Double press detected
|
|
condition: template
|
|
value_template: '{{ event == ''off'' }}'
|
|
sequence:
|
|
- alias: No action for double press
|
|
stop: Double press - no action configured
|
|
- id: 56046ae8-2eaa-47c0-b6ad-953cd4b5c641
|
|
alias: Lights on sunset and arrival home
|
|
mode: single
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: It gets dark inside
|
|
trigger: state
|
|
entity_id: binary_sensor.light_inside
|
|
from: 'on'
|
|
to: 'off'
|
|
id: dark
|
|
- alias: House mode changed from away to home
|
|
trigger: state
|
|
entity_id: sensor.house_mode
|
|
from: Afwezig
|
|
to: Thuis
|
|
id: home
|
|
- alias: NVIDIA Shield turned on
|
|
trigger: state
|
|
entity_id: media_player.nvidia_shield
|
|
from: 'off'
|
|
not_to:
|
|
- unavailable
|
|
- unknown
|
|
id: dark
|
|
- alias: Person arrived home
|
|
trigger: state
|
|
entity_id:
|
|
- person.martijn
|
|
- person.marleen
|
|
from: not_home
|
|
to: home
|
|
id: home_while_sleeping
|
|
actions:
|
|
- alias: Arriving home
|
|
choose:
|
|
- conditions:
|
|
- condition: trigger
|
|
id: home_while_sleeping
|
|
- alias: Check if house is in sleep mode
|
|
condition: state
|
|
entity_id: sensor.house_mode
|
|
state: Slapen
|
|
sequence:
|
|
- alias: Turn on dining table light dimmed
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: light.eettafel
|
|
data:
|
|
brightness: 100
|
|
- conditions:
|
|
- condition: trigger
|
|
id: home
|
|
sequence:
|
|
- alias: Turn on extractor hood plug when arriving home
|
|
action: switch.turn_on
|
|
target:
|
|
entity_id: switch.afzuigkap
|
|
- alias: Check if it's not bedtime yet
|
|
condition: time
|
|
after: 06:00
|
|
before: '22:00:00'
|
|
- choose:
|
|
- conditions:
|
|
- condition: trigger
|
|
id:
|
|
- dark
|
|
- shield
|
|
- home
|
|
- alias: Dark inside?
|
|
condition: state
|
|
entity_id: binary_sensor.light_inside
|
|
state: 'off'
|
|
- alias: Check if it's after sunset (with offset)
|
|
condition: sun
|
|
after: sunset
|
|
after_offset: -03:00:00
|
|
- alias: Check if house mode allows lighting
|
|
condition: state
|
|
entity_id: sensor.house_mode
|
|
state:
|
|
- Thuis
|
|
- Gast
|
|
- Vakantie
|
|
sequence:
|
|
- alias: Turn on lights
|
|
action: light.turn_on
|
|
entity_id:
|
|
- light.tv_lamp
|
|
- light.keukenspotjes
|
|
- alias: Turn on play area light
|
|
action: light.turn_on
|
|
entity_id:
|
|
- light.speelhoek
|
|
data:
|
|
brightness: 80
|
|
- alias: Turn on bookcase led
|
|
action: light.turn_on
|
|
entity_id: light.boekenkast
|
|
data:
|
|
brightness_pct: 15
|
|
color_temp_kelvin: 2000
|
|
- alias: TV on, bedtime children or holiday mode
|
|
choose:
|
|
- conditions:
|
|
- alias: After bedtime?
|
|
condition: time
|
|
after: '19:15:00'
|
|
- alias: Check if TV is not on
|
|
not:
|
|
- alias: TV aan?
|
|
condition: state
|
|
entity_id: media_player.nvidia_shield
|
|
state: 'off'
|
|
sequence:
|
|
- alias: Dim some lights
|
|
action: light.turn_on
|
|
target:
|
|
entity_id:
|
|
- light.eettafel
|
|
data:
|
|
brightness: 100
|
|
- id: cfeadbfe-57cd-4034-b993-e09a4eb3ce7d
|
|
alias: Assist Satellites off when TV turns on
|
|
mode: single
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: NVIDIA Shield turned on
|
|
trigger: state
|
|
entity_id: media_player.nvidia_shield
|
|
from: 'off'
|
|
actions:
|
|
- variables:
|
|
playing: "{{\n [\n 'media_player.woonkamer',\n 'media_player.keuken'\n\
|
|
\ ]\n | select('is_state', 'playing')\n | list\n}}\n"
|
|
- if: '{{ playing | count > 0 }}'
|
|
then:
|
|
- alias: Turn off Voice Satellites that are playing
|
|
action: media_player.turn_off
|
|
target:
|
|
entity_id: '{{ playing }}'
|
|
- id: '1752261526546'
|
|
alias: Set Shield to Launcher on start
|
|
triggers:
|
|
- alias: Shield turned on from off to idle
|
|
trigger: state
|
|
entity_id:
|
|
- media_player.nvidia_shield
|
|
to: idle
|
|
from: 'off'
|
|
actions:
|
|
- alias: Send HOME command to Shield
|
|
action: androidtv.adb_command
|
|
data:
|
|
command: HOME
|
|
target:
|
|
entity_id: media_player.nvidia_shield
|
|
mode: single
|
|
- id: 95757e21-9bcd-4379-a1c8-a7e2d502d2de
|
|
alias: Dude, Where's my car
|
|
triggers:
|
|
- alias: Martijn disconnected from Android Auto
|
|
trigger: state
|
|
entity_id: binary_sensor.pixel_10_pro_android_auto
|
|
from: 'on'
|
|
to: 'off'
|
|
id: leave_car
|
|
- alias: Home Assistant started
|
|
trigger: homeassistant
|
|
event: start
|
|
id: ha_start
|
|
variables:
|
|
loc: "{{\n states('sensor.pixel_10_pro_geocoded_location')\n if trigger.id ==\
|
|
\ 'leave_car'\n else state_attr('sensor.variables', 'variables').get('car_location',\
|
|
\ {}).get('location')\n}}\n"
|
|
lat: "{{\n state_attr('person.martijn', 'latitude')\n if trigger.id == 'leave_car'\n\
|
|
\ else state_attr('sensor.variables', 'variables').get('car_location', {}).get('latitude')\n\
|
|
}}\n"
|
|
lon: "{{\n state_attr('person.martijn', 'longitude')\n if trigger.id == 'leave_car'\n\
|
|
\ else state_attr('sensor.variables', 'variables').get('car_location', {}).get('longitude')\n\
|
|
}}\n"
|
|
actions:
|
|
- if:
|
|
- condition: trigger
|
|
id: leave_car
|
|
then:
|
|
- alias: Store car location in variables
|
|
event: set_variable
|
|
event_data:
|
|
key: car_location
|
|
value:
|
|
location: '{{ loc }}'
|
|
latitude: '{{ lat }}'
|
|
longitude: '{{ lon }}'
|
|
set_timestamp: false
|
|
- alias: Update car device tracker location
|
|
action: device_tracker.see
|
|
data:
|
|
dev_id: car
|
|
host_name: Locatie Auto
|
|
location_name: '{{ loc }}'
|
|
gps:
|
|
- '{{ lat }}'
|
|
- '{{ lon }}'
|
|
- id: e666e5ab-6dda-4c3b-8a1e-980104c2f102
|
|
alias: Actions for music buttons kids
|
|
triggers:
|
|
- alias: Trigger on button press
|
|
trigger: state
|
|
entity_id:
|
|
- event.knop_muziek_pepijn_action
|
|
- event.knop_muziek_floris_action
|
|
not_from: unavailable
|
|
not_to: unavailable
|
|
actions:
|
|
- alias: Define variables
|
|
variables:
|
|
area: '{{ area_id(trigger.entity_id) }}'
|
|
event_type: '{{ trigger.to_state.attributes.event_type | default(none) }}'
|
|
data_mapper:
|
|
slaapkamer_floris:
|
|
playlist: library://playlist/252
|
|
player: media_player.floris
|
|
exclude_lights: []
|
|
slaapkamer_pepijn:
|
|
playlist: library://playlist/251
|
|
player: media_player.pepijn
|
|
exclude_lights:
|
|
- light.pepijn_template
|
|
- light.pepijn
|
|
player: "{{\n integration_entities('music_assistant')\n | select('in', area_entities(area))\n\
|
|
\ | first\n | default\n}}\n"
|
|
- alias: Perform the right actions based on the button press
|
|
choose:
|
|
- conditions:
|
|
- alias: Light on button short press
|
|
condition: template
|
|
value_template: '{{ event_type == ''on'' }}'
|
|
sequence:
|
|
- alias: Enable party lights
|
|
action: script.party_party
|
|
data:
|
|
party_on: true
|
|
area: '{{ area }}'
|
|
exclude_lights: '{{ data_mapper[area].exclude_lights }}'
|
|
set_by: Music Button
|
|
- alias: Enable shuffle
|
|
action: media_player.shuffle_set
|
|
target:
|
|
entity_id: '{{ data_mapper[area].player }}'
|
|
data:
|
|
shuffle: true
|
|
- alias: Start playlist
|
|
action: music_assistant.play_media
|
|
target:
|
|
entity_id: '{{ data_mapper[area].player }}'
|
|
data:
|
|
enqueue: replace
|
|
media_id: '{{ data_mapper[area].playlist }}'
|
|
- conditions:
|
|
- alias: Light off button short press
|
|
condition: template
|
|
value_template: '{{ event_type == ''off'' }}'
|
|
sequence:
|
|
- alias: Disable party lights
|
|
action: script.party_party
|
|
data:
|
|
party_on: false
|
|
area: '{{ area }}'
|
|
set_by: Music Button
|
|
- alias: Start playlist
|
|
action: media_player.turn_off
|
|
target:
|
|
entity_id: '{{ data_mapper[area].player }}'
|
|
- conditions:
|
|
- alias: Left arrow short press
|
|
condition: template
|
|
value_template: '{{ event_type == ''arrow_left_click'' }}'
|
|
sequence:
|
|
- alias: Previous song
|
|
action: media_player.media_previous_track
|
|
target:
|
|
entity_id: '{{ data_mapper[area].player }}'
|
|
- conditions:
|
|
- alias: Right arrow short press
|
|
condition: template
|
|
value_template: '{{ event_type == ''arrow_right_click'' }}'
|
|
sequence:
|
|
- alias: Next song
|
|
action: media_player.media_next_track
|
|
target:
|
|
entity_id: '{{ data_mapper[area].player }}'
|
|
- conditions:
|
|
- alias: Light on button short press
|
|
condition: template
|
|
value_template: '{{ event_type == ''brightness_move_up'' }}'
|
|
sequence:
|
|
- alias: Enable party lights
|
|
action: script.party_party
|
|
data:
|
|
party_on: true
|
|
area: '{{ area }}'
|
|
exclude_lights: '{{ data_mapper[area].exclude_lights }}'
|
|
set_by: Music Button
|
|
- conditions:
|
|
- alias: Light off button long press
|
|
condition: template
|
|
value_template: '{{ event_type == ''brightness_move_down'' }}'
|
|
sequence:
|
|
- alias: Disable party lights
|
|
action: script.party_party
|
|
data:
|
|
party_on: false
|
|
area: '{{ area }}'
|
|
set_by: Music Button
|
|
- conditions:
|
|
- alias: Left arrow long press
|
|
condition: template
|
|
value_template: '{{ event_type == ''arrow_left_hold'' }}'
|
|
sequence:
|
|
- alias: Start playlist
|
|
action: media_player.turn_off
|
|
target:
|
|
entity_id: '{{ data_mapper[area].player }}'
|
|
- conditions:
|
|
- alias: Right arrow long press
|
|
condition: template
|
|
value_template: '{{ event_type == ''arrow_right_hold'' }}'
|
|
sequence:
|
|
- alias: Enable shuffle
|
|
action: media_player.shuffle_set
|
|
target:
|
|
entity_id: '{{ data_mapper[area].player }}'
|
|
data:
|
|
shuffle: true
|
|
- alias: Start playlist
|
|
action: music_assistant.play_media
|
|
target:
|
|
entity_id: '{{ data_mapper[area].player }}'
|
|
data:
|
|
enqueue: replace
|
|
media_id: '{{ data_mapper[area].playlist }}'
|
|
- id: 782ed19b-f497-47b9-adb2-782d538e8e33
|
|
alias: Disable Printer ingegration
|
|
triggers:
|
|
- alias: Printer connectivity status changed
|
|
trigger: state
|
|
entity_id: binary_sensor.printer
|
|
to:
|
|
- 'on'
|
|
- 'off'
|
|
actions:
|
|
- alias: Toggle printer status monitoring automation
|
|
action: automation.turn_{{ trigger.to_state.state }}
|
|
target:
|
|
entity_id: automation.f2_status_messages_for_printer
|
|
- alias: Enable or disable printer config entries based on connectivity
|
|
action: homeassistant.{{ 'disable' if trigger.to_state.state == 'off' else 'enable'
|
|
}}_config_entry
|
|
data:
|
|
config_entry_id:
|
|
- ca207fdeedd4443f3ffd84b518b1edae
|
|
- 032578ad1a4457ef750d888d0ec9cb47
|
|
- id: fab3e0d1-1d3a-46ce-b1c1-5c56e788bf02
|
|
alias: Status messages for printer
|
|
triggers:
|
|
- alias: Toner level dropped below 26%
|
|
trigger: template
|
|
value_template: "{{\n 'sensor.dcp_l2530dw_black_toner_remaining' | has_value\n\
|
|
\ and states('sensor.dcp_l2530dw_black_toner_remaining') | float < 26\n}}\n"
|
|
id: toner
|
|
- alias: Toner level dropped below 11% (critical)
|
|
trigger: template
|
|
value_template: "{{\n 'sensor.dcp_l2530dw_black_toner_remaining' | has_value\n\
|
|
\ and states('sensor.dcp_l2530dw_black_toner_remaining') | float < 11\n}}\n"
|
|
id: toner
|
|
- alias: Drum life dropped below 26%
|
|
trigger: template
|
|
value_template: "{{\n 'sensor.dcp_l2530dw_drum_remaining_life' | has_value\n\
|
|
\ and states('sensor.dcp_l2530dw_drum_remaining_life') | float < 26\n}}\n"
|
|
id: drum
|
|
- alias: Drum life dropped below 11% (critical)
|
|
trigger: template
|
|
value_template: "{{\n 'sensor.dcp_l2530dw_drum_remaining_life' | has_value\n\
|
|
\ and states('sensor.dcp_l2530dw_drum_remaining_life') | float < 11\n}}\n"
|
|
id: drum
|
|
conditions:
|
|
- alias: Previous state is not unavailable or unkown
|
|
condition: template
|
|
value_template: '{{ trigger.from_state.state not in [''unavailable'', ''unknown'']
|
|
}}'
|
|
actions:
|
|
- alias: Prepare notification message based on trigger type
|
|
variables:
|
|
message: "{%- if trigger.id == 'toner' %}\n \"De toner is nog maar voor {{\
|
|
\ states('sensor.dcp_l2530dw_black_toner_remaining') }}% vol\"\n{%- else %}\n\
|
|
\ \"De levensduur van de drum is nog maar {{ states('sensor.dcp_l2530dw_drum_remaining_life')\
|
|
\ }}\"\n{%- endif %}\n"
|
|
- alias: Notificatie naar telefoon Martijn
|
|
action: notify.mobile_app_pixel_10_pro
|
|
data:
|
|
title: Printer {{ trigger.id }} status
|
|
message: '{{ message }}'
|
|
data:
|
|
channel: Printer
|
|
ttl: 0
|
|
priority: high
|
|
notification_icon: mdi:printer
|
|
- id: b54906bf-51b0-4e0f-919a-ced9436588d6
|
|
alias: Xiaomi button Guest Bed
|
|
triggers:
|
|
- trigger: state
|
|
entity_id: event.knop_logeerbed_action
|
|
not_from: unavailable
|
|
variables:
|
|
event: '{{ trigger.to_state.attributes.event_type | default(''unknown'', true)
|
|
}}'
|
|
actions:
|
|
- alias: Which click type
|
|
choose:
|
|
- conditions: '{{ event == ''single'' }}'
|
|
sequence:
|
|
- alias: Toggle office ceiling light with dim warm setting
|
|
action: light.toggle
|
|
target:
|
|
entity_id: light.werkkamer_martijn_plafond
|
|
data:
|
|
brightness: 10
|
|
color_temp_kelvin: 2000
|
|
- conditions: '{{ event == ''hold'' }}'
|
|
sequence:
|
|
- if: '{{ is_state(''light.awtrix_martijn_matrix'', ''off'') }}'
|
|
then:
|
|
- alias: Turn on matrix display with low brightness
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: light.awtrix_martijn_matrix
|
|
data:
|
|
brightness: 10
|
|
- alias: Wait 10 seconds before turning off matrix
|
|
delay: 10
|
|
- alias: Turn off matrix display
|
|
action: light.turn_off
|
|
target:
|
|
entity_id: light.awtrix_martijn_matrix
|
|
- conditions: '{{ event == ''double'' }}'
|
|
sequence:
|
|
- alias: Toggle office ceiling light with bright cool setting
|
|
action: light.toggle
|
|
target:
|
|
entity_id: light.werkkamer_martijn_plafond
|
|
data:
|
|
brightness: 255
|
|
color_temp_kelvin: 6535
|
|
- conditions: '{{ event == ''release'' }}'
|
|
sequence: []
|
|
- id: 012eb968-e871-4029-8096-a63044a42029
|
|
alias: Turn off desk Martijn switch
|
|
triggers:
|
|
- trigger: state
|
|
entity_id:
|
|
- binary_sensor.computer_zolder
|
|
- binary_sensor.laptop_werk_martijn_lan
|
|
- binary_sensor.laptop_werk_martijn_wifi
|
|
- media_player.martijn
|
|
to:
|
|
- idle
|
|
- 'off'
|
|
for: 00:30:00
|
|
conditions:
|
|
- alias: Everyting off?
|
|
condition: state
|
|
entity_id:
|
|
- binary_sensor.computer_zolder
|
|
- binary_sensor.laptop_werk_martijn_lan
|
|
- binary_sensor.laptop_werk_martijn_wifi
|
|
- media_player.martijn
|
|
state:
|
|
- idle
|
|
- 'off'
|
|
for: 00:30:00
|
|
actions:
|
|
- alias: Turn off desk plug when devices are idle
|
|
action: switch.turn_off
|
|
target:
|
|
entity_id: switch.shelly1pm_bureau_martijn_relay
|
|
- id: 43077f87-25be-4516-b241-0db9d1e4ff98
|
|
alias: Start vacuum cleaner on Tuesday
|
|
triggers:
|
|
- id: vacuum
|
|
trigger: time
|
|
at:
|
|
- 08:00:00
|
|
- 09:00:00
|
|
weekday:
|
|
- tue
|
|
- trigger: event
|
|
event_type: mobile_app_notification_action
|
|
event_data:
|
|
action: not_today
|
|
id: not_today
|
|
conditions:
|
|
- alias: Vacuum working
|
|
condition: state
|
|
entity_id: binary_sensor.vacuum
|
|
state: 'on'
|
|
- condition: not
|
|
conditions:
|
|
- alias: Not on holiday
|
|
condition: state
|
|
entity_id: sensor.house_mode
|
|
state: Vakantie
|
|
- '{{ not is_state(''vacuum.valetudo_brokenachingdragonfly'', [''unavailable'',
|
|
''unknown'']) }}'
|
|
actions:
|
|
- alias: Action?
|
|
choose:
|
|
- conditions: '{{ trigger.id == ''not_today'' }}'
|
|
sequence:
|
|
- alias: Turn on no vacuum today boolean
|
|
action: input_boolean.turn_on
|
|
target:
|
|
entity_id: input_boolean.no_vacuum_today
|
|
- conditions:
|
|
- alias: Na 9u?
|
|
condition: time
|
|
after: 09:00:00
|
|
sequence:
|
|
- if:
|
|
- alias: Input Boolean off
|
|
condition: state
|
|
entity_id: input_boolean.no_vacuum_today
|
|
state: 'off'
|
|
then:
|
|
- alias: Start vacuum cleaner
|
|
action: vacuum.start
|
|
target:
|
|
entity_id: vacuum.valetudo_brokenachingdragonfly
|
|
else:
|
|
- alias: Turn off no vacuum today boolean
|
|
action: input_boolean.turn_off
|
|
target:
|
|
entity_id: input_boolean.no_vacuum_today
|
|
default:
|
|
- alias: Send vacuum start notification to phones
|
|
action: notify.all_phones
|
|
data:
|
|
message: Is alles van de grond?
|
|
title: De stofzuiger begint om 09:00
|
|
data:
|
|
channel: Vacuum
|
|
ttl: 0
|
|
priority: high
|
|
notification_icon: mdi:robot-vacuum
|
|
actions:
|
|
- action: not_today
|
|
title: Vandaag niet
|
|
- id: 501645e8-f419-4349-9f0b-57a2f915b345
|
|
alias: Notifications vacuum cleaner
|
|
mode: single
|
|
max_exceeded: silent
|
|
triggers:
|
|
- trigger: state
|
|
entity_id: vacuum.valetudo_brokenachingdragonfly
|
|
from: returning
|
|
to: docked
|
|
id: docked
|
|
- trigger: state
|
|
entity_id: vacuum.valetudo_brokenachingdragonfly
|
|
to: error
|
|
id: error
|
|
- trigger: time
|
|
at: '17:00:00'
|
|
id: time
|
|
- trigger: event
|
|
event_type: mobile_app_notification_action
|
|
event_data:
|
|
action: empty_vacuum_bin
|
|
id: empty
|
|
actions:
|
|
- if: '{{ trigger.id == ''docked'' }}'
|
|
then:
|
|
- alias: Increase vacuum dust bin counter
|
|
action: counter.increment
|
|
target:
|
|
entity_id: counter.vacuum_dust_bin
|
|
- choose:
|
|
- conditions: '{{ trigger.id in [''docked'', ''error''] }}'
|
|
sequence:
|
|
- variables:
|
|
title: "{%- if trigger.id == 'docked' %}\n Stofzuiger is klaar\n{%- else\
|
|
\ %}\n Probleem met stofzuiger\n{%- endif %}\n"
|
|
message: "{%- if trigger.id == 'docked' %}\n De stofzuiger is klaar en\
|
|
\ staat weer op z'n plek. Hij heeft nu {{ states('counter.vacuum_dust_bin')\
|
|
\ }} ladingen in z'n bakkie.\n{%- else %}\n Er is iets mis met de stofzuiger.\
|
|
\ De melding is: {{ states('sensor.valetudo_brokenachingdragonfly_error')\
|
|
\ }}\n{%- endif %}\n"
|
|
- alias: Send vacuum status notification to phones
|
|
action: notify.all_phones
|
|
data:
|
|
title: '{{ title }}'
|
|
message: '{{ message }}'
|
|
data:
|
|
channel: Vacuum
|
|
ttl: 0
|
|
priority: high
|
|
tag: vacuum_error
|
|
notification_icon: mdi:robot-vacuum
|
|
- conditions:
|
|
- condition: trigger
|
|
id: time
|
|
- alias: Bin full
|
|
condition: numeric_state
|
|
entity_id: counter.vacuum_dust_bin
|
|
above: 2
|
|
- alias: At home
|
|
condition: state
|
|
entity_id: person.martijn
|
|
state: home
|
|
- alias: Workday
|
|
condition: state
|
|
entity_id: binary_sensor.workday_sensor
|
|
state: 'on'
|
|
sequence:
|
|
- alias: Send vacuum bin full notification to Martijn
|
|
action: notify.mobile_app_pixel_10_pro
|
|
data:
|
|
title: Bakje vol
|
|
message: Maak het bakje van de stofzuiger leeg!
|
|
data:
|
|
channel: Vacuum
|
|
ttl: 0
|
|
priority: high
|
|
notification_icon: mdi:robot-vacuum
|
|
actions:
|
|
- action: empty_vacuum_bin
|
|
title: Done!
|
|
- conditions: '{{ trigger.id == ''empty'' }}'
|
|
sequence:
|
|
- alias: Reset vacuum dust bin counter
|
|
action: counter.reset
|
|
target:
|
|
entity_id: counter.vacuum_dust_bin
|
|
- id: ca0dceb5-ad00-4d9f-b0fc-9453574b1891
|
|
alias: Actions with Xiaomi Cube
|
|
mode: parallel
|
|
triggers:
|
|
- trigger: state
|
|
entity_id: event.magic_cube_action
|
|
not_from: unavailable
|
|
variables:
|
|
event: '{{ trigger.to_state.attributes.event_type | default(''unknown'', true)
|
|
}}'
|
|
actions:
|
|
- alias: Which action
|
|
choose:
|
|
- alias: Actions with shake
|
|
conditions: '{{ event == ''shake'' }}'
|
|
sequence:
|
|
- alias: Turn on desk power switch
|
|
action: switch.turn_on
|
|
target:
|
|
entity_id: switch.shelly1pm_bureau_martijn_relay
|
|
- alias: Turn on radio if morning on workday
|
|
choose:
|
|
- conditions:
|
|
- alias: Morning
|
|
condition: time
|
|
before: '11:00:00'
|
|
- alias: Workday
|
|
condition: state
|
|
entity_id: binary_sensor.workday_sensor
|
|
state: 'on'
|
|
sequence:
|
|
- alias: Wait for media player to be available
|
|
wait_template: '{{ ''media_player.martijn'' | has_value }}'
|
|
timeout:
|
|
minutes: 3
|
|
continue_on_timeout: false
|
|
- alias: Set media player volume to 50%
|
|
action: media_player.volume_set
|
|
target:
|
|
entity_id: media_player.martijn
|
|
data:
|
|
volume_level: 0.5
|
|
- alias: Start playing Studio Brussel radio
|
|
action: music_assistant.play_media
|
|
target:
|
|
entity_id: media_player.martijn
|
|
data:
|
|
media_id: Studio Brussel
|
|
media_type: radio
|
|
- alias: Actions with rotate
|
|
conditions: '{{ ''rotate'' in event }}'
|
|
sequence:
|
|
- variables:
|
|
volume: '{{ state_attr(''media_player.martijn'', ''volume_level'') }}'
|
|
- if: '{{ volume is not none }}'
|
|
then:
|
|
- alias: Adjust media player volume based on cube rotation
|
|
action: media_player.volume_set
|
|
target:
|
|
entity_id: media_player.martijn
|
|
data:
|
|
volume_level: '{% set c = 0.05 if event == ''rotate_right'' else -0.05
|
|
%} {{ ([ 0, volume + c, 1] | sort)[1] | round(2) }}
|
|
|
|
'
|
|
- mode: restart
|
|
variables: &id002
|
|
open: "{{\n trigger.id == 'open'\n and \n (\n states('sensor.weather_combined_max_temp_tomorrow')\
|
|
\ | float(21) <= 20\n or not is_state('binary_sensor.rain_until_morning',\
|
|
\ 'off')\n or as_local(as_datetime(states('sensor.sun_next_rising'))).time()\
|
|
\ > today_at('07:00').time()\n )\n}}\n"
|
|
triggers: &id003
|
|
- alias: closing time
|
|
trigger: template
|
|
value_template: "{% set close_time = close_time_workday\n if is_state('binary_sensor.workday_sensor',\
|
|
\ 'on')\n else close_time_weekend %}\n{{ now() > today_at(close_time) }}\n"
|
|
id: close
|
|
- alias: closing time
|
|
trigger: template
|
|
value_template: '{{ extra_close_time is defined and now() > today_at(extra_close_time)
|
|
}}'
|
|
id: close
|
|
- alias: outside temp above 18
|
|
trigger: numeric_state
|
|
entity_id: sensor.weather_combined_max_temp_today
|
|
above: 18
|
|
id: close
|
|
- alias: currently sunny weather
|
|
trigger: state
|
|
entity_id: weather.combined
|
|
to:
|
|
- sunny
|
|
- partycloudy
|
|
id: close
|
|
- alias: no rain for 15 minutes
|
|
trigger: state
|
|
entity_id: binary_sensor.rain
|
|
to: 'off'
|
|
for:
|
|
minutes: 15
|
|
id: close
|
|
- alias: inside temp above 20
|
|
trigger: template
|
|
value_template: '{{ states(temp) | float(0) >= 22 or (states(temp) | float(0)
|
|
> 20 and now().month in range(4,9)) }}'
|
|
id: close
|
|
- alias: Wait for manual override period to end
|
|
trigger: template
|
|
value_template: '{{ is_state(manual, ''off'') }}'
|
|
- alias: opening time
|
|
trigger: template
|
|
value_template: '{{ now() > today_at(open_time) }}'
|
|
id: open
|
|
conditions: &id004
|
|
- alias: During screen season (March through September)
|
|
condition: template
|
|
value_template: '{{ 3 <= now().month <= 8 }}'
|
|
- condition: or
|
|
conditions:
|
|
- alias: open
|
|
condition: and
|
|
conditions:
|
|
- alias: open trigger
|
|
condition: trigger
|
|
id: open
|
|
- alias: cold day tomorrow or rain expected
|
|
condition: template
|
|
value_template: "{{\n trigger.id == 'open'\n and \n (\n \
|
|
\ states('sensor.weather_combined_max_temp_tomorrow') | float(21) <= 20\n\
|
|
\ or not is_state('binary_sensor.rain_until_morning', 'off')\n \
|
|
\ )\n}}\n"
|
|
- alias: close
|
|
condition: and
|
|
conditions:
|
|
- alias: close trigger
|
|
condition: trigger
|
|
id: close
|
|
- alias: closing time
|
|
condition: template
|
|
value_template: "{% set close_time = close_time_workday\n if is_state('binary_sensor.workday_sensor',\
|
|
\ 'on')\n else close_time_weekend %}\n{{ today_at(close_time) < now() <\
|
|
\ today_at(open_time) }}\n"
|
|
- alias: outside temp above 18
|
|
condition: numeric_state
|
|
entity_id: sensor.weather_combined_max_temp_today
|
|
above: 18
|
|
- alias: currently sunny weather
|
|
condition: state
|
|
entity_id: weather.combined
|
|
state:
|
|
- sunny
|
|
- partycloudy
|
|
- alias: no rain for 15 minutes
|
|
condition: state
|
|
entity_id: binary_sensor.rain
|
|
state: 'off'
|
|
- alias: inside temp above 20
|
|
condition: template
|
|
value_template: '{{ states(temp) | float(0) >= 20 }}'
|
|
- alias: not manually opened/closed in the last period
|
|
condition: template
|
|
value_template: "{{ \n manual is undefined\n or not is_state(manual,\
|
|
\ 'on')\n}}\n"
|
|
actions: &id005
|
|
- choose:
|
|
- conditions:
|
|
- alias: close trigger
|
|
condition: trigger
|
|
id: close
|
|
- alias: cover is completely open or time is after 11:00
|
|
condition: template
|
|
value_template: "{% set cleaning = \n 'floris' in cover\n and now().weekday()\
|
|
\ == 3\n and extra_close_time is defined\n and today_at(open_time) < now()\
|
|
\ < today_at(extra_close_time)\n%} {{\n not is_state_attr(cover, 'cover_position',\
|
|
\ 0)\n and\n (\n not cleaning \n or is_state_attr(cover, 'cover_position',\
|
|
\ 100)\n )\n}}\n"
|
|
sequence:
|
|
- alias: close the cover
|
|
action: cover.close_cover
|
|
target:
|
|
entity_id: '{{ cover }}'
|
|
- conditions:
|
|
- alias: open trigger
|
|
condition: trigger
|
|
id: open
|
|
- alias: cover is not already completely open
|
|
condition: template
|
|
value_template: '{{ not is_state_attr(cover, ''cover_position'', 100) }}'
|
|
sequence:
|
|
- alias: open the cover
|
|
action: cover.open_cover
|
|
target:
|
|
entity_id: '{{ cover }}'
|
|
id: 27c39fe7-4505-4e6a-a739-bcc20f8f4c4b
|
|
alias: Open and close cover Pepijn when needed
|
|
trigger_variables:
|
|
cover: cover.pepijn_template
|
|
temp: sensor.pepijn_temp
|
|
manual: binary_sensor.screen_pepijn_manual
|
|
close_time_workday: 07:30
|
|
close_time_weekend: 08:30
|
|
open_time: '18:00'
|
|
- mode: restart
|
|
variables: *id002
|
|
triggers: *id003
|
|
conditions: *id004
|
|
actions: *id005
|
|
id: 4711e349-f3e2-4e7d-adcb-e3b000162fd8
|
|
alias: Open or close covers Floris when needed
|
|
trigger_variables:
|
|
cover: cover.floris
|
|
temp: sensor.floris_temp
|
|
manual: binary_sensor.screen_floris_manual
|
|
close_time_workday: 07:30
|
|
close_time_weekend: 08:30
|
|
extra_close_time: '11:00'
|
|
open_time: '22:00'
|
|
- mode: restart
|
|
variables: *id002
|
|
triggers: *id003
|
|
conditions: *id004
|
|
actions: *id005
|
|
id: dd78d7db-7bd2-48ce-9543-64ee16d98732
|
|
alias: Open or close covers office Marleen when needed
|
|
trigger_variables:
|
|
cover: cover.werkkamer_marleen
|
|
temp: sensor.werkkamer_marleen_temp
|
|
manual: binary_sensor.screen_werkkamer_marleen_manual
|
|
close_time_workday: 07:30
|
|
close_time_weekend: 08:30
|
|
open_time: '18:00'
|
|
- mode: restart
|
|
variables: *id002
|
|
triggers: *id003
|
|
conditions: *id004
|
|
actions: *id005
|
|
id: aab636cd-dac7-4837-82a8-720affe3879f
|
|
alias: Open or close covers bedroom when needed
|
|
trigger_variables:
|
|
cover: cover.slaapkamer_zolder_template
|
|
temp: sensor.awair_slaapkamer_temperature
|
|
manual: binary_sensor.screen_slaapkamer_manual
|
|
close_time_workday: 07:30
|
|
close_time_weekend: 08:30
|
|
open_time: '21:30'
|
|
- mode: restart
|
|
variables: *id002
|
|
triggers: *id003
|
|
conditions: *id004
|
|
actions: *id005
|
|
id: 04423f6c-4db1-4375-8f94-1b1b4438920d
|
|
alias: Open or close covers landing when needed
|
|
trigger_variables:
|
|
cover: cover.overloop_zolder_template
|
|
temp: sensor.awair_slaapkamer_temperature
|
|
manual: binary_sensor.screen_overloop_zolder_manual
|
|
close_time_workday: 07:30
|
|
close_time_weekend: 08:30
|
|
open_time: '21:30'
|
|
- id: fa2ca8c5-675c-4d6a-928b-4e0477cfed3
|
|
alias: Make sure cover is open for cleaning
|
|
mode: restart
|
|
triggers:
|
|
- trigger: state
|
|
entity_id: cover.floris_links
|
|
attribute: current_position
|
|
to: 0
|
|
for:
|
|
minutes: 2
|
|
- trigger: time
|
|
at: 08:30
|
|
conditions:
|
|
- alias: Cleaning time
|
|
condition: time
|
|
after: 08:30:00
|
|
before: '11:00:00'
|
|
weekday:
|
|
- thu
|
|
- alias: cover closed
|
|
condition: state
|
|
entity_id: cover.floris_links
|
|
attribute: current_position
|
|
state: 0
|
|
actions:
|
|
- alias: Set middle cover to 50%
|
|
action: cover.set_cover_position
|
|
target:
|
|
entity_id: cover.floris_links
|
|
data:
|
|
position: 50
|
|
- id: 48718b8b-2768-4e79-9ac6-fa4f3a10cabe
|
|
alias: Screens up with upcoming rain
|
|
triggers:
|
|
- trigger: state
|
|
entity_id: binary_sensor.rain
|
|
to: 'on'
|
|
for: 00:00:10
|
|
- alias: Home Assistant startup
|
|
trigger: homeassistant
|
|
event: start
|
|
id: start
|
|
variables:
|
|
screens:
|
|
- cover.floris
|
|
- cover.pepijn_template
|
|
- cover.werkkamer_marleen
|
|
- cover.overloop_zolder_template
|
|
- cover.slaapkamer_zolder_template
|
|
down_entity_id: "{{\n screens\n | select('has_value')\n | reject('is_state_attr',\
|
|
\ 'current_position', 100)\n | list\n}}\n"
|
|
screens_down: '{{ down_entity_id | map(''state_attr'', ''friendly_name'') | list
|
|
}}'
|
|
screens_unavailable: "{{\n screens\n | reject('has_value')\n | map('state_attr',\
|
|
\ 'friendly_name')\n | list\n}}\n"
|
|
conditions:
|
|
- or:
|
|
- alias: Screens open?
|
|
condition: template
|
|
value_template: '{{ screens_down | count > 0 }}'
|
|
- alias: Screens unavailable?
|
|
condition: template
|
|
value_template: '{{ screens_unavailable | count > 0 }}'
|
|
- alias: Verify it's currently raining
|
|
condition: state
|
|
entity_id: binary_sensor.rain
|
|
state: 'on'
|
|
for:
|
|
seconds: '{{ 0 if trigger.id == ''start'' else 10 }}'
|
|
actions:
|
|
- alias: Open screens
|
|
choose:
|
|
- conditions: '{{ screens_down | count > 0 }}'
|
|
sequence:
|
|
- alias: Screens up
|
|
action: cover.open_cover
|
|
target:
|
|
entity_id: '{{ down_entity_id }}'
|
|
- alias: Send rain notification to phone Martijn
|
|
action: notify.mobile_app_pixel_10_pro
|
|
data:
|
|
title: "{%- if screens_unavailable | count > 0 %}\n \"LET OP! Niet alle screens\
|
|
\ beschikbaar\"\n{%- else %}\n \"Screens gaan open\"\n{%- endif %}\n"
|
|
message: "{%- if screens_unavailable | count > 0 and screens_down | count >\
|
|
\ 0 %}\n {{ screens_unavailable | join(', ') }} {{ iif(screens_unavailable\
|
|
\ | count > 1, 'zijn', 'is') }} niet beschikbaar, deze {{ iff(screens_down\
|
|
\ | count > 1, 'gaan', 'gaat') }} open: {{ screens_down | join(', ') }}\"\n\
|
|
{%- elif screens_unavailable | count > 0 %}\n {{ screens_unavailable | join(',\
|
|
\ ') }} {{ iif(screens_unavailable | count > 1, 'zijn', 'is') }} niet beschikbaar,\
|
|
\ er gaan geen screens open\n{%- else %}\n Er komt regen aan, deze screens\
|
|
\ gaan nu open: {{ screens_down | join(', ') }}\n{%- endif %}\n"
|
|
data:
|
|
channel: Screens
|
|
ttl: 0
|
|
priority: high
|
|
notification_icon: mdi:weather-rainy
|
|
- id: 767b2b4c-8dc6-4e42-b871-fad275273ebc
|
|
alias: Party Time!
|
|
mode: parallel
|
|
triggers:
|
|
- trigger: state
|
|
entity_id:
|
|
- media_player.floris
|
|
- media_player.pepijn
|
|
- media_player.woonkamer
|
|
for:
|
|
seconds: 1
|
|
variables:
|
|
song_titles:
|
|
- europapa
|
|
artists:
|
|
- snollebollekes
|
|
area_mapper:
|
|
media_player.woonkamer:
|
|
area_list:
|
|
- woonkamer
|
|
- speelhoek
|
|
media_player.pepijn:
|
|
area_list:
|
|
- slaapkamer_pepijn
|
|
exclude_lights:
|
|
- light.pepijn
|
|
media_player.floris:
|
|
area_list:
|
|
- slaapkamer_floris
|
|
party_on: "{{\n trigger.to_state.state == 'playing'\n and\n (\n trigger.to_state.attributes.get('media_title')\
|
|
\ | lower is search(song_titles | default([]) | join('|') | lower)\n or\n\
|
|
\ trigger.to_state.attributes.get('media_artist') | lower is search(artists\
|
|
\ | default([]) | join('|') | lower)\n )\n}}\n"
|
|
area_list: '{{ area_mapper[trigger.entity_id].area_list }}'
|
|
exclude_lights: '{{ area_mapper[trigger.entity_id].get(''exclude_lights'', [])
|
|
}}'
|
|
actions:
|
|
- delay: '{{ this.attributes.current * 0.5 }}'
|
|
- repeat:
|
|
for_each: '{{ area_list }}'
|
|
sequence:
|
|
- variables:
|
|
current_state: "{{\n ((state_attr('sensor.variables', 'variables') | default({},\
|
|
\ true)).get('party_mode', {}).items()\n | selectattr('0', 'eq', repeat.item)\n\
|
|
\ | map(attribute= '1')\n | list\n | first\n | default({})).get('state',\
|
|
\ false)\n}}\n"
|
|
current_set_by: "{{\n ((state_attr('sensor.variables', 'variables') | default({},\
|
|
\ true)).get('party_mode', {}).items()\n | selectattr('0', 'eq', repeat.item)\n\
|
|
\ | map(attribute= '1')\n | list\n | first\n | default({})).get('set_by',\
|
|
\ 'unknown')\n}}\n"
|
|
- if:
|
|
- '{{ party_on != current_state }}'
|
|
- '{{ current_set_by == ''song'' if not party_on else true }}'
|
|
then:
|
|
- action: script.turn_on
|
|
target:
|
|
entity_id: script.party_party
|
|
data:
|
|
variables:
|
|
area: '{{ repeat.item }}'
|
|
party_on: '{{ party_on }}'
|
|
exclude_lights: '{{ exclude_lights }}'
|
|
set_by: song
|
|
- delay: 0.5
|
|
- id: 6d0dc8bd-d264-42b8-8488-10e2e44d9393
|
|
alias: Update device trackers for phone Martijn
|
|
triggers:
|
|
- alias: Martijn's phone location or battery changed
|
|
trigger: state
|
|
entity_id:
|
|
- sensor.location_phone_martijn_bt
|
|
- sensor.pixel_10_pro_battery_level
|
|
from: null
|
|
- alias: Home Assistant started
|
|
trigger: homeassistant
|
|
event: start
|
|
actions:
|
|
- alias: Update Martijn's phone device tracker
|
|
action: device_tracker.see
|
|
data:
|
|
dev_id: phone_martijn_bt
|
|
host_name: Phone Martijn BT
|
|
mac: 0C:C4:13:45:75:85
|
|
battery: '{{ states(''sensor.pixel_10_pro_battery_level'') }}'
|
|
location_name: "{% if is_state('sensor.location_phone_martijn_bt', 'Niet Thuis')\
|
|
\ %}\n not_home\n{% elif is_state('sensor.location_phone_martijn_bt', ['unavailable',\
|
|
\ 'unknown']) %}\n {{ states('sensor.location_phone_martijn_bt') }}\n{% else\
|
|
\ %}\n home\n{% endif %}\n"
|
|
- id: efac28d0-19f8-42d7-928f-04e09d1191a5
|
|
alias: Send Digid code for kids to Marleen
|
|
triggers:
|
|
- alias: New SMS notification received on Martijn's phone
|
|
trigger: state
|
|
entity_id: sensor.pixel_10_pro_last_notification
|
|
to: null
|
|
conditions:
|
|
- alias: Notification from SMS app
|
|
condition: state
|
|
entity_id: sensor.pixel_10_pro_last_notification
|
|
attribute: package
|
|
state: com.google.android.apps.messaging
|
|
- alias: SMS regarding DigID code
|
|
condition: template
|
|
value_template: '{{ ''Uw DigiD sms-code om in te loggen bij'' in states(''sensor.pixel_10_pro_last_notification'')
|
|
}}
|
|
|
|
'
|
|
actions:
|
|
- alias: Send notification to Marleen
|
|
action: notify.mobile_app_pixel_8_marleen
|
|
data:
|
|
title: DigiD code
|
|
message: '{{ trigger.to_state.state }}'
|
|
- id: 35106a4b-1055-44db-958c-99b9d9cf721b
|
|
alias: Open music app on phone Martijn on BT connection
|
|
mode: restart
|
|
triggers:
|
|
- alias: Bluetooth connection changed on Martijn's phone
|
|
trigger: state
|
|
entity_id: sensor.pixel_10_pro_bluetooth_connection
|
|
attribute: connected_paired_devices
|
|
variables:
|
|
bt_added: "{%- set bt_old_list = trigger.from_state.attributes.connected_paired_devices\
|
|
\ %} {%- set bt_new_list = trigger.to_state.attributes.connected_paired_devices\
|
|
\ %} {{ \n bt_new_list\n | reject('in', bt_old_list)\n | join\n}}\n"
|
|
headphones:
|
|
- 60:AB:D2:3C:85:66 (LE-Big Ears)
|
|
- E0:67:81:01:F7:D3 (Haylou GT3)
|
|
- E8:07:BF:13:99:AB (Soundcore Spirit X)
|
|
actions:
|
|
- if: '{{ bt_added in headphones }}'
|
|
then:
|
|
- alias: Send music app selection notification
|
|
action: notify.mobile_app_pixel_10_pro
|
|
data:
|
|
title: Muziekje?
|
|
message: Wat wil je luisteren
|
|
data:
|
|
tag: music_choose
|
|
ttl: 0
|
|
priority: high
|
|
notification_icon: mdi:music
|
|
actions:
|
|
- action: URI
|
|
title: Spotify
|
|
uri: app://com.spotify.music
|
|
- action: URI
|
|
title: YT Music
|
|
uri: app://com.google.android.apps.youtube.music
|
|
- action: URI
|
|
title: TuneIn
|
|
uri: app://tunein.player
|
|
- alias: Wait before clearing notification
|
|
delay:
|
|
minutes: 10
|
|
- alias: Clear music app selection notification
|
|
action: notify.mobile_app_pixel_10_pro
|
|
data:
|
|
message: clear_notification
|
|
data:
|
|
tag: music_choose
|
|
- id: e7e51e10-c152-4514-bfc7-393c6d16d468
|
|
alias: Turn on right sound mode and beacon Martijn based on home proximity
|
|
mode: queued
|
|
triggers:
|
|
- alias: Martijn within 2 km of home
|
|
trigger: numeric_state
|
|
entity_id: sensor.thuis_martijn_distance
|
|
below: 2000
|
|
id: home
|
|
- alias: Martijn outside 2 km of home
|
|
trigger: numeric_state
|
|
entity_id: sensor.thuis_martijn_distance
|
|
above: 2000
|
|
id: not_home
|
|
actions:
|
|
- alias: Home or not?
|
|
if:
|
|
- condition: trigger
|
|
id: home
|
|
then:
|
|
- alias: Set phone to normal sound mode
|
|
action: notify.mobile_app_pixel_10_pro
|
|
data:
|
|
message: command_ringer_mode
|
|
data:
|
|
command: normal
|
|
- action: notify.mobile_app_pixel_10_pro
|
|
data:
|
|
message: command_ble_transmitter
|
|
data:
|
|
command: turn_on
|
|
else:
|
|
- alias: Set phone to vibrate mode
|
|
action: notify.mobile_app_pixel_10_pro
|
|
data:
|
|
message: command_ringer_mode
|
|
data:
|
|
command: vibrate
|
|
- action: notify.mobile_app_pixel_10_pro
|
|
data:
|
|
message: command_ble_transmitter
|
|
data:
|
|
command: turn_off
|
|
- id: aef85bb7-d7c6-4727-84b7-c15f222d7f71
|
|
alias: Menu for Grandstream
|
|
variables:
|
|
allowed_callers:
|
|
- '**621'
|
|
triggers:
|
|
- alias: SIP call webhook received
|
|
trigger: webhook
|
|
webhook_id: sip_call_webhook_id
|
|
local_only: true
|
|
conditions:
|
|
- alias: Check if webhook is for incoming call
|
|
condition: template
|
|
value_template: '{{ trigger.json.event == ''incoming_call'' }}'
|
|
actions:
|
|
- variables:
|
|
number_calling: '{{ trigger.json.parsed_caller }}'
|
|
- choose:
|
|
- conditions:
|
|
- alias: Check if caller is in allowed caller list
|
|
condition: template
|
|
value_template: "{{\n number_calling in allowed_callers\n if allowed_callers\
|
|
\ is defined and allowed_callers | length > 0\n else true\n}}\n"
|
|
sequence:
|
|
- alias: Start phone menu system
|
|
action: hassio.addon_stdin
|
|
data:
|
|
addon: c7744bff_ha-sip
|
|
input:
|
|
command: answer
|
|
number: '{{ number_calling }}'
|
|
menu:
|
|
message: 'Hallo draai 1 om papa te bellen, 2 om mama te bellen, 3
|
|
om oma van Balloe te bellen en 4 om oma van de Poes te bellen. Draai
|
|
8 om de alarmdiensten te bellen. Gebruik dit alleen als er echt een
|
|
noodgeval is. Draai 9 om te stoppen.
|
|
|
|
'
|
|
timeout: 30
|
|
choices:
|
|
'1':
|
|
id: papa
|
|
message: Papa wordt gebeld
|
|
action:
|
|
domain: script
|
|
service: turn_on
|
|
entity_id: script.make_call
|
|
service_data:
|
|
variables:
|
|
to_call: dad
|
|
number_calling: '{{ number_calling }}'
|
|
post_action: noop
|
|
'2':
|
|
id: mama
|
|
message: Mama wordt gebeld
|
|
action:
|
|
domain: script
|
|
service: turn_on
|
|
entity_id: script.make_call
|
|
service_data:
|
|
variables:
|
|
to_call: mom
|
|
number_calling: '{{ number_calling }}'
|
|
post_action: noop
|
|
'3':
|
|
id: grandma_dog
|
|
message: Oma van Balloe wordt gebeld
|
|
action:
|
|
domain: script
|
|
service: turn_on
|
|
entity_id: script.make_call
|
|
service_data:
|
|
variables:
|
|
to_call: grandma_dog
|
|
number_calling: '{{ number_calling }}'
|
|
post_action: noop
|
|
'4':
|
|
id: grandma_dog
|
|
message: Oma van de Poes wordt gebeld
|
|
action:
|
|
domain: script
|
|
service: turn_on
|
|
entity_id: script.make_call
|
|
service_data:
|
|
variables:
|
|
to_call: grandma_cat
|
|
number_calling: '{{ number_calling }}'
|
|
post_action: noop
|
|
'8':
|
|
id: alarm
|
|
message: 112 wordt gebeld
|
|
action:
|
|
domain: script
|
|
service: turn_on
|
|
entity_id: script.make_call
|
|
service_data:
|
|
variables:
|
|
to_call: alarm
|
|
number_calling: '{{ number_calling }}'
|
|
post_action: noop
|
|
'9':
|
|
id: bye
|
|
message: Tot horens
|
|
post_action: hangup
|
|
default:
|
|
id: wrong_code
|
|
message: Dit nummer doet niets, probeer het opnieuw
|
|
post_action: return
|
|
timeout:
|
|
id: timeout
|
|
message: Er is geen keuze gemaakt. Tot horens
|
|
post_action: hangup
|
|
mode: restart
|
|
- id: ec867a7d-71bf-4fee-89aa-1ac88a201711
|
|
alias: Notify when plants have moisture issues
|
|
triggers:
|
|
- alias: Check every evening
|
|
trigger: time
|
|
at: '20:00:00'
|
|
id: time
|
|
- alias: Check on a state change of the plant problem sensor
|
|
trigger: state
|
|
entity_id: sensor.plant_problems_count
|
|
not_from:
|
|
- unavailable
|
|
- unknown
|
|
not_to:
|
|
- unavailable
|
|
- unknown
|
|
id: sensor
|
|
for:
|
|
hours: 1
|
|
conditions:
|
|
- alias: Check if a message is required
|
|
condition: template
|
|
value_template: "{{\n trigger.to_state.state | int > trigger.from_state.state\
|
|
\ | int \n if trigger.id == 'sensor' \n else states('sensor.plant_problems_count')\
|
|
\ | int(0) > 0\n}}\n"
|
|
actions:
|
|
- alias: Assign texts for thirsty and flooded plants
|
|
variables:
|
|
thirsty: "{%- set ns = namespace(plants=[]) -%}\n{%- for plant in state_attr('sensor.plant_problems_count',\
|
|
\ 'thirsty') -%}\n {%- set ns.plants = ns.plants + [state_attr(plant, 'friendly_name')\
|
|
\ | trim ~ ' in ' ~ area_name(plant)] -%}\n{%- endfor -%}\n{%- set plants\
|
|
\ = (ns.plants[:-1] | join(', ') ~ ' en ' ~ ns.plants[-1]) if ns.plants |\
|
|
\ count > 2 else ns.plants | join(' en ') -%}\n{{ ('De volgende planten hebben\
|
|
\ dorst: ' ~ plants) if plants }}\n"
|
|
flooded: "{%- set ns = namespace(plants=[]) -%} {%- for plant in state_attr('sensor.plant_problems_count',\
|
|
\ 'flooded') -%}\n {%- set ns.plants = ns.plants + [state_attr(plant, 'friendly_name')\
|
|
\ | trim ~ ' in ' ~ area_name(plant)] -%}\n{%- endfor -%} {%- set plants =\
|
|
\ (ns.plants[:-1] | join(', ') ~ ' en ' ~ ns.plants[-1]) if ns.plants | count\
|
|
\ > 2 else ns.plants | join(' en ') -%} {{ ('De volgende planten hebben te\
|
|
\ veel water: ' ~ plants) if plants }}\n"
|
|
- alias: Send message
|
|
action: rest_command.signal_send_message
|
|
data:
|
|
message: '{{ [''🌱 Plant Alarm!'', thirsty, flooded] | select() | join(''\n'')
|
|
}}
|
|
|
|
'
|
|
mode: single
|
|
- rest_command:
|
|
postcodeloterij:
|
|
url: https://www.postcodeloterij.nl/public/rest/drawresults/winnings/NPL/P_{{
|
|
'E' if extra | default(false) | bool(false) else 'M' }}T_P{{ month | default((now().replace(day=1)
|
|
- timedelta(days=1)).strftime("%Y%m")) }}/?resultSize=10
|
|
method: POST
|
|
payload: secret postcodeloterij
|
|
headers:
|
|
Content-Type: application/x-www-form-urlencoded
|
|
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,
|
|
like Gecko) Chrome/117.0.0.0 Safari/537.36
|
|
template:
|
|
- triggers:
|
|
- alias: trigger at 18:00
|
|
trigger: time
|
|
at: '18:15'
|
|
- alias: trigger on manual event
|
|
trigger: event
|
|
event_type: update_postcodeloterij_prizes
|
|
id: manual
|
|
conditions:
|
|
- alias: Check if it triggered on the manual event, or if it is the in the first
|
|
3 days of the month
|
|
condition: template
|
|
value_template: '{{ trigger.id == ''manual'' or now().day in [1,2,3] }}'
|
|
actions:
|
|
- variables:
|
|
notify_action: notify.mobile_app_pixel_10_pro
|
|
- alias: Create variables for the month to use in the rest commands and messages
|
|
variables:
|
|
month: "{{\n trigger.event.data.month | int\n if\n trigger.platform ==\
|
|
\ 'event'\n and trigger.event.data is defined\n and 'month' in trigger.event.data\n\
|
|
\ else\n (now().replace(day=1) - timedelta(days=1)).strftime(\"%Y%m\"\
|
|
) | int\n}}\n"
|
|
month_formatted: '{% set months = [''januari'', ''februari'', ''maart'', ''april'',
|
|
''mei'', ''juni'', ''juli'', ''augustus'', ''september'', ''october'', ''november'',
|
|
''december''] %} {{ months[month % 100 -1] ~ '' '' ~ month // 100 }}
|
|
|
|
'
|
|
- alias: Issue rest command for the monthly draws
|
|
action: rest_command.postcodeloterij
|
|
data:
|
|
month: '{{ month }}'
|
|
response_variable: prizes
|
|
- alias: Issue rest command for the extra draws in June and December
|
|
action: rest_command.postcodeloterij
|
|
data:
|
|
extra: true
|
|
month: '{% set y = month // 100 %} {% set m = month % 100 %} {% set mapping
|
|
= {6: 13, 12: 14} %} {{ y * 100 + mapping[m] | default(m) }}
|
|
|
|
'
|
|
response_variable: prizes_extra
|
|
- alias: Create variables for the results of the rest commands
|
|
variables:
|
|
prizecount: '{{ prizes.content.prizeCount }}'
|
|
prizes: "{% set ns = namespace(prizes=[]) %} {% for p in prizes.content.wonPrizes\
|
|
\ %}\n {% set ns.prizes = ns.prizes + [p.description ~ ' (€ ' ~'{:.2f}'.format(p.prizeValue\
|
|
\ / 100) ~ ')'] %}\n{% endfor %} {{ ns.prizes }}\n"
|
|
prize_text: "{% if prizecount > 0 %}\n {% set m = 'prijs' if prizecount ==\
|
|
\ 1 else (prizecount ~ ' prijzen') %}\n {{ m }} in de trekking van {{ month_formatted\
|
|
\ }}: {{ prizes | join(', ') }}\n{% endif %}\n"
|
|
prizecount_extra: '{{ prizes_extra.content.prizeCount }}'
|
|
prizes_extra: "{% set ns = namespace(prizes=[]) %} {% for p in prizes_extra.content.wonPrizes\
|
|
\ %}\n {% set ns.prizes = ns.prizes + [p.description ~ ' (€ ' ~'{:.2f}'.format(p.prizeValue\
|
|
\ / 100) ~ ')'] %}\n{% endfor %} {{ ns.prizes }}\n"
|
|
prize_text_extra: "{% if prizecount_extra > 0 %}\n {% set m = 'prijs' if\
|
|
\ prizecount_extra == 1 else (prizecount_extra ~ ' prijzen') %}\n {{ m\
|
|
\ }} in de extra trekking: {{ prizes_extra | join(', ') }}\n{% endif %}\n"
|
|
prizecount_total: '{{ prizecount + prizecount_extra }}'
|
|
prize_text_full: 'We hebben {{ [prize_text, prize_text_extra] | select() |
|
|
join('' en '') }}
|
|
|
|
'
|
|
- alias: Send out notification to phone in case there are one of more pizes
|
|
if: "{{\n prizecount_total | default(0) > 0\n and month_formatted = state_attr('sensor.postcodeloterij',\
|
|
\ 'month')\n}}\n"
|
|
then:
|
|
- alias: Send notification
|
|
action: '{{ notify_action }}'
|
|
data:
|
|
title: 🎁 Winnen doe je bij...
|
|
message: '{{ prize_text_full }}'
|
|
data:
|
|
channel: LotteryPrize
|
|
ttl: 0
|
|
priority: high
|
|
notification_icon: mdi:gift
|
|
tag: LotteryPrize
|
|
sensor:
|
|
- name: Postcodeloterij
|
|
unique_id: 12f71395-3d76-434a-a3d0-9f01a03b834c
|
|
icon: '{{ ''mdi:gift'' if prizecount > 0 else ''mdi:emoticon-cry'' }}'
|
|
state: '{{ prizecount + prizecount_extra }}'
|
|
attributes:
|
|
prizes: '{{ prizes }}'
|
|
month: '{{ month_formatted }}'
|
|
extra: '{{ month % 100 in [6, 12] }}'
|
|
prizes_extra: '{{ prizes_extra }}'
|
|
last_updated: '{{ now().strftime(''%d-%m-%Y %H:%M'') }}'
|
|
- id: 1dc827cc-4287-48b1-8894-ad2e0202dd94
|
|
alias: Make sure entities which should not be turned off are always on
|
|
triggers:
|
|
- trigger: template
|
|
value_template: '{{ label_entities(''always_on'') | select(''is_state'', ''off'')
|
|
| list | count > 0 }}'
|
|
actions:
|
|
- alias: Turn entity on
|
|
action: homeassistant.turn_on
|
|
target:
|
|
entity_id: '{{ label_entities(''always_on'') | select(''is_state'', ''off'')
|
|
| list }}'
|
|
- alias: Reset bedside lamp Martijn when unavailable
|
|
id: 24622ebc-3be8-4ca2-a4ae-0920b97dc11b
|
|
triggers:
|
|
- trigger: state
|
|
entity_id: light.bedside_lamp
|
|
to: unavailable
|
|
for:
|
|
minutes: 5
|
|
- trigger: time
|
|
at:
|
|
- '21:00:00'
|
|
- 09:00:00
|
|
conditions:
|
|
- condition: state
|
|
entity_id: light.bedside_lamp
|
|
state: unavailable
|
|
- condition: time
|
|
after: 09:00:00
|
|
before: '21:00:01'
|
|
actions:
|
|
- alias: Turn off bedside lamp reset switch
|
|
action: switch.turn_off
|
|
target:
|
|
entity_id: switch.nachtlampje_martijn_reset
|
|
- alias: Wait 10 seconds before turning reset switch back on
|
|
delay:
|
|
seconds: 10
|
|
- alias: Turn on bedside lamp reset switch to complete reset
|
|
action: switch.turn_on
|
|
target:
|
|
entity_id: switch.nachtlampje_martijn_reset
|
|
- id: 1021cdb8-6a53-4e31-bc04-5d776323e1c8
|
|
alias: Actions for stairs closet sonoff
|
|
mode: parallel
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: Sonoff stairs closet button pressed
|
|
trigger: state
|
|
entity_id: event.sonoff_trapkast_sonoff_trapkast
|
|
not_from: unavailable
|
|
conditions:
|
|
- alias: Check if button is in detached mode
|
|
condition: state
|
|
entity_id: select.sonoff_trapkast_button_type
|
|
state: Detached
|
|
actions:
|
|
- alias: Check if light entity is available
|
|
if: '{{ ''light.trapkast'' | has_value }}'
|
|
then:
|
|
- alias: Choose action based on press type
|
|
choose:
|
|
- conditions:
|
|
- alias: Single press detected
|
|
condition: template
|
|
value_template: '{{ trigger.to_state.attributes.event_type == ''single_press''
|
|
}}'
|
|
sequence:
|
|
- alias: Toggle stairs closet light
|
|
action: light.toggle
|
|
target:
|
|
entity_id: light.trapkast_template
|
|
- conditions:
|
|
- alias: Double press detected
|
|
condition: template
|
|
value_template: '{{ trigger.to_state.attributes.event_type == ''double_press''
|
|
}}'
|
|
sequence:
|
|
- alias: Toggle stairs closet light to full brightness
|
|
action: light.toggle
|
|
target:
|
|
entity_id: light.trapkast_template
|
|
data:
|
|
brightness: 255
|
|
else:
|
|
- alias: Toggle Sonoff relay as fallback
|
|
action: switch.toggle
|
|
target:
|
|
entity_id: switch.sonoff_trapkast_relay
|
|
- rest_command:
|
|
signal_get_messages:
|
|
url: secret signal_receive_url
|
|
timeout: 30
|
|
signal_send_message:
|
|
url: http://192.168.2.94:8080/v2/send
|
|
method: POST
|
|
timeout: 30
|
|
payload: "{#\n add default recipient and sender number for messages here,\n\
|
|
\ I use my variables sensor to not expose private phone numbers on GitHub\n\
|
|
#}\n {% set default_recipient = [state_attr('sensor.variables', 'variables').get('default_signal_number')]\
|
|
\ %}\n {% set sender_number = state_attr('sensor.variables', 'variables').get('signal_sender')\
|
|
\ %}\n{# ensure recipient is provided and ensure it is a list #}\n {% set\
|
|
\ recip = recipients | default(default_recipient) %}\n {% set recip = recip\
|
|
\ if recip is list else recip.split(',') | map('trim') | list %}\n\n{{\n \
|
|
\ {\n \"message\": message | default(\"\"),\n \"number\": sender_number,\n\
|
|
\ \"recipients\": recip,\n \"text_mode\": text_mode | default(\"normal\"\
|
|
)\n } | to_json\n}}\n"
|
|
template:
|
|
- triggers:
|
|
- alias: Time pattern trigger to fetch messages
|
|
trigger: time_pattern
|
|
minutes: /1
|
|
actions:
|
|
- alias: Fetch Signal messages from API
|
|
action: rest_command.signal_get_messages
|
|
response_variable: rest_messages
|
|
- alias: Parse and format message data
|
|
variables:
|
|
messages: "{% set ns = namespace(data=[]) %} {% set message_data = (rest_messages\
|
|
\ | default({}, true)).get('content')\n | from_json([]) %}\n{% for e in\
|
|
\ message_data\n if message_data is mapping\n and e.envelope is defined\n\
|
|
\ and e.envelope.dataMessage is defined \n%}\n {% set d = e.envelope %}\n\
|
|
\ {% set ns.data = ns.data + \n [\n dict(\n source=d.source,\n\
|
|
\ name=d.sourceName,\n received=(d.timestamp | int | multiply(0.001)\
|
|
\ | as_datetime | as_local).isoformat(),\n message=d.dataMessage.message\n\
|
|
\ )\n ]\n %}\n{% endfor %} {{ ns.data }}\n"
|
|
sensor:
|
|
- unique_id: e03f4dae-0e7d-4a78-9e34-80e050743332
|
|
name: Signal messages
|
|
state: '{{ messages | map(attribute=''received'') | max if messages | count
|
|
> 0 else this.state }}'
|
|
attributes:
|
|
messages: '{% set current = this.attributes.get(''messages'', []) %} {{ (messages
|
|
+ current)[:5] if messages | count <= 5 else messages }}
|
|
|
|
'
|
|
- id: 2017abca-a756-420b-98fb-228824ce182a
|
|
alias: Voice - Manage Shield and Soundbar on voice command in living room or kitchen
|
|
mode: parallel
|
|
variables:
|
|
tv_playing: '{{ is_state(''media_player.nvidia_shield'', ''playing'') }}'
|
|
soundbar_source: '{{ state_attr(''media_player.samsung_soundbar'', ''source'')
|
|
| default(''off'', true) }}'
|
|
living: '{{ area_name(trigger.entity_id) == ''Woonkamer'' }}'
|
|
satellite_player: '{{ device_entities(device_id(trigger.entity_id)) | select(''match'',
|
|
''media_player'') | list | first }}'
|
|
triggers:
|
|
- trigger: state
|
|
entity_id:
|
|
- assist_satellite.woonkamer
|
|
- assist_satellite.keuken
|
|
to: listening
|
|
actions:
|
|
- if: '{{ tv_playing and living }}'
|
|
then:
|
|
- alias: Pause the Shield
|
|
action: media_player.media_pause
|
|
target:
|
|
entity_id: media_player.nvidia_shield
|
|
- if: '{{ tv_playing }}'
|
|
then:
|
|
- alias: Create scene with current soundbar status
|
|
action: scene.create
|
|
data:
|
|
scene_id: soundbar_before
|
|
snapshot_entities:
|
|
- media_player.samsung_soundbar
|
|
- alias: Wait for satellite to enter processing state
|
|
wait_for_trigger:
|
|
- trigger: state
|
|
entity_id:
|
|
- assist_satellite.woonkamer
|
|
- assist_satellite.keuken
|
|
to: processing
|
|
timeout:
|
|
seconds: 10
|
|
- variables:
|
|
living: '{{ area_name(wait.trigger.entity_id) == ''Woonkamer'' }}'
|
|
- if: '{{ wait.trigger is not none }}'
|
|
then:
|
|
- alias: Set volume soundbar
|
|
action: media_player.volume_set
|
|
target:
|
|
entity_id:
|
|
- media_player.samsung_soundbar
|
|
data:
|
|
volume_level: '{{ 0.1 if living else 0.02 }}'
|
|
- alias: Store current volume satellite
|
|
variables:
|
|
sat_vol: '{{ state_attr(satellite_player, ''volume_level'') }}'
|
|
- alias: Set volume voice satellite
|
|
action: media_player.volume_set
|
|
target:
|
|
entity_id: '{{ satellite_player }}'
|
|
data:
|
|
volume_level: 0.7
|
|
- if: '{{ living }}'
|
|
then:
|
|
- alias: Ensure soundbar is on
|
|
action: media_player.turn_on
|
|
target:
|
|
entity_id: media_player.samsung_soundbar
|
|
- alias: Ensure Soundbar is set to aux
|
|
action: media_player.select_source
|
|
data:
|
|
source: aux
|
|
target:
|
|
entity_id: media_player.samsung_soundbar
|
|
- alias: Wait for satellite to return to idle state
|
|
wait_for_trigger:
|
|
- trigger: template
|
|
value_template: '{{ is_state(trigger.entity_id, ''idle'') }}'
|
|
for:
|
|
seconds: 0.5
|
|
- alias: Set volume voice satellite back to old setting
|
|
action: media_player.volume_set
|
|
target:
|
|
entity_id: '{{ satellite_player }}'
|
|
data:
|
|
volume_level: '{{ sat_vol }}'
|
|
- if: '{{ tv_playing }}'
|
|
then:
|
|
- alias: Apply scene with previous soundbar settings
|
|
action: scene.turn_on
|
|
target:
|
|
entity_id: scene.soundbar_before
|
|
- if: '{{ not is_state(''media_player.nvidia_shield'', ''playing'') }}'
|
|
then:
|
|
- alias: Resume playing on Shield
|
|
action: media_player.media_play
|
|
target:
|
|
entity_id: media_player.nvidia_shield
|
|
- if: '{{ not tv_playing and living }}'
|
|
then:
|
|
- variables:
|
|
player: "{{\n integration_entities('music_assistant')\n | select('in',\
|
|
\ area_entities(area_id(trigger.entity_id)))\n | list\n | first\n\
|
|
\ | default('unknown')\n}}\n"
|
|
- alias: Wait for music to start playing
|
|
wait_template: '{{ is_state(player, ''playing'') }}'
|
|
timeout:
|
|
seconds: 10
|
|
- variables:
|
|
something_played: '{{ wait.completed }}'
|
|
- alias: Wait for music to stop playing
|
|
wait_for_trigger:
|
|
- trigger: template
|
|
value_template: "{{\n something_played\n and not is_state(player, 'playing')\n\
|
|
}}\n"
|
|
for:
|
|
seconds: 10
|
|
timeout:
|
|
minutes: 5
|
|
- if: '{{ wait.trigger is not none }}'
|
|
then:
|
|
- alias: Turn soundbar off again
|
|
action: media_player.turn_off
|
|
target:
|
|
entity_id: media_player.samsung_soundbar
|
|
- id: bd5c40c0-6c25-4560-9455-8318d1e3924a
|
|
alias: Make sure Soundbar is set to right source when something is playing
|
|
triggers:
|
|
- trigger: state
|
|
entity_id:
|
|
- media_player.nvidia_shield
|
|
to: playing
|
|
id: optical
|
|
- trigger: state
|
|
entity_id:
|
|
- media_player.woonkamer
|
|
to: playing
|
|
for:
|
|
seconds: 2
|
|
id: aux
|
|
conditions:
|
|
- alias: Soundbar not on right source
|
|
condition: template
|
|
value_template: '{{ not is_state_attr(''media_player.samsung_soundbar'', ''source'',
|
|
trigger.id) }}'
|
|
actions:
|
|
- if:
|
|
- condition: state
|
|
entity_id: media_player.samsung_soundbar
|
|
state: 'off'
|
|
then:
|
|
- alias: Turn on soundbar
|
|
action: media_player.turn_on
|
|
target:
|
|
entity_id: media_player.samsung_soundbar
|
|
- alias: Wait for soundbar to turn on
|
|
wait_template: '{{ is_state(''media_player.samsung_soundbar'', ''on'') }}'
|
|
- alias: Select correct soundbar source
|
|
action: media_player.select_source
|
|
data:
|
|
source: '{{ trigger.id }}'
|
|
target:
|
|
entity_id: media_player.samsung_soundbar
|
|
mode: single
|
|
- id: 5e74e69a-7e31-4769-ad6a-c438fce816dc
|
|
alias: Notifications for new HA version
|
|
mode: parallel
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: Home Assistant update available
|
|
trigger: state
|
|
entity_id:
|
|
- update.home_assistant_core_update
|
|
- update.home_assistant_operating_system_update
|
|
to: 'on'
|
|
variables:
|
|
what: '{{ trigger.to_state.attributes.title }}'
|
|
from: '{{ trigger.to_state.attributes.installed_version }}'
|
|
to: '{{ trigger.to_state.attributes.latest_version }}'
|
|
url: "{%- \n if what == 'Home Assistant Operating System'\n or\n (\n \
|
|
\ (not version(to).beta and version(to).patch == '0' )\n or\n \
|
|
\ (version(to).beta and version.modifier == 'b0')\n )\n%}\n {{ 'url'\
|
|
\ }}\n{%- else %}\n https://github.com/home-assistant/core/releases/tag/{{\
|
|
\ to }}\n{%- endif %}\n"
|
|
actions:
|
|
- alias: Set up variables for notification actions
|
|
variables:
|
|
action_update: '{{ ''UPDATE_'' ~ context.id }}'
|
|
action_skip: '{{ ''SKIP_'' ~ context.id }}'
|
|
- alias: Send Home Assistant update notification to phone
|
|
action: notify.mobile_app_pixel_10_pro
|
|
data:
|
|
title: 'Update: {{ what }}
|
|
|
|
'
|
|
message: Versie {{ to }} is nu beschikbaar. Je zit nu op {{ from }}.
|
|
data:
|
|
tag: ha_update_{{ what | slugify }}
|
|
channel: Home Assistant
|
|
ttl: 0
|
|
priority: high
|
|
clickAction: /config/dashboard
|
|
actions:
|
|
- action: URI
|
|
title: Changelog
|
|
uri: '{{ url }}'
|
|
- action: '{{ action_skip }}'
|
|
title: Skip
|
|
- action: '{{ action_update }}'
|
|
title: Update
|
|
- alias: Wait for user response on notification
|
|
wait_for_trigger:
|
|
- alias: Update button pressed
|
|
trigger: event
|
|
event_type: mobile_app_notification_action
|
|
event_data:
|
|
action: '{{ action_update }}'
|
|
- alias: Skip button pressed
|
|
trigger: event
|
|
event_type: mobile_app_notification_action
|
|
event_data:
|
|
action: '{{ action_skip }}'
|
|
- alias: Install or skip update based on user choice
|
|
action: update.{{ 'install' if 'UPDATE' in wait.trigger.event.data.action else
|
|
'skip' }}
|
|
target:
|
|
entity_id: '{{ trigger.entity_id }}'
|
|
- alias: Set reboot notification flag if update was installed
|
|
if: '{{ wait.trigger.event.data.action == action_update }}'
|
|
then:
|
|
- alias: Write reboot flag to variables sensor
|
|
event: set_variable
|
|
event_data:
|
|
key: reboot_from_notification
|
|
value: true
|
|
set_timestamp: false
|
|
- id: 8034c218-8019-4f21-8921-fabfd38043a8
|
|
alias: Turn on light technical area based on door sensor
|
|
triggers:
|
|
- trigger: state
|
|
entity_id: binary_sensor.technische_ruimte_contact
|
|
from:
|
|
- 'on'
|
|
- 'off'
|
|
to:
|
|
- 'on'
|
|
- 'off'
|
|
actions:
|
|
- alias: Turn on light
|
|
action: light.turn_{{ trigger.to_state.state }}
|
|
target:
|
|
entity_id: light.technische_ruimte
|
|
- id: 690cc2c9-f014-4b38-90e8-51217659d49e
|
|
alias: Notifications for trash containers
|
|
mode: single
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: Morning trash reminder (7:00 AM)
|
|
trigger: time
|
|
at: 07:00:00
|
|
variables:
|
|
when_en: today
|
|
when_nl: Vandaag
|
|
- alias: Evening trash reminder (8:00 PM)
|
|
trigger: time
|
|
at: '20:00:00'
|
|
variables:
|
|
when_en: tomorrow
|
|
when_nl: Morgen
|
|
variables:
|
|
sensor: sensor.afvalwijzer_{{ when_en }}
|
|
trash_descr:
|
|
restgft: rest- en GFT-bak
|
|
dhm: papier- en PMD-bak
|
|
papier: papier- en PMD-bak
|
|
kerstbomen: kerstboom
|
|
trash_pickup: '{%- set trash = states(sensor).split('', '') %} {{ trash_descr.items()
|
|
| list | selectattr(''0'', ''in'', trash) | map(attribute=''1'') | list }}
|
|
|
|
'
|
|
conditions:
|
|
- alias: Notification needed?
|
|
condition: template
|
|
value_template: '{{ states(sensor) != ''geen'' }}'
|
|
actions:
|
|
- alias: Notification phones
|
|
action: notify.all_phones
|
|
data:
|
|
title: "{%- if trash_pickup | length > 1 %}\n Denk aan de {{ trash_pickup[:-1]\
|
|
\ | join(', ') }} en {{ trash_pickup[-1] }}!\n{%- else %}\n Denk aan de {{\
|
|
\ trash_pickup[0] }}!\n{%- endif %}\n"
|
|
message: "{%- if trash_pickup | length > 1 %}\n {{ when_nl }} moeten de {{\
|
|
\ trash_pickup[:-1] | join(', ') }} en {{ trash_pickup[-1] }} buiten.\n{%-\
|
|
\ else %}\n {{ when_nl }} moet de {{ trash_pickup[0] }} buiten.\n{%- endif\
|
|
\ %}\n"
|
|
data:
|
|
channel: Trash
|
|
ttl: 0
|
|
priority: high
|
|
notification_icon: mdi:trash-can-outline
|
|
- id: 98e424f3-e458-4061-8562-c9e2700e0c3a
|
|
alias: Ulanzi activate or deactivate app
|
|
mode: queued
|
|
triggers:
|
|
- alias: Monitor Ulanzi battery level changes
|
|
trigger: state
|
|
entity_id: sensor.awtrix_martijn_battery
|
|
to: null
|
|
variables:
|
|
show: '{{ trigger.to_state.state = ''100'' }}'
|
|
app: bat
|
|
conditions:
|
|
- alias: Check app is defined and valid
|
|
condition: template
|
|
value_template: '{{ app is defined and app is not none }}'
|
|
- alias: Check update flag is enabled
|
|
condition: template
|
|
value_template: '{{ update | default(true) | bool(true) }}'
|
|
actions:
|
|
- alias: Publish app activation status to MQTT
|
|
action: mqtt.publish
|
|
data:
|
|
qos: 0
|
|
retain: false
|
|
topic: awtrix_martijn/apps
|
|
payload: "{{\n [\n dict(\n name = app,\n show = show | default(true)\
|
|
\ | bool(true)\n )\n ] | to_json\n}}\n"
|
|
- id: 52dd10e9-7bf6-4778-b4b7-a8967a4b5fb8
|
|
alias: Ulanzi indicators
|
|
mode: queued
|
|
triggers:
|
|
- alias: Monitor WhatsApp notification status
|
|
trigger: state
|
|
entity_id: binary_sensor.whatsapp_notification_active
|
|
to: null
|
|
variables:
|
|
action: '{{ trigger.to_state.state }}'
|
|
indicator: 1
|
|
color_name: green
|
|
- alias: Monitor rain data status
|
|
trigger: state
|
|
entity_id: binary_sensor.raindata
|
|
to: null
|
|
variables:
|
|
action: '{{ trigger.to_state.state }}'
|
|
indicator: 2
|
|
color_name: blue
|
|
- alias: Monitor net power consumption status
|
|
trigger: state
|
|
entity_id: binary_sensor.net_power_consumption
|
|
to: null
|
|
variables:
|
|
action: '{{ trigger.to_state.state in [''on'', ''off''] }}'
|
|
indicator: 3
|
|
color_name: '{{ ''yellow'' if trigger.to_state.state == ''off'' else ''purple''
|
|
}}'
|
|
conditions:
|
|
- alias: Check update flag is enabled for indicators
|
|
condition: template
|
|
value_template: '{{ update | default(true) | bool(true) }}'
|
|
actions:
|
|
- if: '{{ action | default(true) | bool(true) }}'
|
|
then:
|
|
- alias: Turn Ulanzi indicator light on
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: light.awtrix_martijn_indicator_{{ indicator | default(1) | int(1)
|
|
}}
|
|
data:
|
|
brightness: '{{ brightness | default(state_attr(''light.matrix'', ''brightness''))
|
|
| int(255) }}'
|
|
color_name: '{{ color_name | default(''white'') }}'
|
|
else:
|
|
- alias: Turn Ulanzi indicator light off
|
|
action: light.turn_off
|
|
target:
|
|
entity_id: light.awtrix_martijn_indicator_{{ indicator }}
|
|
- id: 10d5d325-1ed3-47a8-9352-b1b1d121802e
|
|
alias: Ulanzi notificatons and custom apps
|
|
mode: queued
|
|
triggers:
|
|
- alias: Monitor weather changes for display
|
|
trigger: state
|
|
entity_id: weather.combined
|
|
to: null
|
|
variables: &id006
|
|
app: weather
|
|
text: '{{ state_attr(''weather.combined'', ''temperature'') }} °C'
|
|
icon: '{{ states(''weather.combined'') }}'
|
|
update: '{{ state_attr(''weather.combined'', ''temperature'') is not none }}'
|
|
- alias: Monitor weather temperature changes
|
|
trigger: state
|
|
entity_id: weather.combined
|
|
attribute: temperature
|
|
variables: *id006
|
|
- alias: Monitor office temperature and humidity sensors
|
|
trigger: state
|
|
entity_id:
|
|
- sensor.werkkamer_martijn_temp
|
|
- sensor.werkkamer_martijn_vocht
|
|
not_to: unavailable
|
|
variables:
|
|
app: '{{ trigger.to_state.attributes.device_class }}'
|
|
text: '{{ states(trigger.entity_id, with_unit=true) }}'
|
|
icon: "{% if app == 'humidity' %}\n humidity\n{% elif trigger.to_state.state\
|
|
\ | float >= 25 %}\n temp-hot\n{% elif trigger.to_state.state | float <=\
|
|
\ 18 %}\n temp-cold\n{% else %}\n temp-normal\n{% endif %}\n"
|
|
- alias: Monitor phone notification changes
|
|
trigger: state
|
|
entity_id: sensor.pixel_10_pro_last_notification
|
|
to: null
|
|
variables:
|
|
sender_name: secret name_gf
|
|
update: "{{\n trigger.to_state.attributes['package'] is defined\n and trigger.to_state.attributes['package']\
|
|
\ == 'com.whatsapp'\n and trigger.to_state.attributes['android.title'] ==\
|
|
\ sender_name\n and is_state('person.martijn', 'home')\n}}\n"
|
|
icon: whatsapp
|
|
text: "{%- if trigger.to_state.attributes['android.textLines'] is defined %}\n\
|
|
\ {{ trigger.to_state.attributes['android.textLines'] | last }}\n{%- else\
|
|
\ %}\n {{ trigger.to_state.attributes['android.text'] }}\n{%- endif %}\n"
|
|
repeat: 2
|
|
textCase: 2
|
|
pushIcon: 2
|
|
- alias: Monitor doorbell button press
|
|
trigger: state
|
|
entity_id: binary_sensor.smart_doorbell_button
|
|
to: 'on'
|
|
variables:
|
|
icon: dingdong
|
|
text: Ding Dong
|
|
background: 4CBEFC
|
|
- alias: Monitor rain data for graph display
|
|
trigger: state
|
|
entity_id: binary_sensor.raindata
|
|
variables:
|
|
update: '{{ trigger.to_state.state in [''on'', ''off''] }}'
|
|
icon: rainy
|
|
graph_max: 8
|
|
graph_data: '{{ trigger.to_state.attributes.raindata.data if trigger.to_state.state
|
|
== ''on'' else none }}'
|
|
graph_type: bar
|
|
graph_color:
|
|
- 0
|
|
- 0
|
|
- 255
|
|
graph_round: ceil
|
|
app: rain
|
|
deactivate: '{{ trigger.to_state.state = ''on'' }}'
|
|
variables:
|
|
plot_graph: '{{ graph_data is defined and graph_data is not string and graph_data
|
|
is iterable }}'
|
|
conditions:
|
|
- alias: Check update flag is enabled for notifications
|
|
condition: template
|
|
value_template: '{{ update | default(true) | bool(true) }}'
|
|
- alias: Check if app deactivation or content is defined
|
|
condition: template
|
|
value_template: '{{ deactivate is defined or plot_graph is defined or text is
|
|
defined }}'
|
|
actions:
|
|
- if: '{{ deactivate | default(false) }}'
|
|
then:
|
|
- alias: Deactivate custom app via MQTT
|
|
action: mqtt.publish
|
|
data:
|
|
qos: 0
|
|
retain: false
|
|
topic: awtrix_martijn/custom/{{ app }}
|
|
payload: ''
|
|
else:
|
|
- alias: Update custom app or send notification via MQTT
|
|
action: mqtt.publish
|
|
data:
|
|
qos: 0
|
|
retain: false
|
|
topic: awtrix_martijn/{{ 'notify' if app | default('notify') == 'notify' else
|
|
('custom/' ~ app) }}
|
|
payload: "{%- set graph_type = graph_type | default('bar') %} {%- set graph_round\
|
|
\ = graph_round | default('common') %} {%- set grap_round = graph_round\
|
|
\ if graph_round in [ 'common', 'ceil', 'floor'] else 'common' %} {%- set\
|
|
\ autoscale = not iif(graph_max | default(none)) if plot_graph else none\
|
|
\ %} {%- set icon = icon | default() %} {%- set color = graph_color | default(none)\
|
|
\ if plot_graph else text_color | default(none) %} {%- set data = (graph_data[:11]\
|
|
\ if icon else graph_data[:16]) if plot_graph else [] %} {%- set data =\
|
|
\ data\n | select('is_number')\n | map('multiply',\
|
|
\ 8/graph_max | default(8))\n | map('round', 0, graph_round)\n\
|
|
\ | map('int')\n | list\n%} {%- set graph_data\
|
|
\ = { graph_type: (data[:11] if icon else data[:16]) if plot_graph else\
|
|
\ none }%} {%- set data = dict(\n graph_data,\n \
|
|
\ autoscale = autoscale,\n text = text if not\
|
|
\ plot_graph else none,\n repeat = repeat | default(none),\n\
|
|
\ rainbow = rainbow | default(none),\n \
|
|
\ icon = icon | default(none),\n pushIcon = pushIcon |\
|
|
\ default(none),\n textCase = textCase | default(none),\n\
|
|
\ color = color | default(none),\n background\
|
|
\ = background | default(none)\n )\n%} {%- set data = dict(data.items()\
|
|
\ | rejectattr('1', 'none')) %} {{ data | to_json }}\n"
|
|
- id: 964ca72d-0e82-488d-b6e8-0ac72a5eabc0
|
|
alias: Ulanzi turn screen on and off
|
|
mode: queued
|
|
triggers:
|
|
- alias: Monitor house mode changes for screen control
|
|
trigger: state
|
|
entity_id: sensor.house_mode
|
|
to: null
|
|
variables:
|
|
action: "{{\n 'off'\n if is_state('sensor.house_mode', 'Slapen')\n or now()\
|
|
\ > today_at('22:00')\n or now() < today_at('07:00')\n else 'on'\n}}\n"
|
|
update: "{{\n is_state('person.martijn', 'home')\n and is_state('switch.shelly1pm_bureau_martijn_relay',\
|
|
\ 'on')\n and is_state('script.computer_martijn_off', 'off')\n if action\
|
|
\ == 'on'\n else true\n}}\n"
|
|
- alias: Monitor office power switch for screen control
|
|
trigger: state
|
|
entity_id: switch.shelly1pm_bureau_martijn_relay
|
|
to: null
|
|
variables:
|
|
action: '{{ trigger.to_state.state if (not is_state(''sensor.house_mode'', ''Slapen'')
|
|
and is_state(''person.martijn'', ''home'')) else ''off'' }}
|
|
|
|
'
|
|
update: "{{\n is_state('person.martijn', 'home')\n and is_state('switch.shelly1pm_bureau_martijn_relay',\
|
|
\ 'on')\n and is_state('script.computer_martijn_off', 'off')\n if action\
|
|
\ == 'on'\n else true\n}}\n"
|
|
- alias: Schedule screen on/off at specific times
|
|
trigger: time
|
|
at:
|
|
- 07:00
|
|
- '22:00'
|
|
variables:
|
|
action: "{{\n 'off'\n if states('sensor.house_mode') == 'Slapen' or not is_state('person.martijn',\
|
|
\ 'home')\n else 'on'\n}}\n"
|
|
update: "{{\n is_state('person.martijn', 'home')\n and is_state('switch.shelly1pm_bureau_martijn_relay',\
|
|
\ 'on')\n and is_state('script.computer_martijn_off', 'off')\n if action\
|
|
\ == 'on'\n else true\n}}\n"
|
|
- alias: Monitor person presence for screen control
|
|
trigger: state
|
|
entity_id: person.martijn
|
|
to: null
|
|
variables:
|
|
action: '{{ is_state(''person.martijn'', ''home'') }}'
|
|
update: "{{\n (is_state('switch.shelly1pm_bureau_martijn_relay', 'on') and\
|
|
\ not is_state('sensor.house_mode', 'Slapen'))\n if action == 'on'\n else\
|
|
\ true\n}}\n"
|
|
conditions:
|
|
- alias: Check update flag is enabled for screen control
|
|
condition: template
|
|
value_template: '{{ update | default(true) | bool(true) }}'
|
|
actions:
|
|
- alias: Turn Ulanzi matrix display on or off
|
|
action: light.turn_{{ iif(action | default(true) | bool(true), 'on', 'off') }}
|
|
target:
|
|
entity_id: light.awtrix_martijn_matrix
|
|
- id: 630ae4fd-f5fd-41f9-8d83-837e991a08c8
|
|
alias: Run actions on Awtrix button press
|
|
triggers:
|
|
- alias: Monitor all Awtrix button presses
|
|
trigger: state
|
|
entity_id:
|
|
- binary_sensor.awtrix_martijn_button_left
|
|
- binary_sensor.awtrix_martijn_button_select
|
|
- binary_sensor.awtrix_martijn_button_right
|
|
- binary_sensor.awtrix_floris_button_left
|
|
- binary_sensor.awtrix_floris_button_select
|
|
- binary_sensor.awtrix_floris_button_right
|
|
- binary_sensor.awtrix_pepijn_button_left
|
|
- binary_sensor.awtrix_pepijn_button_select
|
|
- binary_sensor.awtrix_pepijn_button_right
|
|
from: 'off'
|
|
to: 'on'
|
|
actions:
|
|
- alias: Wait 2 seconds for button release
|
|
wait_for_trigger:
|
|
- alias: Check if button is released
|
|
trigger: template
|
|
value_template: '{{ is_state(trigger.entity_id, ''off'') }}'
|
|
timeout:
|
|
seconds: 2
|
|
- alias: Determine if long press or short press
|
|
if: '{{ wait.trigger is none }}'
|
|
then:
|
|
- alias: Send hold event for long press
|
|
event: awtrix_button_event
|
|
event_data:
|
|
area: '{{ area_id(trigger.entity_id) }}'
|
|
button: '{{ trigger.entity_id.split(''_'')[-1] }}'
|
|
click: hold
|
|
else:
|
|
- alias: Handle short press sequence
|
|
repeat:
|
|
sequence:
|
|
- alias: Wait for additional button presses
|
|
wait_for_trigger:
|
|
- alias: Check for new button press
|
|
trigger: template
|
|
value_template: '{{ is_state(trigger.entity_id, ''on'') }}'
|
|
timeout:
|
|
seconds: 0.5
|
|
- alias: Send click event if no additional presses
|
|
if: '{{ wait.trigger is none }}'
|
|
then:
|
|
- alias: Send button click event
|
|
event: awtrix_button_event
|
|
event_data:
|
|
area: '{{ area_id(trigger.entity_id) }}'
|
|
button: '{{ trigger.entity_id.split(''_'')[-1] }}'
|
|
click: '{{ ''single'' if repeat.index == 1 else ''multiple'' }}'
|
|
count: '{{ repeat.index }}'
|
|
until: '{{ wait.trigger is none }}'
|
|
- id: dc9ec434-0886-4fd3-a504-006ca6e8ec40
|
|
alias: Awtrix button Pepijn
|
|
mode: parallel
|
|
max_exceeded: silent
|
|
triggers:
|
|
- trigger: event
|
|
event_type: awtrix_button_event
|
|
event_data:
|
|
area: slaapkamer_pepijn
|
|
variables:
|
|
event: '{{ trigger.event.data.click }}'
|
|
button: '{{ trigger.event.data.button }}'
|
|
actions:
|
|
- alias: Which click type
|
|
choose:
|
|
- conditions: '{{ event == ''single'' }}'
|
|
sequence:
|
|
- action: light.toggle
|
|
target:
|
|
entity_id: "{%\n set button_map = \n {\n 'left': 'light.wereldbol',\n\
|
|
\ 'select': 'light.bed_pepijn',\n 'right': 'light.pepijn_leeslamp'\n\
|
|
\ }\n%} {{ button_map[button] }}\n"
|
|
- conditions: '{{ event == ''hold'' }}'
|
|
sequence:
|
|
- alias: Light off
|
|
action: light.turn_off
|
|
target:
|
|
entity_id: "{{\n area_entities('slaapkamer_pepijn')\n | select('in',\
|
|
\ label_entities('off_long_press'))\n | list\n}}\n"
|
|
- conditions: '{{ event == ''double'' }}'
|
|
sequence: []
|
|
- conditions: '{{ event == ''release'' }}'
|
|
sequence: []
|
|
- id: 1bb3f63c-c210-4299-a36e-14e70a2e6950
|
|
alias: Update ulanzi Pepijn
|
|
mode: parallel
|
|
triggers:
|
|
- alias: Update Pepijn display every minute
|
|
trigger: time_pattern
|
|
seconds: '0'
|
|
- alias: Pepijn sleeping state changed
|
|
trigger: state
|
|
entity_id: binary_sensor.pepijn_sleeping
|
|
from:
|
|
- 'on'
|
|
- 'off'
|
|
to:
|
|
- 'on'
|
|
- 'off'
|
|
- alias: Pepijn Ulanzi display came back online
|
|
trigger: state
|
|
entity_id: light.awtrix_pepijn_matrix
|
|
from:
|
|
- unavailable
|
|
- alias: Weather or Pepijn clock correction changed
|
|
trigger: state
|
|
entity_id:
|
|
- weather.combined
|
|
- input_number.correction_clock_pepijn
|
|
to: null
|
|
variables:
|
|
correction: '{{ states(''input_number.correction_clock_pepijn'') | float(0) }}'
|
|
actions:
|
|
- if: '{{ is_state(''binary_sensor.pepijn_sleeping'', ''on'') }}'
|
|
then:
|
|
- if: '{{ not is_state(''select.awtrix_pepijn_brightness_mode'', ''Manual'') }}'
|
|
then:
|
|
- alias: Set Pepijn display brightness to manual mode
|
|
action: select.select_option
|
|
data:
|
|
option: Manual
|
|
target:
|
|
entity_id: select.awtrix_pepijn_brightness_mode
|
|
- if: '{{ not is_state_attr(''light.awtrix_pepijn_matrix'', ''brightness'', 2)
|
|
}}'
|
|
then:
|
|
- alias: Dim Pepijn display for nighttime
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: light.awtrix_pepijn_matrix
|
|
data:
|
|
brightness: 2
|
|
- alias: Publish sleep clock display for Pepijn
|
|
action: mqtt.publish
|
|
data:
|
|
qos: 0
|
|
retain: false
|
|
topic: awtrix_pepijn/custom/sleep_clock
|
|
payload: "{% set n = now() + timedelta(hours=correction) %} {% set awake_time\
|
|
\ = today_at(states('input_datetime.pepijn_time_awake')) %} {% set awake_time\
|
|
\ = awake_time + timedelta(days=1) if n > awake_time else awake_time %}\
|
|
\ {% set qh = ((awake_time - n).total_seconds() / 60 / 15) | round(0, 'ceil')\
|
|
\ %} {% set progress = [100 - int((100/24 * qh)), 0] | max if n < awake_time\
|
|
\ or n > today_at('19:00') else 100 %} {% set icon = 'star-up' if is_state('sensor.house_mode',\
|
|
\ 'Slapen') else 'star-down' %} {{\n dict(\n icon = icon,\n \
|
|
\ text = n.strftime('%-I:%M'),\n color = [160,0,0],\n progress\
|
|
\ = progress,\n progressC = [0,0,0],\n progressBC = [160,0,0]\n\
|
|
\ )\n}}\n"
|
|
else:
|
|
- alias: Publish weather clock display for Pepijn
|
|
action: mqtt.publish
|
|
data:
|
|
qos: 0
|
|
retain: false
|
|
topic: awtrix_pepijn/custom/sleep_clock
|
|
payload: "{{\n dict(\n icon = states('weather.combined'),\n \
|
|
\ text = (now() + timedelta(hours=correction)).strftime('%-I:%M')\n \
|
|
\ )\n}}\n"
|
|
- if: '{{ not is_state(''select.awtrix_pepijn_brightness_mode'', ''Auto'') }}'
|
|
then:
|
|
- alias: Set Pepijn display brightness to auto mode
|
|
action: select.select_option
|
|
data:
|
|
option: Auto
|
|
target:
|
|
entity_id: select.awtrix_pepijn_brightness_mode
|
|
- if: '{{ not is_state(''sensor.awtrix_pepijn_current_app'', ''sleep_clock'') }}'
|
|
then:
|
|
- alias: Switch Pepijn display to sleep clock app
|
|
action: mqtt.publish
|
|
data:
|
|
qos: 0
|
|
retain: false
|
|
topic: awtrix_pepijn/switch
|
|
payload: '{{ dict(name = ''sleep_clock'') }}'
|
|
- id: 8c6c0182-b227-47b8-a53b-c88075761b1a
|
|
alias: Awtrix button Floris
|
|
triggers:
|
|
- alias: Floris Ulanzi button pressed
|
|
trigger: event
|
|
event_type: awtrix_button_event
|
|
event_data:
|
|
area: slaapkamer_floris
|
|
variables:
|
|
event: '{{ trigger.event.data.click }}'
|
|
button: '{{ trigger.event.data.button }}'
|
|
actions:
|
|
- alias: Which click type
|
|
choose:
|
|
- conditions: '{{ event == ''single'' }}'
|
|
sequence:
|
|
- alias: Toggle selected Floris light based on button pressed
|
|
action: light.toggle
|
|
target:
|
|
entity_id: "{%\n set button_map = \n {\n 'left': 'light.bedlamp_floris',\n\
|
|
\ 'select': 'light.planeet',\n 'right': 'light.floris_leeslamp'\n\
|
|
\ }\n%} {{ button_map[button] }}\n"
|
|
- conditions: '{{ event == ''hold'' }}'
|
|
sequence:
|
|
- alias: Light off
|
|
action: light.turn_off
|
|
target:
|
|
entity_id: "{{\n area_entities('slaapkamer_floris')\n | select('in',\
|
|
\ label_entities('off_long_press'))\n | list\n}}\n"
|
|
- conditions: '{{ event == ''double'' }}'
|
|
sequence: []
|
|
- conditions: '{{ event == ''release'' }}'
|
|
sequence: []
|
|
- id: 0b959006-4674-4343-b316-ebf1e124f826
|
|
alias: Update ulanzi Floris
|
|
mode: parallel
|
|
triggers:
|
|
- alias: Update Floris display every minute
|
|
trigger: time_pattern
|
|
seconds: '0'
|
|
- alias: Floris sleeping state changed
|
|
trigger: state
|
|
entity_id: binary_sensor.floris_sleeping
|
|
from:
|
|
- 'on'
|
|
- 'off'
|
|
to:
|
|
- 'on'
|
|
- 'off'
|
|
- alias: Floris Ulanzi display came back online
|
|
trigger: state
|
|
entity_id: light.awtrix_floris_matrix
|
|
from:
|
|
- unavailable
|
|
- alias: Weather or Floris clock correction changed
|
|
trigger: state
|
|
entity_id:
|
|
- weather.combined
|
|
- input_number.correction_clock_floris
|
|
to: null
|
|
variables:
|
|
correction: '{{ states(''input_number.correction_clock_floris'') | float(0) }}'
|
|
actions:
|
|
- if: '{{ is_state(''binary_sensor.floris_sleeping'', ''on'') }}'
|
|
then:
|
|
- if: '{{ not is_state(''select.awtrix_floris_brightness_mode'', ''Manual'') }}'
|
|
then:
|
|
- alias: Set Floris display brightness to manual mode
|
|
action: select.select_option
|
|
data:
|
|
option: Manual
|
|
target:
|
|
entity_id: select.awtrix_floris_brightness_mode
|
|
- if: '{{ not is_state_attr(''light.awtrix_floris_matrix'', ''brightness'', 2)
|
|
}}'
|
|
then:
|
|
- alias: Dim Floris display for nighttime
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: light.awtrix_floris_matrix
|
|
data:
|
|
brightness: 2
|
|
- alias: Publish sleep clock display for Floris
|
|
action: mqtt.publish
|
|
data:
|
|
qos: 0
|
|
retain: false
|
|
topic: awtrix_floris/custom/sleep_clock
|
|
payload: "{% set n = now() + timedelta(hours=correction) %} {% set awake_time\
|
|
\ = today_at(states('input_datetime.floris_time_awake')) %} {% set awake_time\
|
|
\ = awake_time + timedelta(days=1) if n > awake_time else awake_time %}\
|
|
\ {% set qh = ((awake_time - n).total_seconds() / 60 / 15) | round(0, 'ceil')\
|
|
\ %} {% set progress = [100 - int((100/24 * qh)), 0] | max if n < awake_time\
|
|
\ or n > today_at('19:00') else 100 %} {% set icon = 'star-up2' if is_state('sensor.house_mode',\
|
|
\ 'Slapen') else 'star-down2' %} {{\n dict(\n icon = icon,\n \
|
|
\ text = n.strftime('%-I:%M'),\n color = [160,0,0],\n \
|
|
\ progress = progress,\n progressC = [0,0,0],\n progressBC\
|
|
\ = [160,0,0]\n )\n}}\n"
|
|
else:
|
|
- alias: Publish weather clock display for Floris
|
|
action: mqtt.publish
|
|
data:
|
|
qos: 0
|
|
retain: false
|
|
topic: awtrix_floris/custom/sleep_clock
|
|
payload: "{{\n dict(\n icon = states('weather.combined'),\n \
|
|
\ text = (now() + timedelta(hours=correction)).strftime('%-I:%M')\n \
|
|
\ )\n}}\n"
|
|
- if: '{{ not is_state(''select.awtrix_floris_brightness_mode'', ''Auto'') }}'
|
|
then:
|
|
- alias: Set Floris display brightness to auto mode
|
|
action: select.select_option
|
|
data:
|
|
option: Auto
|
|
target:
|
|
entity_id: select.awtrix_floris_brightness_mode
|
|
- if: '{{ not is_state(''sensor.awtrix_floris_current_app'', ''sleep_clock'') }}'
|
|
then:
|
|
- alias: Switch Floris display to sleep clock app
|
|
action: mqtt.publish
|
|
data:
|
|
qos: 0
|
|
retain: false
|
|
topic: awtrix_floris/switch
|
|
payload: '{{ dict(name = ''sleep_clock'') }}'
|
|
- id: 645ac57b-f743-429e-9765-9a14149a2f4a
|
|
alias: Bedtime Kids
|
|
triggers:
|
|
- alias: Trigger sentence
|
|
trigger: conversation
|
|
command:
|
|
- (floris|pepijn) gaat naar bed
|
|
- de kinderen gaan naar bed
|
|
actions:
|
|
- variables:
|
|
who: "{% if 'floris' in trigger.sentence | lower %}\n Floris\n{% elif 'pepijn'\
|
|
\ in trigger.sentence | lower %}\n Pepijn\n{% else %}\n {{ ['Pepijn', 'Floris']\
|
|
\ | shuffle | join(' en ') }}\n{% endif %}\n"
|
|
- alias: Start script for bedtime lights
|
|
action: script.turn_on
|
|
target:
|
|
entity_id: "{% if ' en ' in who %}\n [ 'script.bedtime_pepijn_routine', 'script.bedtime_floris_routine'\
|
|
\ ]\n{% else %}\n script.bedtime_{{ who | lower }}_routine\n{% endif %}\n"
|
|
- alias: Set response
|
|
set_conversation_response: 'Slaap lekker {{ who }}!
|
|
|
|
'
|
|
mode: single
|
|
- id: 4082634b-2b59-4371-b5c1-82cd3710c865
|
|
alias: Voice - Get calendar events
|
|
triggers:
|
|
- trigger: conversation
|
|
command:
|
|
- wat staat er op de (agenda|kalender|planning)[[ voor] {query}]
|
|
- wat staat er [voor] {query} op de (agenda|kalender|planning)
|
|
- staat er iets op de (agenda|kalender|planning)[ [voor] {query}]
|
|
- staat er [voor] {query} iets op de (agenda|kalender|planning)
|
|
variables:
|
|
calendars:
|
|
- calendar.thefes
|
|
- calendar.m_m
|
|
- calendar.kids
|
|
conversation_agent: conversation.openai_normaal
|
|
output_language: Dutch
|
|
actions:
|
|
- alias: convert the query to the right format for the calendar.get_events action
|
|
action: conversation.process
|
|
data:
|
|
agent_id: '{{ conversation_agent }}'
|
|
text: 'You are an AI process that transforms a date and time query into a structured
|
|
JSON. The query can be in Dutch or English and can be a part of a day to multiple
|
|
days. In case the request is a weekend or week end, this includes both Saturday
|
|
and Sunday The query is: "{{ trigger.slots.query | default("today") }}"
|
|
|
|
Here is the structured JSON that I expect in response {"start_date_time":
|
|
"start_date", "end_date_time": "end_date"} Both "start_date" and "end_date"
|
|
should be a isoformat datetime string in the format "YYYY-MM-DD 00:00:00+01:00"
|
|
The timezone of the datetime string should be the timezone in the Netherlands
|
|
(corrected for Daylight Savings if that is needed)
|
|
|
|
Output only the json string or "unknown" if it is not possible to convert
|
|
the query to datetime values. Note that when the output is "unknown", this
|
|
should only be this one word, so not the json string. The output will be used
|
|
in further automtions, so don''t add any additional text or explanation.
|
|
|
|
'
|
|
response_variable: response
|
|
- alias: set the output to a varialbe
|
|
variables:
|
|
output: '{{ response.response.speech.plain.speech }}'
|
|
- alias: check the calendars for events for these dates
|
|
action: calendar.get_events
|
|
target:
|
|
entity_id: '{{ calendars }}'
|
|
data: '{{ output if output != ''unknown'' else dict(start_date_time=now().isoformat(),
|
|
end_date_time=now().isoformat()) }}'
|
|
response_variable: events
|
|
- alias: create summary of the events
|
|
action: conversation.process
|
|
data:
|
|
agent_id: '{{ conversation_agent }}'
|
|
text: 'Give a short summary of these calendar events: {{ events }} In case there
|
|
are no events for a specific calendar, ignore that calendar. In case there
|
|
are no events at all, mention that there are no events for the time period.
|
|
Combine all events of the calendars in one summary, don''t mention to which
|
|
calendar they belong. Don''t use special characters (as "*"" or "-"") as the
|
|
result will be used in a Text To Speech (TTS) response. Keep it short and
|
|
to the point and respond in {{ output_language }}.
|
|
|
|
'
|
|
response_variable: summary
|
|
- alias: Set response for voice satellite
|
|
set_conversation_response: '{{ summary.response.speech.plain.speech if output
|
|
!= ''unknown'' else ''Ik begrijp niet voor welke datum je de agenda wil weten''
|
|
}}
|
|
|
|
'
|
|
- id: fa1ca856-95ab-4317-bb6e-7681d74f136f
|
|
alias: Voice - Remaing time dishwasher
|
|
mode: parallel
|
|
triggers:
|
|
- alias: Trigger sentence
|
|
trigger: conversation
|
|
command:
|
|
- hoe lang moet [de] vaat[wasser] [nog]
|
|
- (wanneer|hoe laat) is de vaat[wasser] klaar
|
|
actions:
|
|
- alias: Set response
|
|
set_conversation_response: "{%- set time_set = states('sensor.dishwasher_end_time')\
|
|
\ | as_datetime %} {%- if now() < time_set and is_state('binary_sensor.dishwasher_active',\
|
|
\ 'on') %}\n {%- set seconds = (time_set - now()).seconds %}\n {%- set hours\
|
|
\ = (seconds / 3600) | int %}\n {%- set minutes = (((seconds / 3600) - hours)\
|
|
\ * 60) | int %}\n {%- if hours == 0 %}\n De vaatwasser is over {{ minutes\
|
|
\ ~ (' minuut' if minutes == 1 else ' minuten') }} klaar.\n {%- else %}\n \
|
|
\ De vaatwasser is klaar rond {{ time_set.strftime('%H:%M') }}.\n {%- endif\
|
|
\ %}\n{%- elif now() < time_set | as_local %}\n De vaatwasser is nu elk moment\
|
|
\ klaar\n{%- else %}\n De vaatwasser is niet actief\n{%- endif %}\n"
|
|
- id: f9e73c28-8d45-4148-8a9c-2b4e5323334b
|
|
alias: Voice - Remaing time washing machine
|
|
mode: parallel
|
|
triggers:
|
|
- alias: Trigger sentence
|
|
trigger: conversation
|
|
command:
|
|
- hoe lang moet [de] was[machine] [nog]
|
|
- (wanneer|hoe laat) is de was[machine] klaar
|
|
actions:
|
|
- alias: Set response
|
|
set_conversation_response: "{% set delta = as_timedelta(states('sensor.wasmachine_remain_time'))\
|
|
\ %} {% if delta is none %}\n Kan de wasmachine nu niet bereiken\n{% else %}\n\
|
|
\ {%- set seconds = delta.seconds %}\n {%- set hours = (seconds / 3600) |\
|
|
\ int %}\n {%- set minutes = (((seconds / 3600) - hours) * 60) | int %}\n \
|
|
\ {%- if seconds == 0 %}\n De wasmachine is niet actief\n {%- elif hours\
|
|
\ == 0 %}\n De wasmachine is over {{ minutes ~ (' minuut' if minutes == 1\
|
|
\ else ' minuten') }} klaar.\n {%- else %}\n De wasmachine is klaar rond\
|
|
\ {{ (now() + delta).strftime('%H:%M') }}.\n {%- endif %}\n{% endif %}\n"
|
|
- id: fe7ae331-8db2-4470-8e84-14709861edf8
|
|
alias: Enable Party mode for kids
|
|
mode: parallel
|
|
triggers:
|
|
- trigger: state
|
|
entity_id:
|
|
- event.ha_voice_floris_button_press
|
|
- event.ha_voice_pepijn_button_press
|
|
alias: Button press event
|
|
not_from: unavailable
|
|
- alias: Trigger sentence
|
|
trigger: conversation
|
|
command:
|
|
- Tijd voor een (feestje|disco)
|
|
- Zet (disco|feest)[ ](modus|stand) aan
|
|
- Ik wil (disco[{en}]|feesten)
|
|
id: sentence
|
|
conditions:
|
|
- alias: Double press event
|
|
condition: template
|
|
value_template: "{{\n trigger.id == 'sentence'\n or trigger.to_state.attributes.event_type\
|
|
\ == 'triple_press'\n}}\n"
|
|
actions:
|
|
- alias: Set response
|
|
set_conversation_response: 'Feestmodus aan!
|
|
|
|
'
|
|
- variables:
|
|
area: '{{ area_id(trigger.device_id if trigger.id == ''sentence'' else trigger.entity_id)
|
|
}}'
|
|
player: "{{\n integration_entities('music_assistant')\n | select('in', area_entities(area))\n\
|
|
\ | list\n}}\n"
|
|
- alias: Play Music
|
|
action: music_assistant.play_media
|
|
target:
|
|
entity_id: '{{ player }}'
|
|
data:
|
|
media_type: playlist
|
|
media_id: Leuke liedjes Pepijn en Floris
|
|
enqueue: replace
|
|
- alias: Set shuffle
|
|
action: media_player.shuffle_set
|
|
target:
|
|
entity_id: '{{ player }}'
|
|
data:
|
|
shuffle: true
|
|
- alias: Enable Party lights
|
|
action: script.party_party
|
|
data:
|
|
party_on: true
|
|
exclude_lights:
|
|
- light.pepijn_template
|
|
set_by: voice_satellite
|
|
area: '{{ area }}'
|
|
- id: c1f376c8-2a14-4d27-b55a-688a8c2635e3
|
|
alias: Voice - ETA Marleen & Martijn
|
|
triggers:
|
|
- alias: Trigger sentence
|
|
trigger: conversation
|
|
command:
|
|
- (wanneer|hoe laat) is (Marleen|Martijn|mama|papa) thuis
|
|
- (wanneer|hoe laat) wordt (Marleen|Martijn|mama|papa) thuis verwacht
|
|
- (wanneer|hoe laat) kan ik (Martijn|Marleen|mama|papa) thuis verwachten
|
|
- '[wat is] [de] ETA [van] (Martijn|Marleen|mama|papa)'
|
|
actions:
|
|
- alias: Set variables for entities
|
|
variables:
|
|
name: '{{ ''Martijn'' if trigger.sentence | lower is search(''martijn|papa'')
|
|
else ''Marleen'' }}
|
|
|
|
'
|
|
gender: '{{ ''hij'' if name == ''Martijn'' else ''ze'' }}'
|
|
person: person.{{ name | lower }}
|
|
waze: sensor.{{ name | lower }}_naar_huis
|
|
proximity: sensor.thuis_{{ name | lower }}_direction_of_travel
|
|
- alias: Make sure entity states are updated
|
|
action: homeassistant.update_entity
|
|
target:
|
|
entity_id: '{{ [waze,proximity, person] }}'
|
|
- alias: Short delay to make sure updates are done
|
|
delay: 0.5
|
|
- alias: Set response
|
|
set_conversation_response: "{%- set eta = (now() + timedelta(minutes=2 + states(waze)\
|
|
\ | float(0))).strftime('%H:%M') %} {%- if is_state(person, 'home') %}\n {{\
|
|
\ name }} is al thuis\n{%- elif is_state(waze, 'towards') %}\n {{ name }} is\
|
|
\ om {{ eta }} thuis.\n{%- elif is_state(proximity, 'away_from') %}\n {{ name\
|
|
\ }} gaat de verkeerde kant op, maar als {{ gender }} nu omdraait is {{ gender\
|
|
\ }} om {{ eta }} thuis.\n{%- else %}\n {{ name }} is nog niet onderweg, maar\
|
|
\ als {{ gender }} nu vertrekt is {{ gender }} om {{ eta }} thuis.\n{%- endif\
|
|
\ %}\n"
|
|
- id: efce766d-893e-4e59-b09c-a05ff49f1965
|
|
alias: Good morning actions
|
|
triggers:
|
|
- alias: Trigger sentence
|
|
trigger: conversation
|
|
command:
|
|
- '[{unwanted misheard stuff} ]Goe(d|i)e[ ]morgen[ nabu][ {unwanted misheard stuff}]'
|
|
actions:
|
|
- alias: Start script for good morning lights
|
|
action: script.turn_on
|
|
target:
|
|
entity_id: script.good_morning_routine
|
|
data:
|
|
variables:
|
|
area: '{{ area_name(trigger.device_id) }}'
|
|
- alias: Get daily weather forecast
|
|
action: weather.get_forecasts
|
|
data:
|
|
type: daily
|
|
target:
|
|
entity_id: weather.combined
|
|
response_variable: response
|
|
- variables:
|
|
forecast: "{% set weather_condition = {\n 'clear': ['en helder', 'zonnige'],\n\
|
|
\ 'clear-night': ['en helder'],\n 'cloudy': ['en bewolkt', 'grijze'],\n\
|
|
\ 'exceptional': ['en extreem', 'extreme'],\n 'fog': ['met mist', 'mistige'],\n\
|
|
\ 'hail': ['met hagel', 'hagelachtige'],\n 'lightning': ['met onweer', 'onweerachtige'],\n\
|
|
\ 'lightning-rainy': ['met onweer en regen', 'onweer- en regenachtige'],\n\
|
|
\ 'partlycloudy': ['en gedeeltelijk bewolkt', 'gedeeltelijk bewolkte'],\n\
|
|
\ 'pouring': ['met stortregen', 'kletsnatte'],\n 'rainy': ['met regen',\
|
|
\ 'regenachtige'],\n 'snowy': ['met sneeuw', 'besneewude'],\n 'snowy-rainy':\
|
|
\ ['met sneeuw en regen', 'sneeuw- met regenachtige'],\n 'sunny': ['en zonnig'\
|
|
\ 'zonnige'],\n 'windy': ['met wind', 'winderige'],\n 'windy-variant': ['met\
|
|
\ wind en bewolking', 'winderige en bewolkte']\n} %} {% set forecast = response['weather.combined'].forecast[0]\
|
|
\ %}\n{% set wind = [\n dict(speed=12, name='matige wind'),\n dict(speed=29,\
|
|
\ name='vrij krachtige wind'),\n dict(speed=29, name='krachtige wind'),\n\
|
|
\ dict(speed=49, name='harde wind'),\n dict(speed=62, name='stormachtige\
|
|
\ wind'),\n dict(speed=75, name='storm'),\n dict(speed=89, name='zware storm'),\n\
|
|
\ dict(speed=103, name='zeer zware storm'),\n dict(speed=117, name='orkaan')\n\
|
|
] %}\nDe huidige weersomstandigheden zijn {{ state_attr('weather.combined',\
|
|
\ 'temperature') | round(0) }} graden {{ weather_condition[states('weather.combined')][0]\
|
|
\ }}. Vandaag wordt het een {{ weather_condition[forecast.condition][1] }}\
|
|
\ dag met een temperatuur tussen de {{ forecast.templow | round(0) }} en\
|
|
\ {{ forecast.temperature | round(0) }} graden. {% if forecast.temperature\
|
|
\ | round(0) != forecast.apparent_temperature | default(forecast.temperature)\
|
|
\ | round(0) %}Het voelt als {{ forecast.apparent_temperature | round(0)\
|
|
\ }} graden.{% endif %} {% if forecast.precipitation_probability > 10 %}Er\
|
|
\ is {{ forecast.precipitation_probability | round(0) }}% kans op {{ forecast.precipitation\
|
|
\ | round(0) }} mm regen, neem voor de zekerheid maar een paraplu mee naar\
|
|
\ buiten.{% endif %} {% if forecast.wind_speed >= 12 %}Er is vandaag {{ wind\
|
|
\ | selectattr('speed', '>=', forecast.wind_speed) | map(attribute='name')\
|
|
\ | list | first }}.{% endif %} {% if forecast.wind_speed >= 62 %}Dus als\
|
|
\ je niet weg hoeft, blijf maar beter binnen.{% elif forecast.wind_speed\
|
|
\ >= 29 %}Dus zorg dat je {% if forecast.precipitation_probability > 10 %}paraplu\
|
|
\ {% endif %}niet weg waait!{% endif %} {% if forecast.uv_index > 3 and forecast.condition\
|
|
\ in ['clear', 'partlycloudy'] %}De zon schijnt lekker fel vandaag, zorg\
|
|
\ dus dat je je goed insmeert als je naar buiten gaat.{% endif %}\n"
|
|
forecast_today: '{{ response[''weather.combined''].forecast[0] }}'
|
|
current_temp: '{{ state_attr(''weather.combined'', ''temperature'') ~ '' °C''
|
|
}}'
|
|
current_state: '{{ state_translated(''weather.combined'') }}'
|
|
- alias: Set response
|
|
set_conversation_response: 'Goedemorgen. {{ forecast }}
|
|
|
|
'
|
|
mode: single
|
|
- id: 7f409c21-989e-425f-8a8e-1fc73d57b58d
|
|
alias: Initiate call using Assist
|
|
triggers:
|
|
- alias: Trigger sentence to initiate call
|
|
trigger: conversation
|
|
command:
|
|
- (Bel|Telefoneer) [naar|met] {to_call}
|
|
- (Ik wil|Wij willen) [met|naar] {to_call} (bellen|praten|telefoneren|kletsen|babbelen)
|
|
actions:
|
|
- alias: Send search to OpenAI
|
|
action: conversation.process
|
|
data:
|
|
agent_id: conversation.chatgpt_phone_book_helper
|
|
text: '{{ trigger.slots.to_call }}'
|
|
response_variable: response
|
|
- alias: Set variables
|
|
variables:
|
|
supported_devices:
|
|
582822583c5a151feaca918b1c3e48ae: phone
|
|
dea1020edbc703c3e64857daa55730a4: sattelite
|
|
satellite: '{{ device_entities(trigger.device_id) | select(''match'', ''assist_satellite'')
|
|
| first }}
|
|
|
|
'
|
|
phone_number: '{{ response.response.speech.plain.speech }}'
|
|
known_number: '{{ phone_number != ''sip:+31000000000@192.168.2.100'' }}'
|
|
- alias: Check if resonse comes from a supported device
|
|
if: '{{ known_number and trigger.device_id in supported_devices }}'
|
|
then:
|
|
- alias: Call script
|
|
action: script.turn_on
|
|
target:
|
|
entity_id: script.make_call_assist
|
|
data:
|
|
variables:
|
|
to_call: '{{ phone_number }}'
|
|
satellite: '{{ satellite }}'
|
|
- alias: Set response
|
|
set_conversation_response: "{% if known_number and trigger.device_id in supported_devices\
|
|
\ %}\n {{ trigger.slots.to_call }} wordt gebeld {{ 'zodra je de telefoon oplegt'\
|
|
\ if supported_devices[trigger.device_id] == 'phone' }}. Neem de hoorn op zodra\
|
|
\ de telefoon rinkelt.\n{% elif trigger.device_id not in supported_devices %}\n\
|
|
\ Vanaf dit apparaat kun je niet bellen, probeer het met een telefoon.\n{%\
|
|
\ else %}\n Ik heb geen telefoonnummer voor {{ trigger.slots.to_call }}. Probeer\
|
|
\ het nog eens met een andere naam.\n{% endif %}\n"
|
|
mode: single
|
|
- id: 9df1d5c9-373c-483a-98f4-bf376942dde0
|
|
alias: Voice - Next trash pickup
|
|
triggers:
|
|
- alias: Trigger sentence
|
|
trigger: conversation
|
|
command:
|
|
- Welke [afval](container|bak) [moet er [{wanneer}] (buiten|aan [de] straat)]
|
|
- Wanneer moet ([de] [afval](container|bak)|[het] afval) (buiten|aan [de] straat)
|
|
actions:
|
|
- alias: Set response
|
|
set_conversation_response: '{{ state_attr(''sensor.first_trash'', ''pickup'')
|
|
}} moet {{ state_attr(''sensor.first_trash'', ''friendly_name'') }} {{ [''buiten'',
|
|
''aan straat''] | random }}.
|
|
|
|
'
|
|
- id: '1737388853880'
|
|
alias: Turn off Studio Code Server add-on
|
|
triggers:
|
|
- alias: Mobile app VSCode stop notification received
|
|
trigger: event
|
|
event_type: mobile_app_notification_action
|
|
event_data:
|
|
action: action_vscode_off
|
|
actions:
|
|
- alias: Stop VSCode Server add-on
|
|
action: hassio.addon_stop
|
|
data:
|
|
addon: a0d7b954_vscode
|
|
mode: single
|
|
- id: d6878855-2179-46fa-a1f2-069c6311746f
|
|
alias: Actions with wall buttons
|
|
mode: parallel
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: Trigger on button press event entity
|
|
trigger: state
|
|
entity_id:
|
|
- event.sonof_werkkamer_martijn_plafond
|
|
- event.sonoff_slaapkamer_plafond
|
|
- event.shelly1_werkkamer_marleen_shelly1_werkkamer_marleen
|
|
- event.sonoff_badkamer_zolder
|
|
- event.sonoff_badkamerspiegel_zolder
|
|
- event.shelly1_eettafel_shelly1_eettafel
|
|
- event.dimmer_woonkamer_plafond
|
|
- event.dimmer_overloop
|
|
- event.dimmer_keuken
|
|
- event.dimmer_badkamer_badkamer
|
|
- event.shelly_badkamerspiegel_shelly1_badkamerspiegel
|
|
- event.sonoff_floris_sonoff_floris
|
|
- event.shelly1_pepijn_shelly1_pepijn
|
|
- event.dimmer_zolder_zolder
|
|
- event.sonoff_wasmachinehoek_sonoff_wasmachinehoek
|
|
- event.dimmer_hal_hal
|
|
not_from: unavailable
|
|
variables:
|
|
event: '{{ trigger.to_state.attributes.event_type | default(''unknown'', true)
|
|
}}'
|
|
area: '{{ area_id(trigger.entity_id) }}'
|
|
floor: '{{ floor_id(trigger.entity_id) }}'
|
|
relay: "{{ device_entities(device_id(trigger.entity_id))\n | select('search',\
|
|
\ '^switch.*_relay')\n | map('states')\n | join\n | default('No\
|
|
\ relay')\n}}\n"
|
|
dim_switch: "{{\n device_id(trigger.entity_id)\n | device_entities\n \
|
|
\ | select('search', 'switch.*_dim_down')\n | join\n}}\n"
|
|
dimmer: "{{\n device_entities(device_id(trigger.entity_id))\n | select('search',\
|
|
\ '^light.')\n | list\n | count > 0\n}}\n"
|
|
control_light: "{{\n dimmer or\n device_entities(device_id(trigger.entity_id))\n\
|
|
\ | select('search', '^select.*_button_type')\n | map('states')\n \
|
|
\ | join \n | default('Detached', true) in ['Detached', 'Events Only']\n\
|
|
}}\n"
|
|
start_brightness: "{{\n device_entities(device_id(trigger.entity_id))\n \
|
|
\ | select('search', 'start_brightness')\n | map('states')\n | map('float',\
|
|
\ 100)\n | list\n | default([100], true)\n | average\n}}\n"
|
|
scope: "{{ device_entities(device_id(trigger.entity_id))\n | select('search',\
|
|
\ '^select.*_long_press_scope')\n | map('states')\n | join\n \
|
|
\ | default('Area', true)\n}}\n"
|
|
toggle: "{% set main = device_entities(device_id(trigger.entity_id))\n |\
|
|
\ select('search', '^select.*_connected_light_type')\n | map('states')\n\
|
|
\ | join\n | default('Main', true) == 'Main'\n%} {{ 'main_light' if\
|
|
\ main else 'support_light' }}\n"
|
|
long_press_entities: "{% if scope == 'Area' %}\n {{\n area_entities(area)\n\
|
|
\ | select('in', label_entities('off_long_press'))\n | list\n }}\n\
|
|
{% elif scope == 'Floor' %}\n {{\n floor_entities(floor)\n | select('in',\
|
|
\ label_entities('off_long_press'))\n | list\n }}\n{% elif scope ==\
|
|
\ 'House' %}\n {{ label_entities('off_long_press') }}\n{% else %}\n {{\n\
|
|
\ area_entities(area)\n | select('in', label_entities(toggle))\n \
|
|
\ | list\n }}\n{% endif %}\n"
|
|
toggle_lights: "{{\n long_press_entities\n | select('in', area_entities(area))\n\
|
|
\ | select('in', label_entities(toggle))\n | list\n}}\n"
|
|
actions:
|
|
- alias: Click type?
|
|
choose:
|
|
- alias: Actions on single press event (toggle assigned lights)
|
|
conditions:
|
|
- alias: Short?
|
|
condition: template
|
|
value_template: '{{ event == ''single_press'' and control_light }}'
|
|
sequence:
|
|
- choose:
|
|
- alias: Check if the button has a relay, if the relay is on and if any of
|
|
the assigned lights is available
|
|
conditions: "{{\n relay | has_value \n and\n (\n is_state(relay,\
|
|
\ 'off')\n or toggle_lights | select('has_value') | list | count\
|
|
\ == 0\n )\n}}\n"
|
|
sequence:
|
|
- alias: Toggle Relay
|
|
action: switch.toggle
|
|
target:
|
|
entity_id: '{{ relay }}'
|
|
- alias: Check if any of the assigned lights is on
|
|
conditions: '{{ toggle_lights | select(''is_state'', ''on'') | list | count
|
|
> 0 }}'
|
|
sequence:
|
|
- alias: Turn off lights
|
|
action: light.turn_off
|
|
target:
|
|
entity_id: '{{ toggle_lights }}'
|
|
default:
|
|
- alias: Turn on lights
|
|
repeat:
|
|
for_each: '{{ toggle_lights }}'
|
|
sequence:
|
|
- alias: Set correct light settings for each light
|
|
variables:
|
|
data:
|
|
brightness_pct: "{{\n start_brightness\n if repeat.item | has_value\
|
|
\ \n and states[repeat.item].attributes.brightness is defined\n\
|
|
\ else 'na'\n}}\n"
|
|
kelvin: "{% set kelvin_used = repeat.item | has_value \n and\
|
|
\ states[repeat.item].attributes.min_color_temp_kelvin is defined\n\
|
|
%} {% if kelvin_used %}\n {% set k_min = state_attr(repeat.item,\
|
|
\ 'min_color_temp_kelvin') %}\n {% set k_max = state_attr(repeat.item,\
|
|
\ 'max_color_temp_kelvin') %}\n {{ ((k_max - k_min) * start_brightness\
|
|
\ / 100 + k_min) | round(0) }}\n{% else %}\n na\n{% endif %}\n"
|
|
- alias: Turn each of the assigned lights on with the correct settings
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: '{{ repeat.item }}'
|
|
data: '{{ dict(data.items() | selectattr(''1'', ''is_number'')) }}'
|
|
- alias: Set dim toggle to either dim down or up
|
|
if: '{{ dim_switch | has_value }}'
|
|
then:
|
|
- alias: Set dim switch
|
|
action: switch.turn_{{ 'on' if start_brightness >= 50 else 'off' }}
|
|
target:
|
|
entity_id: '{{ dim_switch }}'
|
|
- conditions:
|
|
- alias: Actions on double press event (100%)
|
|
condition: template
|
|
value_template: '{{ event == ''double_press'' and control_light }}'
|
|
sequence:
|
|
- alias: Turn each toggle light to 100% (if supported)
|
|
repeat:
|
|
for_each: '{{ toggle_lights }}'
|
|
sequence:
|
|
- alias: Set correct light settings for each light
|
|
variables:
|
|
data:
|
|
brightness_pct: "{{\n 100\n if repeat.item | has_value\n and\
|
|
\ states[repeat.item].attributes.brightness is defined\n else 'na'\n\
|
|
}}\n"
|
|
kelvin: "{{\n state_attr(repeat.item, 'max_color_temp_kelvin')\n\
|
|
\ if repeat.item | has_value \n and states[repeat.item].attributes.color_temp_kelvin\
|
|
\ is defined\n else 'na'\n}}\n"
|
|
- alias: Turn on light on 100%
|
|
action: light.turn_on
|
|
target:
|
|
entity_id: '{{ repeat.item }}'
|
|
data: '{{ dict(data.items() | selectattr(''1'', ''is_number'')) }}'
|
|
- alias: Set dim toggle to either dim down
|
|
if: '{{ dim_switch | has_value }}'
|
|
then:
|
|
- alias: Set dim switch
|
|
action: switch.turn_on
|
|
target:
|
|
entity_id: '{{ dim_switch }}'
|
|
- conditions:
|
|
- alias: Actions for long press event (all lights off, or activate 'scene')
|
|
condition: template
|
|
value_template: '{{ event == ''long_press'' }}'
|
|
sequence:
|
|
- if: "{{\n scope != 'Custom'\n and\n long_press_entities\n | select('has_value')\n\
|
|
\ | select('is_state', ['on', 'playing'])\n | list\n | count >\
|
|
\ 0\n}}\n"
|
|
then:
|
|
- alias: Turn off selected entities
|
|
action: homeassistant.turn_off
|
|
target:
|
|
entity_id: '{{ long_press_entities | select(''has_value'') | list }}'
|
|
else:
|
|
- alias: Start script with actions for area
|
|
action: script.turn_on
|
|
target:
|
|
entity_id: script.long_press_button_actions
|
|
data:
|
|
variables:
|
|
area: '{{ area }}'
|
|
floor: '{{ floor }}'
|
|
scope: '{{ scope }}'
|
|
toggle: '{{ toggle }}'
|
|
long_press_entities: '{{ long_press_entities }}'
|
|
- conditions:
|
|
- alias: Actions for short-long press event (Dim lights if supported)
|
|
condition: template
|
|
value_template: '{{ event == ''single_long_press'' and control_light }}'
|
|
sequence:
|
|
- variables:
|
|
dim_down: '{{ is_state(dim_switch, ''on'') }}'
|
|
- if: '{{ dim_down }}'
|
|
then:
|
|
- alias: Press button to dim down
|
|
action: button.press
|
|
target:
|
|
entity_id: "{{\n long_press_entities\n | map('device_id')\n | map('device_entities')\n\
|
|
\ | flatten\n | select('search', '^button.*_dim_down')\n |\
|
|
\ list\n}}\n"
|
|
else:
|
|
- alias: Press button to dim down
|
|
action: button.press
|
|
target:
|
|
entity_id: "{{\n long_press_entities\n | map('device_id')\n | map('device_entities')\n\
|
|
\ | flatten\n | select('search', '^button.*_dim_up')\n | list\n\
|
|
}}\n"
|
|
- alias: Toggle dim switch
|
|
action: switch.toggle
|
|
target:
|
|
entity_id: '{{ dim_switch }}'
|
|
- conditions:
|
|
- alias: Actions for button release event (Stop Dim)
|
|
condition: template
|
|
value_template: '{{ event == ''release'' and control_light }}'
|
|
sequence:
|
|
- alias: Stop dimming
|
|
action: button.press
|
|
target:
|
|
entity_id: "{{\n long_press_entities\n | map('device_id')\n | map('device_entities')\n\
|
|
\ | flatten\n | select('search', '^button.*_dim_stop')\n | list\n\
|
|
}}\n"
|
|
- id: 806efebe-1dd4-44c5-9087-c12b6a896bd0
|
|
alias: Change start brightness for light buttons based on House Mode
|
|
triggers:
|
|
- trigger: state
|
|
entity_id: sensor.house_mode
|
|
to: null
|
|
variables:
|
|
house_mode: '{{ trigger.to_state.state }}'
|
|
actions:
|
|
- alias: Set settings for number entities
|
|
variables:
|
|
settings:
|
|
- entity: number.sonof_werkkamer_martijn_plafond_start_brightness
|
|
when: Tandenpoetsen
|
|
percentage: 30
|
|
- entity: number.sonoff_slaapkamer_plafond_start_brightness
|
|
when: Tandenpoetsen
|
|
percentage: 30
|
|
- entity: number.sonoff_badkamer_zolder_start_brightness
|
|
when: Tandenpoetsen
|
|
percentage: 30
|
|
- entity: number.dimmer_woonkamer_plafond_start_brightness
|
|
when: Tandenpoetsen
|
|
percentage: 30
|
|
- entity: number.dimmer_overloop_start_brightness
|
|
when: Tandenpoetsen
|
|
percentage: 30
|
|
- entity: number.dimmer_keuken_start_brightness
|
|
when: Tandenpoetsen
|
|
percentage: 30
|
|
- entity: number.shelly1_eettafel_start_brightness
|
|
when: Tandenpoetsen
|
|
percentage: 40
|
|
- entity: number.dimmer_zolder_start_brightness
|
|
when: Tandenpoetsen
|
|
percentage: 30
|
|
- entity: number.sonoff_wasmachinehoek_start_brightness
|
|
when: Tandenpoetsen
|
|
percentage: 30
|
|
- entity: number.dimmer_hal_start_brightness
|
|
when: Tandenpoetsen
|
|
percentage: 30
|
|
- entity: number.dimmer_badkamer_start_brightness
|
|
when: Slapen
|
|
percentage: 30
|
|
- entity: number.dimmer_badkamer_start_brightness
|
|
when: Opstaan
|
|
percentage: 100
|
|
- alias: Determine which actions to take
|
|
choose:
|
|
- alias: Actions when house mode changes to Thuis (in the morning)
|
|
conditions: '{{ house_mode == ''Thuis''}}'
|
|
sequence:
|
|
- alias: Set all number entities to 100
|
|
action: number.set_value
|
|
target:
|
|
entity_id: '{{ settings | map(attribute=''entity'') | list }}'
|
|
data:
|
|
value: 100
|
|
- alias: Actions when house mode changes to Tandenpoetsen
|
|
conditions: '{{ house_mode == ''Tandenpoetsen''}}'
|
|
sequence:
|
|
- alias: Set the selected number entiteis to the provided percentage
|
|
repeat:
|
|
for_each: '{{ settings | selectattr(''when'', ''eq'', house_mode) | list
|
|
}}'
|
|
sequence:
|
|
- action: number.set_value
|
|
target:
|
|
entity_id: '{{ repeat.item.entity }}'
|
|
data:
|
|
value: '{{ repeat.item.percentage }}'
|
|
- alias: Actions when house mode changes to Slapen
|
|
conditions: '{{ house_mode == ''Slapen''}}'
|
|
sequence:
|
|
- alias: Set the selected number entiteis to the provided percentage
|
|
repeat:
|
|
for_each: '{{ settings | selectattr(''when'', ''eq'', house_mode) | list
|
|
}}'
|
|
sequence:
|
|
- action: number.set_value
|
|
target:
|
|
entity_id: '{{ repeat.item.entity }}'
|
|
data:
|
|
value: '{{ repeat.item.percentage }}'
|
|
- id: 4671f017-f0a9-41ad-ac00-360ed28398ae
|
|
alias: Change long press lights for kids to ensure night light is kept on
|
|
triggers:
|
|
- trigger: state
|
|
entity_id:
|
|
- input_boolean.nachtlampje_pepijn
|
|
- binary_sensor.pepijn_sleeping
|
|
- input_boolean.nachtlampje_floris
|
|
- binary_sensor.floris_sleeping
|
|
to: null
|
|
actions:
|
|
- alias: Assign variables to be used in action
|
|
variables:
|
|
area: '{{ area_id(trigger.entity_id) }}'
|
|
boolean: "{{\n 'input_boolean.nachtlampje_floris'\n if 'floris' in area\n\
|
|
\ else 'input_boolean.nachtlampje_pepijn'\n}}\n"
|
|
- alias: Add or remove off_long_press label to night light entity
|
|
action: "{{\n 'homeassistant.remove_label_from_entity'\n if\n trigger.to_state.state\
|
|
\ == 'on'\n and is_state(boolean, 'on')\n else 'homeassistant.add_label_to_entity'\n\
|
|
}}\n"
|
|
data:
|
|
label_id:
|
|
- off_long_press
|
|
entity_id: "{{\n area_entities(area)\n | select('in', label_entities('night_light'))\n\
|
|
\ | list\n}}\n"
|
|
- id: 991bfa0a-ba49-462b-b78a-2aed72317903
|
|
alias: Notifications washing machine
|
|
mode: single
|
|
max_exceeded: silent
|
|
triggers:
|
|
- alias: Washing machine finished (timer reached 0)
|
|
entity_id: sensor.wasmachine_remain_time
|
|
trigger: state
|
|
from: 0:01:00
|
|
to: 0:00:00
|
|
actions:
|
|
- alias: Notification to phones
|
|
action: notify.all_phones
|
|
data:
|
|
title: 💦 Wasmachine is klaar
|
|
message: Haal snel de was er uit voordat het allemaal kreukt.
|
|
data:
|
|
channel: Washing machine
|
|
ttl: 0
|
|
priority: high
|
|
notification_icon: mdi:washing-machine
|
|
- template:
|
|
- triggers:
|
|
- alias: Monitor rain sensor becoming unavailable
|
|
trigger: state
|
|
entity_id: binary_sensor.regensensor_water_leak
|
|
to: unavailable
|
|
for:
|
|
seconds: 30
|
|
- alias: Monitor rain sensor and weather integration state changes
|
|
trigger: state
|
|
entity_id:
|
|
- binary_sensor.regensensor_water_leak
|
|
- binary_sensor.rain_from_weather_integrations
|
|
- binary_sensor.around_sunrise
|
|
to:
|
|
- 'on'
|
|
- 'off'
|
|
binary_sensor:
|
|
- unique_id: e1a060ac-8130-465f-938c-1dc25dbe6eff
|
|
name: Rain
|
|
state: "{% set around_sunrise = is_state('binary_sensor.around_sunrise', 'on')\
|
|
\ %} {% set use_rain_sensor =\n 'binary_sensor.regensensor_water_leak' |\
|
|
\ has_value \n and\n (\n not is_state('binary_sensor.around_sunrise',\
|
|
\ 'on')\n or is_state('binary_sensor.regensensor_water_leak', 'off')\n\
|
|
\ )\n%} {{\n states('binary_sensor.regensensor_water_leak') | bool\n \
|
|
\ if use_rain_sensor\n else states('binary_sensor.rain_from_weather_integrations')\
|
|
\ | bool\n}}\n"
|
|
availability: "{{ \n (\n 'binary_sensor.regensensor_water_leak' | has_value\n\
|
|
\ and not is_state('binary_sensor.around_sunrise', 'on')\n )\n or'binary_sensor.rain_from_weather_integrations'\
|
|
\ | has_value\n}}\n"
|
|
icon: '{{ ''mdi:weather-sunny'' if this.state == ''off'' else ''mdi:weather-rainy''
|
|
}}
|
|
|
|
'
|
|
- binary_sensor:
|
|
- unique_id: 6f4263c2-b7ae-41fe-b868-a5ebf88658ab
|
|
name: Rain from weather integrations
|
|
state: "{%- set p1 = state_attr('sensor.neerslag_buienalarm_regen_data', 'data')\
|
|
\ %} {%- set p1 = p1.precip[:4] | reject('eq', 77) | list | sum if p1 else\
|
|
\ 'na' %} {%- set p2 = states('sensor.pirateweather_precip_intensity') | float('na')\
|
|
\ %} {%- set p3 = states('sensor.br_precipitation') | float('na') %} {%- set\
|
|
\ p4 = state_attr('sensor.neerslag_buienradar_regen_data', 'data') %} {%-\
|
|
\ if p4 %}\n {%- set ns = namespace(p=[]) %}\n {%- for item in p4.split('\
|
|
\ ')[:4] %}\n {%- set ns.p = ns.p + [(item.split('|')[0] | float / 1000)\
|
|
\ | round(2) ] %}\n {%- endfor %}\n {%- set p4 = ns.p | sum %}\n{%- else\
|
|
\ %}\n {%- set p4 = 'na' %}\n{%- endif %} {{ [p1, p2, p3, p4] | select('is_number')\
|
|
\ | max | default(0) }}\n"
|
|
availability: '{%- set p1 = ''sensor.neerslag_buienalarm_regen_data'' %} {%-
|
|
set p2 = ''sensor.pirateweather_precip_intensity'' %} {%- set p3 = ''sensor.br_precipitation''
|
|
%} {%- set p4 = ''sensor.neerslag_buienradar_regen_data'' %} {{ [ p1, p2,
|
|
p3, p4 ] | select(''has_value'') | list | count > 0 }}
|
|
|
|
'
|
|
icon: '{{ ''mdi:weather-sunny'' if this.state == ''off'' else ''mdi:weather-rainy''
|
|
}}
|
|
|
|
'
|
|
- triggers:
|
|
- alias: Trigger around sunrise period start
|
|
trigger: sun
|
|
event: sunrise
|
|
offset: -00:15:00
|
|
id: 'on'
|
|
- alias: Trigger around sunrise period end
|
|
trigger: sun
|
|
event: sunrise
|
|
offset: 01:00:00
|
|
id: 'off'
|
|
binary_sensor:
|
|
- unique_id: 59785817-f055-49ca-bcbb-499de6a776ba
|
|
name: Around sunrise
|
|
state: '{{ trigger.id }}'
|
|
icon: '{{ ''mdi:weather-sunset-up'' if this.state == ''on'' else ''mdi:weather-sunset-down''
|
|
}}'
|
|
- triggers:
|
|
- alias: Update hourly forecast data every 30 minutes
|
|
trigger: time_pattern
|
|
minutes: '30'
|
|
actions:
|
|
- alias: Fetch hourly weather forecast from combined weather entity
|
|
service: weather.get_forecasts
|
|
target:
|
|
entity_id: weather.combined
|
|
data:
|
|
type: hourly
|
|
response_variable: hourly
|
|
binary_sensor:
|
|
- icon: '{{ ''mdi:weather-pouring'' if this.state == ''on'' else ''mdi:weather-sunny''
|
|
}}'
|
|
availability: "{{\n hourly is defined\n and hourly['weather.combined'] is\
|
|
\ defined\n and hourly['weather.combined'].forecast is defined\n and hourly['weather.combined'].forecast\
|
|
\ is list\n and hourly['weather.combined'].forecast | count > 0\n}}\n"
|
|
unique_id: b42aac64-7a0d-4409-b26c-44c803b7e033
|
|
name: Rain until afternoon
|
|
state: "{%- set end = today_at('13:00') %} {%- set end = end + timedelta(days=1)\
|
|
\ if now() > end else end %} {{ hourly['weather.combined'].forecast\n \
|
|
\ | selectattr('datetime', '<=', end.isoformat())\n | map(attribute='precipitation')\n\
|
|
\ | sum\n}}"
|
|
- icon: '{{ ''mdi:weather-pouring'' if this.state == ''on'' else ''mdi:weather-sunny''
|
|
}}'
|
|
availability: "{{\n hourly is defined\n and hourly['weather.combined'] is\
|
|
\ defined\n and hourly['weather.combined'].forecast is defined\n and hourly['weather.combined'].forecast\
|
|
\ is list\n and hourly['weather.combined'].forecast | count > 0\n}}\n"
|
|
unique_id: 09b40872-f8cd-400d-b3e0-889211cd7449
|
|
name: Rain until morning
|
|
state: "{%- set end = today_at('8:00') %} {%- set end = end + timedelta(days=1)\
|
|
\ if now() > end else end %} {{ hourly['weather.combined'].forecast\n \
|
|
\ | selectattr('datetime', '<=', end.isoformat())\n | map(attribute='precipitation')\n\
|
|
\ | sum\n}}"
|
|
- binary_sensor:
|
|
- unique_id: d2920d48-13b8-47db-8518-6a7a1eb92851
|
|
name: Raindata
|
|
state: '{{ this.attributes.get(''raindata'', dict(source=''none'', data=[0]*12)).data
|
|
| max > 0 }}'
|
|
attributes:
|
|
raindata: "{% set radar = state_attr(\"sensor.neerslag_buienradar_regen_data\"\
|
|
,\"data\") %} {% set alarm = state_attr(\"sensor.neerslag_buienalarm_regen_data\"\
|
|
,\"data\") %} {% if radar %}\n {% set raindata = (radar | replace('|',\
|
|
\ ' ')).split(' ') | reject('contains', ':') | select() | map('int') | list\
|
|
\ %}\n {% set ns = namespace(raindata=[]) %}\n {%- for rain in raindata\
|
|
\ %}\n {%- set rainintensity = (10**((0-109)/32)) | round(2) %}\n \
|
|
\ {%- set mapvalues = [ 0, 0.5, 1.5, 2, 3.5, 5, 10] %}\n {%- set ns.raindata\
|
|
\ = ns.raindata + [((mapvalues + [rainintensity]) | sort).index(rainintensity)]\
|
|
\ %}\n {%- endfor %}\n {{ dict(source='buienradar', data=ns.raindata[:11])\
|
|
\ }}\n{% elif alarm %}\n {%- set raindata = alarm.precip %}\n {% set ns\
|
|
\ = namespace(raindata=[]) %}\n {%- for rainintensity in raindata %}\n\
|
|
\ {%- set mapvalues = [ 0, 0.5, 1.5, 2, 3.5, 5, 10] %}\n {%- set ns.raindata\
|
|
\ = ns.raindata + [((mapvalues + [rainintensity]) | sort).index(rainintensity)]\
|
|
\ %}\n {%- endfor %}\n {{ dict(source='buienalarm', data=ns.raindata[:11])\
|
|
\ }}\n{% else %}\n {{ dict(source='none', data=[0]*12) }}\n{% endif %}\n"
|
|
- binary_sensor:
|
|
- unique_id: 89607e16-e3fe-41aa-ade9-4b3d3ece55f5
|
|
name: Temperature Bedroom
|
|
device_class: heat
|
|
state: "{{ \n states('sensor.awair_slaapkamer_temperature') | float(0.0) >\
|
|
\ states('sensor.br_temperature') | float(0.0) \n and states('sensor.awair_slaapkamer_temperature')\
|
|
\ | float(0.0) > 21\n}}"
|
|
delay_on: 00:05:00
|
|
delay_off: 00:05:00
|
|
- unique_id: 110ecf9a-de85-4976-a49a-6ec6c54ab5a6
|
|
name: Temperature Pepijn
|
|
device_class: heat
|
|
state: "{{ \n states('sensor.pepijn_temp') | float(0.0) > states('sensor.br_temperature')\
|
|
\ | float(0.0) \n and states('sensor.pepijn_temp') | float(0.0) > 21\n}}"
|
|
delay_on: 00:05:00
|
|
delay_off: 00:05:00
|
|
- unique_id: 1676e0c4-f873-406f-8223-c0c0565f0039
|
|
name: Temperature Livingroom
|
|
device_class: heat
|
|
state: "{{ \n states('sensor.woonkamer_multi_temperature') | float(0.0) > states('sensor.br_temperature')\
|
|
\ | float(0.0) \n and states('sensor.woonkamer_multi_temperature') | float(0.0)\
|
|
\ > 21\n}}"
|
|
delay_on: 00:05:00
|
|
delay_off: 00:05:00
|
|
- unique_id: b998425b-81e2-41da-bb0c-4e9564035e68
|
|
name: Temperature Floris
|
|
device_class: heat
|
|
state: "{{ \n states('sensor.floris_temp') | float(0.0) > states('sensor.br_temperature')\
|
|
\ | float(0.0) \n and states('sensor.floris_temp') | float(0.0) > 21\n}}"
|
|
delay_on: 00:05:00
|
|
delay_off: 00:05:00
|
|
binary_sensor:
|
|
- platform: tod
|
|
name: Night
|
|
after: sunset
|
|
before: sunrise
|
|
- platform: trend
|
|
sensors:
|
|
trend_werkkamer_marleen_temp:
|
|
unique_id: 2980cae6-8b1f-4de4-b293-6471a3a0cd8a
|
|
entity_id: sensor.werkkamer_marleen_temp
|
|
device_class: heat
|
|
trend_pepijn_temp:
|
|
unique_id: 4c3e1fe1-2a8b-4407-b580-c5aba886cc9d
|
|
entity_id: sensor.pepijn_temp
|
|
device_class: heat
|
|
trend_floris_temp:
|
|
unique_id: 694c3d35-19a3-4163-ad10-f5d4fb4c4736
|
|
entity_id: sensor.floris_temp
|
|
device_class: heat
|
|
trend_slaapkamer_temp:
|
|
unique_id: df62cf8a-f573-43bb-9a0e-3596095a1487
|
|
entity_id: sensor.awair_slaapkamer_temperature
|
|
device_class: heat
|
|
trend_woonkamer_temp:
|
|
unique_id: c53a6dfd-5fca-4621-a7d6-1e1049d1a6ff
|
|
entity_id: sensor.woonkamer_multi_temperature
|
|
device_class: heat
|
|
- id: '1732562382351'
|
|
alias: 'Restart Zigbee2MQTT '
|
|
triggers:
|
|
- alias: MQTT restart needed for 5 minutes
|
|
trigger: state
|
|
entity_id: binary_sensor.mqtt_restart_needed
|
|
to: 'on'
|
|
for:
|
|
hours: 0
|
|
minutes: 5
|
|
seconds: 0
|
|
actions:
|
|
- alias: Restart Zigbee2MQTT addon
|
|
action: hassio.addon_restart
|
|
data:
|
|
addon: 45df7312_zigbee2mqtt
|
|
mode: single
|