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

 找回密码
 立即注册
查看: 3480|回复: 11

[教程系列] 系列教程《HA+NR流程控制》之四:在NR中使用状态机初级篇

[复制链接]

6

主题

36

帖子

562

积分

高级会员

Rank: 4

积分
562
金钱
526
HASS币
0
发表于 2023-7-24 18:04:10 | 显示全部楼层 |阅读模式
本帖最后由 afkkk 于 2023-7-24 18:17 编辑

这是一个系列教程:

* 之一:等待无人状态持续x秒
* 之二:满足多个条件后关闭灯光
* 之三:Aqara和HA+NR通讯

去年装修后开始使用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 20230608.0 + Node-RED 3.0.2


-----------------------------------------------以下为正文-----------------------------------------------


从这个post开始,大概会用3-4节介绍一下在NR中使用状态机,以及为什么要使用状态机。这篇从比较简单的场景开始 -- 使用两个motion_sensor判断人的行走方向。

----------------------------------
入口                                      出口
----------------------------------
假设有上图所示的一条走廊,在走廊入口和出口处都设有人体传感器。我们知道在智能家居App中很容易设置如下Automation。
if 入口有人 then 执行操作1
if 出口有人 then 执行操作2
这些App还允许你设置逻辑与和或,
if 入口有人 and 出口有人 then 执行操作1
if 入口有人 or 出口有人 then 执行操作2
在Node-RED下,是否能超越这种简单的if-else,实现更复杂的逻辑呢?例如结合两个人体传感器的数据,实现
if 入口处有人 随后 出口处有人 then 表明有人从入口走向出口,执行某操作
答案是肯定的,这就是典型的使用状态机的场景。但在开始介绍状态机之前,我想先回到米家App,看看在米家App中虽然曲折但仍然可行的实现。

米家app实现双传感器联动:
1. 设置规则1:当 入口传感器有人移动 ,则 开启自动化规则2,等待15秒后,关闭自动化规则2
2. 设置规则2:当 出口传感器有人移动,则执行操作
3. 把规则1设为启用,把规则2初始设为禁用

这个规则组合能够实现超出if-else逻辑的原因是,我们配置了两条规则;并且我们把15秒内入口是否有人移动这个信息,存储在规则2是否为启用状态上了。而某条规则是否enable,也基本上是各智能家居App唯一支持使用的变量。而在Node-RED中,当然可以模拟传统的做法,这里有一个典型的例子和传统思路下的解决方案

但这种中间变量,其实就是手写有限状态机,随着场景的复杂,手写状态机会变得非常困难 -- 难以实现和难以维护。为什么不直接使用状态机呢?好在Node-RED插件库是非常全的,我们不需要自己实现一遍,我试过几个插件,最后选择插件node-red-contrib-xstate-machine,它是对xstate的简单封装。

我们把场景转化为状态图如下:
微信截图_20230724165044.png

即:1. 初始状态为无人状态
2. 当 入口传感器 事件发生时,状态机从 无人状态 进入 入口有人状态;如果在15秒内出现 出口传感器 事件,则进一步进入 入口向出口方向移动 状态,否则回到无人状态
3. 出口传感器 事件触发的逻辑,与此同理。

NR流程图如下:
微信截图_20230724170725.png
SMXState节点的配置如下:
微信截图_20230724175702.png
这段配置对于没有接触过编程的朋友学习曲线会稍有点陡峭,但其实我们认真看一下会发现还是很直观:
1. machine定义了初始节点为无人状态
2.states定义了
无人状态, 入口有人状态, 出口有人状态, 入口向出口方向移动, 出口向入口方向移动,一共5种状态;
3.每种state的on指定了这个状态可以转换为什么状态;
4.after表示当前状态在没有任何其他事件影响的情况,会在15000毫秒后自动转到target的状态;在这里用来达成15秒延迟复位的效果。

更多的内容可以参考SMXStateXstate的文档。这里先回到流程图:

1. 最左侧蓝色events: state节点监听人体传感器状态,把对应事件转化作为smxstate的输入;
2. 浅绿色smxstate节点处理所有的逻辑;
3. 黄色switch节点捕捉我们关心的结果状态,并调用最后的call-service

这里需要特别注意的是,smxstate使用的是msg.topic而不是msg.payload作为输入。记得要正确设置smxstate的上游节点
微信截图_20230724172319.png

