家庭自动化 / 家庭设备发布 内容更新

ESPHome 温湿度节点:把 SHT40 接进 Home Assistant 看历史

用固定SHT40模块与完整YAML发布温湿度,增加35秒陈旧超时、数据有效标记与HA不可用模板,再检查Recorder和HA重启后的历史边界。

读完能做什么
获得带单位、明确采样周期和失效状态的温湿度实体,并能区分正常历史、缺样与HA停机。
开始之前
已经会ESPHome首刷、日志和HA加密API加入;按计划先完成H01,本篇完整配置也可独立构建。
所需器材
DevKitC-1 v1.1 N8R8、Adafruit SHT40 STEMMA QT PID4885、USB数据线、短I2C导线、已有HA实例与ESPHome首刷/集成基础、故障实验:低压SPST信号开关,断电预装在单模块SDA支路
版本组合
参考板:ESP32-S3-DevKitC-1 v1.1 / WROOM-1-N8R8ESPHome / Python:2026.9.1 / 3.12.13;实际macOS arm64设备框架:原生ESP-IDF toolchain / 5.5.5HA资料范围:Core2026.10.2源码;未在真实HA执行
适用范围

官方S3 DevKitC-1 v1.1 N8R8 + Adafruit PID4885,SDA8/SCL9、0x44;ESPHome2026.9.1与IDF5.5.5;HA代码按Core2026.10.2源码核对,未运行。

这篇验证到了哪一步

资料核对已通过
docs/esp32-evidence/home-assistant.md验证日期:
构建 / 配置已通过
docs/esp32-evidence/esphome-builds.json;config与固件compile均Exit 0;不含HA配置运行、USB首刷或实板验证对象:esp32-s3-devkitc-1 / ESP32S3 / 8MB Flash + 8MB OPI PSRAM版本:ESPHome 2026.9.1 / Python 3.12.13 / ESP-IDF 5.5.5验证日期:
仿真不适用
未使用硬件或HA仿真
本站实板待验证
未有本站实板或真实Home Assistant运行;首刷/实体/OTA/模块行为仍待验证

构建通过只说明指定环境中的代码或配置通过检查;实物功能、功耗和稳定性以对应的实板记录为准。

01 / 家庭设备

先定义“当前值有效”,再谈历史曲线

本篇用10秒采样的SHT40构建家庭温湿度节点。重要的完成物不只是一对数字,还包括单位、命名、数据失效和恢复时的状态。传感器断开后旧数字仍在,不能继续被解释成实时温湿度。

ESPHome2026.9.1的sht4x驱动在读命令、总线或CRC失败时会警告并停止本次发布,旧值可能保留。因此完整配置给每个数值增加35秒timeout和Data valid实体,再用HA availability包装出明确不可用的数值实体。

参考:[4] ESPHome2026.9.1:SHT4x读取、失败与加热[5] ESPHome2026.9.1:Sensirion CRC读取[6] ESPHome2026.9.1:timeout过滤器实际NaN失效逻辑[7] HA Core2026.10.2:ESPHome集成源码[8] Home Assistant:Template availability和数值状态

02 / 家庭设备

只接指定PID4885的四根线

固定Adafruit SHT40 STEMMA QT PID4885。VIN接S3的3V3,GND共地,GPIO8/J1-12接SDA,GPIO9/J1-15接SCL,100kHz,地址0x44。该模块已有电平转换与10kΩ上拉,本例不再并联;3V标注是模块输出,不能当第二路输入。

暂时只接这一个I2C模块,缩短导线并先断电检查。匿名SHT40裸板可能没有同样的稳压/上拉,不能以名字一样套接线。温度计放在稳定位置,远离开发板和手指热源;本例没有与标准仪器做精度比较。

DevKitC-1 v1.1PID4885说明
3V3VIN3.3V电源/逻辑域
GNDGND公共参考
GPIO8/J1-12SDA数据
GPIO9/J1-15SCL时钟;0x44

参考:[2] DevKitC-1 v1.1固定文档提交927ed7e:排针、电源与USB[3] Adafruit PID4885:VIN/3V、上拉与I2C地址

03 / 家庭设备

完整配置与第一次有限数值

按H01相同的Python3.12.13/ESPHome2026.9.1方法安装,下载本篇独立配置并创建私有secrets.yaml;包内的工具锁、IDF组件锁与README说明如何重建。不要把上一台设备名称或密钥未核对就写进另一台板。

这里高精度、10秒周期,heater_max_duty=0明确关加热。驱动通过Sensirion共同层检查CRC,只在成功样本后发布;timeout在最后一个有效发布后没有新值约35秒时送出NaN。启动没有样本时保持未知,不用0占位。

Data valid同时要求温湿度都有有限数值。NaN经HA ESPHome数值集成表现为unknown,而设备网络掉线通常表现为unavailable;它们来自不同层。后面的包装实体使传感器故障也有明确unavailable。

代码 / 配置
esphome:
  name: esp32-sht40
  friendly_name: ESP32 SHT40
  min_version: 2026.9.1
  on_boot:
    priority: -100
    then:
      - logger.log: "H02-A booted; inspect real device logs"

esp32:
  board: esp32-s3-devkitc-1
  variant: ESP32S3
  flash_size: 8MB
  flash_mode: qio
  flash_frequency: 80MHz
  toolchain: esp-idf
  framework:
    type: esp-idf
    version: 5.5.5

psram:
  mode: octal
  speed: 80MHz

logger:
  baud_rate: 115200
  hardware_uart: UART0
  level: DEBUG

api:
  encryption:
    key: !secret api_key
  reboot_timeout: 0s

ota:
  - platform: esphome
    encryption:
      key: !secret api_key

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  reboot_timeout: 0s
  ap:
    ssid: "esp32-sht40 Recovery"
    password: !secret fallback_password
    ap_timeout: 90s

captive_portal:

i2c:
  id: sensor_bus
  sda: GPIO8
  scl: GPIO9
  frequency: 100kHz
  scan: true
  timeout: 10ms

sensor:
  - platform: sht4x
    id: room_sht40
    i2c_id: sensor_bus
    address: 0x44
    precision: High
    heater_max_duty: 0.0
    update_interval: 10s
    temperature:
      id: room_temperature
      name: "Temperature"
      filters:
        - timeout: 35s
    humidity:
      id: room_humidity
      name: "Humidity"
      filters:
        - timeout: 35s

binary_sensor:
  - platform: template
    name: "Data valid"
    lambda: |-
      return id(room_temperature).has_state() && std::isfinite(id(room_temperature).state)
          && id(room_humidity).has_state() && std::isfinite(id(room_humidity).state);

参考:[1] ESPHome2026.9.1固定发布与源码[4] ESPHome2026.9.1:SHT4x读取、失败与加热[5] ESPHome2026.9.1:Sensirion CRC读取[6] ESPHome2026.9.1:timeout过滤器实际NaN失效逻辑[7] HA Core2026.10.2:ESPHome集成源码

04 / 家庭设备

在HA检查源ID,再合并availability模板

按实际日志加入HA集成,先在开发者工具→状态找到实际温度、湿度与Data valid的entity_id。默认可能类似sensor.esp32_sht40_temperature,但名称冲突、重命名或已有实体会改变它,不能只照抄。

下载中的home-assistant-template.yaml是完整template片段。先把其中三个源ID改成实际值,再合并进已有template列表,不重复顶层键;在HA模板编辑器检查表达式,并按当前HA的配置检查/重载步骤生效。下面为对应完整片段,本站只做源码与YAML检查,未启动HA执行。

包装实体要求valid=on且原值为数值,失效后返回unavailable;数值state只输出数字或none,不用字符串unknown冒充温度。记录包装后的实际ID,后面的仪表和历史选用它们。

代码 / 配置
# Home Assistant Core 2026.10.2 source-checked fragment; no live HA validation.
# Verify the real ESPHome entity IDs in Developer Tools -> States before using.
template:
  - sensor:
      - name: "Esp32 Sht40 Temperature Valid"
        unique_id: "hixinwu_esp32_sht40_temperature_valid_v1"
        default_entity_id: "sensor.esp32_sht40_temperature_valid"
        unit_of_measurement: "°C"
        device_class: temperature
        state_class: measurement
        availability: "{{ is_state('binary_sensor.esp32_sht40_data_valid', 'on') and is_number(states('sensor.esp32_sht40_temperature')) }}"
        state: "{{ states('sensor.esp32_sht40_temperature') | float(none) }}"
      - name: "Esp32 Sht40 Humidity Valid"
        unique_id: "hixinwu_esp32_sht40_humidity_valid_v1"
        default_entity_id: "sensor.esp32_sht40_humidity_valid"
        unit_of_measurement: "%"
        device_class: humidity
        state_class: measurement
        availability: "{{ is_state('binary_sensor.esp32_sht40_data_valid', 'on') and is_number(states('sensor.esp32_sht40_humidity')) }}"
        state: "{{ states('sensor.esp32_sht40_humidity') | float(none) }}"

