HomeAssistant与ESP32
Table of contents
前言¶
因为突然对智能家居很感兴趣, 稍微 折腾了一下
Home Assistant¶
Home Assistant是一个用Python实现的开源智能家居平台,着眼于不依赖于云服务的离线智能家居。有赖于社区动力, 主流智能家居供应商的产品大多可接入Home Assistant管理。许多开源家居智能化方案也接入了Home Assistant。 就不过多介绍了。
Tasmota¶
简介¶
Tasmota是一个ESP32/ESP8266平台的开源固件,通过MQTT或HTTP API进行数据交互。 它将各个平台抽象为一系列模板,用统一的固件+硬件模板配置适配了各种各样的商业产品。 比如我手上的小米米家台灯1S,就可以刷成Tasmota固件。
通过其内置的三种脚本系统(rules,scripts,berry scripts)可以实现很多复杂的功能,例如 联机自动注册设备、自动上报数据、自动触发某一长时间运行的流程。
想在Home Assistant Core中接入Tasmota,只要自己搭建好MQTT服务器、启用MQTT和Tasmota集成, 再配置好Tasmota设备接入即可。
实例:Tasmota+人体传感器+HASS¶
鉴于很多传感器都不需要多少配置就能无缝整合入Home Assistant,这里介绍一个需要一点操作的案例。
人体传感器,简单版,参考下列资料
- https://tasmota.github.io/docs/PIR-Motion-Sensors/
- https://tasmota.github.io/docs/Rules/
- https://www.home-assistant.io/integrations/mqtt
步骤概要:
- 配置Tasmota中检测信号的GPIO
- 配置Tasmota中对应的自动化规则
- 在Home Assistant中配置相关设备集成
首先是人体传感器信号检测。这里使用HLK-LD2410传感器,其支持已加入Tasmota 12.3.1,不过下面做的其实和所谓支持关系不大。
LD2410提供了一个OUT信号脚,在检测到人体时是高电平,一段时间未检测到人体后就变为低电平。将OUT与ESP32的某个GPIO
(下称GPIOx)相连,在Tasmota配置页面进入 Configuration
→ Configure Module
,将对应的GPIOx设置为Switch,并分配一个闲置ID。
下面假设这个Switch的ID是1。
Note
Switch的ID无所谓,只要选空闲的就好。后面的指令需要将对应命令、Switch1等字串末尾的1改成对应ID。默认情况下,Switch会控制ID相同的灯。
进入 Consoles
→ Console
,设置对应Switch模式,关闭其开关相同编号设备的作用,同时关闭开关对应的MQTT消息。
SwitchMode1 1
SwitchTopic 0
给Tasmota配置一个自动化规则,在信号发生变化的时候发送MQTT消息,在连接到MQTT服务时向Home Assistant注册该传感器。
rule1
on Switch1#state=1 do publish stat/%topic%/PIR1 ON endon
on Switch1#state=0 do publish stat/%topic%/PIR1 OFF endon
on mqtt#connected do publish2 homeassistant/binary_sensor/presence_%deviceid%/config { "name": "Presence Sensor", "object_id": "presence_%deviceid%", "device_class": "presence", "state_topic": "stat/%topic%/PIR1"} endon
rule说明
rule有三个存储空间,分别为rule1、rule2、rule3。其中每个空间至少可以存储1000字节的指令,考虑到压缩,可能会更多。 rule1后面的1 不用 和对应开关的ID一致!
Note
在终端输入上述指令时注意合并成一行!
下面提供另外一种写法,不过根据配置不同,数据刷新可能不够及时
rule1
on mqtt#connected do publish2 homeassistant/binary_sensor/presence_%deviceid%/config { "name": "Presence Sensor", "object_id": "presence_%deviceid%", "device_class": "presence", "state_topic": "tele/%topic%/SENSOR", "value_template": "{{ value_json.Switch1 }}"} endon
接下来启用rule1,保存配置并重启
rule1 1
restart 1
最后便可以在Home Assistant的实体注册表找到名为“Presence Sensor”的人体存在检测设备了。 通过复杂一点的脚本,还能实现人体动态与静态的检测,当然这就需要启用LD2410传感器对应的支持以利用串口数据了。
ESPHome¶
架构介绍¶
就我目前所知,ESPHome的设计大致如下:
- 所有ESPHome设备的固件由一组ESPHome程序(Dashboard或CLI)根据给出的设备配置(YAML)生成
- 算是一揽子服务(配合PlatformIO CLI)
- 初见比较难hack
- YAML解析有一些特殊语法
- 每个ESPHome设备可以独立运行,不依赖面板/Dashboard
- 面板只有UI/UX变了
- CLI有提供指引系统,但是支持的开发板数量较少,如果一开始就要使用不支持的开发板会比较困难
- 固件可以通过USB安装,HTTPS连接dashboard的情况下可以用Web USB给ESP32编程
- Home Assistant通过约定的API接口与ESPHome设备交互数据,需要在设备配置YAML中写一行
api:
开启API
(不得不说这个项目的文档很不适合我,很难检索到所需的资料)
也就是说,ESPHome包括编译系统和边缘设备两部分。
使用Python虚拟环境准备ESPHome部署环境¶
鉴于官网已经花费了大量篇幅从一开始就为Home Assistant和Docker用户介绍了对应的使用方法,这里将 完整地介绍一遍不使用Docker、Home Assistant插件来使用ESPHome的流程。
前面说过,ESPHome把相关工作都包揽了,这里只需要构建一个虚拟环境作为工作空间就好。 构建虚拟环境可以使用下面的指令。
# 创建虚拟环境
python3 -m venv esphome-venv
# 激活虚拟环境
source esphome-venv/bin/activate
虚拟环境的pypi镜像与代理配置
可以直接在虚拟环境文件夹(上例中是 esphome-venv
)内新建一个pip.conf,在其中添加对应配置,例如使用阿里云的pypi源:
[global]
index-url = https://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host=mirrors.aliyun.com
接下来随意创建一个保存YAML的文件夹作为工作空间便可以了。
实例:使用LuatOS-CORE-ESP32C3开发板制作低功耗蓝牙(BLE)网关¶
参考了下列资料:
- https://digiblur.com/wiki/ha/esphome-bluetooth-proxy-esp32c3/
- https://esphome.io/components/display/index.html
- https://esphome.io/components/display/st7735.html
激活虚拟环境,在你的配置保存文件夹内编写如下YAML,保存为 ble-gateway.yaml
。
substitutions:
display_name: core-esp32c3-btproxy
esphome:
name: ${display_name}
platformio_options:
board_build.mcu: esp32c3
board_build.variant: esp32c3
esp32:
variant: ESP32C3
board: esp32dev
framework:
type: esp-idf
sdkconfig_options:
CONFIG_BT_BLE_50_FEATURES_SUPPORTED: y
CONFIG_BT_BLE_42_FEATURES_SUPPORTED: y
CONFIG_ESP_TASK_WDT_TIMEOUT_S: "10"
logger:
api:
ota:
button:
- platform: safe_mode
name: ${display_name} (Safe Mode)
# 记得改WiFi和密码
wifi:
ssid: "Your SSID"
password: "Your secret password"
#manual_ip:
# static_ip: !secret ip_esp32c3_btproxy
# gateway: !secret ip_gateway
# subnet: !secret ip_subnet
# dns1: !secret ip_dns1
esp32_ble_tracker:
scan_parameters:
# 可能需要调参
# interval: 1100ms
# window: 1100ms
active: true
bluetooth_proxy:
active: true
#### 下面是给显示器模块配置的 ###
# 五个按钮
# 由于 ESPHome 把 GPIO12、GPIO13强制占用了(原本控制Flash的),所以有一个按钮不能用。
binary_sensor:
- platform: gpio
name: "Up Button"
pin:
number: GPIO9
inverted: true
mode:
input: true
pullup: true
- platform: gpio
name: "Down Button"
pin:
number: GPIO5
inverted: true
mode:
input: true
pullup: true
- platform: gpio
name: "Left Button"
pin:
number: GPIO8
inverted: true
mode:
input: true
pullup: true
# - platform: gpio
# name: "Right Button"
# pin:
# number: GPIO13 # this pin is spared on CORE-ESP32C3
# inverted: true
# mode:
# input: true
# pullup: true
- platform: gpio
name: "Center Button"
pin:
number: GPIO4
inverted: true
mode:
input: true
pullup: true
# 显示器SPI
spi:
clk_pin: GPIO2
mosi_pin: GPIO3
# 来点显示的东西
# 可惜写这个的时间貌似还没支持
#time:
# - platform: sntp
# id: sntp_time
font: # 字体需要自己拷贝一份哦,下面是相对于该配置文件的位置
- file: "fonts/iosevka-regular.ttf"
id: my_font
# display ST7735
display:
- platform: st7735
model: "INITR_MINI160X80"
reset_pin: GPIO10
cs_pin: GPIO7
dc_pin: GPIO6
device_width: 80
device_height: 160
col_start: 0
row_start: 0
use_bgr: true
lambda: |-
it.print(0, 1, id(my_font), "Hello");
it.print(0, 22, id(my_font), "World!");
// it.strftime(0, 35, id(my_font), "%Y-%m-%d %H:%M", id(sntp_time).now());
接上设备,执行下面的命令刷机,就可以在Home Assistant里配置了。
esphome run ble-gateway.yaml --device=/dev/ttyACM0
Warning
记得先激活虚拟环境!