太阳能热水器通过esp32接入homeassistant
前言
家里安装有太阳能热水器,但是使用并不方便,一是不知道水热不热,二是每次上水得手动上,每次使用完都得记得手动上水。后来我在淘宝上看到了太阳能的传感器,搜了一下实现原理,感觉可以用esp32将传感器接入智能家居,遂购买后进行尝试。
前排提示:本人并无电路基础,所得结果为思考和ai的共同结果,对电路理解较为浅显,如有错误还请指出。本文旨在给各位提供一个新的思路,大家和谐讨论,不喜勿喷
实现逻辑

我购买的传感器探头是4芯的,2芯的原理没看明白,好像更复杂,就用了更简单的4芯。绿白线是水温,红蓝线是水位。
水温部分实际原理是NTC,在esphome页面可以直接找到相关的配置样例,我用了5.1k的电阻进行分压,用3.3v供电。
水位部分应该是多个电阻,水位不同时电阻也不同,我用了62k的电阻进行分压,用5v供电。
由于线路会进行更改,所以我还购买了面包板,方便原件插接。
逻辑迭代
版本1
最初版本接线(已迭代)最初版本接线
最开始的版本中,接线逻辑如下:
5v-62k电阻-红线-蓝线-gnd 64k电阻和红线间接gpio口检测电压,理论上红蓝线不分正反
3.3v-5.1k电阻-绿线-白线-gnd 5.1k电阻和绿线间接gpio口检测电压,理论上白绿线不分正反
使用esphome接入后,观察了一段时间,温度准确。但是发现一个问题,水位会向上漂移,电压值会线性越来越高,准确性很差。我查资料后发现,可能是电解水导致的小气泡在电极上负极,越来越多后电压就越来越高,影响到了准确性。
版本2
我修改了接线逻辑,如下:
5v-62k电阻-红线-蓝线-gpio模拟gnd(可控通断) 64k电阻和红线间接gpio口检测电压,理论上红蓝线不分正反
3.3v-5.1k电阻-绿线-白线-gpio模拟gnd(可控通断) 5.1k电阻和绿线间接gpio口检测电压,理论上白绿线不分正反
这次使用esphome接入后,电压较为平稳。观察记录水位对应的电压后,重新写到代码中(这里需要自行观察,水位变化的时候电压变化还是很明显的。)



esphome代码
我的代码中包含了蓝牙网关的部分,可自行删除。如果数值和我不同,也可自行调整。部分为ai生成,已自行使用过一段时间。
substitutions:
# Name the device and it's entities
device: "esp32-ble-tracker"
device_name: esp32-ble-tracker
esphome:
name: $device
friendly_name: $device
# 5. 开机初始化:确保初始断电
on_boot:
then:
- output.turn_off: water_level_ground
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "key"
ota:
- platform: esphome
password: "password"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
fast_connect: on
reboot_timeout: 23min
ap:
ssid: "Esp32-Ble-Tracker"
password: !secret wifi_password
captive_portal:
external_components:
- source: github://myhomeiot/esphome-components
esp32_ble_tracker:
scan_parameters:
interval: 120ms
window: 99ms
active: true
bluetooth_proxy:
active: true
binary_sensor:
- platform: homeassistant
id: ble_gateway_discovery
entity_id: binary_sensor.ble_gateway
attribute: discovery
on_state:
then:
lambda: id(blegateway).set_discovery(x);
ble_gateway:
id: blegateway
discovery: true
on_ble_advertise:
then:
- homeassistant.event:
event: esphome.on_ble_advertise
data:
packet: !lambda return packet;
gateway_id: $device_name
text_sensor:
- platform: homeassistant
id: ble_gateway_devices
entity_id: binary_sensor.ble_gateway
attribute: devices
on_value:
then:
lambda: id(blegateway).set_devices(x);
- platform: wifi_info
ip_address:
name: $device_name IP address
id: ip_address
- platform: version
name: $device_name ESPHome Version
switch:
- platform: template
id: switch_ble_gateway_discovery
name: BLE Gateway Discovery
icon: mdi:bluetooth-connect
lambda: return id(blegateway).get_discovery();
turn_on_action: [lambda: id(blegateway).set_discovery(true);]
turn_off_action: [lambda: id(blegateway).set_discovery(false);]
disabled_by_default: false
entity_category: config
sensor:
# WiFi signals strength sensor
- platform: wifi_signal
name: $device WiFi Signal Sensor
update_interval: 60s
# —— 温度原始 ADC ——
- platform: adc
id: solar_temp_adc
pin: GPIO34
name: "solar_temp_adc1"
update_interval: never
accuracy_decimals: 2
attenuation: 11db
filters:
- median:
window_size: 3 # 奇数,建议 3~7
send_every: 1 # 每次都输出(使用中值)
# —— NTC 温度(基于 resistance)——
- platform: resistance
id: resistance_sensor
sensor: solar_temp_adc # 指向上面的 ADC
configuration: DOWNSTREAM
resistor: 5.024kOhm # 分压电阻(接在 VCC 和 OUT 之间)
- platform: ntc
id: solar_temp_ntc
sensor: resistance_sensor
calibration:
b_constant: 3435
reference_temperature: 25°C
reference_resistance: 10kOhm
name: "solar_temp"
accuracy_decimals: 1
#################### 太阳能水位传感器 ####################
# 2. ADC 电压传感器
- platform: adc
id: solar_water_level_adc
pin: GPIO32
name: "solar_water_level_adc4" # 保留原名
update_interval: never # 关闭自动采样!
accuracy_decimals: 2
attenuation: 11db
# 3. 水位百分比(基于同一电压值计算)
- platform: template
id: solar_water_level_pct
name: "solar_water_level"
unit_of_measurement: "%"
accuracy_decimals: 0
icon: mdi:cup-water
update_interval: never # 由 interval 统一触发,不自动更新
# 1. 电源控制引脚(用于给水位传感器供电)
output:
- platform: gpio
pin: GPIO25
id: water_level_ground
inverted: true # 低电平 = 接地(导通)
# 4. 核心:定时通电采样(每15秒一次)
interval:
- interval: 15s
then:
# 1. 接通共地(GPIO24 输出 LOW)
- output.turn_on: water_level_ground
- delay: 30ms # 等待电压稳定
# 2. 手动更新 ADC 值
- component.update: solar_water_level_adc
- component.update: solar_temp_adc
- delay: 7ms
# 3. 发布水位
- lambda: |-
float v = id(solar_water_level_adc).state;
float level = 100;
if (v > 1.6) level = 0;
else if (v > 1.4) level = 25;
else if (v > 1.0) level = 50;
else if (v > 0.78) level = 75;
id(solar_water_level_pct).publish_state(level);
- delay: 7ms
# 4.5 断电(防止电解)
- output.turn_off: water_level_ground
homeassistant中显示效果
上面的电压是温度的,下面的是水位的

水位电压显示效果

写在最后
这样将太阳能热水器加入homeassistant中后,再将上水管加上电磁阀,用智能开关控制,即可实现自动上水。总体效果还算满意。
