近来天气渐热。遂购入一台普通可充电小风扇。此风扇的电源和风速调节只有一个按钮。且无遥控器。刚好家里还有几片剩余没有用的ESP12 。试试能不能改装一下远程控制,接入home-assisstant。
因为此风扇自带电池。内部按钮是个未知的MCU控制的,测量发现MCU的供电电压是3.6v左右。也可以用来给ESP供电。按钮是低电平触发。所以只要用ESP控制GPIO给按钮低电平就可以控制这个风扇了。
连接电路如下:
ESPHOME还不支持Fan Template。其Binary-Fan又只能通过一个GPIO来控制开关。此风扇的开关实际上是个循环的速度调节器,从0-5档。所以我需要一个fake的GPIO什么也不做。在on_turn_on和on_turn_off时用lambda来控制连接风扇按钮的GPIO。开机简单,直接trigger一下GPIO就OK。关机要连续trigger直到切换到0 。所以加了个binary-sensor GPIO检测开机状态。lambda通过for + if开控制实现关机。
fan:
- platform: binary
output: fake_out
name: Fan
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
then:
- logger.log: "Turn On Fan"
- script.execute: button_press
- script.wait: button_press
- logger.log: "Turn On Fan End"
on_turn_off:
then:
- logger.log: "Turn Off Fan"
- script.execute: always_press_until_off
- script.wait: always_press_until_off
- logger.log: "Turn Off Fan End"
binary_sensor:
- platform: gpio
pin: GPIO5. # 连接检测点,检测电源状态
id: fan_power
name: "Fan Power"
filters:
- delayed_on: 10ms
output:
- id: output_io
platform: gpio
pin: GPIO14
inverted: true
- platform: template
id: fake_out # 什么都不做
type: float
write_action:
- logger.log: "NoThing"
script:
- id: button_press
then:
- logger.log: "Press Start"
- output.turn_on: output_io
- delay: 200ms
- output.turn_off: output_io
- logger.log: "Press End"
- id: always_press_until_off
then:
- repeat:
count: 4
then:
- if:
condition:
binary_sensor.is_on: fan_power
then:
- logger.log: "Press Start"
- output.turn_on: output_io
- delay: 100ms
- output.turn_off: output_io
- delay: 500ms # 电源关机有一定延迟
- logger.log: "Press End"
else:
- logger.log: "Check Else"
增加调节风速的按钮,这个比较简单:
button:
- platform: template
name: "Fan Speed +"
on_press:
- script.execute: button_press
- script.wait: button_press
打开web server测试效果
web_server:
测试OK后打开api,接入home-assisstant。
api:
password: "PASSWORD"
因为风扇是电池供电,为了防止esp把电池耗尽,加入一点休眠机制:
esphome:
name: fan
platform: ESP8266
board: esp12e
platformio_options:
board_build.ldscript: eagle.flash.2m.ld
on_loop:
then:
- if:
condition:
sensor.in_range:
id: vcc
below: 3.82
then:
- logger.log: "Enter Deep Sleep"
- deep_sleep.enter:
id: deep_sleep_1
sleep_duration: 20min
else:
- deep_sleep.prevent: deep_sleep_1
sensor:
- platform: adc
pin: VCC
id: vcc
name: "Fan VCC"
update_interval: 100ms
deep_sleep:
id: deep_sleep_1
run_duration: 60s
sleep_duration: 20min
完整代码如下:
https://gist.github.com/yufeikang/aa21ad464a992d4b47f1b0f7ed1ebb79