【智能家居】3 ESP8266智能开关接入ESPHome 和 HA

7 人赞同了该文章

目录

收起

一、ESPHome开发智能开关

1. Mac(类Unix)上 ESPHome安装

2. ESP8266控制舵机

3. ESP01S控制继电器

4. HA端集成

二、Arduino开发智能开关

软件模拟PWM

B站的实例[^3]

三、ESP32-CAM使用

Configuration for Ai-Thinker Camera

参考资料

本篇是智能家居折腾系列的第三期,完稿于第5期之后,内容有穿插请跳转查看。

本篇主要介绍ESP8266单片机和ESPHome的开发使用,以及将开发版接入Home Assistant的方法。项目均为测试上手之用,完成度不高,仅做尝试。

这一期围绕使用支持Wi-Fi的单片机制作可使用Home Assistant控制的能远程开关灯的物联网设备,主要介绍使用ESP8266 Node MCU结合舵机制作的简易关灯装置、使用ESP01-S配合继电器模块设计的简易单火线墙壁开关、ESP32-CAM作为IP摄像头。

本文完成时间距内容创造时间较长,详细过程和实物图片就不全展示了,可以找相关教程和文档。

nodemcu_esp8266-full

一、ESPHome开发智能开关

ESPHome is a system to control your ESP8266/ESP32 by simple yet powerful configuration files and control them remotely through Home Automation systems.

ESP8266和Node MCU开发板这里就不详细介绍了,可以查阅相关页面:

ESP8266-NodeMCU介绍. 太极创客:http://www.taichi-maker.com/homepage/reference-index/arduino-hardware-refrence/nodemcu/

1. Mac(类Unix)上 ESPHome安装

根据官方文档引导,使用 pip 安装 ESPHome(此步骤可以不加user):

pip3 install --user esphome

注意ESPHome --user 安装位置:/Users/gakki/Library/Python/3.9/bin,使用时需要添加环境变量

export PATH="$PATH:/Users/gakki/Library/Python/3.9/bin"

看自己安装的方式,我的需要加 sudo 启动:

sudo esphome esphome_config/ dashboard

访问Web localhost:6052

ESPHome Dashboard

对于nodeMCU,板载CH340的USB转TTL芯片,在mac上可以免驱直连;对于ESP01等小板,需要搭配烧录器连接至电脑。

连接后,在编辑页面输入配置文件,检查成功后可直接编译烧录至单片机。

ESPHome的优点就是无需编写代码,使用高度集成的配置文件式编程。更多细节请参阅相关文档。

2. ESP8266控制舵机

ESP8266有部分引脚可以输出PWM信号,进而可以操控舵机,

我使用的是SG90舵机,旋转角度仅为90度,供电和GND接开发版,数据线接D4引脚。

硬件输出PWM控制舵机

案例:接入ESPHome用ESP8266控制舵机喂狗:https://bbs.hassbian.com/thread-8741-1-1.html

ESPHOME 舵机项目[^1]

官方文档中所给出的ESPHome中关于舵机的配置,使用 esp8266_pwm 输出PWM至指定引脚,并创建舵机实体。

# Example configuration entry
servo:
  - id: my_servo
    output: pwm_output

# Example output platform
# On ESP32, use ledc output
output:
  - platform: esp8266_pwm
    id: pwm_output
    pin: D1
    frequency: 50 Hz

用舵机控制墙壁开关

我尝试将舵机贴近墙壁开关粘贴放置,使得舵机旋转半周后刚好能将开关关闭(由于已拆除,已无现场图片),单片机开发板则从插座取电。

我烧录的yaml:

esphome:
  name: node_mcu
  platform: ESP8266
  board: nodemcuv2

wifi:
  ssid: "blue_sky"
  password: "720805zzy"
  power_save_mode: light
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  #ap:
  #ssid: "Servos Fallback Hotspot"
  #password: "VYTOwxqxxlOT"

#captive_portal:

# Enable logging
logger:

# Enable Home Assistant API
api:
  services:
    - service: control_servo
      variables:
        level: float
      then:
        - servo.write:
            id: my_servo
            level: !lambda 'return level / 100.0;'

ota:
  password: "123"

servo:
  - id: my_servo
    output: pwm_output

# Example output platform
# On ESP32, use ledc output
output:
  - platform: esp8266_pwm
    id: pwm_output
    pin: D4
    frequency: 50 Hz
    
light:
  - platform: monochromatic
    name: "LED On Board"
    output: pwm_output

