Hace tiempo que andaba buscando un sensor de temperatura con display LCD para ir cambiando los Xiaomi WSDCGQ01LM que tan bien han funcionado
Encontre estos en Aliexpress que tienen muy buena pinta

En la parte trasera llevan un codigo QR que nos da la url de un manual

Este seria el manual pasado a pdf
Una vez abierto y alimentado la verdad es que su tamaño es ideal , ni muy grande ni muy pequeño

Si pulsamos el botón durante mas de cinco segundos entramos en el modo de emparejamiento

Zigbee2MQTT lo reconoce perfectamente , aquí esta la información del dispositivo https://www.zigbee2mqtt.io/devices/SZ-T04.html#nous-sz-t04

Este seria el json que nos devuelve zigbee2mqtt
{
"device": {
"applicationVersion": 210,
"dateCode": "",
"friendlyName": "0xa4c138c9a6fc34ea",
"hardwareVersion": 0,
"ieeeAddr": "0xa4c138c9a6fc34ea",
"manufacturerID": 4742,
"manufacturerName": "_TZE200_qrztc3ev",
"model": "SZ-T04",
"networkAddress": 39152,
"powerSource": "Battery",
"softwareBuildID": "3.1.2",
"stackVersion": 2,
"type": "EndDevice",
"zclVersion": 3
},
"humidity": 60,
"humidity_sensitivity": 6,
"last_seen": "2026-01-02T17:08:36+01:00",
"linkquality": 65,
"max_humidity": 100,
"min_humidity": 0,
"min_temperature": -10,
"temperature": 18.8,
"temperature_sensitivity": 0.6
}Ajustaremos los parámetros , básicamente serian los de intervalo de reporte para evitar agotar las baterías y las de de precisión de la lectura de temperatura y humedad

En ajustes específicos calibraremos la lectura según algun termómetro patrón que tengamos

Procedemos a crear estos sensores el nuestro configuration.yaml
### TERMOMETRO HABITACION MATRIMONIO
- state_topic: "zigbee2mqtt/temperatura_matrimonio"
availability_topic: "zigbee2mqtt/bridge/state"
unit_of_measurement: "°C"
device_class: "temperature"
value_template: "{{ value_json.temperature }}"
name: "temperatura_matrimonio_temperatura"
- state_topic: "zigbee2mqtt/temperatura_matrimonio"
availability_topic: "zigbee2mqtt/bridge/state"
unit_of_measurement: "%"
device_class: "humidity"
value_template: "{{ value_json.humidity }}"
name: "temperatura_matrimonio_humedad"
- state_topic: "zigbee2mqtt/temperatura_matrimonio"
availability_topic: "zigbee2mqtt/bridge/state"
unit_of_measurement: "%"
icon: "mdi:battery"
device_class: "battery"
value_template: "{{ value_json.battery }}"
expire_after: 86400
force_update: true
name: "temperatura_matrimonio_bateria"
- state_topic: "zigbee2mqtt/temperatura_matrimonio"
availability_topic: "zigbee2mqtt/bridge/state"
icon: "mdi:signal"
unit_of_measurement: "lqi"
value_template: "{{ value_json.linkquality }}"
name: "temperatura_matrimonio_estado"
- state_topic: "zigbee2mqtt/temperatura_matrimonio"
availability_topic: "zigbee2mqtt/bridge/state"
icon: "mdi:calendar-clock"
value_template: "{{ value_json.last_seen }}"
name: "temperatura_matrimonio_ultima_conexion" Una vez creado yo suelo usar estos sensores donde incluyo la calibración fina tanto de temperatura como de humedad , además de hacer el calculo de la sensación térmica.
- platform: template
sensors:
temperatura_matrimonio_calibrada:
friendly_name: 'Temperatura Matrimonio'
value_template: >
{% set temperatura = states('sensor.temperatura_matrimonio_temperatura') | float(0) %}
{% if temperatura == 0 %}
{{ states('sensor.temperatura_matrimonio_calibrada') | float(0) | round(1) }}
{% else %}
{% set ajuste = -0.7 %}
{{ (temperatura + ajuste) | round(1) }}
{% endif %}
unit_of_measurement: '°C'
icon_template: mdi:thermometer
- platform: template
sensors:
humedad_matrimonio_calibrada:
friendly_name: 'Humedad Matrimonio'
value_template: >
{% set humedad = states('sensor.temperatura_matrimonio_humedad') | float(0) %}
{% if humedad == 0 %}
{{ states('sensor.humedad_matrimonio_calibrada') | float(0) | round(1) }}
{% else %}
{% set ajuste = 7.0 %}
{{ (humedad + ajuste) | round(1) }}
{% endif %}
unit_of_measurement: '%'
icon_template: mdi:water-percent
- platform: template
sensors:
sensacion_calor_matrimonio_calibrada:
friendly_name: 'Indice de calor matr.'
value_template: >-
{% set T = ((states.sensor.temperatura_matrimonio_calibrada.state | float(0) | round(2,default=0))*1.8)+32 %}
{% set RH = states.sensor.humedad_matrimonio_calibrada.state | float(0) | round(5,default=0) %}
{% set STEADMAN_HI = 0.5 * (T + 61.0 + ((T-68.0)*1.2) + (RH*0.094)) %}
{% if STEADMAN_HI >= 80 %}
{% set ROTHFUSZ_HI = -42.379 + 2.04901523*T + 10.14333127*RH - 0.22475541*T*RH - 0.00683783*T*T - 0.05481717*RH*RH + 0.00122874*T*T*RH + 0.00085282*T*RH*RH - 0.00000199*T*T*RH*RH %}
{% set HI = ROTHFUSZ_HI %}
{% if RH < 13 and 80 < T < 112 %}
{% set ADJUSTMENT = ((13-RH)/4)*((17-(T-95)|abs)/17)*0.5 %}
{% set HI = HI - ADJUSTMENT %}
{% elif RH > 85 and 80 < T < 87 %}
{% set ADJUSTMENT = ((RH-85)/10) * ((87-T)/5) %}
{% set HI = HI + ADJUSTMENT %}
{% endif %}
{% else %}
{% set HI = STEADMAN_HI %}
{% endif %}
{% set HI_C = (HI-32)/1.8 %}
{{- HI_C|round(1,default=0) -}}
unit_of_measurement: '°C'
icon_template: mdi:thermometerSi queremos controlar el ultimo envio para poder generar alarmas en caso de que no envíe durante un periodo determinado usaríamos este sensor por ejemplo
- platform: template
sensors:
temperatura_matrimonio_ultima_conexion_minutos:
value_template: >-
{% set x1 = as_timestamp(states('sensor.temperatura_matrimonio_ultima_conexion')) %}
{% set x2 = as_timestamp(now()) %}
{% set time = x2 - x1 | int(0) %}
{% set days = (time/86400) | int %}
{% set hours = (time / 3600 % 24) | int %}
{% set minutes = (((time / 3600) % 1) * 60) | int %}
{{ days ~ 'd ' ~ hours ~ 'h ' ~ minutes ~ 'm' }}
friendly_name: Ultima conexión sensor temp. matrimonio
icon_template: "mdi:calendar-clock"Ya tenemos las dos graficas , temperatura ….

