『瀚思彼岸』» 智能家居技术论坛

标题: 多方式实现小爱音箱控制HA设备及小爱主动问询根据回答操作 [打印本页]

作者: Hinata    时间: 2025-8-6 11:23
标题: 多方式实现小爱音箱控制HA设备及小爱主动问询根据回答操作
本帖最后由 Hinata 于 2025-8-12 10:05 编辑

思路来源:主要来自于微信群群友朱总,其他热心群友参与讨论
实现思路:使用米家APP创建手动智能场景,唤醒小爱同学对话使用智能场景,小爱同学执行指令后不会出现类似于没有此设备这类回复,node-red接收触发并实现所有HA设备的控制
记录:
250807 增加评论区中提到有小米中枢网关的情况下使用虚拟事件
250812 因群友czx提到根据条件触发小爱主动询问,在获取回答后触发条件,增加这部分内容
注:我迟早得把群友全搬上来

备注:帖子中均使用node-red的方式实现,大部分情况下是可以使用HA自带的自动化去实现的,原理一样。

多方法控制实现方式:
1、无小米中枢网关,有闲置设备
(1)在米家APP创建手动控制,如“睡眠模式”,可以在设备调整中,针对你的闲置设备进行设置,比如我有一个四键开关闲置,那我就可以打开这个按键1
[attach]72658[/attach][attach]72661[/attach]
(2)在node-red中创建对应的流程,操作设备或其他动作
在举例图中,我是使用一个四开按键进行居家模式的变更,使用传感实体记录按键开关状态,最终统计不同的按键开关组合去确定要执行什么操作,并在处理操作之后重新关闭按键
[attach]72662[/attach]
注:实际使用中,如果需要控制空调具体温度,是可以使用可以调光的灯泡,把灯珠拆掉,可以设置不同亮度,直接对应到node-red中设置不同的温度或者其他数值类的操作。
(3)使用小爱音箱执行指令
此时已经可以使用小爱音箱,唤醒后,直接说“睡眠模式”,就可触发对应的操作

2、无小米中枢网关,无闲置设备
(1)在米家APP创建手动控制,如“打开空调”,可以在设备调整中,选择你不需要调整的设备,比如我有个开关的背光,本来就是关闭的,我再次选择调整到关闭
[attach]72659[/attach]
(2)使用集成 Xiaomi Miot Auto ,在node-red中使用小爱音箱的对话记录传感器实体
[attach]72663[/attach]
(3)在node-red中创建对应的流程,操作设备或其他动作
在举例图中,我是使用在1分钟内传递的msg.payload(也就是对话内容)是否是我设置的具体文本,是的话则触发操作
[attach]72664[/attach]
注:可以使用正则匹配,但是跟米家设置的手动控制不匹配的话,小爱会进行对话的回复,虽然不影响操作,但是影响强迫症
(4)使用小爱音箱执行指令
此时已经可以使用小爱音箱,唤醒后,直接说“打开空调”,就可触发对应的操作

3、有小米中枢网关,不需真实设备
(1)在米家APP创建手动控制,选择设备“中枢网关”,创建对应的产生虚拟事件,如“睡眠模式”
[attach]72695[/attach][attach]72696[/attach]
(2)使用官方集成 Xiaomi Home ,在node-red中使用中枢网关的虚拟事件发生记录实体
[attach]72697[/attach]
(3)在node-red中创建对应的流程,操作设备或其他动作
在举例图中,我是使用虚拟事件发生记录实体的msg.data.new_state.attributes.事件名称(也就是虚拟事件内容)是否为特定触发词,是的话则触发操作

[attach]72698[/attach]
注:1)虚拟事件可以也模拟设备,比如创建虚拟事件中“开关A开”,“开关A关”,后续使用中,可以通过触发这两个虚拟事件来模拟开关A的开关状态
2)虚拟事件在触发后因为没有默认状态所以不会自动复位,建议在使用上触发后增加复位(设置默认虚拟事件)
(4)使用小爱音箱执行指令
此时已经可以使用小爱音箱,唤醒后,直接说“睡眠模式”,就可触发对应的操作


