ESPHome入门指引(伪)

hassbian的三木大做了斐讯DC1固件,于是乎买了两个来玩玩,开始接触了ESPHome,折腾下来有了一些心得,写点东西总结总结吧。由于接触时间有限,理解不一定准确,仅供参考。


1. 快速理解

1.1 刷固件三件套

以刷斐讯DC1固件为例,涉及三个项目。

  1. esphome
    • 项目地址:https://github.com/Samuel-0-0/esphome
    • 作用:基于python的ESPHome管理工具,负责编译、烧录固件。

      INFO:安装该项目会同时安装platformio依赖,platformio是一个8266开发板的开发环境。

  2. esphome-core
  3. platform-espressif8266

1.2 编译固件的步骤

  1. 建立配置文件
  2. esphome根据配置文件生成C++工程的配置文件
  3. esphome调用platformio的接口编译C++工程文件,生成.bin固件

1.3 烧录固件的姿势

  1. 线刷:接串口线烧录;可以用esphome run/upload命令(参数指定串口–device=/dev/ttyUSB0),也可以用esphome-flasher软件。
  2. OTA:使用TCP或者UDP通信刷机;可以用esphome run/upload命令,也可以用设备的web服务(配置文件启用web_server组件),也可以用Home Assistant的ESPHome集成服务。

    INFO:如果配置文件中没有给设备指定IP地址(静态IP或设置use_address属性),命令行OTA会尝试解析{NodeName}.local的IP地址。如果客户机没有mDNS服务是找不到IP的,要么安装mDNS服务(配合设备的mDNS服务工作);要么在hosts文件手动添加解析记录;如果电脑用的是路由器DNS服务,也可以在路由器上添加解析记录。

1.4 设备工作模式

ESPHome提供三种工作模式对设备进行控制.

模式 接入Home Assistant 所需编译配置 通信协议
ESPHome集成服务 Home Assistant 配置-集成-ESPHome,连接到设备后自动生成 api组件 ESPHome自有通信协议
MQTT Home Assistant启用mqtt的discovery自动发现、生成 mqtt组件 MQTT
RESTful API 自行开发 web_server组件 HTTP

WARN:api组件不能和mqtt组件一起使用。


2. esphome cli

介绍一下esphome命令行。

  • 编译
    1
    2
    # 编译生成固件文件
    esphome dc1.yaml compile

成功编译后会固件{CONFIG_DIR}/{NODE_NAME}/.pioenvs/{NODE_NAME}/firmware.bin

INFO:举个例子,有一个/esphome/dc1.yaml,里面设置的NODE_NAME(设备名称)是phicomm_dc1,则编译后固件路径在/esphome/phicomm_dc1/.pioenvs/phicomm_dc1/firmware.bin

  • 刷机

    1
    2
    # 如果带参数--device=/dev/ttyUSB0,则线刷;如果不带参数,则OTA:根据配置文件的静态IP或解析{NODE_NAME}.local的IP进行刷机
    esphome dc1.yaml upload
  • 编译+刷机

    1
    2
    # 就是编译+刷机,参数和刷机命令一样
    esphome dc1.yaml run

INFO:会同时进入日志输出界面。


3. 配置文件

和Home Assistant的配置文件类似,可以搭积木地自由启用组件,挑一些出来分析。

  • esphome组件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 核心配置
esphome:
name: $device_name # 设备名称,不能和其它设备重复
platform: ESP8266
board: $board_model
esphome_core_version: #指定esphome_core来源,如果只用latest、dev,则会从官方的项目下载。
#local: path/to/esphome-core #指定本地来源
repository: https://github.com/Samuel-0-0/esphome-core.git #指定外部来源,项目作用上面有介绍过
branch: dc1
build_path: build/$device_name # 编译路径,默认是{CONFIG_DIR}/{NODE_NAME}
esp8266_restore_from_flash: yes
arduino_version: 2.5.0
platformio_options:
platform: https://github.com/Samuel-0-0/platform-espressif8266.git#dc1 # 项目作用上面有介绍过

INFO:$device_name是使用了substitutions设定的变量。
INFO:编译后生成固件路径{build_path}/.pioenvs/{NODE_NAME}/firmware.bin

  • wifi组件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# wifi连接
wifi:
ssid: $wifi_ssid # wifi名称
password: $wifi_password # wifi密码
use_address: 192.168.178.230 # 指定烧录固件时候目标设备IP,优先级高于静态IP
# 设置静态地址,建议设置,根据自己网络配置
manual_ip:
static_ip: 192.168.178.230
gateway: 192.168.178.1
subnet: 255.255.255.0
dns1: 1.1.1.1
dns2: 1.2.2.1
domain: .local # 组合后设备主机名为{NodeName}.local,不设置默认就这个
reboot_timeout: $wifi_reboot_timeout # 无wifi连接自动重启时间,默认5min
power_save_mode: none # 节能模式,启用的话不会一直连接wifi
fast_connect: $wifi_fast_connect # 快速连接,不执行完整的wifi扫描,当存在多个相同wifi可能会直接连接到最弱的信号
  • ota组件
1
2
3
ota:
safe_mode: true # 连续10次启动失败,进入安全模式,只加载Serial Logging+WiFi+OTA组件
password: $ota_password
  • web_server组件
