- 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