小爱主动询问后根据回答再操作实现方式:
(1)创建事件触发点:可以参照上面控制的实现方式,原理是一样的。例如使用虚拟事件,分别创建了“是的”“不是”来确定回答指向
(2)在小爱音箱的个人训练中,增加你可能使用的回答,统一指向你的事件触发点,方便后续随时根据自己及家人的用语习惯调整,需个人根据个人情况设置
[attach]72809[/attach]

(3)在node-red创建对应流程,整体思路:设置特定条件,触发,开始播放特定语句,唤醒音箱,自己说话,触发手动控制的特定词,执行特定行为,小爱播报行为结果,结束
在举例图中,我是有人在客厅10分钟,而且电视关着的情况下,小爱开始询问要不要帮忙开电视,在播放完文本后(这个时间采用了自行估算)听取我的回答,再根据我的回答或者我不回答,在后续继续触发操作
[attach]72810[/attach]
(4)实际测试,在回答后触发操作
注:1)这部分内容只是给出示例,因大部分都直接采取了自动化,询问场景相对较少,也不太容易根据实际情况分开触发,比如客厅开电视这个询问,应该是要加上是不是有客人以及时间段限定
2)本质上是可以直接在nr流程通过传递参数,直接只获取自己对小爱音箱说的话就触发对应操作,只是为了方便随时根据情况修改触发词以及虚拟事件本地化尽量减少延迟才给出这个方式示例

多个小爱音箱自动回应:
顺嘴说一下,如果多个小爱音箱,想要根据你询问的小爱音箱回应,那只要根据时间去判断就可以选择到对应的小爱了,个人觉得应该是根据人在哪个位置然后选择最近的

作者: ZDZX    时间: 2025-8-6 11:38
看看我的

【丢掉巴法云!超低成本解决HA读取小爱语音内容有延迟的问题】 https://www.bilibili.com/video/BV11hB7YFE9o/?share_source=copy_web&vd_source=d17175c986cec83b4c79184b625c9ea2
作者: hassmingovo    时间: 2025-8-6 11:52
本帖最后由 hassmingovo 于 2025-9-15 10:15 编辑

如果有中枢网关的话,可以结合官方的xiaomi home集成,在米家建一些虚拟事件来匹配触发, 反应很快,不需要坐额外的改造,缺点就是手动建比较多虚拟事件比较麻烦
[attach]72665[/attach]



alias: 小米虚拟事件分流自动化
description: 根据event属性事件名称做分流
triggers:
  - entity_id: event.xiaomi_cn_729076089_rd08_virtual_event_e_7_1
    trigger: state
conditions: []
actions:
  - choose:
      - conditions:
          - condition: template
            value_template: >
              {{
              state_attr('event.xiaomi_cn_729076089_rd08_virtual_event_e_7_1',
              '事件名称') == '打开电视' }}
        sequence:
          - type: turn_on
            device_id: device_id
            entity_id: entity_id
            domain: remote
      - conditions:
          - condition: template
            value_template: >
              {{
              state_attr('event.xiaomi_cn_729076089_rd08_virtual_event_e_7_1',
              '事件名称') == '关闭电视' }}
        sequence:
          - type: turn_off
            device_id: device_id
            entity_id: entity_id
            domain: remote
    default:
      - data:
          name: 虚拟事件未匹配操作
          message: >
            触发事件名称为 {{
            state_attr('event.xiaomi_cn_729076089_rd08_virtual_event_e_7_1',
            '事件名称') }}
        action: logbook.log
mode: single



作者: mhbj    时间: 2025-8-6 16:18
虚拟事件才是最好用的
作者: Hinata    时间: 2025-8-7 09:10
hassmingovo 发表于 2025-8-6 11:52
如果有中枢网关的话,可以结合官方的xiaomi home集成,在米家建一些虚拟事件来匹配触发, 反应很快,不需要 ...

之前没说明场景是在没有小米中枢网关下实现的,谢谢提醒,已经增加这部分内容
作者: Hinata    时间: 2025-8-7 09:15
ZDZX 发表于 2025-8-6 11:38
看看我的

