Files
Home-Assistant/esphome/fdm-exhaust-fan-control.yaml
T

132 lines
2.9 KiB
YAML
Raw Normal View History

2026-06-28 14:27:20 -04:00
substitutions:
device_name: fdm-exhaust-fan-control
friendly_name: "FDM Exhaust Fan Control"
esphome:
name: ${device_name}
friendly_name: ${friendly_name}
esp32:
board: seeed_xiao_esp32c3
framework:
type: esp-idf
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: !secret api_encryption_key
ota:
- platform: esphome
password: !secret ota_password
wifi:
ssid: !secret wifi_iot_ssid
password: !secret wifi_password
manual_ip:
static_ip: 192.168.69.110
gateway: 192.168.69.1
subnet: 255.255.255.0
ap:
ssid: "${friendly_name} Fallback"
password: !secret fallback_password
# Prevents aggressive reconnection attempts
power_save_mode: none # Use 'light' for battery devices
# Slower but more reliable connection
fast_connect: true
# Handle connection failures gracefully
on_connect:
- logger.log: "Wi-Fi connected!"
on_disconnect:
- logger.log: "Wi-Fi disconnected!"
# Reduce mDNS traffic
mdns:
disabled: true # Set to true if you use static IPs and don't need discovery
captive_portal:
web_server:
port: 80
# GPIO Outputs for fan control
# IMPORTANT: inverted: true because NPN transistor driver inverts the logic
# GPIO HIGH -> NPN ON -> Gate LOW -> Fan OFF
# GPIO LOW -> NPN OFF -> Gate HIGH (5V via pull-up) -> Fan ON
output:
- platform: gpio
pin:
number: GPIO3 # D1 on XIAO
inverted: true
id: fan_80mm_output
- platform: gpio
pin:
number: GPIO4 # D2 on XIAO
inverted: true
id: fan_120mm_output
# Fan entities for Home Assistant
fan:
- platform: binary
name: "80mm Exhaust Fan"
id: fan_80mm
output: fan_80mm_output
- platform: binary
name: "120mm Exhaust Fan"
id: fan_120mm
output: fan_120mm_output
# Optional: Add a switch to control both fans together
switch:
- platform: template
name: "All Fans"
id: all_fans
turn_on_action:
- fan.turn_on: fan_80mm
- fan.turn_on: fan_120mm
turn_off_action:
- fan.turn_off: fan_80mm
- fan.turn_off: fan_120mm
lambda: |-
return id(fan_80mm).state && id(fan_120mm).state;
# Diagnostic sensors
sensor:
- platform: wifi_signal
name: "${device_name} WiFi Signal"
update_interval: 60s
- platform: uptime
name: "${device_name} Uptime"
update_interval: 60s
text_sensor:
- platform: wifi_info
ip_address:
name: "${device_name} IP Address"
ssid:
name: "${device_name} Connected SSID"
bssid:
name: "${device_name} BSSID"
# Watchdog to auto-reboot if things go wrong
interval:
- interval: 5min
then:
- if:
condition:
and:
- lambda: 'return millis() > 300000;' # >5 min uptime
- not:
wifi.connected:
then:
- logger.log: "Wi-Fi not connected for 5 min, rebooting..."
- delay: 10s
- lambda: 'App.safe_reboot();'