For my first esphome project I’m creating a fan controller for my rack with an D1 Mini (8266). So far everything seems to work. Any tips or suggestions are welcome.
substitutions:
friendly_name: Rack Fan
esphome:
name: rack-fan
globals:
- id: dhttemp
type: float
restore_value: yes
initial_value: '0'
#########################
# ESP32 AND NETWORK SETUP
esp8266:
board: d1_mini
# pid climate log update is noisy, dial it back to warn
logger:
level: DEBUG
logs:
dht: DEBUG
# default HA integration, OTA updater and backup http web portal
api:
password: !secret ota_password
ota:
password: !secret ota_password
on_begin:
then:
- logger.log: "OTA start"
on_progress:
then:
- logger.log:
format: "OTA progress %0.1f%%"
args: ["x"]
on_end:
then:
- logger.log: "OTA end"
captive_portal:
wifi:
# Read the wifi/pass from secrets.yaml:
# wifi_ssid: "My Wifi XX"
# wifi_password: "XXXXXXX"
ssid: !secret wifi_ssid
password: !secret wifi_password
fast_connect: true
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: !secret wifi_ssid_backup
password: !secret wifi_password
text_sensor:
# Send IP Address
- platform: wifi_info
ip_address:
name: $friendly_name IP Address
# Send Uptime in raw seconds
- platform: template
name: $friendly_name Uptime
id: uptime_human
icon: mdi:clock-start
sensor:
# Send WiFi signal strength & uptime to HA
- platform: wifi_signal
name: $friendly_name WiFi Strength
update_interval: 60s
# RPM Signal from Fan
- platform: pulse_counter
pin:
number: D2
name: ${friendly_name} Fan Speed
id: fan_pulse
unit_of_measurement: 'RPM'
filters:
- multiply: 0.5
count_mode:
rising_edge: INCREMENT
falling_edge: DISABLE
update_interval: 30s
# This is a bit of overkill. It sends a human readable
# uptime string
# 1h 41m 32s instead of 6092 seconds
- platform: uptime
name: $friendly_name Uptime
id: uptime_sensor
update_interval: 60s
on_raw_value:
then:
- text_sensor.template.publish:
id: uptime_human
# Custom C++ code to generate the result
state: !lambda |-
int seconds = round(id(uptime_sensor).raw_state);
int days = seconds / (24 * 3600);
seconds = seconds % (24 * 3600);
int hours = seconds / 3600;
seconds = seconds % 3600;
int minutes = seconds / 60;
seconds = seconds % 60;
return (
(days ? to_string(days) + "d " : "") +
(hours ? to_string(hours) + "h " : "") +
(minutes ? to_string(minutes) + "m " : "") +
(to_string(seconds) + "s")
).c_str();
########################################################
# START THE FAN CONTROLLER SETUP
# GET TEMP/HUMIDITY FROM DHT11
- platform: dht
pin: D0
model: DHT11
temperature:
name: "Temperature"
id: rack_fan_temperature
accuracy_decimals: 3
on_value_range:
- above: 50.0
then:
if:
condition:
fan.is_off: rack_fan_toggle
then:
- logger.log: "Set fan level 100 over 50C"
- output.set_level:
id: rack_fan_speed
level: 100%
- above: 40.0
then:
if:
condition:
fan.is_off: rack_fan_toggle
then:
- logger.log: "Set fan level 66 over 40C"
- output.set_level:
id: rack_fan_speed
level: 66%
- above: 30.0
then:
if:
condition:
fan.is_off: rack_fan_toggle
then:
- logger.log: "Set fan level 33 over 30C"
- output.set_level:
id: rack_fan_speed
level: 33%
- below: 30.0
then:
if:
condition:
fan.is_off: rack_fan_toggle
then:
- logger.log: "Set fan level 0 under 30C"
- output.set_level:
id: rack_fan_speed
level: 0%
humidity:
name: "Humidity"
id: rack_fan_humidity
update_interval: 2s
output:
# Wire this pin (15) into the PWM pin of your 12v fan
# ledc is the name of the pwm output system on an esp32
- platform: esp8266_pwm
id: rack_fan_speed
pin: D1
# 25KHz is standard PC fan frequency, minimises buzzing
frequency: "25000 Hz"
# my fans stop working below 13% powerful.
# also they're powerful and loud, cap their max speed to 80%
min_power: 1%
max_power: 100%
fan:
- platform: speed
output: rack_fan_speed
name: ${friendly_name} Override Enable
id: rack_fan_toggle
on_turn_on:
- output.set_level:
id: rack_fan_speed
level: !lambda |-
return id(fan_speed_override).state/100.0;
on_turn_off:
- logger.log: "Power of Fan turned OFF"
- delay: 1s
- output.set_level:
id: rack_fan_speed
level: !lambda |-
if (id(rack_fan_temperature).raw_state > 50){
return 1;}
else if (id(rack_fan_temperature).raw_state > 40){
return 0.66;}
else if (id(rack_fan_temperature).raw_state > 30){
return 0.33;}
else
return 0;
number:
- platform: template
name: "Fan Speed Override"
id: fan_speed_override
internal: false
max_value: 100.0
min_value: 0.0
step: 33.3
optimistic: true
mode: slider
on_value:
then:
if:
condition:
fan.is_on: rack_fan_toggle
then:
- output.set_level:
id: rack_fan_speed
level: !lambda "return x/100;"
switch:
# Expose an ESP32 restart button to HA
- platform: restart
name: "Rack Fan D1 Pro Mini Restart"
Screenshots from HA reading temp:
Override Enabled:
Circuit diagram: