afkkk 发表于 2023-5-2 20:24:49

系列教程《HA+NR流程控制》之二:满足多个条件后关闭灯光

本帖最后由 afkkk 于 2023-5-2 22:29 编辑

这是一个系列教程:
* 之一:等待无人状态持续x秒

去年装修后开始使用HA,经过一段时间调整,目前各项配置属于比较稳定、便捷的状态。其中使用了一些技巧很少被提及,特别是对新人来说难以找到这方面的资料。所以用《HA+NR流程控制》为标题总结分享一下。每篇帖子单独分享一个技巧。

这个系列将给读者带来的帮助:

[*]熟悉NR常用排名在10以后的节点
[*]熟悉多种不同复杂度的范式,并运用其实现更强大的智能家居控制流
[*]了解一些使用HA+NR接入/控制外围设备的例子
阅读需要具备的背景知识:

[*]运行和维护Home Assistant系统;
[*]以任何方式安装了Node-RED,并将Node-RED接入Home Assistant系统;
[*]熟悉Home Assistant中常用基本概念:如Integration, Device, Service, Entity;
[*]在Node-RED中编写过Flow,了解NR内置以及node-red-contrib-home-assistant-websocket插件中常用节点;
环境:Home Assistant 20230309.1 + Node-RED 3.0.1
-----------------------------------------------以下为正文-----------------------------------------------


容易的范式 - 满足多个条件后X秒关闭灯光

设计效果:同时监听多个Entity的状态,当每个Entity的状态都符合对应条件时,触发一个操作。一个简单的例子是,房间内有A、B两个传感器,当它们无人X秒后关闭灯光
经典实现:如下图,在A、B传感器之一状态变化时触发,连续通过两个current state节点重新查询A、B传感器的状态,只有两个节点都为off时才会进入后续关灯的流程。

但上图其实有个问题,在delay节点等待时,即使传感器再次检测到有人也不会中止,固定X秒后仍然会关闭灯光。因此一个小的补丁如下:

区别在于,当current state检测到有人时,多了一个reset分支,将向delay节点发送reset消息,取消之前的关闭动作。

但这个经典实现存在一个问题,当条件继续增多时,会形成一个非常长的current state链,维护起来比较麻烦,逻辑关系也不直观。例如在我的NR中,有一条12个输入的流程,还需要AND和OR组合,显然不适合继续使用这种方法。我也曾试过把这种逻辑放到HA的template中,直接用template运算得到一个最终结果来驱动后续流程,但修改template要比NR麻烦很多。
所以这种情况可以请出插件node-red-contrib-boolean-logic-ultimate。这个插件中的BooleanLogicUltimate节点允许接入多个输入,并输出这些输入的逻辑运算结果(类似插件很多,这里随便介绍一个)

如上图所示,Topic 1/2/3是BooleanLogicUltimate的三个输入,BooleanLogicUltimate会记住这三个输入各自最后的状态,并把AND/OR/XOR的结果分别输出到Output 1/2/3。msg.topic是BooleanLogicUltimate记忆的依据。

流程图:以下是一个更真实的例子

解释:
1. 传感器或灯光的任意的状态变化,都会由event: state节点触发整个流程进行运算,其中只有这次变化的Entity会向BooleanLogicUltimate传入新的输入,其他输入的数据BooleanLogicUltimate会沿用上一个结果(event: state节点的topic默认就是entity id)
3. 这里用了4个function节点,把event: state节点中on/off这样的payload转为true/false,具体可参见附件。其他做法是把这种转换直接用表达式写入event: state中,或者用change来实现类似的效果,对我来说function节点更容易维护。
3. 相比前文提到的delay + reset节点的组合,这里用了一种新的方法 -- trigger节点,具体配置如下

trigger节点在接到payload = true的消息后,会等待X秒然后继续后续关闭灯光流程;除非在等待期间接收到payload = false的消息,这种情况它将reset之前的等待。有delay + reset的例子,相信trigger节点这种用法也会很容易理解吧。
注意BooleanLogicUltimate不会对状态进行持久化,如果NR重启各分支的最后状态记录会消失,因此最好勾选event: state的Output on Connect,或者用其它方式完成初始化。

顺便说一下trigger节点。作为Node-RED内置节点之一,它的功能非常强大。比较常见的用法:
1. delay: 在收到消息后什么也不做,等待一段时间,如果没有被reset就转发这个消息;
2. watchdog: 在收到消息(heartbeat消息)后什么也不做,继续等待下一条消息,如果超时未收到,则发出消息通知下游进行异常/离线处理;
3. rail switch: 在收到消息后每隔一段时间发出一条新消息,直到trigger被reset。如果配合分流逻辑,可以实现每隔一段时间开关设备,或者呼吸灯的效果。
下一篇预告:Aqara和HA+NR通讯




mic365 发表于 2023-5-3 07:55:10

很好的分享贴,简单易懂,谢谢!

MX10085 发表于 2023-5-3 10:04:14

学习了,已用上

13990973177 发表于 2023-5-3 10:54:50

感谢分享

KleinerSource 发表于 2023-5-3 11:45:01

最简单的还是用 function 来写

bainiu 发表于 2023-5-3 23:22:31

KleinerSource 发表于 2023-5-3 11:45
最简单的还是用 function 来写

函数的逻辑运算,函数存取数据

735473216 发表于 2023-5-4 08:29:35

非常长的current state确实是痛点,学习了

ylilike 发表于 2023-5-4 08:36:12

谢谢分享,受教了

紫·HA 发表于 2023-5-4 10:16:14

感谢分享

360341024 发表于 2023-5-12 16:22:43

很有用,很贴近现实生活
页: [1] 2
查看完整版本: 系列教程《HA+NR流程控制》之二:满足多个条件后关闭灯光