Photo by Ilse Orsel on Unsplash

Redundancia. Sensores a prueba de fallo en Home Assistant

Existen muchas técnicas en el mundo industrial para construir un sistema robusto, más tolerante a fallos usando redundancia. Sobre todo se utilizan en misiones críticas donde un fallo puede provocar un incidente serio.

Aquí vamos a explicar, implementar y dejar funcionando un sistema por votación llamado 2oo3 de alta disponibilidad, por sus siglas en inglés (2 out of 3), o votación 2 de 3 en nuestro sistema Home Assistant.

Qué es redundancia por votación 2oo3

Hay alguas variantes, pero en esencia se basa en tener en cuenta 3 instrumentos midiendo la misma variable. En teoría los 3 han de medir lo mismo, pero en la práctica siempre hay pequeñas desviaciones.

Como primera opción podríamos pensar en realizar la media de los 3 instrumentos, pero dicha solución no es la más robusta. Es mejor seleccionar la mediana (o valor central) de los 3 valores.

Veamos porqué es así con un ejemplo concreto de 3 temperaturas:

temperatura_1 = 20 ºC
temperatura_2 = 22 ºC
temperatura_3 = 25 ºC
Media = 22.3 ºC
Mediana = 22 ºC
3 instrumentos funcionando

Vemos que en circunstancias normales la media y la mediana serán muy parecidas. ¿Pero qué pasa si uno de los instrumentos mide mal y da valores extremadamente bajos o altos?:

temperatura_1 = 5 ºC
temperatura_2 = 22 ºC
temperatura_3 = 25 ºC
Media = 16.6 ºC
Mediana = 22 ºC
2 instrumentos funcionando y 1 descalibrado

Vemos que la mediana es una representación más robusta que la media ante fallos de este tipo a la hora de representar una medida usando 3 mediciones en principio correctas.

3 sensores funcionando

El sistema puede tolerar un fallo de uno de los sensores, en cuyo caso tomaría la media entre los 2 sensores restantes, si podemos detectar dicho fallo.

2 sensores funcionando

Incluso si fallan 2 medidas podemos coger el tercero como reprepesentativo.

1 sensor funcionando

Es decir, y resumiendo, podemos decir que con un sistema 2oo3 harán falta 3 fallos al unísono para que nuestro sistema no tenga una medida representativa. Como podéis imaginar es extremadamente improbable:

3 sensores fallando
SituaciónResultado
3 sensores funcionandoMediana
2 sensores funcionandoMedia
1 sensor funcionandoSensor operativo
Ningún sensor funcionandoFallo
Lógica 2oo3

Nota: Los Sistemas Instrumentados de Seguridad (SIS) es un tema mucho más complejo de lo explicado aquí, pues han de tener en cuenta no solo la instrumentación, sino los otros componentes del circuito de control (tarjetas, conexionado, controladores, etc), así como las tasas de fallo de esos componentes para poder garantizar que la tasa de fallo en conjunto cumple con el requisito de la instalación.

Detección de fallos

La redundancia como concepto es muy fácil de entender, pero no tan fácil de implementar, pues en cualquier sistema hay muchos componentes que pueden fallar, y de varios modos distintos. No siempre es fácil detectar cuando falla un instrumento de medida.

Pongamos el ejemplo real que luego vamos a desarrolar:

Imaginad que se usa un sistema domótico como Home Assistant para hacernos un termostato simple en un aire acondicionado: Esencialmente tendremos un relé y un sensor de temperatura.

En su forma más básica el relé cerrará un contacto cuando la temperatura esté por encima de un valor que fijemos, y abrirá el contacto cuando baje por debajo de dicho valor.

¿Qué puede ocurrir si el sensor que usemos para medir la temperatura ambiente falla? Bueno, dependerá de cómo falle: Puede simplemente quedar fijo en un valor sin variar y que el sistema no pare nunca (o no arranque nunca).

O bien puede quedarse sin batería, o en estado «Unknown» si pierde la comunicación. En ese caso si nuestra automatización no lo tiene en cuenta tampoco funcionará.

Dependerá del sensor en cuestión, pero en Home Assistant en este caso vamos a detectar 2 tipos de fallo que podréis usar en otras automatizaciones:

  • Fallo por estar no disponible la medida (normalmente en estado Unknown)
  • Fallo por no actualizar la medida en un tiempo determinado.

Sensor 2oo3 en Home Assistant

Una vez que conocemos el concepto de redundancia y su uso en sistemas 2oo3 con 3 instrumentos de medida, vamos a implementar un template que podremos particularizar para cualquier caso con solo cambiar los sensores a usar y el tiempo límite para dar la conexión por perdida.

