用Node-RED编程彻底解决子擎人在传感器抽疯的毛病

2023-10-16 21:15:10 1点赞 24收藏 23评论

一、序言

子擎人在传感器发布之后,我买了2个,在洗手间和厨房各布置了一个。

装了子擎之后,基本上人在灯亮,人走灯灭的问题都ok。不过,用了一段时间之后,发现了一个很闹心的问题,子擎的传感器会误判,明明没有人,它却判断有人,一家人在餐厅吃饭,厨房灯自己亮了,然后半天都不灭;明明大家都在各自房间看电视,洗手间灯亮了……

厨房里面误判的情况比洗手间严重得多,估计是厨房里面的热源比较丰富的缘故,炉头、油烟机、电热水壶、高压锅、电饭煲、洗碗机和热水器都是热源。

频繁的误判让我被家人嘲笑了,领导发话不解决就拆掉,这让我很没面子,智能家居居然成了智障家居。

米家APP里面,可以对子擎传感器进行高级设置,进行训练,但实际上,啥用都没有!

二、解决方案1:不需要js编程的零代码方案(满分10分,自认可以评7分)

最后,不得不把Node-RED请出来,搞了一个曲线救国的方法:每15秒检测一次房间灯亮的状态,如果是亮的,那么再检测一下有没有人在房间,没有就关掉灯。

用了这招之后,厨房和洗手间自己亮灯的情况依然存在,但是至少,最多15秒,它就自动熄灯了。有时刚被强制熄灯了,又会马上再亮,一会儿又再次强制熄灯。看着闹心但起码不用担心灯亮了一晚上不关呀。

用Node-RED编程彻底解决子擎人在传感器抽疯的毛病

三、解决方案2:使用js编程的终极大招(满分10分,自认可以评9分)

评论里面有位叫值友(值友1181616891)提供了他的思路,即开灯时并不靠一次“有人”的消息,而是收到第一次“有人”消息后,过500毫秒再判断一次子擎传感器的状态是否还是“有人”,这个思路其实就是单片机编程时,对按键进行去抖动的思路,即在一段时间内连续收到“有人”的消息,才认为有人,如果仅是一个短暂的“有人”消息,持续的时间长度达不到我们预设的阈值,那么我们把它当作毛刺(即,误报消息)丢弃掉。

我的代码,采取了相对保守的策略:(1)对“有人”判断进行了长达1s的去抖动(这个时长读者可以自己调整),系统必须在1s内持续接收到“有人”消息,才会执行开灯,这就基本上杜绝了因为子擎传感器误报而错误开灯的情况;(2)对“无人”判断进行了长达60s的去抖动(其实设置成5s或者10s也非常好用,我是应家人要求,设的60s),系统必须在60s内持续接收到“无人”消息,才会执行关灯,当我们坐在马桶上玩手机时,只要不保持60s静止不动,灯都不会关掉,再也不怕人明明在洗手间里面,突然灯关了,只能摸黑嘘嘘或者摸黑冲凉了!

3.1 Node-RED流程图

Node-RED流程图Node-RED流程图

3.2 evnets:state节点的设置:

使用这个“events:state”节点,我们可以捕捉到子擎传感器名为“binary_sensor.xxxxx_occupancy”这个实体(它对应的值是:有人时“on”,无人时“off”)值发生翻转,并通过消息“msg.payload"把当前的值传递给下个节点。

evnets:state节点的设置evnets:state节点的设置

3.3 function节点的代码:

// 在流程的上下文中分别存储“无人”和“有人”状态的定时器ID

const noManTimerId = flow.get('no_man_timer_id') || null;

const hasManTimerId = flow.get('has_man_timer_id') || null;

// 检查消息是否表示有人

if (msg.payload === 'on') {

// 有人,如果还没有有人的定时器正在运行,则设置一个新的1秒定时器

if (!hasManTimerId) {

const newHasManTimerId = setTimeout(function() {

// 1秒后发送消息以开灯

//node.warn('开灯');

node.send({ payload: '开灯' });

// 清除此定时器ID

flow.set('yes_man_timer_id', null);

}, 1000);

// 将新的定时器ID存储在流程的上下文中

flow.set('yes_man_timer_id', newHasManTimerId);

}

// 如果已经设置了无人的定时器,清除它

if (noManTimerId) {

clearTimeout(noManTimerId);

flow.set('no_man_timer_id', null);

}

// 不发送任何消息,直到定时器结束

return null;

} else if (msg.payload === 'off') {

// 无人,如果还没有无人的定时器正在运行,则设置一个新的60秒定时器

if (!noManTimerId) {

const newNoManTimerId = setTimeout(function() {

// 60秒后发送消息以关灯

//node.warn('关灯');

node.send({ payload: '关灯' });

// 清除此定时器ID

flow.set('no_man_timer_id', null);

}, 60000);

// 将新的定时器ID存储在流程的上下文中

flow.set('no_man_timer_id', newNoManTimerId);

}

// 如果已经设置了有人的定时器,清除它

if (hasManTimerId) {

clearTimeout(hasManTimerId);

flow.set('has_man_timer_id', null);

}

// 不发送任何消息,直到定时器结束

return null;

}

// 默认情况下返回原始消息

return msg;

3.4 switch节点的设置:

这个节点的功能很简单,根据function节点传过来的消息(“开灯” or “关灯”),分别向对应的设备(吸顶灯)发出开灯和关灯的指令。

switch节点的设置switch节点的设置

3.5 2个call service节点的设置:

下面这个是switch节点的输出1所接的设备呼叫服务的节点,即开灯:

负责执行开灯的call service节点设置负责执行开灯的call service节点设置

下面这个是switch节点的输出2所接的设备呼叫服务的节点,即关灯:

负责执行关灯的call service节点设置负责执行关灯的call service节点设置

四、回答评论里面值友的问题

用Node-RED编程彻底解决子擎人在传感器抽疯的毛病

小米的绝大多数设备(包括兼容小米智能的,例如“子擎”、“领普”传感器),都是靠这个“xiaomi Gateway 3”插件接入HA的,另外那个“xiaomi Miiot Auto”插件是个摆设,没啥用处。

五、关于小米多模网关2的固件版本

如果你手里的小米多模网关2(方的,可以插网线的这种),固件版本是1.05或者更旧的,千万保护好它,千万不要手欠点“升级固件”,把米家APP里面的“自动升级”选项去掉勾选。因为1.06或者1.07版本的固件,需要拆开外壳焊线接到笔记本电脑上进行破解才能继续用,超级超级麻烦!说了都是泪!

作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~

展开 收起
23评论

  • 精彩
  • 最新
  • 雷达就是这样 很容易误判,我自己搞的海凌科的雷达也老是误判。我的解决方案就是开灯的时候要判断2次,间隔500毫秒,如果2次的结果都是有人才开灯,离开之后延迟5秒后在判断一次,如果依然没人才关灯。这样误判的情况就很少了。

    校验提示文案

    提交
    老哥你这个办法妙啊!简直就是当年写单片机程序,检测物理按键的处理去抖动方法的翻版😂

    校验提示文案

    提交
    回家也去改进一下我的流程,说不定我这个强制关灯的自动化流程就可以免了

    校验提示文案

    提交
    还有7条回复
    收起所有回复
  • trio误判确实很多

    校验提示文案

    提交
    我文章里面的是子擎Lite。至于你说的子擎Trio我还没用过。

    校验提示文案

    提交
    收起所有回复
  • 应该是你那屋躲了个东西,你看不见罢了

    校验提示文案

    提交
    阿飘具有红外特征?或者雷达可以检测?兄弟你的发现可以拿2024诺贝尔生物学大奖了!

    校验提示文案

    提交
    阿飘没有咩。。。。 [惊喜]

    校验提示文案

    提交
    收起所有回复
  • 你是用miio 接入ha ?

    校验提示文案

    提交
    抱歉最近才看到你的留言。我是用xiaomi Gateway 3 这个插件来接入HA的,请看我更新的图片2。

    校验提示文案

    提交
    收起所有回复
  • 快2025年了,依旧误判严重,后悔刚买时没发现后面现在过了退货期,还买了许多个以及相应配件。这东西如果出厂做不到没问题的能用就算不合格了。

    校验提示文案

    提交
    我目前用node-red写代码来辅助以后,准确率高多了。以洗手间为例,人不在却开灯的情况彻底没了,人在却熄灯的情况,只有坐在马桶上连续15秒(可调)保持完全不动才发生,正常情况下不会熄灯了。

    校验提示文案

    提交
    你有技术可以,我们普通消费者就达不到买个东西要自己写代码了才能用 [赞一个]

    校验提示文案

    提交
    收起所有回复
  • 请问作者用的哪款,是Lite吗,为什么我的误判有人时on状态都会持续好几秒,这样间隔1秒判断两次最终还是会误判有人 [皱眉]

    校验提示文案

    提交
    我用的就是lite。你的环境可能干扰太多了

    校验提示文案

    提交
    应该不是环境干扰的问题,是第一个节点状态变化没那么快,导致函数判断失效,现在改成开启红外辅助判断误判少了

    校验提示文案

    提交
    收起所有回复
提示信息

取消
确认
评论举报

相关文章推荐

更多精彩文章
更多精彩文章
最新文章 热门文章
24
扫一下,分享更方便,购买更轻松