本帖最后由 polisher 于 2024-1-21 19:25 编辑
应友友们的要求,ESPHOME代码附后,不妥之处望能指正,以便更好的完善。刷机方法见五楼
之前在某宝买的智能喂鱼器,用于孔雀鱼饲养还是挺管用。APP用的是“小美智能”,为了便于自动化,想想还是把这货集成到HA里面吧。
电路不复杂,ESP32-C3的芯片,通过LN8503控制电机正反转。微型行程开关判断托盘位置,红外发射管、接收管判断饲料是否缺少,外部1个手动按钮。IO口如下图,已成功刷入ESPHOME固件,初步测试功能均正常。
这玩意儿比较小众,有人需要再放代码吧。
设备界面
esphome:
name: fish-feeder
friendly_name: 智能喂鱼器
comment: 选择自动喂食,根据设定的间隔时间自动喂食,喂食信息将显示距离下次喂食的时间;禁用自动喂食,喂食信息将显示距离上次喂食的时间。
esp32:
board: esp32-c3-devkitm-1
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "85WJ9FhrcX1PhoSMW/ARpg7oWLBjJ6ecZSOTKHf8M7k="
ota:
password: "c7482694d7b07b649f1754af82cc73c9"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Fish-Feeder Fallback Hotspot"
password: "kYnJzHqGgJ9H"
captive_portal:
globals:
- id: auto_feeding #自动喂食
type: bool
restore_value: yes
initial_value: "false"
- id: feeding_interval #自动喂食间隔,小时
type: int
restore_value: yes
initial_value: "8"
- id: last_feeding #上次喂食时间距离当前时间,分钟
type: int
restore_value: no
initial_value: "0"
substitutions:
device_name: Fish Feeder
Stroke_Switch: GPIO8 #行程开关
Manual_button: GPIO9 #手动按钮
Red_led: GPIO19 #红色指示灯
Blue_led: GPIO18 #蓝色指示灯
Infrared_LED: GPIO2 #红外发射管
Phototransistor: GPIO3 #红外接收管
Forward: GPIO6 #出料盘前进
Reversed: GPIO7 #出料盘后退
# 故障指示灯
status_led:
pin: $Red_led
binary_sensor:
# 运行指示灯
- platform: status
id: binary_status
internal: false
on_press:
- switch.turn_on: blue_led
on_release:
- switch.turn_off: blue_led
#行程开关
- platform: gpio
pin:
number: GPIO8
internal: false
id: stroke_switch
on_press:
then:
- delay: 800ms
- switch.turn_off: ina_switch
- lambda: id(last_feeding)=0;
- if:
condition:
lambda: 'return id(auto_feeding) ;'
then:
- lambda:
id(text_feeding_time).publish_state("下次还剩"+to_string((id(feeding_interval)*60-id(last_feeding))/60)+"时"+to_string((id(feeding_interval)*60-id(last_feeding))%60)+"分");
else:
- lambda:
id(text_feeding_time).publish_state("上次已过"+to_string(id(last_feeding)/60)+"时"+to_string(id(last_feeding)%60)+"分");
# 手动按钮
- platform: gpio
pin: GPIO9
id: sw_buttion
internal: false
filters:
- delayed_on: 10ms
on_press:
then:
- switch.toggle: ina_switch
# 红外接收
- platform: gpio
pin: $Phototransistor
id: phototransistor
internal: false
# 缺料信息
text_sensor:
- platform: template
name: "Missing Feed"
update_interval: never
id: missing_feed
entity_category: DIAGNOSTIC
# 喂食信息
- platform: template
name: "Feeding time"
icon: mdi:message
update_interval: never
id: text_feeding_time
entity_category: DIAGNOSTIC
switch:
# 蓝色指示灯
- platform: gpio
pin: GPIO18
id: blue_led
internal: false
# 马达驱动器
- platform: gpio
pin: GPIO7
id: ina_switch
internal: false
# 红外发射管
- platform: gpio
pin: $Infrared_LED
id: infrared_led
internal: false
# 是否自动喂食
- platform: template
name: "Auto Feeding"
icon: mdi:format-list-checks
entity_category: config
lambda: |-
return id(auto_feeding);
turn_on_action:
- lambda: id(auto_feeding)=true;
turn_off_action:
- lambda: id(auto_feeding)=false;
button:
- platform: template
name: "Feeding"
id: btn_feeding
on_press:
- switch.turn_on: ina_switch
- delay: 20s
select:
- platform: template
name: "Feeding Interval select"
id: select_Feeding_Interval
optimistic: true
restore_value: True
entity_category: config
options:
- 1 小时
- 2 小时
- 4 小时
- 6 小时
- 8 小时
- 12 小时
- 24 小时
- 48 小时
initial_option: 8 小时
on_value:
then:
- lambda: |-
switch(i)
{
case 0:
id(feeding_interval)=1;
break;
case 1:
id(feeding_interval)=2;
break;
case 2:
id(feeding_interval)=4;
break;
case 3:
id(feeding_interval)=6;
break;
case 4:
id(feeding_interval)=8;
break;
case 5:
id(feeding_interval)=12;
break;
case 6:
id(feeding_interval)=24;
break;
case 7:
id(feeding_interval)=48;
break;
}
interval:
# 每10秒检测是否缺料
- interval: 10min
then:
- switch.turn_on: infrared_led
- delay: 100ms
- if:
condition:
lambda: 'return (id(phototransistor).state) ;'
then:
- text_sensor.template.publish:
id: missing_feed
state: !lambda 'return "缺料";'
else:
- text_sensor.template.publish:
id: missing_feed
state: !lambda 'return "不缺料";'
- switch.turn_off: infrared_led
# 每1分检测是否喂食
- interval: 1min
then:
- if:
condition:
lambda: 'return id(auto_feeding) ;'
then:
- if:
condition:
lambda: 'return id(last_feeding)>=(id(feeding_interval)*60) ;'
then:
- switch.turn_on: ina_switch
- lambda:
id(text_feeding_time).publish_state("下次还剩"+to_string((id(feeding_interval)*60-id(last_feeding))/60)+"时"+to_string((id(feeding_interval)*60-id(last_feeding))%60)+"分");
else:
- lambda:
id(text_feeding_time).publish_state("上次已过"+to_string(id(last_feeding)/60)+"时"+to_string(id(last_feeding)%60)+"分");
- lambda: id(last_feeding)=id(last_feeding)+1;
|