
Programador Semanal de Persianas
Este tutorial parte de la idea de Macs, sin el cual, habría abandonado ya que me faltan conocimientos de como funciona yaml y sin su ayuda, el ordenador hubiera acabado por la ventana mientras configuraba los parámetros.
Antes que nada, quiero explicaros un poco como funcionan los diferentes apartados que tiene.
Como veis, dispone de un apartado con la vista semanal, el cual permite variar el estado de cada día individualmente o todos de una vez mediante la pestaña "Todos"
Pasamos a los apartados:
- Apagado: No hace nada como es lógico.
- H.Manual: Sube la persiana hasta el limite puesto en el apartado correspondiente y la baja completamente a las horas que le indiques en las casillas correspondientes.
- Automático: Sube la persiana hasta el limite puesto en el apartado correspondiente y la baja completamente coincidiendo con las horas de Amanecer/Atardecer.
- R.Temperatura: Sube o baja la temperatura en función de la diferencia de temperatura exterior e interior y siempre por encima de la temperatura mínima que le pongamos de confort para que no se active en invierno.
Explicare un poco mas a fondo la función de Regulación de Temperatura, por ejemplo si la casa esta a 20º y la calle a 21º bajara un 20% (se puede cambiar, ahora esta 20% por cada grado de diferencia) hasta un limite mínimo que permita la entrada de luz por los agujeritos de la persiana (en mi caso este limite coincide con el 20% de posición que ademas desactiva un input boolean al llegar a esa posición, luego explicare para que sirve.)
Y que pasa cuando es de noche y la tº exterior da la casualidad de que es inferior a la interior y por encima de la mínima de confort, pues que la persiana se va abriendo hasta el limite puesto en el apartado correspondiente y ademas activa un input boolean.
Bien este input boolean esta diseñado para asociarlo a 2 posibles opciones que se me ocurren ahora mismo para ventilar la casa y bajar su temperatura, pudiendo así mantenerla "hermética" y fresca el resto del día.
- Motor de Ventana: los cuales han bajado bastante de precio y funcionan en ventanas con cualquier tipo de apertura.
- Ventilación forzada: con lo que con un gasto mínimo (unos 15w según he leído, habrá que ver si es verdad) renueva el aire y lo refresca o calienta por medio de un intercambiador de temperatura, en este caso refrescaría con el aire de la calle.
Os dejo las partes del código que necesitáis:
input_datetime:
hora_persianas_programador_up:
name: Hora de Apertura
has_date: false
has_time: true
hora_persianas_programador_down:
name: Hora de Cierre
has_date: false
has_time: true
input_number:
posicion_apertura_persianas_programador:
name: Posicion Apertura
min: 0
max: 100
step: 1
mode: box
unit_of_measurement: "%"
####################################
temperatura_maxima_confort:
name: Max. Confort
min: 0
max: 40
step: 1
mode: box
unit_of_measurement: "ºC"
temperatura_minima_confort:
name: Min. Confort
min: 0
max: 40
step: 1
mode: box
unit_of_measurement: "ºC"
todo:
name: Todo
options:
- -------
- Apagado
- Automático
- H.Manual
- R.Temperatura
lunes:
name: Lunes
options:
- Apagado
- Automático
- H.Manual
- R.Temperatura
martes:
name: Martes
options:
- Apagado
- Automático
- H.Manual
- R.Temperatura
miercoles:
name: Miercoles
options:
- Apagado
- Automático
- H.Manual
- R.Temperatura
jueves:
name: Jueves
options:
- Apagado
- Automático
- H.Manual
- R.Temperatura
viernes:
name: Viernes
options:
- Apagado
- Automático
- H.Manual
- R.Temperatura
sabado:
name: Sabado
options:
- Apagado
- Automático
- H.Manual
- R.Temperatura
domingo:
name: Domingo
options:
- Apagado
- Automático
- H.Manual
- R.Temperatura
- platform: template
sensors:
dia_de_la_semana:
friendly_name: Dia de la Semana
value_template: " {{ ['Lunes','Martes','Miercoles','Jueves','Viernes','Sabado','Domingo'][now().weekday()] }}"
entity_id: sensor.time
- platform: template
sensors:
next_sunrise:
friendly_name: Amanecer
value_template: '{{ as_timestamp(states.sun.sun.attributes.next_rising) | timestamp_custom("%H:%M") }}'
next_sunset:
friendly_name: Atardecer
value_template: '{{ as_timestamp(states.sun.sun.attributes.next_setting) | timestamp_custom("%H:%M") }}'
alias: 'Programador Persiana Estudio Select'
trigger:
- platform: state
entity_id: input_select.todo
- platform: sun
event: sunset
- platform: sun
event: sunrise
- platform: template
value_template: "{{ states('sensor.time') == (states.input_datetime.hora_persianas_programador_up.attributes.timestamp | int | timestamp_custom('%H:%M', False)) }}"
- platform: template
value_template: "{{ states('sensor.time') == (states.input_datetime.hora_persianas_programador_down.attributes.timestamp | int | timestamp_custom('%H:%M', False)) }}"
- platform: time_pattern
minutes: '/30'
action:
- service: input_select.select_option
data_template:
entity_id: input_select.lunes, input_select.martes, input_select.miercoles, input_select.jueves, input_select.viernes, input_select.sabado, input_select.domingo
option: >
{% if (trigger.entity_id == 'input_select.todo') %}
{% if ((states.input_select.todo.state) == 'H.Manual') %}
H.Manual
{% elif ((states.input_select.todo.state) == 'Automático') %}
Automático
{% elif ((states.input_select.todo.state) == 'R.Temperatura') %}
R.Temperatura
{% elif ((states.input_select.todo.state) == 'Apagado') %}
Apagado
{% endif %}
{% endif %}
- delay:
seconds: 2
- service: input_select.select_option
data_template:
entity_id: input_select.todo
option: >
{% if (trigger.entity_id == 'input_select.todo') %}
{% if ((states.input_select.todo.state) != '-------') %}
-------
{% endif %}
{% endif %}
- service: cover.set_cover_position
data_template:
position: >
{% if ((states.sensor.time.state) == (states.input_datetime.hora_persianas_programador_up.attributes.timestamp | int |timestamp_custom('%H:%M', False))) and
(((states.sensor.dia_de_la_semana.state == 'Lunes') and (states.input_select.lunes.state == 'H.Manual')) or
((states.sensor.dia_de_la_semana.state == 'Martes') and (states.input_select.martes.state == 'H.Manual')) or
((states.sensor.dia_de_la_semana.state == 'Miercoles') and (states.input_select.miercoles.state == 'H.Manual')) or
((states.sensor.dia_de_la_semana.state == 'Jueves') and (states.input_select.jueves.state == 'H.Manual')) or
((states.sensor.dia_de_la_semana.state == 'Viernes') and (states.input_select.viernes.state == 'H.Manual')) or
((states.sensor.dia_de_la_semana.state == 'Sabado') and (states.input_select.sabado.state == 'H.Manual')) or
((states.sensor.dia_de_la_semana.state == 'Domingo') and (states.input_select.domingo.state == 'H.Manual'))) %}
{{ states('input_number.posicion_apertura_persianas_programador') | int }}
{% elif ((states.sensor.time.state) == (states.input_datetime.hora_persianas_programador_down.attributes.timestamp | int |timestamp_custom('%H:%M', False))) and
(((states.sensor.dia_de_la_semana.state == 'Lunes') and (states.input_select.lunes.state == 'H.Manual')) or
((states.sensor.dia_de_la_semana.state == 'Martes') and (states.input_select.martes.state == 'H.Manual')) or
((states.sensor.dia_de_la_semana.state == 'Miercoles') and (states.input_select.miercoles.state == 'H.Manual')) or
((states.sensor.dia_de_la_semana.state == 'Jueves') and (states.input_select.jueves.state == 'H.Manual')) or
((states.sensor.dia_de_la_semana.state == 'Viernes') and (states.input_select.viernes.state == 'H.Manual')) or
((states.sensor.dia_de_la_semana.state == 'Sabado') and (states.input_select.sabado.state == 'H.Manual')) or
((states.sensor.dia_de_la_semana.state == 'Domingo') and (states.input_select.domingo.state == 'H.Manual'))) %}
0
{% elif (trigger.event == 'sunrise') and
(((states.sensor.dia_de_la_semana.state == 'Lunes') and (states.input_select.lunes.state == 'Automático')) or
((states.sensor.dia_de_la_semana.state == 'Martes') and (states.input_select.martes.state == 'Automático')) or
((states.sensor.dia_de_la_semana.state == 'Miercoles') and (states.input_select.miercoles.state == 'Automático')) or
((states.sensor.dia_de_la_semana.state == 'Jueves') and (states.input_select.jueves.state == 'Automático')) or
((states.sensor.dia_de_la_semana.state == 'Viernes') and (states.input_select.viernes.state == 'Automático')) or
((states.sensor.dia_de_la_semana.state == 'Sabado') and (states.input_select.sabado.state == 'Automático')) or
((states.sensor.dia_de_la_semana.state == 'Domingo') and (states.input_select.domingo.state == 'Automático'))) %}
{{ states('input_number.posicion_apertura_persianas_programador') | int }}
{% elif (trigger.event == 'sunset') and
(((states.sensor.dia_de_la_semana.state == 'Lunes') and (states.input_select.lunes.state == 'Automático')) or
((states.sensor.dia_de_la_semana.state == 'Martes') and (states.input_select.martes.state == 'Automático')) or
((states.sensor.dia_de_la_semana.state == 'Miercoles') and (states.input_select.miercoles.state == 'Automático')) or
((states.sensor.dia_de_la_semana.state == 'Jueves') and (states.input_select.jueves.state == 'Automático')) or
((states.sensor.dia_de_la_semana.state == 'Viernes') and (states.input_select.viernes.state == 'Automático')) or
((states.sensor.dia_de_la_semana.state == 'Sabado') and (states.input_select.sabado.state == 'Automático')) or
((states.sensor.dia_de_la_semana.state == 'Domingo') and (states.input_select.domingo.state == 'Automático'))) %}
0
{% elif (trigger.platform == 'time_pattern') and
(((states.sensor.dia_de_la_semana.state == 'Lunes') and (states.input_select.lunes.state == 'R.Temperatura')) or
((states.sensor.dia_de_la_semana.state == 'Martes') and (states.input_select.martes.state == 'R.Temperatura')) or
((states.sensor.dia_de_la_semana.state == 'Miercoles') and (states.input_select.miercoles.state == 'R.Temperatura')) or
((states.sensor.dia_de_la_semana.state == 'Jueves') and (states.input_select.jueves.state == 'R.Temperatura')) or
((states.sensor.dia_de_la_semana.state == 'Viernes') and (states.input_select.viernes.state == 'R.Temperatura')) or
((states.sensor.dia_de_la_semana.state == 'Sabado') and (states.input_select.sabado.state == 'R.Temperatura')) or
((states.sensor.dia_de_la_semana.state == 'Domingo') and (states.input_select.domingo.state == 'R.Temperatura'))) %}
{% if (((states.sensor.dark_sky_apparent_temperature.state |int ) > (states.input_number.temperatura_maxima_confort.state |int )) and (states.cover.persiana_estudio.attributes.current_position |int > 20)) %}
{% if ((states.cover.persiana_estudio.attributes.current_position |int) - ((states.sensor.dark_sky_apparent_temperature.state |int) - (states.input_number.temperatura_maxima_confort.state|int)) *20) <= 20 %}
20
{% elif ((states.cover.persiana_estudio.attributes.current_position |int) - ((states.sensor.dark_sky_apparent_temperature.state |int) - (states.input_number.temperatura_maxima_confort.state|int)) *20) > 20 %}
{{ ((states.cover.persiana_estudio.attributes.current_position |int) - ((states.sensor.dark_sky_apparent_temperature.state |int) - (states.input_number.temperatura_maxima_confort.state|int)) *20) }}
{% endif %}
{% elif ((states.sensor.dark_sky_apparent_temperature.state |int ) < (states.input_number.temperatura_maxima_confort.state |int )) and ((states.sensor.dark_sky_apparent_temperature.state |int ) > (states.input_number.temperatura_minima_confort.state |int )) %}
{% if ((states.cover.persiana_estudio.attributes.current_position |int + 20) < (states('input_number.posicion_apertura_persianas_programador') | int)) %}
{{ states.cover.persiana_estudio.attributes.current_position |int + 20 }}
{% elif ((states.cover.persiana_estudio.attributes.current_position |int + 20) >= (states('input_number.posicion_apertura_persianas_programador') | int)) %}
{{ states('input_number.posicion_apertura_persianas_programador') | int }}
{% endif %}
{% else %}
{{ (states.cover.persiana_estudio.attributes.current_position |int) }}
{% endif %}
{% endif %}
##### El else se pone para evitar que se quede atascado y condtinue al siguiente service ya que va en cascada y si no hace ningun cambio, no lo da por valido y no continua ###
- service_template: >
{% if (trigger.platform == 'time_pattern') and
(((states.sensor.dia_de_la_semana.state == 'Lunes') and (states.input_select.lunes.state == 'R.Temperatura')) or
((states.sensor.dia_de_la_semana.state == 'Martes') and (states.input_select.martes.state == 'R.Temperatura')) or
((states.sensor.dia_de_la_semana.state == 'Miercoles') and (states.input_select.miercoles.state == 'R.Temperatura')) or
((states.sensor.dia_de_la_semana.state == 'Jueves') and (states.input_select.jueves.state == 'R.Temperatura')) or
((states.sensor.dia_de_la_semana.state == 'Viernes') and (states.input_select.viernes.state == 'R.Temperatura')) or
((states.sensor.dia_de_la_semana.state == 'Sabado') and (states.input_select.sabado.state == 'R.Temperatura')) or
((states.sensor.dia_de_la_semana.state == 'Domingo') and (states.input_select.domingo.state == 'R.Temperatura'))) %}
{% if (((states.sensor.dark_sky_apparent_temperature.state |int ) > (states.input_number.temperatura_maxima_confort.state |int )) and
(states.cover.persiana_estudio.attributes.current_position |int <= 20)) %}
input_boolean.turn_off
{% elif (((states.sensor.dark_sky_apparent_temperature.state |int ) < (states.input_number.temperatura_maxima_confort.state |int )) and
((states.sensor.dark_sky_apparent_temperature.state |int ) > (states.input_number.temperatura_minima_confort.state |int )) and
(states.cover.persiana_estudio.attributes.current_position |int >= 20)) %}
input_boolean.turn_on
{% endif %}
{% endif %}
entity_id: input_boolean.ventanas_motorizadas
Si quieres conocer otros artículos parecidos a Programador Semanal de Persianas puedes visitar la categoría Generales.
Deja una respuesta
Saludos! Felicitaciones por el magnifico tutorial, hacia tiempo que buscaba algo como esto, lamentablemente tras haces un copia y pega a mi archivo: "configurations.yaml" no consigo que funcione. Quizas algun espaciado mal puesto o no lo se. Agradeceria enormemente que me pasaran el .yaml o me ayudaran con esto porque me esta volviendo loco. Mi nivel con los "templates" es pesimo. Gracias