WIP: Esta blueprint é um trabalho em desenvolvimento e testes (na minha casa). A ideia seria ter uma blueprint que conseguisse agregar as necessidades de vários utilizadores.
Funcionalidade
Ligar luz com base no movimento e luminusidade da divisão.
Descrição
A ideia da automação é apenas ligar a luz quando ocorre movimento. Caso isto aconteça a luz, após um tempo definido ela desliga-se automáticamente.
Contudo, isto só acontece se a luz estiver inicialmente desligada, caso contrário esta automação não é executada.
Pode ser definido um número máximo de execuções a partir do qual a luz se mantem acesa (evitar que a malta se esteja sempre a abanar).
O tempo que a luz se mantém ligada aumenta ao longo da execuções, ou seja, a primeira vez que a luz acende demora 1x a duração definida.
Após isto, se ela se apagar e for ativada por movimento o tempo é multiplicado por 2 e depois por 3, sucessivamente.
Atenção: esta automação não serve para desligar uma luz após algum tempo caso esta tenha sido ligada manualmente.
Entidades necessárias:
- input_number (registo do modo manual/automático e contador de execuções)
- motion_sensor (sensor usado para ativar a automação)
- light (luz a controlar)
Entidades opcionais:
- Modo de funcionamento (apenas executar a automação caso o modo de funcionamento seja o definido)
- Sensor de luminusidade (device_class: illuminance)
- Nível de luminusidade
- Bloqueio se desligado (apenas executa a automação se entidade não estiver OFF)
- Bloqueio se ligado (apenas executa a automação se entidade não estiver ON)
Esta blueprint pode ser encontrada na minha página de Github: motion_based_lights.yaml.
Código da blueprint
blueprint:
name: Contolador do estado da iluminação
description: >
Ligar luz com base no movimento e luminusidade da divisão.
A ideia da automação é apenas ligar a luz quando ocorre movimento.
Caso isto aconteça a luz, após um tempo definido ela desliga-se automáticamente.
Contudo, isto só acontece se a luz estiver inicialmente desligada, caso contrário esta automação não é executada.
Pode ser definido um número máximo de execuções a partir do qual a luz se mantem acesa (evitar que a malta se esteja sempre a abanar).
No caso deste valor ser mantido a zero ela é executada sempre.
O tempo que a luz se mantém ligada aumenta ao longo da execuções, ou seja, a primeira vez que a luz acende demora 1x a duração definida.
Após isto, se ela se apagar e for ativada por movimento o tempo é multiplicado por 2 e depois por 3, sucessivamente.
Após um período igual ao tempo este contador é reiniciado (ou caso a luz seja desligada manualmente).
Atenção: esta automação não serve para desligar uma luz que tenha sido ligada manualmente após algum tempo.
Caso seja selecionado um modo de funcionamento, quando este altera a luz será desligada caso não deva ser ativada nesse modo.
Entidades necessárias:
- input_number (registo do modo manual/automático e contador de execuções)
- motion_sensor (sensor usado para ativar a automação)
- light (luz a controlar)
Entidades opcionais:
- Modo de funcionamento (apenas executar a automação caso o modo de funcionamento seja o definido)
- Sensor de luminusidade (device_class: illuminance)
- Nível de luminusidade
- Bloqueio se desligado (apenas executa a automação se entidade não estiver OFF)
- Bloqueio se ligado (apenas executa a automação se entidade não estiver ON)
domain: automation
input:
motion_sensor:
name: Sensor de Movimento
description: Sensor que aciona a automação
selector:
entity:
light_mode_counter:
name: Contador de execuções
description: >
Esta entidade guarda o número de execuções da automação e serve de
controlo para decidir se a luz está a ser controlada automáticamente ou manualmente
selector:
entity:
domain: input_number
target_entity:
name: Luz a controlar
description: Luz a controlar pela automação
selector:
entity:
domain: light
no_motion_wait:
name: Duração
description: Duração para manter a luz ligada após não existir movimento
default: 60
selector:
number:
min: 0
max: 600
unit_of_measurement: "s"
illuminance_sensor:
name: (OPCIONAL) Sensor de luminusidade
description: Sensor com o valor de luminusidade na divisão.
default:
selector:
entity:
domain: sensor
device_class: illuminance
illuminance_cutoff:
name: (OPCIONAL) Luminusidade
description: Executar a automação se a luminusidade for abaixo deste valor.
default:
selector:
number:
min: 0
max: 100
only_after_sunset:
name: (OPCIONAL) Funcionamento Exclusivo de Noite
description: Apenas executar a automação durante a noite (após o pôr do sol)
default: "off"
selector:
boolean:
blocker_on_entity:
name: (OPCIONAL) Entidade bloqueadora ON
description: Automção é excluída se esta entidade estiver ON (ex, outras luzes já estarem ligadas).
default:
selector:
entity:
blocker_off_entity:
name: (OPCIONAL) Entidade bloqueadora OFF
description: Automção é excluída se esta entidade estiver OFF (ex, se não estiver ninguém em casa).
default:
selector:
entity:
number_of_repetitions:
name: (OPCIONAL) Número de repetições
description: Número máximo de repetições. Após este número a luz é mantida sempre acesa (Deve ser entre 0 e o número máximo do input_number definido).
default: 0
selector:
number:
min: 0
max: 10
unit_of_measurement: "x"
required_house_mode:
name: (OPCIONAL) Ativar no modo de funcionamento
description: Nome do modo de funcionamento para esta automação
default:
selector:
text:
house_mode:
name: (OPCIONAL) Modo de funcionamento
description: Entidade que define o modo de funcionamento da casa
default:
selector:
entity:
motion_light_main_sw:
name: (OPCIONAL) Controlador Geral das Luzes
description: Entidade que funciona como interruptor geral das automações das luzes
default:
selector:
entity:
domain: input_boolean
room_name:
name: (OPCIONAL) Nome da Divisão
description: >
Nome da divisão onde é aplicada esta regra de forma a cruzar os dados com device_tracker.
Se estiver alguém presente nesta divisão a luz não é apagada.
mode: restart
max_exceeded: silent
trigger:
- platform: state
entity_id: !input motion_sensor
to: "on"
- platform: state
entity_id: !input house_mode
- platform: state
entity_id: !input motion_light_main_sw
from: "on"
to: "off"
variables:
room_name: !input room_name
motion_sensor: !input motion_sensor
target_entity: !input target_entity
illuminance_currently: !input illuminance_sensor
illuminance_cutoff: !input illuminance_cutoff
blocker_on_entity: !input blocker_on_entity
blocker_off_entity: !input blocker_off_entity
no_motion_wait: !input no_motion_wait
required_house_mode: !input required_house_mode
house_mode: !input house_mode
light_mode_counter: !input light_mode_counter
number_of_repetitions: !input number_of_repetitions
motion_light_main_sw: !input motion_light_main_sw
only_after_sunset: !input only_after_sunset
condition:
- condition: or
conditions:
# Run if the light is in automatic mode
- "{{ states[light_mode_counter].state | int > 0 }}"
# If trigger is one of these continue to action
# - condition: template
# value_template: >
# {{
# ((not house_mode == none) and trigger.entity_id == house_mode) or
# ((not motion_light_main_sw == none) and trigger.entity_id == motion_light_main_sw)
# }}
# These are the conditions to enter in automatic mode
# This conditions matter if the light is not in automatic mode
- condition: and
conditions:
# Do not run if light is on (manually turn on)
- condition: state
entity_id: !input target_entity
state: "off"
- "{{ (motion_light_main_sw == none) or (states[motion_light_main_sw].state == 'on') }}"
- "{{ (only_after_sunset == false) or (state_attr('sun.sun', 'elevation') < 10) }}"
- "{{ house_mode == none or required_house_mode == none or states[house_mode].state == required_house_mode }}"
# Do not run if this blocker is ON
- "{{ (blocker_on_entity == none) or (not states[blocker_on_entity].state == 'on') }}"
# Do not run if the blocker is OFF
- "{{ (blocker_off_entity == none) or (not states[blocker_off_entity].state == 'off') }}"
# Check illuminance level
# This is only valid if the light is off for more than 10 sec (refresh time of the lux sensor)
- condition: or
conditions:
- condition: not
conditions:
- condition: state
entity_id: !input target_entity
state: "off"
for:
seconds: 10
- condition: template
value_template: >
{{
(illuminance_currently == none)
or
(illuminance_cutoff == none)
or
(states[illuminance_currently].state | int < illuminance_cutoff | int )
}}
action:
# Check if house mode, automation or sunset is met
#- alias: "Process specific triggers that can change light state"
- choose:
- conditions: >
{{
((not house_mode == none) and trigger.entity_id == house_mode) or
((not motion_light_main_sw == none) and trigger.entity_id == motion_light_main_sw)
}}
sequence:
- choose:
conditions:
- condition: numeric_state
entity_id: !input light_mode_counter
above: 0
- condition: or
conditions:
- "{{ not( (motion_light_main_sw == none) or (states[motion_light_main_sw].state == 'on') ) }}"
- "{{ not( house_mode == none or required_house_mode == none or states[house_mode].state == required_house_mode ) }}"
sequence:
- service: light.turn_off
entity_id: !input target_entity
- service: input_number.set_value
data:
entity_id: !input light_mode_counter
value: 0
# Exit automation
- condition: template
value_template: "{{ false }}"
# Double check if motion is on
- condition: state
entity_id: !input motion_sensor
state: "on"
# - condition: or
# conditions:
# - condition: template
# value_template: "{{ states[light_mode_counter].state | int > 0 }}"
# - condition: and
# conditions:
# # This conditions matter if the light is not in automatic mode
# # Do not run if this blocker is ON
# - condition: template
# value_template: "{{ (blocker_on_entity == none) or (not states[blocker_on_entity].state == 'on') }}"
# # Do not run if the blocker is OFF
# - condition: template
# value_template: "{{ (blocker_off_entity == none) or (not states[blocker_off_entity].state == 'off') }}"
# # Check illuminance level
# - condition: template
# value_template: >
# {{
# (illuminance_currently == none)
# or
# (illuminance_cutoff == none)
# or
# (states[illuminance_currently].state | int < illuminance_cutoff | int )
# }}
# # Do not run if light is on (manually turn on)
# - condition: state
# entity_id: !input target_entity
# state: "off"
- choose:
- conditions: "{{ states[target_entity].state == 'off' }}"
sequence:
- service: input_number.increment
data:
entity_id: !input light_mode_counter
- service: light.turn_on
entity_id: !input target_entity
- delay:
seconds: 1
# Check if we reached the maximum number of executions
# If so reset the counter (this will keep light on)
- choose:
- conditions: "{{ (number_of_repetitions|int > 0 ) and ( states[light_mode_counter].state|int > number_of_repetitions|int) }}"
sequence:
- service: input_number.set_value
data:
entity_id: !input light_mode_counter
value: 0
# Nothing else to do here
- condition: template
value_template: "{{ false }}"
# Wait untill the motion sensor is off or untill light is manually turned off
- wait_template: >
{{
states[motion_sensor].state == 'off'
or
states[target_entity].state == 'off'
}}
# Wait untill room has presence
- wait_template: >
{% if room_name %}
{% set is_device_in_room = namespace(value=0) %}
{% for device in states.device_tracker %}
{% if device.state == room_name %}
{% set is_device_in_room.value = is_device_in_room.value + 1 %}
{% endif %}
{% endfor %}
{% if states[target_entity].state == 'off' or is_device_in_room.value == 0 %}
True
{% else %}
False
{% endif %}
{% else %}
True
{% endif %}
# Wait a defined time or cancel if target is already off
- wait_template: "{{ states[target_entity].state == 'off' }}"
timeout:
seconds: "{{ ( (no_motion_wait|int) * (states[light_mode_counter].state|int) ) | int }}"
# Wait completed means that light was turned off manually
# Also check if light was alredy off
# If so reset counter
- choose:
- conditions: >
{{
wait.completed
or
states[target_entity].state == 'off'
}}
sequence:
- service: input_number.set_value
data:
entity_id: !input light_mode_counter
value: 0
# Terminate if light is off at this point
- condition: state
entity_id: !input target_entity
state: "on"
- service: light.turn_off
entity_id: !input target_entity
- delay:
seconds: 1
- wait_template: "{{ states[target_entity].state == 'on' }}"
timeout:
seconds: "{{ no_motion_wait }}"
- service: input_number.set_value
data:
entity_id: !input light_mode_counter
value: 0