'General purpose' timers
Moderator: leecollings
-
- Posts: 44
- Joined: Wednesday 13 June 2018 12:13
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
'General purpose' timers
Is there any way to configure a general purpose timer and have it fire after a certain time period, and execute an arbitrary block of code?
I don't mean timed events, and I don't mean things like device.switchOn().afterSecs(10)
I would like to be able to run arbitrary code, and possibly switch devices/scenes etc, all triggered from a single one shot timer. Something like the capabilities that this has?
http://wiki.garrysmod.com/page/timer/Create
Any thoughts?
Andy.
I don't mean timed events, and I don't mean things like device.switchOn().afterSecs(10)
I would like to be able to run arbitrary code, and possibly switch devices/scenes etc, all triggered from a single one shot timer. Something like the capabilities that this has?
http://wiki.garrysmod.com/page/timer/Create
Any thoughts?
Andy.
-
- Posts: 1355
- Joined: Friday 29 August 2014 11:26
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Location: Ermelo
- Contact:
Re: 'General purpose' timers
Eh... use the timer trigger?
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
-
- Posts: 44
- Joined: Wednesday 13 June 2018 12:13
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Re: 'General purpose' timers
I'm not sure that fits my needs? Say I have a switch that gets triggered. If I want to execute some arbitrary code 5 minutes after the switch is triggered how would I use that as a timer trigger, which seems to trigger at predefined times?
I guess I could make it repeatedly trigger every minute until the trigger time matches the 'delay' required, but it seems a bit inefficient and back-to-front to do it that way?
-
- Posts: 1355
- Joined: Friday 29 August 2014 11:26
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Location: Ermelo
- Contact:
Re: 'General purpose' timers
Just create one dummy switch with it's own event script for these purposes. And set it in whatever script with an .afterXXX().
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
-
- Posts: 139
- Joined: Tuesday 06 September 2016 20:39
- Target OS: Raspberry Pi / ODroid
- Domoticz version: L stab
- Location: Belgium
- Contact:
Re: 'General purpose' timers
Hi, you can maybe use the lastseen value time of the the switch rhat was triggerd and add your delay time
Domoicz on RPI3 (wifi) directly connected 3x ds18b20 for CV temp, Evohome (9 zone), 1 remote 220V switch based on ESP-12. RFXtrx433E, 16x AMST-606, 5 Somfy RTS motors
Domoticz on RPI3(wifi) as slave for terraruim control
More to come
Domoticz on RPI3(wifi) as slave for terraruim control
More to come
-
- Posts: 1355
- Joined: Friday 29 August 2014 11:26
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Location: Ermelo
- Contact:
Re: 'General purpose' timers
dzVents is a pure slave of Domoticz. If there is no event then nothing happens. So you need something that triggers the event system.
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
- waaren
- Posts: 6028
- Joined: Tuesday 03 January 2017 14:18
- Target OS: Linux
- Domoticz version: Beta
- Location: Netherlands
- Contact:
Re: 'General purpose' timers
Would this approach using set a delayed uservar be an option for you ?
Code: Select all
return {
on = { devices = { "yourSwitch" },
variables = { "yourSwitchDelay" }}, -- Need to be defined once via setup -> more options -> uservariables (as integer)
logging = { level = domoticz.LOG_INFO, -- Change to LOG_DEBUG to check what happens
marker = "delaySwitch" },
execute = function(dz, trigger)
local delay = 300 -- delay in seconds Adjust to your needs
local delayVar = dz.variables("yourSwitchDelay")
if trigger.isVariable then
delayVar.set(0).silent()
dz.log("your code here",dz.LOG_INFO)
else
delayVar.set(1).afterSec(delay) -- Change var after offDelay seconds causing the script
end -- to come back after offDelay seconds
end
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
-
- Posts: 44
- Joined: Wednesday 13 June 2018 12:13
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Re: 'General purpose' timers
Yep, I guess that would probably work too. So many ways to do things!
-
- Posts: 44
- Joined: Wednesday 13 June 2018 12:13
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Re: 'General purpose' timers
That makes complete sense as it is event driven and for your Lua/dzvents script to not have its own runloop or to block, it's just the fact that it has to go via a dummy switch that feels a bit of a hack. When I was considering which platform to go for I ran across a few people commenting that if you want to do any kind of complex scripting you end up with a whole pile of dummy switches to maintain state and trigger things. That's starting to hit me now.
Maybe extending the way that an event script could be triggered by adding a 'user generated event'type, that the script itself could generate in the future. Something like
Code: Select all
on = {
devices = {
'Stairs Motion'
},
userEvents = {
'My Custom Event Name'
}
},
......
domoticz.triggerEvent('My Custom Event Name').afterSeconds(99)
-
- Posts: 1355
- Joined: Friday 29 August 2014 11:26
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Location: Ermelo
- Contact:
Re: 'General purpose' timers
Now well, that is certainly an interesting idea! I'll consider it...
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
- waaren
- Posts: 6028
- Joined: Tuesday 03 January 2017 14:18
- Target OS: Linux
- Domoticz version: Beta
- Location: Netherlands
- Contact:
Re: 'General purpose' timers
Hmm.. A user generated eventtype isn't it already there ?
Code: Select all
return {
on = { devices = { "yourSwitch" },
httpResponses = { "yourSwitchDelay" }},
logging = { level = domoticz.LOG_INFO, -- Change to LOG_DEBUG to check what happens
marker = "delaySwitch" },
execute = function(dz, trigger)
local delay = 300 -- delay in seconds Adjust to your needs
local jsonString = dz.settings['Domoticz url'] .. "/json.htm?type=command¶m=addlogmessage&message=Waiting%20is%20over"
if trigger.isHTTPResponse then
dz.log("your code here",dz.LOG_INFO)
else
dz.openURL ({ url = jsonString,
method = "GET",
callback = "yourSwitchDelay" }).afterSec(delay) -- to come back after delay seconds
end
end
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
-
- Posts: 1355
- Joined: Friday 29 August 2014 11:26
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Location: Ermelo
- Contact:
Re: 'General purpose' timers
Yes but you are misusing the httpRequest here. But it indeed works.
Creator dzVents - RPi3, loads of zwave devices, esp8266, evohome.
- waaren
- Posts: 6028
- Joined: Tuesday 03 January 2017 14:18
- Target OS: Linux
- Domoticz version: Beta
- Location: Netherlands
- Contact:
Re: 'General purpose' timers
Yes that's me... living on the edge

Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
-
- Posts: 44
- Joined: Wednesday 13 June 2018 12:13
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Re: 'General purpose' timers
Cool. I've seen lots of approaches on here to achieve the similar things but they all have 'code smell' in some form... Dummy switches, shared variables, timers that trigger every minute etc. A simple publish/subscribe model with no 3rd party actors is nice and clean.
-
- Posts: 11
- Joined: Monday 14 November 2016 9:30
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Re: 'General purpose' timers
It's pretty OK to trigger on a uservariable also....
- waaren
- Posts: 6028
- Joined: Tuesday 03 January 2017 14:18
- Target OS: Linux
- Domoticz version: Beta
- Location: Netherlands
- Contact:
Re: 'General purpose' timers
@Andyf66, can you please explain in layman's terms what you are looking for and give me an idea how this could be implemented in dzVents, -Lua and or domoticz ? I now have the idea that I miss your point and searching for the terms you use only give me results that are a bit to abstract for me.
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
-
- Posts: 44
- Joined: Wednesday 13 June 2018 12:13
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Re: 'General purpose' timers
Imagine the following scenario. A motion sensor gets tripped. This calls my event driven dzvents script. five minutes after this happens I would like to run some arbitrary code, maybe do come calculations etc. After another 5 minutes I'd like to do some other calculations/switch things on/switch off etc.waaren wrote: ↑Saturday 30 June 2018 0:24 @Andyf66, can you please explain in layman's terms what you are looking for and give me an idea how this could be implemented in dzVents, -Lua and or domoticz ? I now have the idea that I miss your point and searching for the terms you use only give me results that are a bit to abstract for me.
Many ways of achieving this have been posted, but none of them really appear to be particularly well engineered solutions.
- Having your script react to a timer that fires *every* minute and then calculates delay based on the lastUpdated function. Inefficient as your script is called even minute, forever. Also involves some potentially complex and fragile maths code to calculate time offsets etc. Also open to unpredictable interference from other scripts if they change the state of the device you are monitoring for lastUpdated (Maybe you want this though?)
- Having a dummy switch or a shared variable - Potentially more efficient (resources wise) but not immediately transparent in terms of operation. You need to know the code and know the switch/variable and then know the script that gets triggered from the switch. A chain of events that's easily forgotten over time. This makes the setup very 'fragile' or 'brittle'. It's very easy to break the chain by accident when making future modifications some point down the line. Basically, your logic flow isn't transparent - you're relying on 'side effects' of an action to trigger something else.
- Using the HTTP method given previously. Not sure where to start on that one!
All of the Above mentioned methods do work, but are not transparently clear in intention. Code you write one day will be edited at some point down the line, and you'll likely have forgotten how it all fits together. Also, all of the methods require an amount of code/logic just to perform the basic action of triggering after a delay. My proposed solution is literally two lines of code - one to say that your code is interested in a 'user' event, and another line of code to actually generate the event. Completely clear intention and no reliance on side effects. As I posted previously, something like the code below is all you would need, and it would replace all the counting logic / dummy switches etc.
Expanding on the example I previously gave in the previous post, and expanding to the two events proposed in the scenario. something like this would cause two 'user' events to trigger my script, one after 5 minutes and one after 10. Completely clear intention, no 3rd party components (dummy switches/user variables needed) No reliance on 'side effects of other actions and completely transparent in function. You can see exactly what it does just by looking at single file.
Code: Select all
on = {
devices = {
'Stairs Motion'
},
userTriggers = {
'My 5 minute event',
'My 10 minute event'
}
},
execute = function(dz, trigger)
if trigger.isUserTrigger then
if (trigger.name == 'My 5 minute event')
-- Execute my 5 minute tasks
else
-- Execute my 10 minute tasks
else
-- Must be the motion sensor...
domoticz.userEvent('My 5 minute event').afterMins(5)
domoticz.userEvent('My 10 minute event').afterMins(10)
end
end
- waaren
- Posts: 6028
- Joined: Tuesday 03 January 2017 14:18
- Target OS: Linux
- Domoticz version: Beta
- Location: Netherlands
- Contact:
Re: 'General purpose' timers
@Andyf66,
thanks for your comprehensive explanation. I think I understand where you are coming from better now. If I remember correctly, a feature request for a countdown timer was done earlier to @gizmocuz / developers. If implemented that might be a good starting point for designing the userTrigger functionality you described.
Always good to keep learning and improving code. Thanks for that !
thanks for your comprehensive explanation. I think I understand where you are coming from better now. If I remember correctly, a feature request for a countdown timer was done earlier to @gizmocuz / developers. If implemented that might be a good starting point for designing the userTrigger functionality you described.
Always good to keep learning and improving code. Thanks for that !
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
-
- Posts: 44
- Joined: Wednesday 13 June 2018 12:13
- Target OS: Raspberry Pi / ODroid
- Domoticz version:
- Contact:
Re: 'General purpose' timers
Indeed, a countdown timer is actually a logical extension of this mechanism. What I’m proposing is really just a ‘one shot’ countdown.
Who is online
Users browsing this forum: No registered users and 1 guest