【丢掉巴法云!超低成本解决HA读取小爱语音内容有延迟的问题】 https://www.bilibili.com/video/ ...

增加设备是一个思路,不过涉及到esp32应该不太适合新手入手,还是想能在不额外增加设备情况下完成
作者: ZDZX    时间: 2025-8-7 10:11
Hinata 发表于 2025-8-7 09:15
增加设备是一个思路,不过涉及到esp32应该不太适合新手入手,还是想能在不额外增加设备情况下完成 ...

不想要额外设备?可以呀,有早期方案

【【小爱接入HA】解决Node-RED使用小爱对话结果时小爱自己再次执行指令的问题】 https://www.bilibili.com/video/BV1rz421q74C/?share_source=copy_web&vd_source=d17175c986cec83b4c79184b625c9ea2

作者: Hinata    时间: 2025-8-7 11:21
ZDZX 发表于 2025-8-7 10:11
不想要额外设备?可以呀,有早期方案

【【小爱接入HA】解决Node-RED使用小爱对话结果时小爱自己再次执行 ...

你这个跟我现在帖子的是一个思路啊
作者: ZDZX    时间: 2025-8-7 14:19
Hinata 发表于 2025-8-7 11:21
你这个跟我现在帖子的是一个思路啊

是咧,与你2的区别在于我是在小爱侧通过重置语音指令屏蔽了历史消息,而你是通过函数屏蔽了历史消息。我觉得你的流程比较顺,所有逻辑都在Node-RED处理。
作者: lee1985    时间: 2025-8-7 14:29
直接在小米音箱app中训练一下她就好了,让她回答什么都可以,https://blog.lida1985.eu.org/arc ... u-ni-ji-kai-guan-ji
作者: 岩风    时间: 2025-9-12 19:30
强强强!!!
作者: TOEYengXhim    时间: 2025-9-13 16:26
3、有小米中枢网关,不需真实设备方案的流可以分享一下吗
作者: Witness    时间: 2025-9-14 22:33
hassmingovo 发表于 2025-8-6 11:52
如果有中枢网关的话,可以结合官方的xiaomi home集成,在米家建一些虚拟事件来匹配触发, 反应很快,不需要 ...

大佬,自动化代码能分享一下吗
作者: hassmingovo    时间: 2025-9-15 10:12
Witness 发表于 2025-9-14 22:33
大佬,自动化代码能分享一下吗
  1. alias: 小米虚拟事件分流自动化
  2. description: 根据event属性事件名称做分流
  3. triggers:
  4.   - entity_id: event.xiaomi_cn_729076089_rd08_virtual_event_e_7_1
  5.     trigger: state
  6. conditions: []
  7. actions:
  8.   - choose:
  9.       - conditions:
  10.           - condition: template
  11.             value_template: >
  12.               {{
  13.               state_attr('event.xiaomi_cn_729076089_rd08_virtual_event_e_7_1',
  14.               '事件名称') == '打开电视' }}
  15.         sequence:
  16.           - type: turn_on
  17.             device_id: device_id
  18.             entity_id: entity_id
  19.             domain: remote
  20.       - conditions:
  21.           - condition: template
  22.             value_template: >
  23.               {{
  24.               state_attr('event.xiaomi_cn_729076089_rd08_virtual_event_e_7_1',
  25.               '事件名称') == '关闭电视' }}
  26.         sequence:
  27.           - type: turn_off
  28.             device_id: device_id
  29.             entity_id: entity_id
  30.             domain: remote
  31.     default:
  32.       - data:
  33.           name: 虚拟事件未匹配操作
  34.           message: >
  35.             触发事件名称为 {{
  36.             state_attr('event.xiaomi_cn_729076089_rd08_virtual_event_e_7_1',
  37.             '事件名称') }}
  38.         action: logbook.log
  39. mode: single
复制代码

作者: Hinata    时间: 2025-9-19 16:19
TOEYengXhim 发表于 2025-9-13 16:26
3、有小米中枢网关,不需真实设备方案的流可以分享一下吗