1
2
3
4
5
# web端,可以查看排查信息以及进行控制,另外新版可以OTA。
web_server:
port: 80 # web端口
css_url: https://esphome.io/_static/webserver-v1.min.css # css样式,不设置默认就这个,后续官方更新才用上。
js_url: https://esphome.io/_static/webserver-v1.min.js # js文件,不设置默认就这个,后续官方更新才用上。

INFO:会同时启用HTTP RESTful API。

  • api组件
1
2
3
# 本地api服务(esphome自己通信协议)
api:
reboot_timeout: $api_reboot_timeout # 无客户端访问设备API自动重启,默认5min

WARN:不使用Home Assistant的集成服务管理设备的话不要启用改配置,否则会导致不断定期重启。

1
2
3
4
# 日志组件
logger:
# hardware_uart: UART1 # 串口调式,不懂
level: info # 日志等级,默认DEBUG,平常用设置INFO

INFO:启用mqtt后,通过订阅{topic_prefix}/debug也可以获取日志。


4.mqtt模式

ESPHome中大部分组件都能叠加mqtt功能直接使用,只需要相应的配置即可。

4.1配置项说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# mqtt功能
mqtt:
broker: 192.168.0.1 # mqtt服务器ip/域名
username: mosquitto # 账号
password: 123 # 密码
#-------------------------------#
birth_message: # 连接通知,设备发起
topic: phicomm_dc1/state # 默认{TOPIC_PREFIX}/status
payload: online # 默认通知online状态
will_message: # 离线通知,由mqtt服务器发起
topic: phicomm_dc1/state # 默认{TOPIC_PREFIX}/status
payload: offline # 默认通知offline状态
# 如果不设置,默认就是如上配置;如果birth_message、will_message的topic为空或不一样,则不生效。
#-------------------------------#
topic_prefix: phicomm_dc1 # 不设置默认{NodeName}
discovery: True # 发现标记设置(全局)
discovery_prefix: homeassistant # 配置数据topic,默认homeassistant,要与Home Assistant的mqtt组件设置保持一直(默认也是homeassistant)

WARN:mqtt组件不能和api组件一起使用。

1
2
3
4
5
6
7
8
9
# 组件的mqtt配置
switch: # 组件类型,对应topic中的{COMPONENT_TYPE}
- platform: gpio
pin: GPIO14
#LOGO灯
name: "${device_name} LOGO_light" # 组件名称对应topic中的{COMPONENT_NAME}
id: LOGO_light
internal: false
inverted: true
1
2
3
4
5
6
7
8
9
# 启用MQTT组件后,其它的大部分组件都拥有以下可选属性
retain: True # state_topic消息保持,默认True
discovery: True # 如果不设置,取mqtt组件的discovery属性
availability: # 不设置取mqtt组件的birth_message、will_message属性
topic: livingroom/status
payload_available: online
payload_not_available: offline
state_topic: livingroom/custom_state_topic # 不设置默认{TOPIC_PREFIX}/{COMPONENT_TYPE}/{COMPONENT_NAME}/state
command_topic: livingroom/custom_command_topic # 不设置默认{TOPIC_PREFIX}/{COMPONENT_TYPE}/{COMPONENT_NAME}/command

INFO:如果设置internal: True属性隐藏,则不会通过mqtt上报。
INFO:一些不可控组件例如text_sensor,是没有command_topic的。

4.2实际使用样例

只需增加mqtt,其它保持默认即可。

1
2
3
4
5
# api: # 需要取消api组件
mqtt:
broker: 192.168.0.1 # mqtt服务器ip/域名
username: mosquitto # 账号
password: 123 # 密码

假设设备名称{NodeName}为phicomm_dc1,则LOGO灯的topic如下,其它槽位开关的topic不在赘述。

1
2
3
4
# state_topic
phicomm_dc1/switch/phicomm_dc1_logo_light/state
# command_tpoic,payload设置ON/OFF进行打开/关闭操作
phicomm_dc1/switch/phicomm_dc1_logo_light/command

INFO:如果自定义了新topic,需要执行esphome dc1.yaml clean-mqtt命令清除mqtt服务器的信息。

最后Home Assistant中启用mqtt服务。

1
2
3
4
5
6
7
# 注意这个是Home Assistant的configuration.yaml
mqtt:
broker: 192.168.0.1
username: mosquitto
password: 123
discovery: True # 启用主动发现
discovery_prefix: homeassistant # 不设置默认就这个,要和ESPHome的一致


5.小结

  • 为更深入了解ESPHome,想自行搭建了环境再编译固件,结果发现教程里esphome项目放错了链接,折腾了好久,找官方的docker研究了才知道原来有个esphome工具。
  • 因为本人是更偏向与用mqtt接入的,原固件没有相关教程,本来想研究下代码直接把mqtt功能给加上去的,不过发现有点难看懂C++,硬件编程经验太少。后来查看官方文档,发现其实只要简单配置下就能用了。
  • 配置调试mqtt期间,发现增加属性后编译报错,查看相关源码发现esphome cli有对配置文件解析成cpp文件的过程,才对整体的流程以及相关工具的分工更加明晰了。