Presentamos primero el código que tendréis que copiar como siempre en vuestro fichero configuration.yaml y luego explicaremos sus partes:

  - platform: template
    sensors:
      temp_2oo3:
        friendly_name: "Temperatura 2oo3"
        device_class: temperature
        unit_of_measurement: 'ºC'
        value_template: "
{%set sensor1='sensor.ble_temperature_a4c13875227d' %}
{%set sensor2='sensor.ble_temperature_a4c1389e8772' %}
{%set sensor3='sensor.ble_temperature_a4c238a3726e' %}
{%set timeout=600 %} {# tiempo límite en segundos #}

{# establecemos código -99 si no es un número #}
{%set sensor1_value = states(sensor1) |float |default(-99,true) %}
{%set sensor2_value = states(sensor2) |float |default(-99,true) %}
{%set sensor3_value = states(sensor3) |float |default(-99,true) %}

{# calculamos el tiempo transcurrido desde último valor #}
{%set sensor1_scan=(as_timestamp(now())-as_timestamp(states[sensor1.split('.')[0]][sensor1.split('.')[1]].last_changed)) %}
{%set sensor2_scan=(as_timestamp(now())-as_timestamp(states[sensor2.split('.')[0]][sensor2.split('.')[1]].last_changed)) %}
{%set sensor3_scan=(as_timestamp(now())-as_timestamp(states[sensor3.split('.')[0]][sensor3.split('.')[1]].last_changed)) %}

{# establecemos si la medida es válida o no #}
{%set sensor1_valid=(sensor1_value!=-99) and (sensor1_scan<timeout) %}
{%set sensor2_valid=(sensor1_value!=-99) and (sensor2_scan<timeout) %}
{%set sensor3_valid=(sensor1_value!=-99) and (sensor3_scan<timeout) %}


{# 3 instrumentos funcionando, calculamos mediana #}
{% if sensor1_valid and sensor2_valid and sensor3_valid %}
	{{ max(min(sensor1_value,sensor2_value), min(max(sensor1_value,sensor2_value),sensor3_value)) }}

# 2 instrumentos funcionando, calculamos media
{% elif not sensor1_valid and sensor2_valid and sensor3_valid %}
	{{ (sensor2_value+sensor3_value)/2 }}
{% elif sensor1_valid and not sensor2_valid and sensor3_valid %}
	{{ (sensor1_value+sensor3_value)/2 }}
{% elif sensor1_valid and sensor2_valid and not sensor3_valid %}
	{{ (sensor1_value+sensor2_value)/2 }}

{# 1 sensor funcionando, elegimos sensor operativo #}
{% elif sensor1_valid and not sensor2_valid and not sensor3_valid %}
	{{ sensor1_value }}
{% elif not sensor1_valid and sensor2_valid and not sensor3_valid %}
	{{ sensor2_value }}
{% elif not sensor1_valid and not sensor2_valid and sensor3_valid %}
	{{ sensor3_value }}

{# 3 instrumentos fallando #}
{% else %}
	'Fallo'
	
{% endif %}"

Ahora vienen las explicaciones del código:

Hemos usado un pequeño truco para calcular la mediana usando funciones Max y Min que sí tenemos disponibles:

Mediana(a,b,c) = max(min(a,b), min(max(a,b),c))

A la hora de obtener la hora de la última actualización de un sensor (atributo last_changed) hemos tenido que dividir el nombre completo del sensor en su parte de dominio, y el nombre de entidad, para no tener que escribir de nuevo los nombres de los sensores, por lo que el único sitio a modificar para otros casos es únicamente en la primera parte:

{%set sensor1='sensor.ble_temperature_a4c13875227d' %}
{%set sensor2='sensor.ble_temperature_a4c1389e8772' %}
{%set sensor3='sensor.ble_temperature_a4c238a3726e' %}
{%set timeout=600 %} {# tiempo límite en segundos #}

Una vez que tenemos nuestro sensor temp_2oo3, ya podremos usarlo en cualquier automatización que requiera este grado de robustez, por ejemplo en un lazo de control de un termostato:

Redundancia 2oo3 Home Assistant

Conclusiones

Hemos visto el concepto de votación 2oo3 para aumentar la redundancia de un sistema de medidas, y cómo podemos usarlo en nuestro sistema Home Assistant para dotar de más robustez a una automatización.

Lo hemos hecho con un ejemplo concreto usando 3 temperaturas.

Os dejo otras entradas por si os interesa:

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *