summaryrefslogtreecommitdiffstats
path: root/blueprints
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@suren.me>2023-01-21 01:27:13 +0400
committerSuren A. Chilingaryan <csa@suren.me>2023-01-21 01:27:13 +0400
commit614c8a5f4e3bf26d3af0a91685e00eecb171339b (patch)
tree94a94b63fb3e10a1ec4bf132bd5e3dde4dafae3b /blueprints
parent2c0c331eb7b7a03152309bbbd4e0fee157e8d86c (diff)
downloadhass-614c8a5f4e3bf26d3af0a91685e00eecb171339b.tar.gz
hass-614c8a5f4e3bf26d3af0a91685e00eecb171339b.tar.bz2
hass-614c8a5f4e3bf26d3af0a91685e00eecb171339b.tar.xz
hass-614c8a5f4e3bf26d3af0a91685e00eecb171339b.zip
Media controls, occupancy tracking, and fixes
Diffstat (limited to 'blueprints')
-rw-r--r--blueprints/automation/lights/knob-sound-multi-bulb-control.yaml338
-rw-r--r--blueprints/automation/lights/light_button.yaml50
-rw-r--r--blueprints/automation/media/sven_scene_switch.yaml149
-rw-r--r--blueprints/automation/motion/halabyan24.yaml234
-rw-r--r--blueprints/automation/motion/motion_switch.yaml2
-rw-r--r--blueprints/automation/motion/occupancy_tracking.yaml166
6 files changed, 929 insertions, 10 deletions
diff --git a/blueprints/automation/lights/knob-sound-multi-bulb-control.yaml b/blueprints/automation/lights/knob-sound-multi-bulb-control.yaml
new file mode 100644
index 0000000..843b25e
--- /dev/null
+++ b/blueprints/automation/lights/knob-sound-multi-bulb-control.yaml
@@ -0,0 +1,338 @@
+blueprint:
+ name: Knob Sound & Multi-Bulb Control
+ description: Knob (clicking/rotating) to control bulb (or LED band) brightness, color temperature, and hue
+ domain: automation
+ input:
+ knob:
+ name: knob
+ description: controller (select _action entity)
+ selector:
+ entity:
+ domain: sensor
+ lights:
+ name: Bulb
+ description: smart bulb or power socket
+ selector:
+ entity:
+ multiple: true
+ domain: light
+ media_player:
+ name: Media Player
+ description: "Media Player"
+ selector:
+ entity:
+ domain: media_player
+
+ toggle_actions:
+ name: Toggle Actions
+ description: Script to run on clicking knob button (e.g. turn-of bulb power on/off), first action if bulb1 active, second if bulb2 active, etc. (use e.g. choose for grouping)
+ default:
+ - choose: []
+ default: []
+ selector:
+ action:
+
+ name:
+ name: name
+ description: Name of variables tracking bulb parameters (should include ***_current, ***_brighness0, ***_temperature0, ***_hue0
+ default: knob_office
+
+ hue_delay:
+ name: Hue Delay
+ description: Delay between hue changes
+ default: 500
+ selector:
+ number:
+ min: 100
+ max: 10000
+
+ inactivity_delay:
+ name: Inactivity Delay
+ description: Reset to first deveice if no actions (seconds), use 0 to have no inactivity timeout
+ default: 900
+ selector:
+ number:
+ min: 0
+ max: 7200
+
+ volume_steps:
+ name: Hue Delay
+ description: Delay between hue changes
+ default: 4
+ selector:
+ number:
+ min: 1
+ max: 10
+
+trigger:
+ - platform: state
+ id: knob
+ entity_id: !input "knob"
+ to:
+ - "toggle"
+ - "brightness_step_up"
+ - "brightness_step_down"
+ - "color_temperature_step_up"
+ - "color_temperature_step_down"
+ - "hue_move"
+
+variables:
+ name: !input name
+
+ inactivity_delay: !input inactivity_delay
+ last_trigger: '{{ now().timestamp() - as_timestamp(this.attributes.last_triggered) }}'
+
+ current: 'input_number.{{ name + "_current" }}'
+ current_num: '{{ (states(current) | int - 1) if ((inactivity_delay == 0) or (inactivity_delay>last_trigger)) else -1 }}'
+
+ lights: !input lights
+ brightness: 'input_number.{{ name + "_brightness" }}{{ current_num }}'
+ temperature: 'input_number.{{ name + "_temperature" }}{{ current_num }}'
+ hue: 'input_number.{{ name + "_hue" }}{{ current_num }}'
+
+ hue_delay: !input hue_delay
+ volume_steps: !input volume_steps
+
+# We can't use 'queued/restart' if we need to tackle 'double-click'
+#mode: queued
+mode: single
+
+action:
+- if:
+ - condition: template
+ value_template: '{{ last_trigger > inactivity_delay }}'
+ then:
+ - service: input_number.set_value
+ data:
+ value: 0
+ target:
+ entity_id: '{{ current }}'
+
+
+- choose:
+ - conditions:
+ - condition: trigger
+ id: knob
+ sequence:
+ - choose:
+
+# Sounds control
+ - conditions:
+ - condition: template
+ value_template: '{{ trigger.to_state.state == "brightness_step_up" }}'
+ - condition: template
+ value_template: '{{ current_num < 0 }}'
+ sequence:
+ - repeat:
+ count: '{{ volume_steps }}'
+ sequence:
+ - service: media_player.volume_up
+ target:
+ entity_id: !input media_player
+ - conditions:
+ - condition: template
+ value_template: '{{ trigger.to_state.state == "brightness_step_down" }}'
+ - condition: template
+ value_template: '{{ current_num < 0 }}'
+ sequence:
+ - repeat:
+ count: '{{ volume_steps }}'
+ sequence:
+ - service: media_player.volume_down
+ target:
+ entity_id: !input media_player
+ - conditions:
+ - condition: template
+ value_template: '{{ trigger.to_state.state == "color_temperature_step_up" }}'
+ - condition: template
+ value_template: '{{ current_num < 0 }}'
+ - condition: template
+ value_template: '{{ last_trigger > 2 }}'
+ sequence:
+ - service: media_player.media_next_track
+ target:
+ entity_id: !input media_player
+ - conditions:
+ - condition: template
+ value_template: '{{ trigger.to_state.state == "color_temperature_step_down" }}'
+ - condition: template
+ value_template: '{{ current_num < 0 }}'
+ - condition: template
+ value_template: '{{ last_trigger > 2 }}'
+ sequence:
+ - service: media_player.media_previous_track
+ target:
+ entity_id: !input media_player
+ - conditions:
+ - condition: template
+ value_template: '{{ trigger.to_state.state == "hue_move" }}'
+ - condition: template
+ value_template: '{{ current_num < 0 }}'
+ - condition: template
+ value_template: '{{ last_trigger > 2 }}'
+ sequence:
+ - service: script.play_playlist
+ data:
+ media_player: !input media_player
+ playlist: darksoft
+
+# Light control
+ - conditions:
+ - condition: template
+ value_template: '{{ trigger.to_state.state == "brightness_step_up" }}'
+ - condition: template
+ value_template: '{{ current_num >= 0 }}'
+ sequence:
+ - service: input_number.increment
+ target:
+ entity_id: '{{ brightness }}'
+ - service: light.turn_on
+ data:
+ brightness: '{{ states(brightness) }}'
+ target:
+ entity_id: '{{ lights[current_num] }}'
+
+ - conditions:
+ - condition: template
+ value_template: '{{ trigger.to_state.state == "brightness_step_down" }}'
+ - condition: template
+ value_template: '{{ current_num >= 0 }}'
+ sequence:
+ - service: input_number.decrement
+ data: {}
+ target:
+ entity_id: '{{ brightness }}'
+ - service: light.turn_on
+ data:
+ brightness: '{{ states(brightness) }}'
+ target:
+ entity_id: '{{ lights[current_num] }}'
+
+ - conditions:
+ - condition: template
+ value_template: '{{ trigger.to_state.state == "color_temperature_step_up" }}'
+ - condition: template
+ value_template: '{{ current_num >= 0 }}'
+ sequence:
+ - service: input_number.increment
+ target:
+ entity_id: '{{ temperature }}'
+ - service: light.turn_on
+ data:
+ kelvin: '{{ states(temperature) }}'
+ target:
+ entity_id: '{{ lights[current_num] }}'
+
+ - conditions:
+ - condition: template
+ value_template: '{{ trigger.to_state.state == "color_temperature_step_down" }}'
+ - condition: template
+ value_template: '{{ current_num >= 0 }}'
+ sequence:
+ - service: input_number.decrement
+ target:
+ entity_id: '{{ temperature }}'
+ - service: light.turn_on
+ data:
+ kelvin: '{{ states(temperature) }}'
+ target:
+ entity_id: '{{ lights[current_num] }}'
+
+ - conditions:
+ - condition: template
+ value_template: '{{ trigger.to_state.state == "hue_move" }}'
+ - condition: template
+ value_template: '{{ current_num >= 0 }}'
+ sequence:
+ - repeat:
+ until:
+ - condition: template
+ value_template: '{{ wait.trigger != None }}'
+ sequence:
+ - if:
+ - condition: template
+ value_template: '{{ states(hue) | float < 359 }}'
+ then:
+ - service: input_number.increment
+ data: {}
+ target:
+ entity_id: '{{ hue }}'
+ else:
+ - service: input_number.set_value
+ data:
+ value: 0
+ target:
+ entity_id: '{{ hue }}'
+ - service: light.turn_on
+ data:
+ hs_color: '{{ states(hue) }}, 100'
+ target:
+ entity_id: '{{ lights[current_num] }}'
+ - wait_for_trigger:
+ - platform: state
+ entity_id: !input knob
+ to: 'hue_stop'
+ timeout:
+ milliseconds: !input hue_delay
+ continue_on_timeout: true
+
+ - conditions:
+ - condition: template
+ value_template: '{{ trigger.to_state.state == "toggle" }}'
+ - condition: template
+ value_template: '{{ last_trigger > 2 }}'
+ sequence:
+ - wait_for_trigger:
+ - platform: state
+ entity_id: !input knob
+ to:
+ - "toggle"
+ timeout: '2'
+ continue_on_timeout: true
+ - if:
+ - condition: template
+ value_template: '{{ wait.trigger == None }}'
+ then:
+ - if:
+ - condition: template
+ value_template: '{{ current_num < 0 }}'
+ then:
+ - service: media_player.media_play_pause
+ target:
+ entity_id: !input media_player
+
+ - choose: []
+ default: !input toggle_actions
+ else:
+ - service: input_number.increment
+ target:
+ entity_id: '{{ current }}'
+ - if:
+ - condition: template
+ value_template: '{{ states(current) | float > (lights | length) }}'
+ then:
+ - service: input_number.set_value
+ data:
+ value: 0
+ target:
+ entity_id: '{{ current }}'
+ else:
+ - service: light.turn_on
+ target:
+ entity_id: '{{ lights[(states(current) | int) - 1] }}'
+ data:
+ brightness: 255
+ - delay:
+ seconds: 1
+ - service: light.turn_off
+ target:
+ entity_id: '{{ lights[(states(current) | int) - 1] }}'
+ - delay:
+ seconds: 1
+ - service: light.turn_on
+ data:
+ kelvin: '{{ states("input_number." + name + "_temperature" + (((states(current) | int) - 1) | string)) }}'
+ brightness: '{{ states("input_number." + name + "_brightness" + (((states(current) | int) - 1) | string)) }}'
+# hs_color: '{{ states("input_number." + name + "_hue" + (((states(current) | int) - 1) | string)) }}, 100'
+ target:
+ entity_id: '{{ lights[(states(current) | int) - 1] }}'
diff --git a/blueprints/automation/lights/light_button.yaml b/blueprints/automation/lights/light_button.yaml
index 7aeb0ab..34116bc 100644
--- a/blueprints/automation/lights/light_button.yaml
+++ b/blueprints/automation/lights/light_button.yaml
@@ -15,6 +15,28 @@ blueprint:
selector:
entity:
domain: light
+ on_light:
+ name: On Light
+ description: Turn light on automatically or allow complex scenarios using 'on_click'
+ default: 'yes'
+ selector:
+ select:
+ options:
+ - label: Turn on lights automatically
+ value: 'yes'
+ - label: Manage lights using 'on_click' handler
+ value: 'no'
+ off_light:
+ name: Off Light
+ description: Turn light off automatically or allow complex scenarios using 'off_click'
+ default: 'yes'
+ selector:
+ select:
+ options:
+ - label: Turn off lights automatically
+ value: 'yes'
+ - label: Manage lights using 'off_click' handler
+ value: 'no'
temperature:
name: Temperature
description: Color Temperature
@@ -83,6 +105,8 @@ trigger:
variables:
state: !input state
hold: !input hold
+ light_on: !input on_light
+ light_off: !input off_light
# Can't do 'restart' since it will break wait_for_trigger
mode: single
@@ -104,19 +128,27 @@ action:
state: 'on'
then:
- parallel:
- - service: light.turn_off
- target:
- entity_id: !input light
+ - if:
+ - condition: template
+ value_template: '{{ light_off == "yes" }}'
+ then:
+ - service: light.turn_off
+ target:
+ entity_id: !input light
- choose: []
default: !input "off_click"
else:
- parallel:
- - service: light.turn_on
- data:
- brightness_pct: 100
- kelvin: !input temperature
- target:
- entity_id: !input light
+ - if:
+ - condition: template
+ value_template: '{{ light_on == "yes" }}'
+ then:
+ - service: light.turn_on
+ data:
+ brightness_pct: 100
+ kelvin: !input temperature
+ target:
+ entity_id: !input light
- choose: []
default: !input "on_click"
diff --git a/blueprints/automation/media/sven_scene_switch.yaml b/blueprints/automation/media/sven_scene_switch.yaml
new file mode 100644
index 0000000..8f54d8d
--- /dev/null
+++ b/blueprints/automation/media/sven_scene_switch.yaml
@@ -0,0 +1,149 @@
+blueprint:
+ name: Sven Scene Switch
+ description: Scene-switch (4-buttons) to control SmartPi media player
+ domain: automation
+ input:
+ switch_action:
+ name: switch_action
+ description: Scene Switch Action
+ selector:
+ entity:
+ domain: sensor
+ media_player:
+ name: Media Player
+ description: "Media Player"
+ selector:
+ entity:
+ domain: media_player
+ playlist_control:
+ name: Playlist Control
+ description: "Playlist Control Variable (input_number.smartpi_playlist)"
+ selector:
+ entity:
+ domain: input_number
+ power_scene:
+ name: Power Scene
+ description: "Scene controlling Sven Power On/Off"
+ selector:
+ entity:
+ domain: scene
+
+trigger:
+ - platform: state
+ entity_id:
+ - !input switch_action
+ to: 1_single
+ id: single1
+ - platform: state
+ entity_id:
+ - !input switch_action
+ to: 2_single
+ id: single2
+ - platform: state
+ entity_id:
+ - !input switch_action
+ to: 3_single
+ id: single3
+ - platform: state
+ entity_id:
+ - !input switch_action
+ to: 4_single
+ id: single4
+ - platform: state
+ entity_id:
+ - !input switch_action
+ to: 1_double
+ id: double1
+ - platform: state
+ entity_id:
+ - !input switch_action
+ to: 2_double
+ id: double2
+ - platform: state
+ entity_id:
+ - !input switch_action
+ to: 3_double
+ id: double3
+ - platform: state
+ entity_id:
+ - !input switch_action
+ to: 4_dobule
+ id: double4
+
+mode: restart
+
+action:
+ - choose:
+ - conditions:
+ - condition: trigger
+ id: single1
+ sequence:
+ - service: media_player.media_play_pause
+ target:
+ entity_id: !input media_player
+ data: {}
+ - conditions:
+ - condition: trigger
+ id: double1
+ sequence:
+ - service: scene.turn_on
+ target:
+ entity_id: !input power_scene
+
+ - conditions:
+ - condition: trigger
+ id: single2
+ sequence:
+ - service: media_player.media_next_track
+ data: {}
+ target:
+ entity_id: !input media_player
+ - conditions:
+ - condition: trigger
+ id: double2
+ sequence:
+ - service: media_player.media_previous_track
+ data: {}
+ target:
+ entity_id: !input media_player
+
+ - conditions:
+ - condition: trigger
+ id: single3
+ sequence:
+ - service: script.play_playlist
+ data:
+ media_player: !input media_player
+ playlist: darksoft
+ - conditions:
+ - condition: trigger
+ id: double3
+ sequence:
+ - service: input_number.set_value
+ data:
+ value: 0
+ target:
+ entity_id: !input playlist_control
+ - service: script.play_playlist
+ data:
+ media_player: !input media_player
+ playlist: darksoft
+
+ - conditions:
+ - condition: trigger
+ id: single4
+ sequence:
+ - service: script.play_playlist
+ data:
+ media_player: !input media_player
+ playlist: asgard
+ - conditions:
+ - condition: trigger
+ id: double4
+ sequence:
+ - service: script.play_playlist
+ data:
+ media_player: !input media_player
+ playlist: downloads
+
+ default: []
diff --git a/blueprints/automation/motion/halabyan24.yaml b/blueprints/automation/motion/halabyan24.yaml
new file mode 100644
index 0000000..e06c26d
--- /dev/null
+++ b/blueprints/automation/motion/halabyan24.yaml
@@ -0,0 +1,234 @@
+blueprint:
+ name: Halabyan24 Global Motions
+ description: Global motion/tracking rules for Halabyan 24
+ domain: automation
+
+trigger:
+# We get home (we rather rely on motion sensor here)
+# - platform: state
+# id: home
+# entity_id:
+# - group.master_phones
+# from: not_home
+# to: home
+# for:
+# hours: 0
+# minutes: 1
+# seconds: 0
+
+# We get away from home (even near-by)
+ - platform: state
+ id: not_home
+ entity_id:
+ - group.master_phones
+ from: home
+ to: not_home
+ for:
+ hours: 1
+ minutes: 0
+ seconds: 0
+
+# We get in home area (from outside)
+ - platform: state
+ id: around_home
+ entity_id:
+ - device_tracker.lm_g810
+ from: not_home
+ to: HomeHalabyanExtended
+ for:
+ hours: 0
+ minutes: 5
+ seconds: 0
+
+# We get away from home area
+ - platform: state
+ id: away_from_home
+ entity_id:
+ - device_tracker.lm_g810
+ from: HomeHalabyanExtended
+ to: not_home
+ for:
+ hours: 1
+ minutes: 0
+ seconds: 0
+
+# No motions in the hall for a day
+ - platform: state
+ entity_id: binary_sensor.hall_motions_occupancy
+ from: "on"
+ to: "off"
+ for:
+ hours: 24
+ minutes: 0
+ seconds: 0
+ id: empty_day
+
+# No motions in the hall for a week
+ - platform: state
+ entity_id: binary_sensor.hall_motions_occupancy
+ from: "on"
+ to: "off"
+ for:
+ hours: 120
+ minutes: 0
+ seconds: 0
+ id: empty_week
+
+# Motions in the hall detected
+ - platform: state
+ entity_id: binary_sensor.hall_motions_occupancy
+ from: "off"
+ to: "on"
+ for:
+ hours: 0
+ minutes: 1
+ seconds: 0
+ id: motions
+
+# 'Away' security mode is turned off
+ - platform: state
+ entity_id:
+ - input_boolean.mode_away
+ from: 'on'
+ to: 'off'
+ id: away_gone
+
+
+condition: []
+action:
+ - choose:
+
+# Set 'away' security mode if no motions for 1 day (or for 2 hours if we are 'alone' and left 'home area')
+ - conditions:
+ - condition: state
+ entity_id: input_boolean.mode_away
+ state: 'off'
+ - condition: or
+ conditions:
+ - condition: trigger
+ id: empty_day
+ - condition: and
+ conditions:
+ - condition: trigger
+ id: away_from_home
+ - condition: state
+ entity_id: input_boolean.mode_house_sleep
+ state: 'on'
+ sequence:
+ - service: switch.turn_on
+ target:
+ entity_id: switch.hall_lights_right
+
+# Set house to 'sleep' if no motions for 1 day (or for 2 hours if we are 'alone' and left 'home')
+ - conditions:
+ - condition: state
+ entity_id: input_boolean.mode_house_sleep
+ state: 'off'
+ - condition: or
+ conditions:
+ - condition: trigger
+ id: empty_day
+ - condition: and
+ conditions:
+ - condition: trigger
+ id: not_home
+# - condition: state
+# entity_id: input_boolean.mode_alone
+# state: 'on'
+ - condition: state
+ entity_id: input_boolean.mode_guests
+ state: 'off'
+ - condition: state
+ entity_id: binary_sensor.hall_motions_occupancy
+ state: 'off'
+ for:
+ hours: 2
+ minutes: 0
+ seconds: 0
+ sequence:
+ - service: script.sleep_and_wake
+ data:
+ mode: sleep
+ target: house
+
+# Set house to 'hibernate' if no motions for a week
+ - conditions:
+ - condition: trigger
+ id: empty_week
+ - condition: state
+ entity_id: input_boolean.mode_house_hibernate
+ state: 'off'
+ sequence:
+ - service: script.sleep_and_wake
+ data:
+ mode: hibernate
+ target: house
+
+
+# Disable 'away' security mode if our phone is in vicinity
+ - conditions:
+ - condition: trigger
+ id: around_home
+ sequence:
+ - service: switch.turn_off
+ data: {}
+ target:
+ entity_id: switch.hall_lights_right
+
+# 'Wake' house if it was 'sleeping'/'hibernated' and
+# * either there are motions in hall and 'away' security mode is not set
+# * or 'away' security mode is just turned off
+
+ - conditions:
+ - condition: or
+ conditions:
+ - condition: state
+ entity_id: input_boolean.mode_house_sleep
+ state: 'on'
+ for:
+ hours: 0
+ minutes: 10
+ seconds: 0
+ - condition: state
+ entity_id: input_boolean.mode_house_hibernate
+ state: 'on'
+ for:
+ hours: 0
+ minutes: 10
+ seconds: 0
+ - condition: or
+ conditions:
+ - condition: and
+ conditions:
+ - condition: trigger
+ id: motions
+ - condition: state
+ entity_id: input_boolean.mode_away
+ state: 'off'
+ - condition: and
+ conditions:
+ - condition: trigger
+ id: away_gone
+ - type: is_motion
+ condition: device
+ device_id: 6deb0a6fb7a4a849ba22afc166cf9919
+ entity_id: binary_sensor.hall_motions_occupancy
+ domain: binary_sensor
+ sequence:
+ - if:
+ - condition: state
+ entity_id: input_boolean.mode_house_hibernate
+ state: 'on'
+ then:
+ - service: script.sleep_and_wake
+ data:
+ mode: wake
+ target: house
+ - service: input_boolean.turn_off
+ data: {}
+ target:
+ entity_id:
+ - input_boolean.mode_house_sleep
+ - input_boolean.mode_house_hibernate
+ default: []
+mode: single
diff --git a/blueprints/automation/motion/motion_switch.yaml b/blueprints/automation/motion/motion_switch.yaml
index c78e31f..e28d6da 100644
--- a/blueprints/automation/motion/motion_switch.yaml
+++ b/blueprints/automation/motion/motion_switch.yaml
@@ -8,7 +8,7 @@ blueprint:
selector:
entity:
domain: binary_sensor
- device_class: motion
+# device_class: motion
illumination_test:
name: Illumination Test
diff --git a/blueprints/automation/motion/occupancy_tracking.yaml b/blueprints/automation/motion/occupancy_tracking.yaml
new file mode 100644
index 0000000..c573bf9
--- /dev/null
+++ b/blueprints/automation/motion/occupancy_tracking.yaml
@@ -0,0 +1,166 @@
+# This can be used stand-alone or in combination with 'motion_switch' (to allow more complex light-on scenarios, e.g. based on current illumination level)
+# For this reason, 'light on' should be programmed in 'on_action' if necessary
+# We can use blueprint using the same entrance/inside sensors, however, this is least robust variant
+# Re-entry events (take a towel go back in) will break automation
+# We can try to prevent by ensuring there is no repeated motions for prolonged time (but, then, blueprint will fail if we do something at entrance)
+
+blueprint:
+ name: Occupancy tracking
+ description: Tries to track occupancy of single-person places (toilet bathroom)
+ domain: automation
+ input:
+ entrance:
+ name: Entrance
+ description: This can be door sensor or motion sensor monitoring passage via entrance area
+ selector:
+ entity:
+ domain: binary_sensor
+ inside:
+ name: Inside
+ description: Triggers when there is motion inside (this could be the same like entrance or additional sensor, e.g. we monitor motions as 'inside' and door sensor as 'entrance'). Independent sensors are much more robust
+ selector:
+ entity:
+ domain: binary_sensor
+ light:
+ name: Light
+ selector:
+ entity:
+ domain: [switch, light]
+ occupancy:
+ name: Occupancy
+ description: State variable (normally created via Helpers) tracking current state
+ selector:
+ entity:
+ domain: input_boolean
+
+ reentry_wait:
+ name: Re-entry Wait
+ description: Time without motions to handle re-entry events (seconds)
+ default: 1
+ selector:
+ number:
+ min: 0
+ max: 30
+ unit_of_measurement: seconds
+
+ reentry_timeout:
+ name: Re-entry Timeout
+ description: Timeout to assume re-entry if no 'no-motions' trigger were fired within timeout (seconds)
+ default: 10
+ selector:
+ number:
+ min: 1
+ max: 300
+ unit_of_measurement: seconds
+
+ on_action:
+ name: on_action
+ description: Actions to perform while occupancy is detected (lights will not be turned on automatically to allow more complex scenarios via motion-switch automation)
+ default: []
+ selector:
+ action:
+ off_action:
+ name: off_action
+ description: Additional actions to perform when place gets free
+ default: []
+ selector:
+ action:
+
+variables:
+ reentry_wait: !input reentry_wait
+
+# Lights are still on while we are waiting for re-entry. So, we don't need to allow re-trigger in this case and 'single' should do
+mode: single
+
+trigger:
+ # Either door is open or motion in the entrance area is detected
+ - platform: state
+ id: "entrance"
+ entity_id: !input entrance
+ from: "off"
+ to: "on"
+
+ - platform: state
+ id: "inside"
+ entity_id: !input inside
+ from: "off"
+ to: "on"
+
+ # Light is turned off
+ - platform: state
+ id: "light_off"
+ entity_id: !input light
+ from: "on"
+ to: "off"
+
+action:
+ - choose:
+ # Occupancy goes 'on' once movement inside is detected
+ - conditions:
+ - condition: state
+ entity_id: !input inside
+ state: 'on'
+ - condition: or
+ conditions:
+ - condition: state
+ entity_id: !input occupancy
+ state: 'off'
+ - condition: state
+ entity_id: !input light
+ state: 'off'
+ sequence:
+ - parallel:
+ - service: input_boolean.turn_on
+ target:
+ entity_id: !input occupancy
+ - choose: []
+ default: !input "on_action"
+
+ # Occupancy goes 'off' once entrance triggered while occapncy is 'on' and there are no movements inside for a while
+ - conditions:
+ - condition: state
+ entity_id: !input entrance
+ state: 'on'
+ - condition: state
+ entity_id: !input occupancy
+ state: 'on'
+ sequence:
+ - if:
+ - condition: template
+ value_template: '{{ (reentry_wait | float) > 0 }}'
+ then:
+ - wait_for_trigger:
+ - platform: state
+ entity_id: !input inside
+ to: 'off'
+ for:
+ seconds: !input reentry_wait
+ timeout:
+ seconds: !input reentry_timeout
+ continue_on_timeout: false
+
+ - parallel:
+ - service: input_boolean.turn_off
+ target:
+ entity_id: !input occupancy
+ - service: switch.turn_off
+ target:
+ entity_id: !input light
+ - choose: []
+ default: !input "off_action"
+
+ # Occupancy goes 'off' if lights are manually (or on timeout) switched off
+ # We can't do the same to turn occupancy 'on' as 'entrance' event might be fired after manually turning lights on (it will be interpreted as leaving)
+ # Will be retriggered back 'on' on any movement inside (so, it is not so critical if something is wrong)
+ - conditions:
+ - condition: trigger
+ id: "light_off"
+ sequence:
+ - parallel:
+ - service: input_boolean.turn_off
+ target:
+ entity_id: !input occupancy
+ - choose: []
+ default: !input "off_action"
+
+ default: []