参考:[7] HA Core2026.10.2:ESPHome集成源码[8] Home Assistant:Template availability和数值状态[10] Home Assistant:ESPHome集成、手动加入与Noise密钥

05 / 家庭设备

Recorder保存什么,与设备每10秒采样是两件事

在HA历史页选择已核对的两个包装实体,正常采集至少5分钟,确认摄氏温度与百分比湿度。若已有Recorder include/exclude,检查是否把这些实体排除了;本包recorder-example.yaml展示14天保留与特定实体include,必须合并原来的唯一recorder配置,不能覆盖其他设备记录。

采样10秒并不保证历史每10秒恰有一行,相同状态可能合并。state_class:measurement让数值语义清楚,但长时间统计、保留策略和原始历史仍由HA负责。不要为填满曲线而制造重复读数。

重启HA时设备可继续采样,但本例不缓存或补传HA停机期间的样本。重启后检查API重连与最新状态继续进入历史;中间缺样不能画成已经采集的连续数据。

代码 / 配置
# Merge with the ONE existing recorder: block; do not duplicate this top-level key.
# If using include/exclude filters already, preserve and extend your existing lists.
recorder:
  purge_keep_days: 14
  include:
    entities:
      - sensor.esp32_sht40_temperature_valid
      - sensor.esp32_sht40_humidity_valid
      - binary_sensor.esp32_sht40_data_valid
做到这里,你应该看到
正常单位、真实entity_id、Recorder过滤与停机边界都有记录;空白CSV不填虚构数值。

参考:[7] HA Core2026.10.2:ESPHome集成源码[8] Home Assistant:Template availability和数值状态[9] Home Assistant:Recorder保留天数与过滤[10] Home Assistant:ESPHome集成、手动加入与Noise密钥

06 / 家庭设备

用正常、重启HA、断线和恢复四组记录验收

正常模块先记录5分钟的源单位、Data valid、包装实体与历史,再重启HA并检查重连。要检查已有样本的35秒陈旧窗口,先断电在SHT40的SDA信号支路预装低压SPST开关;保持VIN/GND/SCL正常,重新上电取得有效样本后,只操作这个开关断开SDA,不带电拔电源或挪杜邦线。

记录最后有效样本的实际时刻,再断开SDA支路。读取失败后先保留窗口内旧值,最后有效样本约35秒后应发布NaN、Data valid变false、HA包装实体unavailable;分别留日志与HA实际状态,不能从期望时间抄一行结果。随后闭合开关,观察后续有效采样、valid=true及包装恢复;需要重新初始化时再RESET。

冷启动缺模块另测:先断电移除SDA再上电,观察无有效样本和valid=false。此时组件可能被标为failed,接回后需要RESET重建,不能承诺热插拔自动恢复。恢复也先断电接回四线,再RESET,复核0x44、有限温湿度、valid、包装实体与历史继续。

源实体有值但包装不可用时先核对模板源ID;连0x44都没有先回电源/上拉/线序;读数警告查CRC与总线,不把ACK当成测量成功。本站目前无实板、HA重启或历史图结果,以上均是待执行验收。

参考:[3] Adafruit PID4885:VIN/3V、上拉与I2C地址[4] ESPHome2026.9.1:SHT4x读取、失败与加热[5] ESPHome2026.9.1:Sensirion CRC读取[6] ESPHome2026.9.1:timeout过滤器实际NaN失效逻辑[7] HA Core2026.10.2:ESPHome集成源码[8] Home Assistant:Template availability和数值状态[9] Home Assistant:Recorder保留天数与过滤

BACK TO THE SOURCE

资料来源与版本说明

本文依据下列官方文档与上游资料独立整理,适用范围与版本以本文所列组合为准。资料核对日期:。资料核对、程序构建与实板测试分别记录,不互相替代。

  1. ESPHome2026.9.1固定发布与源码
  2. DevKitC-1 v1.1固定文档提交927ed7e:排针、电源与USB
  3. Adafruit PID4885:VIN/3V、上拉与I2C地址
  4. ESPHome2026.9.1:SHT4x读取、失败与加热
  5. ESPHome2026.9.1:Sensirion CRC读取
  6. ESPHome2026.9.1:timeout过滤器实际NaN失效逻辑
  7. HA Core2026.10.2:ESPHome集成源码
  8. Home Assistant:Template availability和数值状态
  9. Home Assistant:Recorder保留天数与过滤
  10. Home Assistant:ESPHome集成、手动加入与Noise密钥