D4管脚刚好对应开发板上的LED灯,实际的效果依然没有视频,不过可以参考B站上同类型的展示:

同类作品

3. ESP01S控制继电器

ESP01S是简化的ESP8266,仅引出两个GPIO,GPIO0GPIO2

淘宝上搜索ESP01+继电器,有搭配ESP01的继电器模块,继电器模块通过5V供电,内部IDO转为3.3V给ESP01供电,因此整个模块需要5V供电,可以从墙壁插座使用变压器供电,若86盒中预留零线的,可以购买220V转5V的模块供电。

我的想法是:ESP01通过ESPHome接入HA,作为一个远程开关;继电器控制电灯火线的开闭;还要兼顾原来物理开关的功能,而且物理开关和HA中的状态可以实时更新同步。

可以参考下面的实例。

CSDN实例[^2]

通过ESPHome接入HA,实现与之前相近的功能,即使用Wi-Fi和实体开关控制继电器。

大体的原理是:一个gpio虚拟成二进制传感器,一个gpio来控制继电器。当这个二进制传感器触发的时候,开关的开与闭合也发生变化。

GPIO0控制继电器的吸和,GPIO2与GND之间焊上原来的物理开关(使用杜邦线相连),并在GPIO和VCC间焊上10K的上拉电阻。(取决于继电器模块的工作模式,此方案是低电平触发,若为高电平触发,则开关要与VCC相连,对应焊接下拉电阻)

具体接线图已无处寻,可以参考CSDN实例[^2] 中的接线方式。

ESPHome 配置

与CSDN例子中不同的是,他的是自动回弹式开关,使用的二进制传感器工作模式为 on_press,即每次按下时开/关灯。

我使用的是传统的墙壁开关,每次扳动时开/关灯,因此使用的模式是 on_state.

烧录文件:

esphome:
  name: esp01s-1
  platform: ESP8266
  board: esp01_1m
 
wifi:
  networks:
    ssid: "blue_sky"  #改成你的wifi名称
    password: "720805zzy" #改成你的wifi密码
  power_save_mode: light
  #manual_ip:
    #static_ip: 192.168.50.189
    #gateway: 192.168.50.1
    #subnet: 255.255.255.0
 
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp01S-1 Fallback Hotspot" #当esp01s连不上网的时候,它会自动发出热点。
    password: "12345678"
 
captive_portal:
 
# Enable logging
logger:
 
# Enable Home Assistant API
api:
#  password: "1"
 
ota:
  password: "123"
  
web_server:
  port: 80
  
switch:
  - platform: gpio
    pin: GPIO0
    name: "书房灯1"
    id: relay2
    inverted: True
    
binary_sensor:
  - platform: gpio
    pin: GPIO2
    name: "press_switch_lib1"
    device_class: opening
    filters:
      - delayed_on_off: 100ms #这里一定要加这个这个起到滤波的作用。
    on_state:  #当这个二进制传感器状态改变的时候,触发gpio0
      then:
        - switch.toggle: relay2

ESPHome Wi-Fi 使用省电模式:

wifi:
  # ...
  power_save_mode: light

深度睡眠请参考:https://www.esphome.io/components/deep_sleep

具体效果请参考我发在B站上的视频(此账号目前已寄):https://www.bilibili.com/video/BV1Ri4y117Kk

4. HA端集成

在Home Assistant中添加ESPHome集成,自动发现设备,将实体添加至HA。

ESPHome添加实体

舵机对应的单色光灯和继电器开关对应的开关实体可以桥接至HomeKit。

二、Arduino开发智能开关

可以使用Arduino为ESP8266编程,使用高度封装的C或C++,详细的编程这里不介绍,可以参考: 太极创客-ESP8266-NodeMCU通过C/C++开发使用物联网

由于ESPHome与HA关系密切,使用更为简单,所以我最后的成品没有使用Arduino编程,以下引用自网络,仅供参考。

软件模拟PWM

案例:ESP8266/ESP01 软件输出PWM二极管调光(Arduino):https://www.cnblogs.com/cuianbing/p/14409053.html

B站的实例[^3]

将普通开关接到GPIO2Vcc之间。

定义了几个系统变量:

  • 继电器状态标识YYXBC_HIGHYYXBC_LOW (以后可用LED_ONLED_OFF代替)

  • 外部IO位置,物理开关与继电器

  • 物理开关工作模式

/*1,继电器高电平触发时,YYXBC_HIGH = 1,YYXBC_LOW  = 0
继电器低电平触发时,YYXBC_HIGH = 0,YYXBC_LOW  = 1 */
const int YYXBC_HIGH = 0 ;	//继电器是低电平触发
const int YYXBC_LOW  = 1 ;
//2,用esp-01时,物理开关接在vcc 和gpio2上,继电器接在gpio0上
//NodeMCU 继电器接D3 GPIO0,物理开关接D4 GPIO2
#define LED_BUILTIN_LIGHT 0
#define LED_BUILTIN_K2 2

/*3,物理开关点动模式1,自锁模式0*/
const int YYXBC_BUTTON_TYPE = 1;

开关响应:

//点动模式按钮,监听按钮状态,执行相应处理
void btnHandler1()
{
  static bool oButtonState = false;
  int state1 =  digitalRead(LED_BUILTIN_K2); //按钮状态
  int state2 =  digitalRead(LED_BUILTIN_LIGHT); //灯的状态
  if(state1 == HIGH )
  {
    if(oButtonState ){
      if(state2 == YYXBC_HIGH )
      { 
        button1_callback(BLINKER_CMD_OFF);
        Serial.println("按钮对灯已执行关闭");
      }else{
        button1_callback(BLINKER_CMD_ON);
        Serial.println("按钮对灯已执行打开");
      }
      oButtonState = false;
    }
  }else{
    oButtonState = true;
  }
}



//自锁模式按钮,监听按钮状态,执行相应处理
void btnHandler2()
{
 static bool is_btn = false;//按钮的标志位,用来逻辑处理对比,判断按钮有没有改变状态
  bool is = digitalRead(LED_BUILTIN_K2);   //按钮状态
  if ( is != is_btn)
  {
    bool is_led = digitalRead(LED_BUILTIN_LIGHT);
    digitalWrite(LED_BUILTIN_LIGHT, !is_led);
    if (is_led == YYXBC_HIGH)
    {
      button1_callback(BLINKER_CMD_OFF);
      Serial.println("按钮对灯已执行关闭");
    }
    else
    {
      button1_callback(BLINKER_CMD_ON);
      Serial.println("按钮对灯已执行打开");
    }
    is_btn = digitalRead(LED_BUILTIN_K2);  //更新按钮状态
  }

三、ESP32-CAM使用

安信可ESP32-CAM模块

安信可的ESP32-CAM对应的ESPHome默认配置如下所示[^4]

Configuration for Ai-Thinker Camera

# Example configuration entry
esp32_camera:
  external_clock:
    pin: GPIO0
    frequency: 20MHz
  i2c_pins:
    sda: GPIO26
    scl: GPIO27
  data_pins: [GPIO5, GPIO18, GPIO19, GPIO21, GPIO36, GPIO39, GPIO34, GPIO35]
  vsync_pin: GPIO25
  href_pin: GPIO23
  pixel_clock_pin: GPIO22
  power_down_pin: GPIO32

  # Image settings
  name: My Camera
  # ...

我烧录的配置文件为:

esphome:
  name: esp32-cam

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  reboot_timeout: 0s
ota:
  password: "1"

wifi:
  ssid: "blue_sky"
  password: "720805zzy"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp32-Cam Fallback Hotspot"
    password: "12345678"

captive_portal:


# Example configuration entry
esp32_camera:
  external_clock:
    pin: GPIO0
    frequency: 20MHz
  i2c_pins:
    sda: GPIO26
    scl: GPIO27
  data_pins: [GPIO5, GPIO18, GPIO19, GPIO21, GPIO36, GPIO39, GPIO34, GPIO35]
  vsync_pin: GPIO25
  href_pin: GPIO23
  pixel_clock_pin: GPIO22
  power_down_pin: GPIO32

  # Image settings
  name: My Camera
  # ...
  
# Flashlight
output:
  - platform: gpio
    pin: GPIO4
    id: gpio_4
light:
  - platform: binary
    output: gpio_4
    name: torch_light

# Binary Sensor
binary_sensor:
  - platform: gpio
    pin: GPIO13
    name: "次卧"
    device_class: motion

在Home Assistant上直接添加ESPHome设备即可。

通过ESPHome添加的摄像头有如下问题:

  • 无声音,HA上可查看串流

  • 桥接至HomeKit无法查看串流,只可查看10s更新一次的缩略图

  • 运动传感器可用,但貌似只有在光线变化剧烈时才会动作