CommandArray executed in steps?

Moderator: leecollings

Post Reply
Bikey
Posts: 331
Joined: Sunday 22 February 2015 12:19
Target OS: Linux
Domoticz version: 2020.x
Location: Netherlands
Contact:

CommandArray executed in steps?

Post 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?
User avatar
jvdz
Posts: 2334
Joined: Tuesday 30 December 2014 19:25
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.107
Location: Netherlands
Contact:

Re: CommandArray executed in steps?

Post 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
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
NickHead
Posts: 83
Joined: Tuesday 29 October 2013 18:30
Target OS: Linux
Domoticz version:
Location: North East Coast of the UK
Contact:

Re: CommandArray executed in steps?

Post 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
A lot of stuff that is doing my head in.
Bikey
Posts: 331
Joined: Sunday 22 February 2015 12:19
Target OS: Linux
Domoticz version: 2020.x
Location: Netherlands
Contact:

Re: CommandArray executed in steps?

Post 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.
User avatar
jvdz
Posts: 2334
Joined: Tuesday 30 December 2014 19:25
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.107
Location: Netherlands
Contact:

Re: CommandArray executed in steps?

Post 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.
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
User avatar
jvdz
Posts: 2334
Joined: Tuesday 30 December 2014 19:25
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.107
Location: Netherlands
Contact:

Re: CommandArray executed in steps?

Post 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
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
Bikey
Posts: 331
Joined: Sunday 22 February 2015 12:19
Target OS: Linux
Domoticz version: 2020.x
Location: Netherlands
Contact:

Re: CommandArray executed in steps?

Post 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.
simonrg
Posts: 329
Joined: Tuesday 16 July 2013 22:54
Target OS: Raspberry Pi / ODroid
Domoticz version: 3.8807
Location: North East England
Contact:

Re: CommandArray executed in steps?

Post 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:
Raspberry Pi 2 B - 2A@5V PSU - Raspbian + Domoticz + RFXtrx(89), LightwaveRF House(dimmers, sockets, wireless/mood switches), Owl CM113, 4 LaCross Temp / Humidity Sensors, 4 Siemens PIR, Smappee, Solaredge, ESP8266
Bikey
Posts: 331
Joined: Sunday 22 February 2015 12:19
Target OS: Linux
Domoticz version: 2020.x
Location: Netherlands
Contact:

Re: CommandArray executed in steps?

Post 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
User avatar
jvdz
Posts: 2334
Joined: Tuesday 30 December 2014 19:25
Target OS: Raspberry Pi / ODroid
Domoticz version: 4.107
Location: Netherlands
Contact:

Re: CommandArray executed in steps?

Post 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
New Garbage collection scripts: https://github.com/jvanderzande/GarbageCalendar
Bikey
Posts: 331
Joined: Sunday 22 February 2015 12:19
Target OS: Linux
Domoticz version: 2020.x
Location: Netherlands
Contact:

Re: CommandArray executed in steps?

Post 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?
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest