I wanted to delay messages, and have them not send if a device returns to the desired state within a set time.
I use dummy switches to trigger my script again after a delay, I do this as the switch can be configured to be momentary with a variable delay, this saves using and delays inside the script. I am also able to read the values of switches in Dashitcz, which I can't do with variables.
This is my switch (1 min Delay)
My first example is a script I use to monitor my Doors\Windows while the AC is on, I have had this in place for sometime, but the messages were instant, if you are just opening a door\window for a moment it is a little annoying. I was considering using the .minsAgo() function, its not yet supported by .notify, and issuing a .cancelQueuedCommands() would cancel any message, not just the ones from this script.
I have the delay switch being triggered from inside a foreach loop that inspects all my "Openings" since it loops through this on each pass the switch will be turned back on as long as any of the openings is open, the end result is the script will run every 1 mins as long as something is open, then return to only device triggers when they are all closed (or the AC is powered off)
I had an issue with "item.lastUpdate.minutesAgo >= 5" inside the loop the open device would report the lastupdate of the time before the opening that triggered the script, so even though the door\window had just opened, triggering the script, it would send a message using just this condition. To resolve that I also check that the script was triggered by my delay switch device, so message will only send if triggered by that, and not by an opening. The openings only activate the delay switch (hope that all makes sense)
I have also added a function to turn the AC off if the device is left open for longer than 60 mins, but that is untested.
I have cut snippets from my larger AC Check script to make it a little easier to digest, If I have messed up something or if something doesn't make sense, just ask.
I also have a RGB Notification Light, near the AC controls, that turns Yellow if something is open, this is not delayed. It turns other colours when zones are too hot\cold, but that's a mix between other scripts.
Code: Select all
-- Device Action Switches
local POWER_SWITCH = "AC Power"
local MODE_SWITCH = "AC Mode"
-- External Windows and Doors
local FRONTDOOR_DEVICE = "Front Door"
local BACKDOOR_DEVICE = "Back Door"
local LAUNDRYWINDOW_DEVICE = "Laundry Window"
local PLAYROOM_DEVICE = "Playroom"
-- Notification Light
local GATEWAY_LIGHT = "Xiaomi Light"
-- Variable Switches
local AC_DOORLIGHT = "AC_DoorLight"
local AC_NOTIFY_DELAY = "AC_Notification_Delay"
local LOGGING = true
return {
active = true,
on = {
devices = {
POWER_SWITCH,
FRONTDOOR_DEVICE,
BACKDOOR_DEVICE,
LAUNDRYWINDOW_DEVICE,
PLAYROOM_DEVICE,
AC_NOTIFY_DELAY,
}
},
logging = {
level = domoticz.LOG_INFO,
marker = "AC Checkz"
},
execute = function(domoticz, device, triggerInfo)
-- define script action switches
local power = domoticz.devices(POWER_SWITCH)
local mode = domoticz.devices(MODE_SWITCH)
-- Notification Light
local gatewaylight = domoticz.devices(GATEWAY_LIGHT)
-- Variable Switches
local doorlight = domoticz.devices(AC_DOORLIGHT)
local notifydelay = domoticz.devices(AC_NOTIFY_DELAY)
-- Door monitoring Devices
local openings = {
[FRONTDOOR_DEVICE]=true,
[BACKDOOR_DEVICE]=true,
[LAUNDRYWINDOW_DEVICE]=true,
[PLAYROOM_DEVICE]=true,
}
-- Check the Doors and Windows (Warning Light)
local open_count = 0
if (power.state == "On" and mode.state ~= "Fan") then
domoticz.devices().filter( function(item)
return (openings[item.name] == true)
end).forEach( function(item)
if LOGGING then domoticz.log(item.name.." is "..item.state, domoticz.LOG_INFO) end
if (item.state == "Open") then
if (doorlight.state == "Off") then -- Check doorlight
if LOGGING then domoticz.log("Turning ON the Openings Light as "..item.name.." is "..item.state..", since "..item.lastUpdate.minutesAgo.." Mins Ago", domoticz.LOG_FORCE) end
domoticz.scenes('Yellow Light').switchOn()
doorlight.switchOn()
end
notifydelay.switchOn().checkFirst().silent()
open_count = open_count + 1
-- Triggered by Delay Swtich and Item Open for longer than 5 Mins, OR Trigged by AC Power turning ON
if ((device.name == notifydelay.name and item.lastUpdate.minutesAgo >= 5) or (device.name == power.name and device.state == "On")) then
if (domoticz.variables('AC_Message1').lastUpdate.minutesAgo > 30) then -- Notification Rate limit (1 per 30 Mins)
if LOGGING then domoticz.log("Sending a notification", domoticz.LOG_INFO) end
count = domoticz.variables('AC_Message1').value + 1
domoticz.variables('AC_Message1').set(count)
domoticz.notify("The " .. item.name .. " is Open",
"The AC is on and " .. item.name .. " is open. Close " .. item.name .. " for better efficency.",
domoticz.PRIORITY_NORMAL,
domoticz.SOUND_COSMIC)
end
-- Triggered by Delay Swtich and Item Open for longer than 60 Mins
if (device.name == notifydelay.name and item.lastUpdate.minutesAgo >= 60) then
power.switchOff() -- Turn the AC OFF
end
end
end
end)
if (open_count == 0 and doorlight.state ~= "Off") then
if LOGGING then domoticz.log("Turning OFF the Openings Light, Opening Closed", domoticz.LOG_FORCE) end
gatewaylight.switchOff().checkFirst()
doorlight.switchOff().checkFirst()
notifydelay.switchOff().checkFirst().silent()
end
end
end
}