Clarity on how global variables update-Bug


#1

I have a question on how global variables get updated after a piston exits. I have a piston per room that executes scenes based on global Boolean flag changes for light out side, dark outside, etc. Each room piston uses two global variables. So far two rooms seem to be behaving right and updates their global’s after the piston exits, two others never update their global variables when exiting. 3 of these pistons use the dark outside flag and trigger concurrently, All logs show the pistons changing the global variable values with no errors. But when I look at the UI and the global variables only one piston changed it’s values.

So my question is when a piston executes, changes a global variable, and then exits is when the global variable is updated. Does the piston just output the changed variable at exit or does the snapshot it takes of the global’s get written out as a whole? This could explain the behavior I have been seeing but want to bounce this off the community.

I have highlighted below the variables used by the programed rooms and the only one that has the right values after a dark outside change is the office global:

image

Thanks


#2

Trying to understand better…

It sounds like you have one piston monitoring the ‘dark’, and when it happens, that one piston is supposed to write to 4 global variables… and those 4 globals are being monitored by 4 other pistons…

Is this your layout?


#3

I have 4 pistons monitoring for the “dark” global variable to change to true. They are

  • Office (Dark to True set to 1, Dark to False set to 0)

  • Basement (Dark to true or false set to 0)

  • Family Room ( Dark to true set to 1, Dark to false set to 0)

  • Dining Room (Dark to true set to 4, Dark to false set to 0)

Each of them then change the @sXXXXProgramitic to their scene number 1-4 , Any manual setting of the room changes the @sXXXX to the manual scene of the room and that always seems to work fine XXXX represents the room

When Dark changes to false the @sXXXXProgramatic and @sXXXX get set to Zero. Every time the global changes only one room the Office has the right value, The Dining Room and Family room never changes to zero’s even though the logs show they did. Here is the results of the Dark changing to False this morning, you can see the only room that changed was the office. But my logs show all 4 pistons ran, I assumed basement stayed the same due to no action taken.

image

That is leading me to think that when this DARK change happens and all 4 of the pistons fire they make a snapshot of all the global’s and use them while the piston is running, Then when a piston exits is seems to write out all the global’s vs. just the ones that changes. Overrding the other rooms where the pistons may have exited a few milliseconds earlier. It the only way I can explain the behavior.

I know the global variables are working in the piston while is running due to my logging and setting piston state on exit to the final value of @sXXXX and @sXXXXprogramatic and the lights and other actions work. The issue is I use the @sXXXXprogramaitc values for other purposes. My technique of using a piston per room for programmatic scene selection and recovery tested out great with one room taking this approach but since I added additional rooms this cropped up.

Thoughts?


#4

Spending about hour this morning I created a test harness to prove that Global Variables are written as a whole from a piston not just changes. I created 4 simple pistons that set it’s own global to it’s piston number in the test when the test global goes true and then back to zero when false The results were that only 2 of the 4 global’s reset to zero after the first time executed. I assume this is a bug not a feature :slight_smile:

I am attaching my testing pistons for review by the community along with the variables Global%20Variable%20Results

Below are the final logs from the pistons when setting the value of each pistons global variable back to zero:

Piston #1

4‎/‎28‎/‎2018‎ ‎6‎:‎57‎:‎17‎ ‎AM +441ms
+0ms╔Received event [Home].:07ee06c3a2155dec348066845fb71c98: = @fTest with a delay of 79ms+96ms║RunTime Analysis CS > 25ms > PS > 43ms > PE > 29ms > CE
+99ms║Runtime (39030 bytes) successfully initialized in 43ms (v0.3.104.20180323) (97ms)
+100ms║╔Execution stage started
+108ms║║Comparison (boolean) false is (boolean) true = false (2ms)
+109ms║║Cancelling condition #4’s schedules…
+110ms║║Condition #4 evaluated false (6ms)
+111ms║║Cancelling condition #1’s schedules…
+112ms║║Condition group #1 evaluated false (state changed) (7ms)
+118ms║║Comparison (boolean) false is (boolean) false = true (1ms)
+119ms║║Condition #8 evaluated true (5ms)
+120ms║║Condition group #5 evaluated true (state did not change) (6ms)
+122ms║║Cancelling statement #6’s schedules…
+125ms║║Executed virtual command setVariable (1ms)
+131ms║║Calculating (string) Test Piston 1 exited with @sTestPiston1 set to + (string) 0 >> (string) Test Piston 1 exited with @sTestPiston1 set to 0
+134ms║╚Execution stage complete. (34ms)
+135ms╚Event processed successfully (135ms)

Piston #2
4‎/‎28‎/‎2018‎ ‎6‎:‎57‎:‎17‎ ‎AM +439ms
+0ms╔Received event [Home].:07ee06c3a2155dec348066845fb71c98: = @fTest with a delay of 78ms+93ms║RunTime Analysis CS > 25ms > PS > 44ms > PE > 24ms > CE
+95ms║Runtime (39016 bytes) successfully initialized in 44ms (v0.3.104.20180323) (94ms)
+96ms║╔Execution stage started
+105ms║║Comparison (boolean) false is (boolean) true = false (1ms)
+106ms║║Cancelling condition #4’s schedules…
+107ms║║Condition #4 evaluated false (6ms)
+108ms║║Cancelling condition #1’s schedules…
+108ms║║Condition group #1 evaluated false (state changed) (7ms)
+115ms║║Comparison (boolean) false is (boolean) false = true (1ms)
+116ms║║Condition #8 evaluated true (5ms)
+117ms║║Condition group #5 evaluated true (state did not change) (5ms)
+119ms║║Cancelling statement #6’s schedules…
+122ms║║Executed virtual command setVariable (1ms)
+128ms║║Calculating (string) Test Piston 2 exited with @sTestPiston2 set to + (string) 0 >> (string) Test Piston 2 exited with @sTestPiston2 set to 0
+131ms║╚Execution stage complete. (35ms)
+132ms╚Event processed successfully (132ms)

Piston #3
4‎/‎28‎/‎2018‎ ‎6‎:‎57‎:‎17‎ ‎AM +448ms
+1ms ╔Received event [Home].:07ee06c3a2155dec348066845fb71c98: = @fTest with a delay of 87ms+101ms║RunTime Analysis CS > 18ms > PS > 57ms > PE > 26ms > CE
+104ms║Runtime (39017 bytes) successfully initialized in 57ms (v0.3.104.20180323) (103ms)
+105ms║╔Execution stage started
+113ms║║Comparison (boolean) false is (boolean) true = false (1ms)
+115ms║║Cancelling condition #4’s schedules…
+116ms║║Condition #4 evaluated false (6ms)
+117ms║║Cancelling condition #1’s schedules…
+117ms║║Condition group #1 evaluated false (state changed) (8ms)
+124ms║║Comparison (boolean) false is (boolean) false = true (1ms)
+125ms║║Condition #8 evaluated true (5ms)
+126ms║║Condition group #5 evaluated true (state did not change) (6ms)
+128ms║║Cancelling statement #6’s schedules…
+132ms║║Executed virtual command setVariable (0ms)
+138ms║║Calculating (string) Test Piston 3 exited with @sTestPiston3 set to + (string) 0 >> (string) Test Piston 3 exited with @sTestPiston3 set to 0
+141ms║╚Execution stage complete. (37ms)
+142ms╚Event processed successfully (142ms)

