Variables broken
Moderator: Martin
Variables broken
... Or correct me if I'm doing something incorrect here.
The variable seems to be resetting itself when in a loop, even though it's intended to break out of the loop.
The attached flow demonstrates this.
http://automagic4android.com/flow.php?i ... 02129505a2
The variable seems to be resetting itself when in a loop, even though it's intended to break out of the loop.
The attached flow demonstrates this.
http://automagic4android.com/flow.php?i ... 02129505a2
Re: Variables broken
So am I the only person running into this?
I'm really a fan of the interface, so I was intent on migrating all of my tasker profiles (a lot of which see very complex), but then ran into this. I've already adjusted my flow to sidestep the problem, but I'd like to understand what's happening...
I'm really a fan of the interface, so I was intent on migrating all of my tasker profiles (a lot of which see very complex), but then ran into this. I've already adjusted my flow to sidestep the problem, but I'd like to understand what's happening...
Re: Variables broken
Hi,
Local variables are local to the flow (per executed instance of the flow) so when you modify the local variable a in the left branch of the flow it will affect the right branch of the flow. The timing is important in this case since you are executing two branches in parallel. The variable a contains the last assigned value when an action is executed. When the left branch assigns 1 to a the right branch will also see value 1 starting from this point.
In your flow the first script initializes a with 0, so the first condition Expression a==0 is true and the right branch continues for now and displays a on the right: 0, the left branch now assigns the value 1 to variable a and displays a on the left: 1, the branch on the right terminates when the condition Expression: a==0 is executed the next time since a contains 1. The left branch also terminates on the same condition.
Regards,
Martin
Local variables are local to the flow (per executed instance of the flow) so when you modify the local variable a in the left branch of the flow it will affect the right branch of the flow. The timing is important in this case since you are executing two branches in parallel. The variable a contains the last assigned value when an action is executed. When the left branch assigns 1 to a the right branch will also see value 1 starting from this point.
In your flow the first script initializes a with 0, so the first condition Expression a==0 is true and the right branch continues for now and displays a on the right: 0, the left branch now assigns the value 1 to variable a and displays a on the left: 1, the branch on the right terminates when the condition Expression: a==0 is executed the next time since a contains 1. The left branch also terminates on the same condition.
Regards,
Martin
Re: Variables broken
This is what it is supposed to do, but not what out does when the trigger is turned on.
If you turn on the conditions for "app starts", then switch out of automagic app and back in, you can see the issue demonstrated. The right branch continues executing even though the left branch sets a to 1 (intending to break the right loop).
Here is a segment of the log showing the if statement returning false, breaking, re-executing and returning true, restarting the loop: 24.01.2014 04:18:04.976 [Keep example] Start executing action 'Script: a = 1'
24.01.2014 04:18:04.977 [Keep example] Start executing condition 'Execution Count: 10 times'
24.01.2014 04:18:04.978 [Keep example] End executing condition 'Execution Count: 10 times' with return value false
24.01.2014 04:18:04.978 [Keep example] Start executing action 'Notification on Screen: a on the left: {a,numberformat,0}'
24.01.2014 04:18:04.979 [Keep example] Action 'Notification on Screen: a on the left: {a,numberformat,0}' Showing toast text 'a on the left: 1'.
24.01.2014 04:18:04.984 [Keep example] End executing action 'Notification on Screen: a on the left: {a,numberformat,0}'
24.01.2014 04:18:04.985 [Keep example] Start executing action 'Sleep: 1s (allow device sleep)'
24.01.2014 04:18:04.985 [Keep example] Action 'Sleep: 1s (allow device sleep)' Sleeping for 1s (allow device sleep)
24.01.2014 04:18:04.990 [Keep example] End executing condition 'Expression: a == 0' with return value true
24.01.2014 04:18:04.991 [Keep example] Flow continues executing with the next step.
24.01.2014 04:18:04.991 [Keep example] Start executing condition 'Expression: a == 0'
24.01.2014 04:18:04.992 [Keep example] Start executing condition 'Expression: a == 0'
24.01.2014 04:18:05.020 [Keep example] End executing action 'Script: a = 1'
24.01.2014 04:18:05.021 [Keep example] End executing condition 'Expression: a == 0' with return value false
24.01.2014 04:18:05.022 [Keep example] End executing condition 'Expression: a == 0' with return value false
24.01.2014 04:18:05.060 [Keep example] Flow ended.
24.01.2014 04:18:05.948 [Keep example] End executing action 'Sleep: 1s (allow device sleep)'
24.01.2014 04:18:05.985 [Keep example] Flow continues executing with the next step.
24.01.2014 04:18:05.986 [Keep example] Start executing condition 'Expression: a == 0'
24.01.2014 04:18:05.987 [Keep example] Start executing action 'Notification on Screen: a on the right: {a,numberformat,0}'
24.01.2014 04:18:05.992 [Keep example] Action 'Notification on Screen: a on the right: {a,numberformat,0}' Showing toast text 'a on the right: 0'.
24.01.2014 04:18:05.995 [Keep example] End executing action 'Notification on Screen: a on the right: {a,numberformat,0}'
24.01.2014 04:18:06.030 [Keep example] End executing condition 'Expression: a == 0' with return value true
24.01.2014 04:18:06.032 [Keep example] End executing action 'Sleep: 1s (allow device sleep)'
If you turn on the conditions for "app starts", then switch out of automagic app and back in, you can see the issue demonstrated. The right branch continues executing even though the left branch sets a to 1 (intending to break the right loop).
Here is a segment of the log showing the if statement returning false, breaking, re-executing and returning true, restarting the loop: 24.01.2014 04:18:04.976 [Keep example] Start executing action 'Script: a = 1'
24.01.2014 04:18:04.977 [Keep example] Start executing condition 'Execution Count: 10 times'
24.01.2014 04:18:04.978 [Keep example] End executing condition 'Execution Count: 10 times' with return value false
24.01.2014 04:18:04.978 [Keep example] Start executing action 'Notification on Screen: a on the left: {a,numberformat,0}'
24.01.2014 04:18:04.979 [Keep example] Action 'Notification on Screen: a on the left: {a,numberformat,0}' Showing toast text 'a on the left: 1'.
24.01.2014 04:18:04.984 [Keep example] End executing action 'Notification on Screen: a on the left: {a,numberformat,0}'
24.01.2014 04:18:04.985 [Keep example] Start executing action 'Sleep: 1s (allow device sleep)'
24.01.2014 04:18:04.985 [Keep example] Action 'Sleep: 1s (allow device sleep)' Sleeping for 1s (allow device sleep)
24.01.2014 04:18:04.990 [Keep example] End executing condition 'Expression: a == 0' with return value true
24.01.2014 04:18:04.991 [Keep example] Flow continues executing with the next step.
24.01.2014 04:18:04.991 [Keep example] Start executing condition 'Expression: a == 0'
24.01.2014 04:18:04.992 [Keep example] Start executing condition 'Expression: a == 0'
24.01.2014 04:18:05.020 [Keep example] End executing action 'Script: a = 1'
24.01.2014 04:18:05.021 [Keep example] End executing condition 'Expression: a == 0' with return value false
24.01.2014 04:18:05.022 [Keep example] End executing condition 'Expression: a == 0' with return value false
24.01.2014 04:18:05.060 [Keep example] Flow ended.
24.01.2014 04:18:05.948 [Keep example] End executing action 'Sleep: 1s (allow device sleep)'
24.01.2014 04:18:05.985 [Keep example] Flow continues executing with the next step.
24.01.2014 04:18:05.986 [Keep example] Start executing condition 'Expression: a == 0'
24.01.2014 04:18:05.987 [Keep example] Start executing action 'Notification on Screen: a on the right: {a,numberformat,0}'
24.01.2014 04:18:05.992 [Keep example] Action 'Notification on Screen: a on the right: {a,numberformat,0}' Showing toast text 'a on the right: 0'.
24.01.2014 04:18:05.995 [Keep example] End executing action 'Notification on Screen: a on the right: {a,numberformat,0}'
24.01.2014 04:18:06.030 [Keep example] End executing condition 'Expression: a == 0' with return value true
24.01.2014 04:18:06.032 [Keep example] End executing action 'Sleep: 1s (allow device sleep)'
Re: Variables broken
It's very hard to say what's going on with only part of the log. Most probably the flow is currently executing multiple times since you are using two triggers that will both execute the flow when Automagic is started (once with * and once with the package name of Automagic).
Is this on purpose or could you remove one of the triggers? When you exit Automagic the app trigger with * will most probably also execute the flow (for the home screen) which makes it even harder to understand.
The log at 24.01.2014 04:18:05.060 shows that only one flow was ended, the second is still running. Each flow has it's own copy of local variable a so the second instance of the flow that is executing might still have variable a with value 0.
Is this on purpose or could you remove one of the triggers? When you exit Automagic the app trigger with * will most probably also execute the flow (for the home screen) which makes it even harder to understand.
The log at 24.01.2014 04:18:05.060 shows that only one flow was ended, the second is still running. Each flow has it's own copy of local variable a so the second instance of the flow that is executing might still have variable a with value 0.
Re: Variables broken
The multiple triggers is intentional (and I was very happy that automagic allowed for it) I'm wanting one trigger for a generic app start, then a second immediate trigger if the app is on a selection list.
The intent is to say: if two quick triggers, notify; if one trigger within two seconds cancel notification. I'm using this to identify which apps are running to determine screen timeouts.
I can use global variables in the future for cases like these but would prefer to avoid it.
The intent is to say: if two quick triggers, notify; if one trigger within two seconds cancel notification. I'm using this to identify which apps are running to determine screen timeouts.
I can use global variables in the future for cases like these but would prefer to avoid it.
- Attachments
-
- log.txt
- (30.14 KiB) Downloaded 661 times
Re: Variables broken
The internal log file is not large enough to capture all output produced by all the parallel executing flows. It seems that the flow is executed at least three times. Once the condition "2 times in 4s" was false (probably the first started instance) so the right branch of this flow instance looped until the execution count of 10 times was reached. It looks OK to me but it's certainly a very complex case and I might be missing something.
Perhaps the flow can be changed in some way to make it simpler.
Is this what you want to achieve?
1) You want use a different (long) screen timeout for a few special apps and you want to switch back to the normal screen timeout when one of the other/regular apps is running.
2) You want to indicate the special (long) screen timeout with the light bulb notification. You want to remove the light bulb when the normal screen timeout is in effect.
Am I missing some additional points?
Perhaps the flow can be changed in some way to make it simpler.
Is this what you want to achieve?
1) You want use a different (long) screen timeout for a few special apps and you want to switch back to the normal screen timeout when one of the other/regular apps is running.
2) You want to indicate the special (long) screen timeout with the light bulb notification. You want to remove the light bulb when the normal screen timeout is in effect.
Am I missing some additional points?
Re: Variables broken
yep, that's exactly it. I've implemented the attached to get away from the issue, but the downside is that it lowers screen timeout before raising it. Alternatively, I can use the same triggers to set a variable in one flow, then call another flow which decides which pass based in the variable, but was limiting it to a one flow implementation.
I mainly wanted to understand the issue so I know how to use variables in the future (and at least point it out if it's unintended behavior)
Is there a way to implement a wait command, that doesn't halt the execution of all flows? Just the specific branch?
http://automagic4android.com/flow.php?i ... bd5b330ef0
I mainly wanted to understand the issue so I know how to use variables in the future (and at least point it out if it's unintended behavior)
Is there a way to implement a wait command, that doesn't halt the execution of all flows? Just the specific branch?
http://automagic4android.com/flow.php?i ... bd5b330ef0
Re: Variables broken
Your solution is very inspiring. I didn't think about using the condition Execution Count in conjunction with two triggers in the same flow in this way yet.
I would have used two flows, which has the downside that the apps need to be configured twice:
Flow 1:
-trigger App Task Started: app1, app2, app3
-action Set Screen Timeout: 10m
-action Notification on Statusbar: Lightbulb 98
Flow 2:
-trigger App Task Ended: app1, app2, app3
-action Set Screen Timeout: 30s
-action Remove Notification on Statusbar: 98
You could also merge the two flows in one but it will not make the flow simpler:
-trigger App Task Started: app1, app2, app3
-trigger App Task Ended: app1, app2, app3
-condition Expression: contains(trigger, "App Task Started")
--> true: -action Set Screen Timeout: 10m, -action Notification on Statusbar: Lightbulb 98
--> false: -action Set Screen Timeout: 30s, -action Remove Notification on Statusbar: 98
A new condition to check if the topmost app is in a given list of apps would have been very useful in this case and it makes also sense for other purposes - I will add this to the todo-list.
If you want to execute actions in parallel and completely independent of each other you need to extract the actions to a separate flow and call the flow with action Execute Flows (almost like a method call in programming).
Regards,
Martin
I would have used two flows, which has the downside that the apps need to be configured twice:
Flow 1:
-trigger App Task Started: app1, app2, app3
-action Set Screen Timeout: 10m
-action Notification on Statusbar: Lightbulb 98
Flow 2:
-trigger App Task Ended: app1, app2, app3
-action Set Screen Timeout: 30s
-action Remove Notification on Statusbar: 98
You could also merge the two flows in one but it will not make the flow simpler:
-trigger App Task Started: app1, app2, app3
-trigger App Task Ended: app1, app2, app3
-condition Expression: contains(trigger, "App Task Started")
--> true: -action Set Screen Timeout: 10m, -action Notification on Statusbar: Lightbulb 98
--> false: -action Set Screen Timeout: 30s, -action Remove Notification on Statusbar: 98
A new condition to check if the topmost app is in a given list of apps would have been very useful in this case and it makes also sense for other purposes - I will add this to the todo-list.
If you want to execute actions in parallel and completely independent of each other you need to extract the actions to a separate flow and call the flow with action Execute Flows (almost like a method call in programming).
Regards,
Martin
Re: Variables broken
That would definitely be a useful condition to have for many cases.
I'm wondering, is it possible to add an option to "execution count" as "output false condition only after time is up", instead of per execution? Also for it to share it's internal counter with the flow... I can see using it as "once wait time is up, check number of executions; if 2 do this, if 1 do that"
I can also see using it as "4seconds after trigger, do this branch", while the rest of the flow might still execute.
Great app though Martin. I'll keep on migrating my tasker profiles, since this interface makes them so much clearer to follow.
I'm wondering, is it possible to add an option to "execution count" as "output false condition only after time is up", instead of per execution? Also for it to share it's internal counter with the flow... I can see using it as "once wait time is up, check number of executions; if 2 do this, if 1 do that"
I can also see using it as "4seconds after trigger, do this branch", while the rest of the flow might still execute.
Great app though Martin. I'll keep on migrating my tasker profiles, since this interface makes them so much clearer to follow.