流程代码: flows.json (7.71 KB, 下载次数: 25)
PS. 调试smxstate其实非常方便,我一般会把状态机所用到的所有state做成一列Inject节点,调试的时候挨个点击即可模拟任意人体传感器触发顺序了,如下图:
微信截图_20230724173516.png

OK,这个最基本的流程就介绍到这里。
最后补充一下:前面介绍的是一个假设场景,请别太在意检测走廊进出有什么用,或者用存在传感器就能得到行走方向,也别在意万一走廊两端各有一个人这类问题。假设这个简化的场景是为了更多的朋友可以快速入门这个稍复杂的插件和技巧。

实际上状态机能适应非常复杂的场景,例如实现以下这些相当复杂的逻辑,甚至可以把这些逻辑糅合到同一个场景中:
1. 使用门窗传感器 + 人体传感器双传感器判断一个密闭空间是否有人,例如卫生间、浴室
2. 传感器自动开灯和关灯的Automation,可以被物理按键Override一段时间
3. 不同时间段,无人关灯等待时间不同
4. 某个特定传感器可以触发开灯,但周围多个传感器都能保持灯不灭
5. 离开卫生间有个必经的传感器,这个传感器被触发可以加速卫生间关灯

但,家里大部分情况其实是不需要使用状态机这么重的解决方案。大家在尝试的过程中,可以根据实际场景复杂度,来使用不同的解决方案。

下一篇,我会进一步展开smxstate的使用,介绍更复杂一点的场景。







评分

参与人数 4金钱 +36 收起 理由
PerryLayne + 8 期待大佬更多教程
咸味土豆 + 12 膜拜大神!
隔壁的王叔叔 + 10 感谢楼主分享!
relliky + 6 论坛有你更精彩!

查看全部评分

回复

使用道具 举报

8

主题

146

帖子

1751

积分

金牌会员

Rank: 6Rank: 6

积分
1751
金钱
1605
HASS币
0
发表于 2023-7-24 18:56:32 | 显示全部楼层
学习、学习、学习
回复

使用道具 举报

0

主题

35

帖子

953

积分

高级会员

Rank: 4

积分
953
金钱
918
HASS币
0
发表于 2023-7-24 19:27:31 | 显示全部楼层
要好好研究研究
回复

使用道具 举报

4

主题

47

帖子

818

积分

高级会员

Rank: 4

积分
818
金钱
771
HASS币
0
发表于 2023-7-24 23:25:06 | 显示全部楼层
学习学习
道行尚浅
回复

使用道具 举报

32

主题

1065

帖子

4946

积分

论坛元老

Rank: 8Rank: 8

积分
4946
金钱
3866
HASS币
90
发表于 2023-7-25 07:17:02 | 显示全部楼层
好东西,一直在用ha自身的自动化和pyscript写状态机,因为畏惧javascript一直没有学习nr,但看完楼主的教程感觉自己可以试试了
我家全屋智能的HA设置 https://github.com/relliky/Tais_Home_Assistant_Config
回复

使用道具 举报

6

主题

259

帖子

2998

积分

金牌会员

Rank: 6Rank: 6

积分
2998
金钱
2739
HASS币
0
发表于 2023-7-25 23:30:28 | 显示全部楼层

学习、学习、学习.太牛了
回复

使用道具 举报

0

主题

17

帖子

84

积分

注册会员

Rank: 2

积分
84
金钱
67
HASS币
0
发表于 2023-8-11 15:27:36 | 显示全部楼层
好好学习,天天研究。。
回复

使用道具 举报

1

主题

22

帖子

100

积分

注册会员

Rank: 2

积分
100
金钱
78
HASS币
0
发表于 2023-8-20 18:26:20 | 显示全部楼层
厉害,需要向大佬学习
回复

使用道具 举报

0

主题

62

帖子

880

积分

高级会员

Rank: 4

积分
880
金钱
818
HASS币
0
发表于 2023-9-27 21:21:25 | 显示全部楼层
分享的都是经典,谢谢
回复

使用道具 举报

6

主题

259

帖子

2998

积分

金牌会员

Rank: 6Rank: 6

积分
2998
金钱
2739
HASS币
0
发表于 2023-9-29 00:50:09 | 显示全部楼层
大神什么时候更新。下一个教程啊。这个教程有一个地方不明白就是”smxstate使用的是msg.topic而不是msg.payload作为输入“。msg.topic没有内容啊。入口是一个人体传感器。msg.topic没有数据。msg.payload是on。这里怎么弄?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian

GMT+8, 2024-11-25 09:07 , Processed in 0.070330 second(s), 35 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表