智能家居。我的理解是:智能的、易用的,能给生活提供极大便利的,才能称之为「智能家居」。

大家好,我是少数派新晋 Martix 作者,目前从事主要以政府项目为主的运营。作为我在少数派潜水多年后的第一篇内容,就是如何利用极低的成本打造属于你的智能家居。

内容背景

本文将以「Home Assistant」智能家居平台(简称 「Home Assistant」,下同),开展工作,并通过 iOS 的 HomeKit 及 Android 自身的设备管理器来控制智能家居配件。关于「Home Assistant」的详细介绍,如何部署及安装插件的教学,少数派已有前辈进行了详细说明,这里不再赘述。

需强调的是,笔者通过 Debian 10 进行部署,版本是 2022.3.8,预装插件与其他方法略有出入。

由于系统过于老旧,「Home Assistant」的 Home Assistant Supervisor 不再支持 Debian 10 ,但使用下来,似乎实际上没有影响。

重复造轮子?

既然前辈已经在少数派中发表了基于「Home Assistant」构建的「智能家居」内容,为何笔者仍然要以此作为在少数派的第一篇内容?不是前辈撰写的内容不好,只是内容方向不同,本文将基于 YAML 语言来定制属于自己的「智能家居」。

本文将尽可能使用通俗的语言,力求做到即使每一位读者未曾接触也不能理解 YAML 语言的情况下能码出自己想要的配置文件,但由于笔者对 YAML 语法也未能做到了然于胸,更多地是一边学习一边进行,涉及到变量的部分无可奉告。

自身情况及案例

自身情况

笔者家中由于入网设备较多,以及需要多网合并带宽等需求,传统路由器性能已无法达到笔者需求,因此家中有一台低功耗服务器作为软路由使用,部署在 VMware 虚拟机中。

所使用网络基于中国电信,配备有公网非固定 IP 和动态域名。

自身案例

以往,每天开车出门以及回家都需要经过好几条钥匙及遥控器。现在通过「Home Assistant」,实现车库和楼宇门禁开关智能家居化,只动口不动手。

动手准备

感谢你耐心看完以上内容,也是为了让读者更好地了解笔者的实际情况,并贴合自身实际情况进行开展。

在安装「Home Assistant」后,我们需要安装「ESPHome」插件和「HomeKit」集成。无需理解插件与集成的区别,只需要按部就班去进行即可。

关于 ESPHome

「ESPHome」是一个通过简单而强大的配置文件控制来ESP8266/ESP32开发板,并通过家庭自动化系统远程控制它们的插件。

你可以在左侧栏找到「配置」按钮,在主页面看到「加载项、备份与 Supervisor」设置

在右下方点击「加载项商店」,搜索 「ESPHome」并安装,勾选「在侧边栏显示」选项。

关于「HomeKit」

这里的「HomeKit」指的是「Home Assistant」中的 HomeKit 集成。用于让「Home Assistant」能够控制以及让非 HomeKit 配件支持 HomeKit 功能。

你可以在左侧栏找到「配置」按钮,在主页面看到「集成与服务」设置

在右下方点击「添加集成」,搜索 「HomeKit」并安装。

勾选「要包含的域」(想要使用的设备)选项,选择提交即可。

列表参考如下表,本案例仅使用 Binary sensor (传感器)、Switch(开关)

你也可以从  「Home Assistant」的 「HomeKit」官方文档 中看到完整的列表及详细说明。

设备类型设备名称设备说明
Binary sensor传感器用于检测和反馈车库门开闭状态
Switch开关用于控制车库门与楼宇门禁的开关

补充

「HomeKit」与「HomeKit 控制器」的区别在于:

前者是让非 HomeKit 配件转变成 HomeKit 配件。即米家等非 HomeKit 设备转 HomeKit 配件;

后者是让 HomeKit 配件转变成 「Home assistant」配件。即 HomeKit 设备也能让非 iOS 设备兼容。

购买设备

为了防止你买了设备后却无法完成上述步骤造成浪费资金,因此所需购买的设备在这里才写出来。

接下来,你需要购买的设备包括:

必须

  1. ESP8266 或 ESP32 开发板(简称开发板,下同)
  2. ESP 继电器模块(简称继电器模块,下同)
  3. CH341 编程器(简称烧录器,下同)
ESP8266
继电器(图中是 ESP8266 和 三路继电器的组合)
烧录器及杜邦线

部分卖家提供以上三个设备的套装购买。

可选

  1. 闲置的、长期在家中的 iPad1 或 HomePod 及 Apple TV 用作 iOS / iPad OS 设备能在 4G/5G 下控制配件的中枢系统。
  2. 门磁传感器(常闭或常开均可),用于反馈配件情况。
iPad 用作中枢
门磁传感器

说明

 

  1. 笔者所使用的开发板为基于 ESP8266 系列的 ESP01 以及 ESP-12F,继电器模块分别为具有一路(用于控制楼宇门禁)和三路(用于控制车库门)的继电器模块。
  2. 关于 ESP8266开发板的详细信息,可以参考 安信可 关于 ESP8266 系列官方文档,尽管该系列开发板有不同的型号,但主要体现在于性能,本文所需要的性能即使是最基础的型号 ESP01 也能做到。
  3. 需要注意的是,ESP01S 与 ESP01 不同之处在于前款型号电阻进行了内部上拉,但由于笔者自身案例与电阻是否上拉和下拉均无关系。
  4. 常见用于「Home Assistant」的开发板有 ESP8266 和 ESP32 ,他们的区别可以在 安信可 官网中找得到,但需要注意的是,由于引脚的定义不同,在「ESPHome」配置页面中务必选择正确,否则可能造成开发板烧毁乃至配件损坏。像一些二次开发的开发板,例如 Sonoff 易微联 这些也应当选择对应设备类型。
  5. 选择强电(220V)输入的继电器模块请在有电气专业人士的陪同下和断电下进行操作,否则可能造成触电危险。

开始动手

设备准备

当你的开发板以及烧录器到手后,此时你的开发板与 「ESPHome」没有任何的联系,你需要编写 YAML 配置来让你的开发板与「ESPHome」携手合作。

关于开发板与「ESPHome」的逻辑关系,可以通过下图来理解

作者:XCary ,出处:玩ESPHome必须明白的基本逻辑关系,再看不懂就趁早别玩了!

其原理通过文字描述就是:

  1. 通过「ESPHome」给开发板「刷机」,让开发板与「ESPHome」之间能够沟通
  2. 「ESPHome」反馈信息给「Home Assistant」和,告诉「Home Assistant」我这里有一块开发板设备可以通过「ESPHome」来联动「Home Assistant
  3. 用户通过手机、平板等设备连接「Home Assistant」控制「ESPHome」的配件

理解以上的内容和完成相应步骤后,即可开始关键步骤。

第一步:创建设备

回到「Home Assistant」页面,在左侧栏找到「ESPHome」,在右上方,有一个「Secrets」按钮,用于配置开发板需要连接的 Wi-Fi 

请注意,根据 安信可 关于 ESP8266 系列官方文档得知,该系列仅支持连接 2.4Ghz 的Wi-Fi。内容按照下方的格式进行填写即可。

点击「Save」 来保存你的 Wi-Fi 配置。

随后点击右下方的「NEW DEVICE」按钮,点击「Continue」进入为设备命名步骤,命名规则是只允许英文 a~z、数字0~9以及横杠「-」,输入名称后,点击「NEXT」进入设备型号选择。

笔者的 ESP-12F 开发板尽管同属 ESP8266 系列,但其部分参数与常规 ESP8266 系列开发板略有出入,需要点击 「Pick specific board」来选择设备型号。尽管列表中没有 ESP-12F 型号,但从 安信可 关于 ESP8266 系列官方文档得知,ESP-12F 与 ESP-12E 的参数是相似的,同时也是「ESPHome」推荐的替代选择

此时,页面提示你完成了创建设备的步骤,但实际上还需要修改配置才能给 ESP8266 刷入固件。

为了让开发板支持 OTA 升级、在线读取日志等功能,你还需要进行以下修改。代码的下方为注释。

esphome:

 name: 设备名称

#在命名步骤为设备命名的名称,无需修改。

esp8266:

 board: esp12e

#开发板型号,无需修改,若要更换型号,例如 ESP8266 系列更改为 ESP32 系列,一定要修改为 ESP32 ,否则可能会因针脚引用错误导致设备损坏。

api:

#设备接口,留空,无需修改。

ota:

#让设备支持 OTA 功能

 password: "*"

# OTA 的密码,保持自动生成,无需修改。

wifi:

 ssid: !secret wifi_ssid

 password: !secret wifi_password

# Wi-Fi 的 SSID 及 密码,这里的「!secret wifi_ssid」和「!secret wifi_password」表示自动引用刚才在 Security.yaml 填写的 Wi-Fi SSID 和密码,无需修改。

logger:

 level: DEBUG

#开启日志输出功能,输出内容级别为 Debug 模式。

web_server:

 port: 80

#让设备开启网页功能

 css_url: https://esphome.io/_static/webserver-v1.min.css

 js_url: https://esphome.io/_static/webserver-v1.min.js

# Enable Home Assistant API

captive_portal:

自此你就可以进行点击 Save 来保存配置文件,随后进行烧录器和开发板的连接,并插入到电脑的 USB 接口中。

因为是基于网页刷入的,连接的电脑无须是 「Home Assistant」宿主机。这个过程只需要浏览器安装烧录插件,并且将烧录器插入实际操作的电脑 USB 端口当中即可。

烧录器与开发板的连接

如果你的开发板是只有针脚,那么直接将开发板插入烧录器即可;

 

但有些开发板与继电器合为一体,可能没有直接引出的针脚,这时候需要在开发板与烧录器之间使用杜邦线来辅助连接。

由于笔者手上没有引脚的继电器已经部署在车库门中,这里只能文字解释,实际上并不难理解。

我们从开发板背面上能看到,从上至下分别是 RXD(接收端)、TXD(发送端)、RST(重置端)、引脚01(GPIO 01)、正极 3.3V、GND(接地)。同样,这样的接口在烧录器上也能看得到,我们只需要使用杜邦线按照同样的顺序,如开发板上的 3.3V 接在 烧录器上的 3.3V 即可。

给开发板烧录固件所需连接的端口分别是:3.3V、GND、RST、引脚01、TXD、RXD。

需要注意的是: 部分的烧录器 TXD RXD 需要反接,即开发板上的 TXD 接在 烧录器的 RXD 上,你可以询问卖家是否需要这么做, 但笔者手上的烧录器由于已经出厂时默认反接,无需由笔者进行反接。

代码部分

下面,我们可以在配置文件中针对自己的内容进行配置了

关于针脚的位置,通常开发板背面会标注。

 

从图中得知,这是一个三路继电器,其继电器的针脚分别是:

1号继电器对应 GPIO 04 针脚

2号继电器对应 GPIO 13 针脚

3号继电器对应 GPIO 15 针脚

这里以笔者的车库门案例作为示例。

switch:

#继电器的设备类型定义为 Switch 开关,关于设备类型请参考代码后的引用。

 - platform: gpio

#接口类型为 GPIO (大多数都是)

   pin: 04

#定义需要用到的针脚为04

   name: "Garage Door Open Switch"

#赋予该开关名称为: Garage Door Open Switch

   id: open_switch

#定义该开关的ID,需要唯一

   on_turn_on:

#表示执行A操作后,自动执行B操作。

#贴近案例地说明也就是:

#通常情况下,以往按下车库门的遥控器的任何开关操作都只需要短按一次

#车库门的开启和关闭不可能同时执行。

#在按下开启按钮后,并不需要「开启车库门」一直保持短接状态

#需要的是「开启车库门」短接后,自动关闭

   - delay: 0.1s

#按下「开启车库门」后,自动进行下一条代码的操作

   - switch.turn_off: open_switch

#执行「开启的继电器」操作后,自动关闭「开启的继电器」

#至此,定义Switch的页面结束

cover:

#Cover的定义开始,告诉「Home Assistant」它是什么设备,想要怎样的控制组件。

 - platform: template

#平台从模板中选择

   device_class: Garage

#表示该设备是车库门,关于Device Class设备类型可以参考代码后的引用。

#需要注意的是,如果需要在 CarPlay 中控制车库门的关闭,需要定义为 Garage

#若定义为诸如 Door 或者 Lock 等设备类型,无法在 CarPlay 中显示,其图标也有错误

   name: "Garage Door"

#定义该设备的名称为 Garage Door

   open_action:

#打开动作的定义

     - switch.turn_off: close_switch

#重置继电器的状态

     - switch.turn_on: open_switch

#告诉「Home Assistant」的车库门控制组件,打开车库门的指令对应 Switch 的哪一个动作

     - delay: 0.1s

# 0.1 秒后执行某个动作

     - switch.turn_off: open_switch

# 0.1 秒后恢复 打开动作 的状态为关闭

以上是所需用到的 Switch (开关)和 Cover(控制组件) 代码解释,由于 Switch 代码中开、关、停是近乎一样的,只需要略作修改(具体请看完整代码部分)

完整代码如下

esphome:

 name: sspai-test

esp8266:

 board: esp12e

# Enable Home Assistant API

api:

ota:

 password: "*"

wifi:

 ssid: !secret wifi_ssid

 password: !secret wifi_password

 # Enable fallback hotspot (captive portal) in case wifi connection fails

switch:

 - platform: gpio

   pin: 04

   name: "Garage Door Open Switch"

   id: open_switch

   on_turn_on:

   - delay: 0.1s

   - switch.turn_off: open_switch

 - platform: gpio

   pin: 15

   name: "Garage Door Close Switch"

   id: close_switch

   on_turn_on:

   - delay: 0.1s

   - switch.turn_off: close_switch

 - platform: gpio

   pin: 13

   name: "Garage Door Stop Switch"

   id: stop_switch

   on_turn_on:

   - delay: 0.1s

   - switch.turn_off: stop_switch

cover:

 - platform: template

   device_class: Garage

   name: "Garage Door"

   open_action:

     # Cancel any previous action

     - switch.turn_off: close_switch

     # Turn the OPEN switch on briefly

     - switch.turn_on: open_switch

     - delay: 0.1s

     - switch.turn_off: open_switch

   close_action:

     - switch.turn_off: open_switch

     - switch.turn_on: close_switch

     - delay: 0.1s

     - switch.turn_off: close_switch

   stop_action:

     - switch.turn_off: open_switch

     - switch.turn_off: close_switch

     - switch.turn_on: stop_switch

     - delay: 0.1s

     - switch.turn_off: stop_switch

   optimistic: true

   assumed_state: true

   #inverted: True

# Enable logging

logger:

 level: DEBUG

web_server:

 port: 80

 css_url: https://esphome.io/_static/webserver-v1.min.css

 js_url: https://esphome.io/_static/webserver-v1.min.js

# Enable Home Assistant API

captive_portal:

如果你不需要车库门停止按钮(或是具备4路继电器),可以考虑将停止按钮(Garage Door Stop Switch部分)作为门磁传感器设备使用。

门磁传感器的原理是:当磁铁与感应器接触时,传感器电路导通,否则处于非导通状态。具体的代码如下:

binary_sensor:

#定义继电器设备类型为传感器

 - platform: gpio

#接口类型为 GPIO (大多数都是)

   pin: 13

#使用的继电器针脚是13

   device_class: Garage_door

#定义设备类型为车库门,这样可以与车门开关进行联动

   filters:

#使用过滤器配置

   - delayed_on: 500ms

#如果门磁传感器处于导通,且导通时长超过 500 毫秒的话就视为确实导通状态

   name: "车库门状态传感器"

#定义该传感器名称为 车库门状态传感器

具有车库门开关以及车库门状态反馈完整代码如下

esphome:

 name: cheku2

esp8266:

 board: esp12e

# Enable Home Assistant API

api:

ota:

 password: "*"

wifi:

 ssid: !secret wifi_ssid

 password: !secret wifi_password

 

 # Enable fallback hotspot (captive portal) in case wifi connection fails

switch:

 - platform: gpio

   pin: 04

   name: "Garage Door Open Switch"

   id: open_switch

   on_turn_on:

   - delay: 0.1s

   - switch.turn_off: open_switch

 - platform: gpio

   pin: 15

   name: "Garage Door Close Switch"

   id: close_switch

   on_turn_on:

   - delay: 0.1s

   - switch.turn_off: close_switch

 - platform: gpio

   pin: 13

   name: "garage door status sensor"

   id: status_sensor

cover:

 - platform: template

   device_class: Garage

   name: "Garage Door"

   open_action:

     # Cancel any previous action

     - switch.turn_off: close_switch

     # Turn the OPEN switch on briefly

     - switch.turn_on: open_switch

     - delay: 0.1s

     - switch.turn_off: open_switch

   close_action:

     - switch.turn_off: open_switch

     - switch.turn_on: close_switch

     - delay: 0.1s

     - switch.turn_off: close_switch

   optimistic: true

   assumed_state: true

   #inverted: True

binary_sensor:

- platform: gpio

  pin: 13

  device_class: Garage_door

  filters:

  - delayed_on: 500ms

  name: "车库门状态传感器"

# Enable logging

logger:

 level: DEBUG

 

web_server:

 port: 80

 css_url: https://esphome.io/_static/webserver-v1.min.css

 js_url: https://esphome.io/_static/webserver-v1.min.js

# Enable Home Assistant API

captive_portal:

这时候你就可以点击 Save 来保存了

保存成功提醒

看到 Saved 配置名称.yaml 即为成功保存,否则你应该检查一下配置文件在语法上或代码配置出现了问题。

因大小写不一致导致报错

像符号错误,id 值和对应的引用值的英文大小写不一致都会出现报错。

现在,你可以点击生成的配件的右侧按钮进行开始编译开发板固件了

点击 Install

选择 Manual download 

选择 Modern format,对开发板固件进行编译。

编译时长大约 1-3 分钟,视 Home Assistant 宿主机的配置决定。

编译完成后,浏览器会自动下载 Bin 固件文件。

 

再次点击配件右侧按钮,选择 Install 

选择 Manual download

选择 Open ESPHome Web 进入网页刷写固件模式

首次刷入给开发板刷入固件需要安装 CH341 烧录器驱动。

由于我已经安装了 CH341 烧写器的驱动,因此可以成功显示

点击 Connect 按钮,弹出选择 USB 端口,然后直接按键盘上的 ESC 按键取消选择。

此时会提示没有连接到支持的端口,下方会列出 CH341 烧写器驱动的下载链接。 你也可以点击超链接直接进入下载。

跳转到 Github 后,选择对应的操作系统即可下载驱动,按照安装向导进行安装即可。

重新刷新Open ESPHome Web 固件刷入页面,按照前部分连接烧录器即可。

Open ESPHome Web 固件刷入页面与烧录器连接成功后,右上角会标注 Connected

单击 INSTALL 选择 BIN 固件

选择固件后,单击 INSTALL 进行安装。

刷写过程
刷入成功提示

刷写完成后,会弹出窗口提示已经刷入成功。

这里以我正在使用的开发板作示例

这时候,回到 ESPHome 页面,我们会发现刚刚刷写的开发板已经成功被 ESPHome 所识别并连接。

Home Assistant 主页

在 Home Assistant 的主页中,点击右侧的开关按钮,继电器发出声音时,即表示电路成功导通,如果身边有万用表,也可以通过导通模式测量是否导通。

最后,只需要将开发板继电器断开,独立给继电器供电。

实装部分

勘测线路

笔者的住宅是建于千禧年前后,其楼宇门禁是老式门禁,只具备贴片编码功能,开门的操作,仅仅是短接其中两条线即可。

笔者的楼宇门禁线路板

经过万用表测量,红线为 +12V 、黑色为负极、绿色与黄色线为通话线,其中红线与绿色为开门键,那么只需要短接红、绿即可(这里必须强调的是笔者的线路仅仅作为参考)

假设在编写 YAML 配置过程中,定义开关的线路为 GPIO4 ,那么只需要将门禁的开门键线路接入到 GPIO4 对应的 继电器1号的常闭即可。

 配置 HomeKit

在配置 HomeKit 实现 iDevices 控制设备的文章已经由前辈说明,这里不再赘述。

小结

  1. 在部署 Home Assistant 的过程中,踩过不少坑,感谢来自各位大佬的视频教学;
  2. 作为在少数派的第一篇 Martix 文章,代码部分少许晦涩,希望大家多多提出文章编写意见;
  3. 成本大小并非重点,重要的是通过这种折腾来提升自己的动手能力。