And for OP digital: each dzvents script consists of a few mandatory sections:
- execute section : WHAT needs to be executed
- on section : WHEN to execute it.
The on section can contain multiple entries for when Domoticz must call the execute function. If you specify more than one entry, Domoticz will call the execute function when the condition(s) is/are met for each of those entries. So if you specify some device in the on section, the execute function will be called every time the state or value in that device changes. When you specify a timer, the execute function will be called when the timer condition is met. In your example this means the execute function will be called at every minute from 9:00 until 16:00.
So when you specified
Code: Select all
on = {
timer = { 'between 09:00 and 16:00' },
devices = { 'Outside Shade' , 'Heating Auto'}
}
this meant the execute function was called at 9:00, at 9:01, at 9:02, .... and at 16:00. But also when the status of device 'Outside Shade' changed or the status for device 'Heating Auto' changed. Regardless of the time when those changes were done: i.e. also outside of the 9:00 to 16:00 time window.
You have to be very careful if you combine timer and device on-clauses and even if you combine multiple on clauses of the same type. It is very easy to make mistakes if you have more than 1 reason why the execute function can be called. The best advice I can give you for any dzvents script's execute function that has more than 1 item in it's on-section is to always first check the reason why the execute function was called: First check for the type of thr "trigger". You can determine this information from the 2nd parameter tot the execute() function as described
here. This 2nd parameter will be a device-object if the reason to call your execute() function was a device in your on list was changed. But it will be a timer-object if the execute was called because the current time equals one of your timer clauses in the on-section. And so on for all of the possible on types, as listed in the documentation. So the first thing you should do in each execute() function when you have multiple types is check for the type of the object in that 2nd parameter. Then if you need to, you should check which device, timer, etc specifically it was that caused execute() to get called. This you can do by looking at the attributes of the object in that 2nd parameter. For a device object that can be for example the .name attribute or the .idx attribute. For a timer object that can be the .trigger attribute.
Code: Select all
execute = function(domoticz, item)
if item.isDevice then
-- todo: do something when a device changes.
-- To check for one specific device, you can check for the device name or idx. For example:
if item.name == "My 1st device" then
-- todo: do something that only needs done when My 1st device changes.
elseif item.idx == 204 then
-- todo: do something when device with idx 204 changes.
else
-- we were called for a device that I didn't expect. You can ignore or raise an error here.
end
elseif item.isTimer then
-- todo: do something when a time event occurs.
-- To check for one specific timer, you can again check for the .name attribute. This will match
-- the text that you specified in the on-section. For example:
if item.trigger == "every minute" then
-- todo: do something that needs to be done every minute.
-- Please note that if you specify a time range the execute function will be called on every
-- minute that falls within the specified time range. So if you specify for example
-- "between 9:00 and 9:05", the execute function will be called at 9:00, 9:01, 9:02, 9:03,
-- 9:04 and 9:05. There are many more ways of specifying a range, for example "at daytime"
-- triggers the execute function every minute from sunrise to sunset.
elseif item.trigger == "every hour" then
-- todo: do something that needs to be done every hour. Please note that at for example 9:00
-- the execute() function will be called twice: once with a timer object in the 2nd parameter
-- with .name = "every minute" and another time with a timer object with .name = "every hour".
else
-- Some other timer definition that we didn't expect caused execute() to get called. You can
-- coose to ignore it or raise an error or you can decide that you still want to do something
-- no matter what. It's up to you and what you're trying to achieve.
end
else
-- Some type of trigger we didn't expect made us get called. You can ignore it or raise an error here.
end
end
I personally don't very much like to use timer triggers in dzvents scripts because they cause the execute
function to be called so often and you'll need all sorts of logic to make sure that you don't do something
that has already been done a minute before. Instead of that I like to define some dummy switch device,
then write the script to execute what needs to be done when the switch goes off or on. Then in the UI i
can easily have the switch go to some state at specific times via the 'timers' button on the switch. This
makes coding scripts a lot easier.