Why is setting global variables taking so long?

I have various global variables used to determine the modes and scenes in rooms. What I am noticing is when anything conditional seems to be running and global variables are set while the conditions are running the time to set them can take up to 1 second. Beleow is one of the room actions that I use for determining what scene to set:

In the current state when the rule executes you can see that in the true block it's taking about 4 seconds to complete the steps there. The true block starts here: 2019-09-02 10:29:02.418 am infoAction: IF (Variable isDay(true) = true(T) AND Variable isEvening(false) = false(T) [TRUE]) THEN

 app:3032019-09-02 10:29:01.469 am infoAction: IF (Variable OfficeProgrammatic(true) = true(T) [TRUE]) THEN
app:3032019-09-02 10:29:01.645 am infoAction: IF (Mode is Awake(F) AND Variable isNight(false) = true(F) [FALSE]) THEN (skipping)
app:3032019-09-02 10:29:01.647 am infoAction: Set OfficeSceneProgrammatic to 'idle' (skipped)
app:3032019-09-02 10:29:01.881 am infoAction: IF (Variable OfficeSceneMode(programmatic) = programmatic(T) [TRUE]) THEN (skipped)
app:3032019-09-02 10:29:01.901 am infoAction: Activate scenes: Office Idle (skipped)
app:3032019-09-02 10:29:01.903 am infoAction: Set OfficeSceneCurrent to '%OfficeSceneProgrammatic%' (skipped)
app:3032019-09-02 10:29:01.905 am infoAction: Set OfficeActionKnown to true (skipped)
app:3032019-09-02 10:29:01.907 am infoAction: END-IF (skipped)
app:3032019-09-02 10:29:01.908 am infoAction: END-IF
app:3032019-09-02 10:29:02.418 am infoAction: IF (Variable isDay(true) = true(T) AND Variable isEvening(false) = false(T) [TRUE]) THEN
app:3032019-09-02 10:29:02.420 am infoAction: Set OfficeSceneProgrammatic to 'off'
app:3032019-09-02 10:29:03.957 am infoAction: IF (Variable OfficeSceneMode(programmatic) = programmatic(T) [TRUE]) THEN
app:3032019-09-02 10:29:03.977 am infoAction: Activate scenes: Office Off
app:3032019-09-02 10:29:04.061 am infoAction: Set OfficeSceneCurrent to '%OfficeSceneProgrammatic%'
app:3032019-09-02 10:29:05.419 am infoAction: Set OfficeActionKnown to true
app:3032019-09-02 10:29:06.683 am infoAction: END-IF
app:3032019-09-02 10:29:06.685 am infoAction: END-IF
app:3032019-09-02 10:29:06.944 am infoAction: IF (Variable isEvening(false) = true(F) [FALSE]) THEN (skipping)
app:3032019-09-02 10:29:06.946 am infoAction: Set OfficeSceneProgrammatic to 'idle' (skipped)
app:3032019-09-02 10:29:07.172 am infoAction: IF (Variable OfficeSceneMode(programmatic) = programmatic(T) [TRUE]) THEN (skipped)
app:3032019-09-02 10:29:07.195 am infoAction: Activate scenes: Office Idle (skipped)
app:3032019-09-02 10:29:07.196 am infoAction: Set OfficeSceneCurrent to '%OfficeSceneProgrammatic%' (skipped)
app:3032019-09-02 10:29:07.198 am infoAction: Set OfficeActionKnown to true (skipped)
app:3032019-09-02 10:29:07.199 am infoAction: END-IF (skipped)
app:3032019-09-02 10:29:07.200 am infoAction: END-IF
app:3032019-09-02 10:29:07.224 am infoAction: IF (Mode is Sleep(F) [FALSE]) THEN (skipping)
app:3032019-09-02 10:29:07.226 am infoAction: Set OfficeSceneProgrammatic to 'off' (skipped)
app:3032019-09-02 10:29:07.228 am infoAction: Set OfficeSceneMode to 'programmatic' (skipped)
app:3032019-09-02 10:29:07.250 am infoAction: Activate scenes: Office Off (skipped)
app:3032019-09-02 10:29:07.252 am infoAction: Set OfficeSceneCurrent to '%OfficeSceneProgrammatic%' (skipped)
app:3032019-09-02 10:29:07.255 am infoAction: Set OfficeActionKnown to true (skipped)
app:3032019-09-02 10:29:07.257 am infoAction: END-IF
app:3032019-09-02 10:29:07.258 am infoAction: END-IF

Any idea on what could be causing this?

Global variables are part of the parent Rule Machine App and not the child rule app. So, every time you set or read a global variable it has to open the parent app to do so. You are doing this to see if a scene is active? You know that the scene device will be "on" if the devices within the scene match the settings of the scene, correct? You might not need as much of this recording as you need. Plus, it would be easier to record the scene that is used when it is triggered. This is definitely going to cause major slow-down of your hub.

Not point I am trying to make Ryan, I am using the global s to set state of the programmatic execution no matter what state of the room is. I have used this technique for over 15 years with home automation since there are many inputs that can override the programmatic actions for the room. The goal is not to re-execute the rules every time but store that programmatic should be. From the Stargate/x10 days, SmartThings, and now Hubitat this technique has worked fine but in the last few updates something changed where the global s are taking longer to work with.

Okay. Bruce has said that setting or reading global variables requires opening the parent app. That's why it takes longer.

Wow! I wish I'd seen this before changing to use global variables in my RM4 rules that are triggered the most often. Oops! I've been beating my head against the wall trying to figure out why I started seeing huge lags and some of my Hue bulbs were not responding as they should -- i.e. not turning on/off or at the wrong level.

I've updated the rules to use local variables and, where necessary, virtual devices to "send" values from one rule to another. Everything is working great now -- no lags and no weird bulbs.

I'm going to be very careful with global variables from now on.

How are you using Virtual devices to transfer values? Any samples you can pass along would be great.

For example, I use a calculated lux value to determine the level I want to set the kitchen lights to. I have one rule that calculates the lux and sets a virtual dimmer to the level I want. The rule that runs the kitchen lights uses the virtual dimmer level to set the level for the kitchen.

Here's part of the light that calculates the lux and sets the virtual dimmer called Weather - Lux Percent. There's more of it that sets other dimmer levels, but this give the idea.

And this is part of the rule that runs the kitchen lights. If private boolean is true, it's first thing in the morning and I always want the lights to come on at 100% and daylight white. Otherwise, it sets a local variable (setLuxPercent) to the level of Weather - Lux Percent that was set in the prior rule, and then the local variable is used to set the kitchen dimmer level.

ETA: "Virtual Lux" in the first rule is a virtual omni sensor. I use it to transfer the calculated lux value to other rules. This is a rule that determines if the kitchen should be automated or not, based on lux:

1 Like

Thanks this looks great. I may try this on a couple of my room scenes.

Just a heads up. I think the issue was caused by the outer if statement that evaluates the true condition. I had all the nested conditions on true. Looking at @jabecker example I noticed he used the "exit" on condition as the first statement. This morning with some free time I tried the same with one of my programmatic room scenes and it ran in under 2 seconds. Before it was taking close to 4+ seconds to run though the actions. Here is my updated code:

You can see the previous code in the first post in this thread: Why is setting global variables taking so long?

I don't know if it's the number of statements in a if condition or the nesting itself. I may try a triple nested condition like my first example with just a few lines to see what the results would be but for right now I am happy that my lighting scenes are all working faster.

There is still a .3 to .4 second impact for using global variables though.

Ah yes… I’d changed a bunch of my rules to use restrictions, because that seemed like a reasonable idea. Just before restrictions were removed. This was the solution to no more restrictions.

Damn. I did not know this about global variables.

I only found this when searching on a global variable triggering issue i am seeing.

1 Like