可能跟你本身的不太契合,摘取了主要部分
[{"id":"3334e18484058ca0","type":"function","z":"fd52b829db4a3552","name":"延时计算","func":" const text = String(msg.message.data.message|| \"\"); \n const cps = 4.5; \n // 每秒字数估算 \n const base = 600; \n // 启停缓冲 \n const minMs = 2500; \n // 最短播报时间 \n let ms = Math.round(text.length / cps * 1000) + base; \n if (ms < minMs) ms = minMs; \n msg.delay = ms; \n return msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":310,"y":990,"wires":[["d66a5cdd219267b1"]]},{"id":"d66a5cdd219267b1","type":"delay","z":"fd52b829db4a3552","name":"播报","pauseType":"delayv","timeout":"10","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":430,"y":990,"wires":[["069d15b996317937"]]},{"id":"069d15b996317937","type":"api-call-service","z":"fd52b829db4a3552","name":"听取","server":"af60973181b8eb80","version":7,"debugenabled":false,"action":"button.press","floorId":[],"areaId":[],"deviceId":[],"entityId":["button.xiaomi_cn_701352757_lx06_wake_up_a_5_3"],"labelId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","blockInputOverrides":true,"domain":"button","service":"press","x":540,"y":990,"wires":[["2f13941137506015"]]},{"id":"2f13941137506015","type":"ha-wait-until","z":"fd52b829db4a3552","name":"执行","server":"af60973181b8eb80","version":3,"outputs":2,"entities":{"entity":["event.xiaomi_cn_1180420111_hub1_virtual_event_e_4_1"],"substring":[],"regex":[]},"property":"attributes.事件名称","comparator":"includes","value":"\"是的,不是\"","valueType":"jsonata","timeout":"2","timeoutType":"num","timeoutUnits":"minutes","checkCurrentState":true,"blockInputOverrides":true,"outputProperties":[{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"x":660,"y":990,"wires":[["efc89ecd69c2ee42","7c425b48f1c66231"],["7d18fba5baf41054"]]},{"id":"efc89ecd69c2ee42","type":"function","z":"fd52b829db4a3552","name":"是的","func":"// @ts-nocheck\nif (msg.data.attributes.事件名称 ===\"是的\") {\n    return msg;\n} else{\n    return null;\n};","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":800,"y":930,"wires":[["0c0418e85a1f9e95"]]},{"id":"7c425b48f1c66231","type":"function","z":"fd52b829db4a3552","name":"不是","func":"// @ts-nocheck\nif (msg.data.attributes.事件名称 ===\"不是\") {\n    return msg;\n} else{\n    return null;\n};","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":800,"y":980,"wires":[["9b18660b82706d1f"]]},{"id":"7d18fba5baf41054","type":"api-call-service","z":"fd52b829db4a3552","name":"超时不操作通知","server":"af60973181b8eb80","version":7,"debugenabled":false,"action":"notify.send_message","floorId":[],"areaId":[],"deviceId":[],"entityId":["notify.xiaomi_cn_701352757_lx06_play_text_a_5_1"],"labelId":[],"data":"{\"message\":\"超过2分钟没有听到你的回复,那就先不操作吧\",\"title\":\"\"}","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","blockInputOverrides":true,"domain":"notify","service":"send_message","x":830,"y":1030,"wires":[[]]},{"id":"af60973181b8eb80","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":true,"heartbeatInterval":"30","areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]

作者: TOEYengXhim    时间: 昨天 16:43
Hinata 发表于 2025-9-19 16:19
可能跟你本身的不太契合,摘取了主要部分
[{"id":"3334e18484058ca0","type":"function","z":"fd52b829db ...

收到 感谢
作者: TOEYengXhim    时间: 昨天 16:59
Hinata 发表于 2025-9-19 16:19
可能跟你本身的不太契合,摘取了主要部分
[{"id":"3334e18484058ca0","type":"function","z":"fd52b829db ...

播报这一块有点不明白,我看这里只有一个delay节点是如何实现播报效果的




欢迎光临 『瀚思彼岸』» 智能家居技术论坛 (https://bbs.hassbian.com/) Powered by Discuz! X3.5