玩玩智能家居7:Domoticz 中的 Events

在使用 Domoticz 的过程中,为了避免让 Domoticz 只是成为一个手机上的遥控器,就需要根据生活使用场景去定制一些自动化的规则,例如在天黑回家时自动打开灯,又或者是在睡觉之后自动关闭不必要的灯,在这个时候,就需要使用 Domoticz 的 Events 系统了。

Domoticz 的 Events 支持很多种类语言的编码,其中还包括图形化的配置工具 Blockly。

当然这里并不会去介绍 Blockly 的配置方式,因为使用编码的方式可以得到更细粒度的控制,以及更自由的场景条件控制。

这里主要介绍一些处理事件时的技巧和思路。

时间差处理

在事件处理过程中,最重要的一件事就是判断事件发生的时间与当前时间的时间差,通过这个时间差,可以很方便的根据不同的时间差来达到不同的目的。

now = os.date('*t')

function timedifference (s)
  year = string.sub(s, 1, 4)
  month = string.sub(s, 6, 7)
  day = string.sub(s, 9, 10)
  hour = string.sub(s, 12, 13)
  minutes = string.sub(s, 15, 16)
  seconds = string.sub(s, 18, 19)
  t1 = os.time()
  t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
  difference = os.difftime (t1, t2)
  return difference
end

直接使用 timedifference(otherdevices_lastupdate['设备名称']) 就可以得到当前距离这个设备状态最后变化的时间了。

使用 UserVariable 记录上次操作时间

在某个事件发生后,可能过一段时间才会触发通知,这个时候就需要使用 Time 类型的事件。但是在发送通知之后,很可能触发通知的条件还是满足的,于是下一分钟,又会重复发送通知,这个时候就可以使用 UserVariable 记录上次通知时间,避免重复发送通知。

commandArray['Variable:上次操作时间'] = tostring(os.time())

需要注意的是,上次操作时间 这个变量需要提前在 UserVariable 面板中添加。

这样,在下次触发通知时,可以多加一个判断条件,就可以避免重复通知了:

if (sendNotication && timedifference(uservariables_lastupdate['上次操作时间']) > 300) {
  commandArray['SendNotification'] = 'subject#message'
}

检测门磁超时未关闭

有些时候会碰到忘记关门的情况,又或者是关门时没有注意到导致门没有被关好,这个时候如果能有一个通知提示就比较好了。通过加一个门磁再上超时检测就可以了:

if otherdevices['入户门磁'] == 'Open' and timedifference(otherdevices_lastupdate['入户门磁']) > 300 then
    commandArray['SendNotification'] = '入户门未关'
end

这样,在入户门磁处于 Open 状态,并且超过 300 秒也就是 5 分钟后,就会发送一个通知到用户。

延时处理

通常我们会有通过人体传感器状态来控制灯的开和关,但是在处理关的时候,并不建议检测到人体传感器状态变为无人就立即关闭灯,这样可能会导致灯被频繁开和关。因此在这个时候就需要同时判断人体传感器的状态和它最后更新的时间间隔:

function checkPIROffWithDelay(name, delay)
    if otherdevices[name] == 'Off' and timedifference(otherdevices_lastupdate[name]) > delay then
        return true
    end
    return false
end

根据时间判断是否开关灯

在回家开门的时候,可能需要根据时间来判断是否开灯,例如只有在太阳下山之后才开灯,或者指定时间内都打开灯:

if (devicechanged['入户门磁'] == 'Open' and timeofday['Nighttime']) then
    commandArray['玄关灯'] = 'On'
end

通过 timeofday['Nighttime'] 可以用来判断是否处于太阳下山之后,当然也可以自己加个变量来判断是否处于自定义的一个时间区间,可以更早的打开灯:

now = os.date('*t')
myNighttime = now.hour < 8 and now.hour > 16

上面的条件就是在下午 4 点之后,早上 8 点之前,都认为是需要打开灯的时间。

定时判断设备在线

电视遥控器上的电源开关是不区分开和关的指令的,这就导致如果需要使用红外遥控来操作电视电源的时候,需要提前判断电视是否处于打开状态,防止出现想要打开电视,但是电视电源已经打开的情况下,又发送了电源指令,导致电视被关闭。

if timedifference(otherdevices_lastupdate['松下']) > 60 and otherdevices['松下'] == 'On' then
    commandArray['UpdateDevice'] = '136|0|0'
end

这样挂一个 ESP8266 在电视的 USB 接口上,设置更新时间为 30 秒,在 Domoticz 中每 60 秒检测一次设备状态有没有被更新,如果没有更新就说明电视电源已经被关闭。

参考资料

  1. Domoticz: LUA commands

—EOF—

发表评论?

0 条评论。

发表评论


注意 - 你可以用以下 HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>