深入理解Home Assistant MQTT:配置、自动化、发布等
MQTT
MQTT(也称为MQ遥测传输)是一种建立在TCP/IP之上的物联网连接协议,用于支持轻量级发布/订阅消息传输。
配置
要将MQTT集成添加到您的Home Assistant实例,使用以下“我的按钮”:
手动配置步骤
如果上面的“My按钮”不起作用,您还可以手动执行以下步骤:
- 浏览到您的Home Assistant实例。
- 转到 设置 > 设备和服务。
- 在右下角,选择“添加集成”按钮。
- 从列表中选择MQTT。
- 按照屏幕上的说明完成设置。
让MQTT和Home Assistant配合的第一步是选择一个代理(broker)。
选择MQTT代理
运行您自己的
最私密的选项是运行您自己的MQTT代理。
建议的设置方法是使用Mosquitto MQTT代理插件。
注意
不支持ActiveMQ MQTT代理和RabbitMQ MQTT插件,应使用已知工作的代理,如Mosquitto。ActiveMQ MQTT代理存在至少两个问题,会破坏MQTT消息保留。
使用公共代理
Mosquitto项目运行一个公共代理。这是最简单的设置方法,但由于所有消息都是公开的,因此没有隐私性。只应用于测试目的,不用于实际跟踪设备或控制家庭。要使用公共Mosquitto代理,请将MQTT集成配置为连接到测试test.mosquitto.org代理,端口为1883或8883。
代理配置
MQTT代理设置是在首次设置MQTT集成时配置的,以后如果需要可以更改。
添加MQTT集成,然后提供您的代理主机名(或IP地址)和端口,以及(如果需要)Home Assistant应该使用的用户名和密码。要稍后更改设置,按照以下步骤操作:
- 转到设置 > 设备和服务。
- 选择MQTT集成。
- 选择配置,然后重新配置MQTT。
注意
如果出现错误消息,如“Failed to connect due to exception: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed”,然后打开高级选项,将代理证书验证Advanced options设置为Auto。
高级代理配置
高级代理配置选项包括设置自定义客户端ID、为身份验证设置客户端证书和密钥,以及启用代理证书的TLS验证。要访问高级设置,打开MQTT代理设置,打开高级选项Advanced options,然后单击“下一步Next”。如果已经存在高级设置,则高级选项将默认显示。
注意
高级代理选项仅在启用高级模式(请参阅用户设置)或已配置高级代理设置时才可访问。
默认客户端ID
您可以设置自定义的MQTT客户端ID,这在调试时很有帮助。请注意,客户端ID必须是唯一的。如果希望Home Assistant生成唯一ID,请保留此设置的默认值。
保持活动时间
在此客户端发送保持活动消息之间的时间,以秒为单位。默认值为60秒。保持活动设置应至少为15秒。
代理证书验证
要启用安全代理,必须验证代理证书。如果您的代理使用受信任的证书,选择自动Auto。这将允许根据捆绑的证书验证CA。如果使用自签名证书,请选择自定义Custom。可以上传自定义PEM编码的CA证书。单击“下一步NEXT”以显示上传CA证书的控件。如果服务器证书与主机名不匹配,那么验证将失败。要允许不验证主机名的连接,请打开忽略代理证书验证Ignore broker certificate validation开关。
MQTT协议
MQTT协议设置默认为版本3.1.1。如果您的MQTT代理支持MQTT版本5,您可以将协议设置为5。
保护连接
通过安全代理连接,可以使用客户端证书进行身份验证。要设置客户端证书和私钥,请打开“使用客户端证书Use a client certificate”选项,然后单击“下一步”以显示上传文件的控件。只能上传PEM编码的客户端证书以及PEM编码的私钥。请确保私钥没有设置密码。
使用WebSockets作为传输
如果您的MQTT代理支持,可以选择WebSocket作为传输方法。当您选择WebSocket并单击“NEXT”时,您将能够添加WebSocket路径(默认值=/)和WebSocket标头(可选)。目标WebSocket URI: ws://{broker}:{port}{WebSockets path} 是使用broker、port和ws_path(WebSocket路径)设置构建的。要配置WebSocket标头,请提供有效的JSON字典字符串。例如,{ "Authorization": "token" , "x-header": "some header" }。默认的传输方法是TCP。WebSocket传输可以使用TLS进行保护,也可以选择使用用户凭据或客户端证书。
注意
配置好的客户证书只有在启用代理证书验证时才会生效。
配置MQTT选项
要更改设置,请按照以下步骤进行:
- 转到 设置 > 设备与服务。
- 选择MQTT集成。
- 选择配置,然后重新配置MQTT。
- 要打开MQTT选项页面,请选择“下一步”。
发现选项
MQTT发现默认启用。可以关闭发现。在这里还可以更改发现主题的前缀(默认为homeassistant)。也可以参考MQTT发现部分。
出生和遗嘱消息
Home Assistant的MQTT集成支持所谓的出生消息和遗嘱消息。前者用于在服务启动后发送消息,后者用于通知其他客户端有关已断开连接的客户端。请注意,无论是干净的(例如Home Assistant关闭)还是不干净的(例如Home Assistant崩溃或失去网络连接)断开连接,遗嘱消息都会被发送。
默认情况下,Home Assistant会发送在线online和离线消息offline到homeassistant/status。
MQTT出生和遗嘱消息可以从用户界面自定义或禁用。要做到这一点,点击用户界面上的集成页面中的“配置”,然后“重新配置MQTT”,然后“下一步”。
测试您的设置
mosquitto代理包提供了命令行工具(通常作为*-clients包)用于发送和接收MQTT消息。要向在localhost上运行的代理发送测试消息,请查看以下示例:
mosquitto_pub -h 127.0.0.1 -t homeassistant/switch/1/on -m "Switch is ON"
手动发送MQTT消息的另一种方法是使用前端的MQTT集成。在左侧菜单上选择“设置”,单击“设备与服务”,并在“Mosquitto代理”瓷砖下选择“配置”。在“发布数据包”下的“主题”字段中输入类似下面的内容,然后按“发布”。
- 转到 设置 > 设备与服务。
- 选择Mosquitto代理集成,然后选择配置。
- 在“发布数据包”下的“主题”字段中输入类似下面的内容。选择“发布”。
homeassistant/switch/1/power
并在有效载荷字段中
ON
在“监听主题”字段中,键入#以查看所有内容,或键入“homeassistant/switch/#”以只关注一个发布的主题,然后按“开始监听”。消息应该类似于下面的文本:
Message 23 received on homeassistant/switch/1/power/stat/POWER at 12:16 PM:
ON
QoS: 0 - Retain: false
Message 22 received on homeassistant/switch/1/power/stat/RESULT at 12:16 PM:
{
"POWER": "ON"
}
QoS: 0 - Retain: false
要读取在localhost上运行的代理上发送的主题homeassistant的所有消息
mosquitto_sub -h 127.0.0.1 -v -t "homeassistant/#"
设备配置共享
MQTT实体可以共享设备配置,这意味着一个实体可以包括完整的设备配置,而其他实体只需设置强制字段即可连接到该设备。强制字段以前仅限于连接和标识符中的至少一个,但现在已扩展到连接和标识符中至少一个以及名称。
MQTT实体的命名
对于每个配置的MQTT实体,Home Assistant会自动分配唯一的实体ID。如果配置了唯一ID选项,您可以在创建后更改实体ID,并更改将存储在实体注册表中。实体ID在第一次加载项目时生成。
如果设置了object_id选项,那么它将用于生成实体ID。例如,如果我们配置了一个传感器,并将object_id设置为test,那么Home Assistant将尝试分配传感器.test作为实体ID,但如果该实体ID已存在,它将附加后缀以使其唯一,例如sensor.test_2。
这意味着作为设备的一部分的任何MQTT实体将自动将其friendly_name属性前缀添加到设备名称
未命名的二进制传感器、按钮、数字和传感器实体现在将根据其设备类而不是命名为“MQTT二进制传感器”等。可以将MQTT实体的名称设置为无(在YAML中使用null)以将其标记为设备的主要特性。
请注意,每个MQTT实体上都将设置has_entity_name属性为True。更多细节可以在此处找到。
MQTT发现
MQTT设备的发现将允许您在Home Assistant方面仅需进行最少配置即可使用MQTT设备。配置是在设备本身和设备使用的主题上完成的,类似于HTTP二进制传感器和HTTP传感器。为了防止设备重新连接时多个相同的条目,需要唯一标识符。设备侧需要两个部分:包含必要设备类型和唯一标识符的配置主题,以及没有设备类型的剩余设备配置。
由MQTT发现支持的实体集成
- 报警控制面板
- 二进制传感器
- 按钮
- 摄像机
- 遮阳器
- 设备跟踪器
- 设备触发器
- 事件
- 风扇
- 加湿器
- 图像
- 气候/暖通
- 割草机
- 灯光
- 锁
- 数字
- 场景
- 选择
- 传感器
- 警报器
- 开关
- 更新
- 标签扫描器
- 文本
- 真空
- 热水器
MQTT发现默认启用,但可以禁用。发现主题的前缀(默认为homeassistant)可以更改。请参见MQTT选项部分
发现消息
发现主题
发现主题需要遵循特定的格式:
<discovery_prefix>/<component>/[<node_id>/]<object_id>/config
<发现前缀>:发现前缀默认为homeassistant。此前缀可以更改。
<组件>:支持的MQTT集成之一,例如二进制传感器。
<节点ID>(可选):提供主题的节点的ID,Home Assistant不使用此节点ID,但可能用于构造MQTT主题。节点的ID必须仅由字符类[a-zA-Z0-9_-](字母数字、下划线和连字符)的字符组成。
<对象ID>:设备的ID。这仅允许为每个设备分别设置主题,并不用于entity_id。设备的ID必须仅由字符类[a-zA-Z0-9_-](字母数字、下划线和连字符)的字符组成。
<节点ID>级别可以由客户端使用一个通配主题<发现前缀>/+/<节点ID>/+/set来仅订阅自己的(命令)主题。
对于具有唯一ID的实体,最佳做法是将设置为unique_id并省略。
发现负载
负载必须是序列化的JSON字典,如果添加新设备,则将像在configuration.yaml文件中的条目一样进行检查,不同之处在于允许未知的配置键,但会被忽略。这意味着缺少的变量将使用集成的默认值填充。所有必需的配置变量必须在负载中存在。允许未知文档键的原因是允许一些向后兼容性,生成MQTT发现消息的软件可以与旧的Home Assistant版本一起使用,旧版本将简单地忽略新功能。
在接收到有效负载的主题上的后续消息将被视为配置更新,并且具有空负载的配置更新将导致先前发现的设备被删除。
负载中可以定义一个基本主题~,以在多次使用相同主题基础时节省内存。在以_topic结尾的配置变量的值中,如果~位于值的开头或结尾,将用基本主题替换~。
发现负载中的配置变量名称可以被缩写,以在从内存受限设备发送MQTT发现消息时节省内存。
鼓励通过在发现负载中添加来源选项(可缩写为o)来为通过MQTT发现提供MQTT实体的来源添加更多信息。请注意,这些选项也支持缩写。项目被发现或更新时,将日志记录有关来源的信息到核心事件日志中。
名称
发现MQTT项目的原始应用程序的名称。此选项为必填项。
sw_version
提供发现的MQTT项目的应用程序的软件版本。
support_url
提供发现的MQTT项目的应用程序的支持URL。
第三方工具的支持
以下软件内置支持MQTT发现:
- ArduinoHA
- Arilux AL-LC0X LED控制器
- ebusd
- ecowitt2mqtt
- EMS-ESP32(和EMS-ESP)
- ESPHome
- ESPurna
- HASS.Agent
- IOTLink(从2.0.0开始)
- MiFlora MQTT守护程序
- MyElectricalData
- Nuki Hub
- Nuki Smart Lock 3.0 Pro,更多信息
- OpenMQTTGateway
- room-assistant(从1.1.0开始)
- SmartHome
- SpeedTest-CLI MQTT
- SwitchBot-MQTT-BLE-ESP32
- Tasmota(从5.11.1e开始,开发已停止)
- TeddyCloud
- Teleinfo MQTT(从3.0.0开始)
- Tydom2MQTT
- What’s up Docker?(从3.5.0开始)
- WyzeSense2MQTT
- Xiaomi DaFang Hacks
- Zehnder Comfoair RS232 MQTT
- Zigbee2MQTT
- Zwave2Mqtt(从2.0.1开始)
发现示例
运动检测(二进制传感器)
一个运动检测设备可以用一个二进制传感器来表示,它会将其配置作为JSON有效负载发送到配置主题。在第一条消息到config后,发送到状态主题的MQTT消息将更新Home Assistant中的状态。
配置主题:homeassistant/binary_sensor/garden/config
状态主题:homeassistant/binary_sensor/garden/state
包含派生设备名称的配置有效负载:
{
"name":null,
"device_class":"motion",
"state_topic":"homeassistant/binary_sensor/garden/state",
"unique_id":"motion01ad",
"device":{
"identifiers":[
"01ad"
],
"name":"Garden"
}
}
保留:使用-r开关将配置主题保留在代理中。如果没有这个,Home Assistant重新启动后传感器将不可用。
还建议添加唯一ID,以允许更改实体和设备映射,以便我们可以将设备的所有传感器分组在一起。如果我们想要继承实体的设备名称,可以将“name”设置为null。如果设置了实体名称,友好名称将是设备名称和实体名称的组合。如果省略名称并设置了device_class,则实体名称部分将派生自device_class。
配置有效负载示例,不设置名称并派生device_class名称:
{
"name":null,
"device_class":"motion",
"state_topic":"homeassistant/binary_sensor/garden/state",
"unique_id":"motion01ad",
"device":{
"identifiers":[
"01ad"
],
"name":"Garden"
}
}
如果没有设置名称,MQTT将设置默认名称(请参阅MQTT平台文档)。
要手动创建一个新的传感器,并将名称设置为null以派生设备名称“Garden”:
mosquitto_pub -r -h 127.0.0.1 -p 1883 -t "homeassistant/binary_sensor/garden/config" -m '{"name": null, "device_class": "motion", "state_topic": "homeassistant/binary_sensor/garden/state", "unique_id": "motion01ad", "device": {"identifiers": ["01ad"], "name": "Garden" }}'
更新状态:
mosquitto_pub -h 127.0.0.1 -p 1883 -t "homeassistant/binary_sensor/garden/state" -m ON
通过发送空消息删除传感器。
mosquitto_pub -h 127.0.0.1 -p 1883 -t "homeassistant/binary_sensor/garden/config" -m ''
有关更多详细信息,请参考MQTT测试部分。
传感器
设置具有多个测量值的传感器需要多个连续的配置主题提交。
配置主题1:homeassistant/sensor/sensorBedroomT/config
配置有效负载1:
{
"device_class":"temperature",
"state_topic":"homeassistant/sensor/sensorBedroom/state",
"unit_of_measurement":"°C",
"value_template":"{{ value_json.temperature}}",
"unique_id":"temp01ae",
"device":{
"identifiers":[
"bedroom01ae"
],
"name":"Bedroom"
}
}
配置主题2:homeassistant/sensor/sensorBedroomH/config
配置有效负载2:
{
"device_class":"humidity",
"state_topic":"homeassistant/sensor/sensorBedroom/state",
"unit_of_measurement":"%",
"value_template":"{{ value_json.humidity}}",
"unique_id":"hum01ae",
"device":{
"identifiers":[
"bedroom01ae"
],
"name":"Bedroom"
}
}
常见的状态有效负载:
{
"temperature":23.20,
"humidity":43.70
}
具有命令主题的实体
设置灯、开关等类似,但需要使用MQTT开关文档中提到的command_topic。
配置主题:homeassistant/switch/irrigation/config
状态主题:homeassistant/switch/irrigation/state
命令主题:homeassistant/switch/irrigation/set
有效负载:
{
"name":"Irrigation",
"command_topic":"homeassistant/switch/irrigation/set",
"state_topic":"homeassistant/switch/irrigation/state",
"unique_id":"irr01ad",
"device":{
"identifiers":[
"garden01ad"
],
"name":"Garden"
}
}
保留:使用-r开关将配置主题保留在代理中。如果没有这个,Home Assistant重新启动后开关将不可用。
mosquitto_pub -r -h 127.0.0.1 -p 1883 -t "homeassistant/switch/irrigation/config" \
-m '{"name": "Irrigation", "command_topic": "homeassistant/switch/irrigation/set", "state_topic": "homeassistant/switch/irrigation/state", "unique_id": "irr01ad", "device": {"identifiers": ["garden01ad"], "name": "Garden" }}}'
设置状态:
mosquitto_pub -h 127.0.0.1 -p 1883 -t "homeassistant/switch/irrigation/set" -m ON
使用缩写和基础主题
使用主题前缀和缩写配置变量名称来减小有效负载长度以设置开关。
配置主题:homeassistant/switch/irrigation/config
命令主题:homeassistant/switch/irrigation/set
状态主题:homeassistant/switch/irrigation/state
配置有效负载:
{
"~":"homeassistant/switch/irrigation",
"name":"garden",
"cmd_t":"~/set",
"stat_t":"~/state"
}
另一个示例,使用缩写主题名称和基础主题设置采用JSON有效负载的灯:
配置主题:homeassistant/light/kitchen/config
命令主题:homeassistant/light/kitchen/set
状态主题:homeassistant/light/kitchen/state
示例状态有效负载:{"state": "ON", "brightness": 255}
配置有效负载:
{
"~": "homeassistant/light/kitchen",
"name": "Kitchen",
"uniq_id": "kitchen_light",
"cmd_t": "~/set",
"stat_t": "~/state",
"schema": "json",
"brightness": true
}
在发现消息中使用缩写的设备和来源信息的示例
{
"~": "homeassistant/light/kitchen",
"name": null,
"uniq_id": "kitchen_light",
"cmd_t": "~/set",
"stat_t": "~/state",
"schema": "json",
"dev": {
"ids": "ea334450945afc",
"name": "Kitchen",
"mf": "Bla electronics",
"mdl": "xya",
"sw": "1.0",
"hw": "1.0rev2",
},
"o": {
"name":"bla2mqtt",
"sw": "2.1",
"url": "https://bla2mqtt.example.com/support",
}
}
使用object_id影响实体ID
实体ID会根据实体的名称自动生成。所有MQTT集成都可以选择提供一个object_id,如果提供了,将使用它。
配置主题:homeassistant/sensor/device1/config
示例配置有效负载:
{
"name":"My Super Device",
"object_id":"my_super_device",
"state_topic": "homeassistant/sensor/device1/state"
}
在上面的示例中,实体ID将是sensor.my_super_device而不是sensor.device1。
手动配置的MQTT项目
对于大多数集成,还可以在configuration.yaml中手动设置MQTT项目。了解有关YAML配置的更多信息。
MQTT支持两种样式的YAML中配置项目的方式。所有配置项目都直接放在mqtt集成键下。请注意,不能混合使用这些样式。当有疑问时,请使用每个项目样式列出的YAML配置。
按项目列出的YAML配置
这种方法期望所有项目都在YAML列表中。每个项目都有一个{domain}键,项目配置直接放在域键下。这种方法被认为是最佳实践。在所有示例中,我们都使用这种格式。
mqtt:
- {domain}:
name: ""
...
- {domain}:
name: ""
...
YAML配置由{domain}键分组和捆绑
根据{domain}分组的所有项目,列出所有配置。
mqtt:
{domain}:
- name: ""
...
- name: ""
...
支持通过YAML进行设置的MQTT组件
如果有许多手动配置的项目,您可能要考虑拆分配置。
使用模板
MQTT集成支持模板。了解有关在MQTT集成中使用模板的更多信息。
MQTT通知
MQTT通知支持与其他通知集成不同。它是一项服务。这意味着在调用服务时需要提供更多细节。
从开发人员工具->服务中的呼叫服务部分,允许您发送MQTT消息。从“可用服务”的列表中选择mqtt.publish,然后将类似下面的示例输入Service Data字段并单击CALL SERVICE。
{
"~":"homeassistant/switch/irrigation",
"name":"garden",
"cmd_t":"~/set",
"stat_t":"~/state"
}
对于自动化,也是一样的。
示例
REST API
使用REST API向给定主题发送消息。
$ curl -X POST \
-H "Authorization: Bearer ABCDEFGH" \
-H "Content-Type: application/json" \
-d '{"payload": "Test message from HA", "topic": "home/notification"}' \
http://IP_ADDRESS:8123/api/services/mqtt/publish
自动化
在自动化中使用作为脚本。
automation:
alias: "Send me a message when I get home"
trigger:
platform: state
entity_id: device_tracker.me
to: "home"
action:
service: script.notify_mqtt
data:
target: "me"
message: "I'm home"
script:
notify_mqtt:
sequence:
- service: mqtt.publish
data:
payload: "{{ message }}"
topic: home/"{{ target }}"
retain: true
发布和转储服务
MQTT集成将注册mqtt.publish服务,允许将消息发布到MQTT主题。有两种指定有效载荷的方法。您可以使用payload来硬编码有效载荷,或者使用payload_template来指定将呈现以生成有效载荷的模板。
SERVICE MQTT.PUBLISH
服务数据属性 可选 描述
主题 否 要发布有效载荷的主题。
主题模板 否 要呈现为发布有效载荷的主题的模板。
有效载荷 是 要发布的有效载荷。
payload_template 是 要呈现为有效载荷值的模板。
qos 是 要使用的服务质量。(默认值: 0)
保留 是 消息是否应设置为保留标志。(默认值: false)
您必须包括topic
或topic_template
中的一个,但不是两者都包括。如果提供有效载荷,则需要包括payload
或payload_template
中的一个,但不是两者都包括。
topic: homeassistant/light/1/command
payload: on
topic: homeassistant/light/1/state
payload_template: "{{ states('device_tracker.paulus') }}"
topic_template: "homeassistant/light/{{ states('sensor.light_active') }}/state"
payload_template: "{{ states('device_tracker.paulus') }}"
有效载荷必须是字符串。如果要使用YAML编辑器发送JSON,那么需要正确格式化/转义它。像这样:
topic: homeassistant/light/1/state
payload: "{\"Status\":\"off\", \"Data\":\"something\"}"`
使用Home Assistant的YAML编辑器格式化JSON时,如果有效载荷包含模板内容,应格外小心。Home Assistant会强制您进入YAML编辑器,并将您的定义视为模板。确保像下面的示例中那样转义模板块。Home Assistant将将结果转换为字符串,并将其传递给MQTT发布服务。
下面的示例显示了如何发布温度传感器“浴室温度”。已设置device_class,因此不需要设置“name”选项。实体将从设置的device_class继承名称,并支持翻译。如果在有效载荷中设置了“name”,实体名称将以设备名称开头。
service: mqtt.publish
data:
topic: homeassistant/sensor/Acurite-986-1R-51778/config
payload: >-
{"device_class": "temperature",
"unit_of_measurement": "\u00b0C",
"value_template": "{{ value|float }}",
"state_topic": "rtl_433/rtl433/devices/Acurite-986/1R/51778/temperature_C",
"unique_id": "Acurite-986-1R-51778-T",
"device": {
"identifiers": "Acurite-986-1R-51778",
"name": "Bathroom",
"model": "Acurite-986",
"manufacturer": "rtl_433" }
}
使用qos和retain的示例:
topic: homeassistant/light/1/command
payload: on
qos: 2
retain: true
SERVICE MQTT.DUMP
监听指定的主题匹配项,并在特定持续时间内将所有接收到的消息转储到配置文件夹中的mqtt_dump.txt文件中。这在调试问题时很有用。
服务数据属性 可选 描述
主题 否 要转储的主题。可以包含通配符(#或+)。
持续时间 是 我们将侦听消息的持续时间(以秒为单位)。默认值为5秒。
topic: openzwave/#
日志
logger集成允许记录接收的MQTT消息。
# Example configuration.yaml entry
logger:
default: warning
logs:
homeassistant.components.mqtt: debug
事件event_mqtt_reloaded
当手动配置的MQTT实体已重新加载并实体可能已更改时,将触发事件event_mqtt_reloaded。
此事件没有额外的数据。
回复