先定义“当前值有效”,再谈历史曲线
本篇用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和数值状态
只接指定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.1 | PID4885 | 说明 |
|---|---|---|
| 3V3 | VIN | 3.3V电源/逻辑域 |
| GND | GND | 公共参考 |
| GPIO8/J1-12 | SDA | 数据 |
| GPIO9/J1-15 | SCL | 时钟;0x44 |
参考:[2] DevKitC-1 v1.1固定文档提交927ed7e:排针、电源与USB[3] Adafruit PID4885:VIN/3V、上拉与I2C地址
完整配置与第一次有限数值
按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集成源码
在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密钥
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密钥
用正常、重启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保留天数与过滤
资料来源与版本说明
本文依据下列官方文档与上游资料独立整理,适用范围与版本以本文所列组合为准。资料核对日期:。资料核对、程序构建与实板测试分别记录,不互相替代。
- ESPHome2026.9.1固定发布与源码
- DevKitC-1 v1.1固定文档提交927ed7e:排针、电源与USB
- Adafruit PID4885:VIN/3V、上拉与I2C地址
- ESPHome2026.9.1:SHT4x读取、失败与加热
- ESPHome2026.9.1:Sensirion CRC读取
- ESPHome2026.9.1:timeout过滤器实际NaN失效逻辑
- HA Core2026.10.2:ESPHome集成源码
- Home Assistant:Template availability和数值状态
- Home Assistant:Recorder保留天数与过滤
- Home Assistant:ESPHome集成、手动加入与Noise密钥