Page 1 of 1

CommandArray executed in steps?

Posted: Sunday 03 April 2016 16:18
by Bikey
Hi,

I have a LUA device script which (amongst others) contains the following:

if (otherdevices[AlarmStatus] == 'On') then
commandArray['AlarmStatus']='Off'
commandArray['AnotherSwitch']='Off'
commandArray['AndAnotherSwitch']='Off'
end
return commandArray

I would think that this could only run once because it resets its own condition (Alarmstatus =on) to "Off".

However, what I see is that the setting of the other switches seems to be executed first, thereby immediately triggering this device-script again, while the AlarmStatus is still "On".

I was thinking all the values would be set to "Off" at the same time, when executing the return commandArray, but this seems not to be true.

Is that normal behaviour? And if so, I can a prevent the script to basically trigger itself with "old" values?

Re: CommandArray executed in steps?

Posted: Sunday 03 April 2016 16:56
by jvdz
There is probably some other condition in your script or else the 'AlarmStatus' would always be "Off"?
What you could do is change the logic to:

Code: Select all

if ('some other condition" and otherdevices[AlarmStatus] == 'On') then
   commandArray['AlarmStatus']='Off'
end
if (devicechanged['AlarmStatus'] == 'Off') then
   commandArray['AnotherSwitch']='Off'
   commandArray['AndAnotherSwitch']='Off'
end
Jos

Re: CommandArray executed in steps?

Posted: Sunday 03 April 2016 17:10
by NickHead
From what I gather, commandarray has to have a number after it
if it contains more than one.

i.e
commandArray[1] = {['UpdateDevice'] = houseid .. "|0|" .. housepower .. ";" .. houseenergy}
commandArray[2] = {['UpdateDevice'] = pumpid .. "|0|" .. pumppower .. ";" .. pumpenergy}
commandArray[3] = {['UpdateDevice'] = solarid .. "|0|" .. solarpower .. ";" .. solarenergy}

or some commands won't be updated correctly.

SEE:

https://www.domoticz.com/wiki/Capturing ... ua_Scripts

Re: CommandArray executed in steps?

Posted: Sunday 03 April 2016 17:26
by Bikey
jvdz wrote:There is probably some other condition in your script or else the 'AlarmStatus' would always be "Off"?
What you could do is change the logic to:

Code: Select all

if ('some other condition" and otherdevices[AlarmStatus] == 'On') then
   commandArray['AlarmStatus']='Off'
end
if (devicechanged['AlarmStatus'] == 'Off') then
   commandArray['AnotherSwitch']='Off'
   commandArray['AndAnotherSwitch']='Off'
end
Jos
Thanks, you helped me in the right direction!
I tried to execute everything within one cycle of the script, but the ran into the unpredictable sequence of execution of the comandArray commands, which triggered the script again too.

With your setup the script always has to be executed twice but with the checking on the devicechanged['AlarmStatus'] I can now be sure that it is triggered by the changing value of the Alarmstatus, but also that this changed before the other switches are changed.

Re: CommandArray executed in steps?

Posted: Sunday 03 April 2016 17:54
by jvdz
NickHead wrote:From what I gather, commandarray has to have a number after it
if it contains more than one.
Not really. This is only really required when you want to do multiple commands on the same device.
eg:

Code: Select all

commandArray[#commandArray+1]={["Lamp"] = "On"
commandArray[#commandArray+1]={["Lamp"] = "Set Level 50 After 60"
Jos

p.s. The #commandArray+1 is a trick to always add one to the current number of entries in the array. Just easier as you don't need to track the number of entries in case of larger scripts with multiple actions.

Re: CommandArray executed in steps?

Posted: Sunday 03 April 2016 17:59
by jvdz
Bikey wrote: With your setup the script always has to be executed twice but with the checking on the devicechanged['AlarmStatus'] I can now be sure that it is triggered by the changing value of the Alarmstatus, but also that this changed before the other switches are changed.
It really depends on you overall logic to trigger the 'AlarmStatus' switch. It likely can all be done in one iteration, but there has to be another If somewhere or else your 'AlarmStatus' switch is always changed to Off. :)

Jos

Re: CommandArray executed in steps?

Posted: Sunday 03 April 2016 23:52
by Bikey
Sure, there is another command in my script that turns the AlarmStatus 'on', but could als have been done by another script or action. That is not really the problem.

Point is, that if I turn it Off in a single action while also switching other devices off in a single run of the script, it looks like I can not be sure that they turn off simultaneously in a single atomic action without triggering the script in between.

So then my script is triggered again by the changing of one of these devices and it checks and sees that AlarmStatus is still on resulting in wrong conclusions in other conditional checks.

Re: CommandArray executed in steps?

Posted: Monday 04 April 2016 0:45
by simonrg
Bikey wrote:Sure, there is another command in my script that turns the AlarmStatus 'on', but could als have been done by another script or action. That is not really the problem.
It really would help people to help and to learn if you could post the whole of your script(s).

It is often other unintended changes of state in a script which give apparently unpredictable behaviour :shock:

Re: CommandArray executed in steps?

Posted: Monday 04 April 2016 10:57
by Bikey
Ok, here it is, the original script that causes unpredictable behavior, hope you can find the issue:

Explanation:
I have 3 alarmsensors from my burglar alarmsystem via the GPIO-pins of my RPI2 connected to Domoticz. If one (or more) of these are "Open" I want to get a notification and activate a group of lights. If all sensors are "closed" the alarm must reset.

I also have 2 Flamingo FA20RF smoke detectors with loud sirens that I want to activate in case of a burglar alarm. While the alarm is active the sirens must be reactivated every 12 seconds to keep making sound.
However if the smoke detectors are active while there is no burglar alarm this has to be detected as an actual smoke alarm.

Problem:
The current script triggers multiple times on a reset off the alarm, because if the "AlarmStatus" virtual switch is set to "Off" in a single action with setting the lights to "off", the the action on the lights seem to retrigger this (device) script before the AlarmStatus ="Off" is executed.

This also sometimes results on triggering a false "smoke alarm" because if the "AlarmStatus" = Off is executed before the execution of the SmokeSensor= "Off", the script thinks it is an smoke alarm situation. Or vice versa when starting the alarm if the smoke sirens are activated this regtriggers the script before actually executing the AlarmStatus="On", again resulting in a false smoke alarm.

Code: Select all

local Alarmsensor_1 ='AlarmDownstairsTripped'
local Alarmsensor_2 ='AlarmUpstairsTripped'
local Alarmsensor_3 ='AlarmPIRTripped'
local AlarmStatus = '$AlarmActivated'
local Smokesensor_Up = 'SmokeSiren_1'
local Smokesensor_Down = 'SmokeSiren_2'
local AlarmLights = 'Group:$BurlarAlarmLights'
local RepeatAlarm = '$AlarmRepeat'

local Loc_Alarmtrigger

commandArray = {}
    Loc_Alarmtrigger = 'Off'
    if devicechanged[Alarmsensor_1] == 'Open' then
        print('<FONT COLOR="#FF00FF">Alarm downstairs!</FONT>')
        Loc_Alarmtrigger = 'On'
    end
    if devicechanged[Alarmsensor_2] == 'Open' then
        print('<FONT COLOR="#FF00FF">Alarm Upstairs!</FONT>')
        Loc_Alarmtrigger = 'On'
    end
    if devicechanged[Alarmsensor_3] == 'Open' then
        print('<FONT COLOR="#FF00FF">Alarm PIR!</FONT>')
        Loc_Alarmtrigger = 'On'
    end
    if ((otherdevices[AlarmStatus] == 'On') and (otherdevices[Alarmsensor_1] == 'Closed') and (otherdevices[Alarmsensor_2] == 'Closed') and (otherdevices[Alarmsensor_3] == 'Closed')) then    
    -- all sensors are closed, reset alarm status
        print('<FONT COLOR="#FF00FF">Alarm reset</FONT>')
        commandArray[AlarmStatus]='Off'
        commandArray[Smokesensor_Up]='Off'
        commandArray[Smokesensor_Down]='Off'
        commandArray[AlarmLights]='Off'
    end
    -- handle alarmtriger first time
    if Loc_Alarmtrigger == 'On' then
        print('<FONT COLOR="#FF00FF">Handling alarm!</FONT>')
        commandArray[AlarmStatus]='On'
        commandArray[AlarmLights]='On'
        --RepeatAlarm has a turn-off delay of 12 seconds and will retrigger this script. 
        commandArray[RepeatAlarm]='On'
        -- Activate the siren on the Smoke detectors:       
        commandArray[Smokesensor_Up]='On'
        commandArray[Smokesensor_Down]='On'
    end
    -- check if smoke sirens must be activated again after expiry of the AlarmRepeat timer
    if ((devicechanged[RepeatAlarm]) == 'Off' and (otherdevices[AlarmStatus] == 'On')) then
        print('<FONT COLOR="#FF0000">Repeating alarm...</FONT>')
        commandArray[RepeatAlarm]='On'
        commandArray[Smokesensor_Up]='On'
        commandArray[Smokesensor_Down]='On'
    end
    -- Check If the smoke sirens are active but not triggered by the burglar alarm, then it is an actual smoke alarm
    if ((otherdevices[AlarmStatus] == 'Off') and (Loc_Alarmtrigger == 'Off')) then
        if devicechanged[Smokesensor_Up] == 'On' then
            print('<FONT COLOR="#FF00FF">Smoke alarm upstairs!</FONT>')
            commandArray['SendNotification']='#HandleAlarm-script#Smoke alarm upstairs!#1'
        end
        if devicechanged[Smokesensor_Down] == 'On' then
            print('<FONT COLOR="#FF00FF">Smoke alarm downstairs!</FONT>')
            commandArray['SendNotification']='#HandleAlarm-script#Smoke alarm downstairs!#1'
        end
    end        
return commandArray

Re: CommandArray executed in steps?

Posted: Monday 04 April 2016 19:12
by jvdz
It is not easy for me to follow all logic you like to have, but it feels you should move all settings of devices into an separate
if devicechanged("AlarmStatus") == "Off" then block to executed them there, avoiding the issue you raised.

Jos

Re: CommandArray executed in steps?

Posted: Monday 04 April 2016 19:59
by Bikey
Yes, I think so too. This is my theory of the odd behaviour:
I guess that the issues occur because this is a Device script: that means that it is triggered whenever a device changes its state, even if the script that changed that state is still running, which then basically triggers itself. So that generates multiple instances of the running script which then checks the state of switches ("otherdevices") that are not yet set by the firs instance.

Question to the developers: am I right to think that Domiticz can multitask and run several scrips simultaneously?