Piston #4
4‎/‎28‎/‎2018‎ ‎6‎:‎57‎:‎17‎ ‎AM +400ms
+1ms╔Received event [Home].:07ee06c3a2155dec348066845fb71c98: = @fTest with a delay of 39ms+71ms║RunTime Analysis CS > 20ms > PS > 31ms > PE > 20ms > CE
+73ms║Runtime (39016 bytes) successfully initialized in 31ms (v0.3.104.20180323) (72ms)
+74ms║╔Execution stage started
+82ms║║Comparison (boolean) false is (boolean) true = false (1ms)
+83ms║║Cancelling condition #4’s schedules…
+84ms║║Condition #4 evaluated false (5ms)
+85ms║║Cancelling condition #1’s schedules…
+86ms║║Condition group #1 evaluated false (state changed) (8ms)
+91ms║║Comparison (boolean) false is (boolean) false = true (1ms)
+92ms║║Condition #8 evaluated true (4ms)
+93ms║║Condition group #5 evaluated true (state did not change) (5ms)
+95ms║║Cancelling statement #6’s schedules…
+98ms║║Executed virtual command setVariable (1ms)
+104ms║║Calculating (string) Test Piston 4 exited with @sTestPiston4 set to + (string) 0 >> (string) Test Piston 4 exited with @sTestPiston4 set to 0
+107ms║╚Execution stage complete. (32ms)
+108ms╚Event processed successfully (107ms)


#5

So I have two thoughts, and either one should work for you.

(1) The piston monitoring the “dark” and setting the dark global to true/false (not seen in any of your pics above) could also write to all 4 of the rooms globals at the same time.

Or you could try:

(2) Letting the rooms monitor the dark global, and then use LOCAL variables to keep track of your flags for that room.

From what I have seen, storing globals for future use works great, but storing globals to be used this instant is not so good.


#6

WCmore,

the issue here I am not storing for immediate execution I have 4 pistons firing off due to the flag changing as shown in my test harness. They change the unique global’s based on the Boolean going true or false. Each unique global should have ended up being ‘zero’ after the @fTest went false but as you can see only two of the four ended up in that state even though the logs show all 4 successfully sent their global’s. I planned on using these global values for future executions to reference the rooms default and current state from or pistons etc. Looks like this bug isn’t going to allow me to continue with this pattern.

I did change global’s to local variables this morning and that solved for the individual pistons maintaining it’s logic but now I am blind to the rooms current values. Oh well. Looking for more alternatives or going to have to wait for a bug fix.


#7

It sounds like there are issues with 4 pistons trying to write to globals at the same time.
(picture 4 kids drawing on the same piece of paper… There’s bound to be issues, LOL)

I think my previous suggestion would work around that, since only one piston would be writing to globals at a time:

(1) The piston monitoring the “dark” and setting the dark global to true/false, could also write to all 4 of the room’s globals at the same time.


#8

Also, in case you are unaware, when dealing with global variables:

Any piston can read to a global
Any piston can write to a global

-BUT-

Any piston that writes to a global will not be able to see/use the new number (within that same piston) until the next time the piston is run.

A good rule of thumb:

  • A piston can read from and then write to a global
  • A piston cannot write to and then read from that global

So if you need to store a variable halfway thru your code, then do X based on that variable, you MUST use local variables (or a second piston)


#9

Thanks but yes I am fully aware that a piston doesn’t update global’s until they exit. Let me restates the bug, if multiple pistons are updating unique global variables like in my examples, Some of the variables that were shown being updated in the log being updated are not updated state due to some type concurrency issue with how global updates are processed upon piston exits.

If you want to reproduce for yourself take my example pistons, create the globals that they use, set the global fTest to true to trigger them, then trigger back to false to set all 4 back to zeros and you will find that all 4 of the variables will neither change to their expected value to even reset back to zero due to the concurrency.


#10

I am not sure of the ‘behind the scenes’ actions, but I would try to avoid having different pistons all trying to edit globals simultaneously.

Old school example:
Have you ever shared a ‘whiteboard’ with multiple coworkers, or used a CB radio? Even though (theoretically) everyone can use it at once, the general practice is, only one at a time should. Things get hectic (or lost) when there are too many active participants.

I think the analogy applies here as well. I still think my (1) suggestion above would solve your issue smoothly, but if you don’t want to go that route, maybe adding pauses of different lengths to each room’s piston will let the globals be written at different times.