Nous SZ-T04 Zigbee e integración en Home Assistant

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:thermometer

Si 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 ……

Restaurar vista previa en carpetas de red tras actualizaciones de Windows

De pronto en el trabajo tras una actualización de seguridad de W10 en el trabajo algunos usuarios que usaban de forma intensiva la vista previa en el explorador dejaron de tener acceso a la vista previa , mucha gente no la usa , pero para el que esta acostumbrado suele ayudar bastante al no ir a ciegas antes de abrir cualquier archivo

La causa principal del problema no es un error, sino un cambio de seguridad intencional. Microsoft bloqueó la vista previa de archivos en ubicaciones de red clasificadas como “zona Internet” a partir de las actualizaciones de octubre 2025 (KB5066791 para Windows 10) para prevenir una vulnerabilidad que permitía fugas de hashes NTLM. La solución más efectiva para carpetas NAS es agregar las rutas de red a la zona de Intranet Local o Sitios de Confianza en Windows.

¿ Por qué las actualizaciones rompen esta funcionalidad ?

El cambio afecta específicamente cómo Windows maneja los archivos con “Mark of the Web” (MotW) y los ubicados en zonas de seguridad consideradas riesgosas. Cuando se previsualiza un archivo, los preview handlers pueden cargar recursos externos referenciados, y si estos apuntan a rutas UNC o URLs file:, Windows puede enviar credenciales NTLM hasheadas a servidores externos.

KB específicos que causan el problema: KB5066791 (Windows 10, octubre 2025) y KB5066835 (Windows 11). Estas actualizaciones modifican el valor URLACTION_SHELL_PREVIEW (0x180F) en la Zona Internet de “Enable” a “Disable”. Desinstalar estos parches no es solución permanente ya que el comportamiento se reimplementa en todas las actualizaciones de seguridad posteriores.

Soluciones al problema :

Opción 1

Crear un archivo de texto con el Bloc de notas y guárdalo como agregar_nas.reg:

Con el contenido

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Ranges\Range1]
":Range"="10.57.45.XX"
"*"=dword:00000001

Lo importamos y reiniciamos explorer.exe

Ya tenemos nuestra vista previa funcionando

Si entrásemos en el editor del registro veríamos los valores importados

Opción 2

Abrir PowerShell como Administrador 

New-Item -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Ranges\Range1" -Force
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Ranges\Range1" -Name ":Range" -Value "10.57.45.XX" -PropertyType String -Force
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Ranges\Range1" -Name "*" -Value 1 -PropertyType DWord -Force

Poe supuesto como mas rapida y directa la opción 1

Y con esto y un bizcocho …..