感谢,买回来就想这样弄了,苦于没技术,昨天折腾一天搞掂,顺便改了下代码,加入蓝牙网关功能,缺料改为喂食完检查。
esphome:
name: fish-feeder
friendly_name: 智能喂鱼器
comment: 包含蓝牙网关功能的智能喂鱼器
# 定义ESP32的基本硬件信息
esp32:
board: esp32-c3-devkitm-1 # 使用ESP32-C3开发板
framework:
type: arduino # 使用Arduino框架
# 启用日志功能,用于调试和记录信息
logger:
# 启用蓝牙扫描功能
esp32_ble_tracker:
# 启用蓝牙网关功能,将蓝牙数据中继到Home Assistant
bluetooth_proxy:
# 启用Home Assistant API,用于与Home Assistant通信
api:
encryption:
key: "85WJ9FhrcX1PhoSMW/ARpg7oWLBjJ6ecZSOTKHf8M7k="
# 启用OTA功能,支持远程固件更新
ota:
platform: esphome
password: "c7482694d7b07b649f1754af82cc73c9"
# Wi-Fi配置
wifi:
ssid: !secret wifi_ssid # Wi-Fi网络名称
password: !secret wifi_password # Wi-Fi密码
# 当Wi-Fi连接失败时启用备用热点模式
ap:
ssid: "Fish-Feeder"
password: "1234567890"
# 启用ESPHome的捕获门户功能,便于设备配置
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 # 延迟800毫秒避免抖动
- 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 # 喂食持续20秒
- switch.turn_off: ina_switch # 喂食结束,停止喂食
- switch.turn_on: infrared_led # 开始检查是否缺料
- delay: 100ms # 延迟100毫秒
- if:
condition:
lambda: 'return id(phototransistor).state;' # 检测是否缺料
then:
- text_sensor.template.publish:
id: missing_feed
state: "缺料"
else:
- text_sensor.template.publish:
id: missing_feed
state: "不缺料"
- switch.turn_off: infrared_led # 关闭红外检查
# 定义选择器
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:
# 每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;
|