Humedad ….

Si los queremos poner en nuestro panel lovelace podemos poner algo similar a esto
- type: history-graph
title: Temperaturas dia Casa
hours_to_show: 24
refresh_interval: 300
entities:
- sensor.temperatura_comedor_calibrada
- sensor.temperatura_balcon_calibrada
- sensor.temperatura_oriol_calibrada
- sensor.temperatura_trastero_calibrada
- sensor.temperatura_matrimonio_calibrada
- type: history-graph
title: Temperaturas semana Casa
hours_to_show: 168
refresh_interval: 300
entities:
- sensor.temperatura_comedor_calibrada
- sensor.temperatura_balcon_calibrada
- sensor.temperatura_oriol_calibrada
- sensor.temperatura_trastero_calibrada
- sensor.temperatura_matrimonio_calibrada
Y para controlar que envien datos o si no generar una alarma , yo uso esta automatización
- alias: aviso sensores temperatura sin datos 8h
id: aviso_sensores_temperatura_sin_datos_8h
initial_state: 'on'
mode: single
trigger:
- platform: time_pattern
minutes: "0" # cada hora
variables:
sensores:
- entity: sensor.temperatura_balcon_temperatura
nombre: Balcón
- entity: sensor.temperatura_comedor_temperatura
nombre: Comedor
- entity: sensor.temperatura_matrimonio_temperatura
nombre: Matrimonio
- entity: sensor.temperatura_trastero_temperatura
nombre: Trastero
- entity: sensor.temperatura_oriol_temperatura
nombre: Oriol
- entity: sensor.temperatura_nevera_temperatura
nombre: Nevera
condition:
- condition: template
value_template: >
{% for s in sensores %}
{% if (now() - states[s.entity].last_changed).total_seconds() > 28800 %}
{{ true }}
{% endif %}
{% endfor %}
{{ false }}
action:
- service: notify.notif_telegram_bot
data:
message: |
🚨 *⚠️ Alerta sensores de temperatura* ⚠️🚨
Los siguientes sensores NO han enviado datos en más de *8 horas*
(la alerta se repetirá cada hora mientras persista)
{% for s in sensores %}
{% set segundos = (now() - states[s.entity].last_changed).total_seconds() %}
{% if segundos > 28800 %}
🌡 *{{ s.nombre }}*
• Valor actual: {{ states(s.entity) }} ºC
• Último dato: {{ states[s.entity].last_changed.strftime('%d/%m %H:%M:%S') }}
• Tiempo sin datos: ⏱ {{ (segundos // 3600) | int }}h {{ ((segundos % 3600) // 60) | int }}m
{% endif %}
{% endfor %}
- service: notify.notif_telegram_grupo_ha
data:
message: |
🚨 *⚠️ Alerta sensores de temperatura* ⚠️🚨
Los siguientes sensores NO han enviado datos en más de *8 horas*
(la alerta se repetirá cada hora mientras persista)
{% for s in sensores %}
{% set segundos = (now() - states[s.entity].last_changed).total_seconds() %}
{% if segundos > 28800 %}
🌡 *{{ s.nombre }}*
• Valor actual: {{ states(s.entity) }} ºC
• Último dato: {{ states[s.entity].last_changed.strftime('%d/%m %H:%M:%S') }}
• Tiempo sin datos: ⏱ {{ (segundos // 3600) | int }}h {{ ((segundos % 3600) // 60) | int }}m
{% endif %}
{% endfor %}
- service: notify.notif_telegram_ha_urgentes
data:
message: |
🚨 *⚠️ Alerta sensores de temperatura* ⚠️🚨
Los siguientes sensores NO han enviado datos en más de *8 horas*
(la alerta se repetirá cada hora mientras persista)
{% for s in sensores %}
{% set segundos = (now() - states[s.entity].last_changed).total_seconds() %}
{% if segundos > 28800 %}
🌡 *{{ s.nombre }}*
• Valor actual: {{ states(s.entity) }} ºC
• Último dato: {{ states[s.entity].last_changed.strftime('%d/%m %H:%M:%S') }}
• Tiempo sin datos: ⏱ {{ (segundos // 3600) | int }}h {{ ((segundos % 3600) // 60) | int }}m
{% endif %}
{% endfor %}Y con esto y un bizcocho ……

