Timer with expression, when expression get refreshed?

expression
triggers
piston

#1

1) Give a description of the problem
I have a piston with a timer and an expression that tell the time of the day to start the routine… Like: if before sunrise, use sunrise, else sunset (more complex but something like that)… I see the next run time in the dashboard and its like 24h… so the expression seem to not refresh automatically! Looks like it need to run piston first… I have several trigger so it works for now but if nothing get triggered I would like to know if it would work and if it exist a workaround!

(PUT YOUR INFO HERE)2) What is the expected behaviour?
refresh auto

3) What is happening/not happening?
not refresh until next run

4) Post a Green Snapshot of the pistonimage
(UPLOAD YOUR IMAGE HERE)

5) Attach logs after turning logging level to Full
(PASTE YOUR LOGS HERE THEN HIGHLIGHT ALL OF THE LOGS AND CLICK ON THE </> ICON TO FORMAT THEM CORRECTLY)

REMOVE BELOW AFTER READING
If a solution is found for your question then please mark the post as the solution.


#2

I am not totally clear what you are doing, but pistons are responsible for scheduling their own next execution time and they update it every time they execute. They may be maintaining a whole list of times when they know they need to execute but they only ever have that next one scheduled. That’s actually a potential problem if there is a glitch and the timer event doesn’t happen, so every time any piston runs, and also at regular intervals, a check is made for any piston where a scheduled timer is overdue by 30 seconds or more and if one is found it is sent a ‘recovery’ event just so it can run and schedule a new time.

In order to update timers, a piston needs to not only execute but it needs to evaluate the actual conditions where the timers are used. So if, for example, you have a timer as the second condition in an AND group and the first condition evaluates as false, the piston won’t (as a default) bother to evaluate the second one so doesn’t use it to update timers.

You will often see users writing pistons with an ‘if time happens at 4am daily then do nothing’ block. The actual time varies to taste but the idea is to make sure the piston executes between possible DST adjustments and the first timed event of the day, and also gets a chance to update sunrise/sunset times for the day.

You can adapt that idea to make sure the piston runs at certain times of day.


#3

Hi,
Thanks for reply! I think its because I use the $now variable to set the trigger time… so when it run it know the first (actually the both first time are ok so far but the last one seem not to work, after running the second trigger, its indicate 24h so it looks like it ignore the last one but if the piston is trigger by a on changes trigger, it seems to update and works…

  I use local variable for all 3 time and also those local seem not to be updated but not sure about it! The evaluation section is always right but since I m inside the piste in editing mode I assume that its up to date! I made a post on this but I would like my local variable to show the result so I could see what its taken but I only see the equation beside the variable... here the piston trigger...

here the local:


#4

Few things to ensure you understand:


#5

thanks for your reply! Here what I have after some test and still have some bug… Do you know why the expressions seems not to be updated on time…In the evaluation section in the piston it gives the right things but it execute well few times and then skip some timer events…


#6

I guess you need to show logs of the piston runs and the results of the evaluation to comment.


#7

The log of the timer part do not exist since its not triggering all the time! When it works, it works great so the log lead nowhere! But I continue to make some test and I think that I found something… It looks like the expression inside the timer itself wont update every times… So I made a local variable that is time based. I set this variable to be the time where I want to trigger the timer, so that variable have the expression that need to be updated…

        I just refer this variable inside timer event... For now it seems to work, I ll be sure after few days... If I use an if condition as trigger at specific time, its working but I cant since it run the entire piston and I have some 'timer' (if variable stays x for 2h...) and it reset those on every run...

       Here what I have for now if it could help someone with same issue, I ll mark it as solved as soon as its working for few das...


#8

looks like nothing gets updated except if the complete piston run… I would try to add a block to set the local variable to the expression inside the timer or even better, inside the @report changes event. The report is updated every 15 minutes (only if actual meteo changes). I can add the block inside the last part wich is calculate the time after trigger…so at each trigger it would set the value for the next!


#9

Also are any of the variables being predefined being modified at run time? I would be careful mixing predefine with runtime changes.


#10

I have some predefined but the one I intent to use to change at run time will be not set.


#11

here the result , I just put a time manually to make it run the first time… and then it works fine!

1- timer event fire
2- inside the timer event I set variable to 1
3- inside this event again, if this variable stay 1 for the delay, return variable to 0 and set the variable that is the next time for the timer event


#12

Finally, its not working… Its like the timer wont subscribe after running. I tried everything and I must press test or edit & save to make it update! I tried to put another timer that run every hour that set variable…and other things like that! It should have an action that is to subscribe the event! The only things that seem to work is to use if block with happen daily at (variable). I ll make other test but I think it would resset stays event timer…


#13

This part to me is a problem. Webcore does not trigger off of a local variable. Stays if I remember correctly is a trigger comparison.

image


#14

I’m not sure I’m seeing the entire piston

Every statements are a ‘piston’ within a piston. Since the every statement is first, it is evaluated first and the value when evaluated is what is used for setting the time.

If you are trying to adjust the every statement evaluation, whatever is adjusting the value for this variable should be set before the every statement (ie move up the adjustments outside of the every statement and before it). If the piston is only the every statement, then things can get more interesting/challenging.

In general I would consider using if vs. every statement myself. Because of the nesting of a ‘piston’ in a piston of the async every block, the if statement may be clearer as to what is happening. I believe the logic in webcore is if the every statement is scheduled and this is not the every run, don’t change it. So every wants to be recurring not adjusting periods iirc. This does not mean you cannot use a variable, it does mean the rescheduling may not be what you expect.

So try calculating your time / variable before the every block. If that does not resolve it, then you should try using an if, and again calculate the time/variable before the if statement. The every or if has to schedule a time definite for the next run, it is not going to reschedule after you have crossed the statement (ie you change the variable further down, and expect the above it schedule to change).


#15

but that part works perfectly… it start a timer and if the variable stays equal to 1 for the delay (variable value) it trigger the action! Its the timer event that trigger only once and then wait 24 h before trigger again…and sometimes it get refresh and trigger at another time! The variable that define the time ti trigger in the time get refreshed but the timer is not triggered … it s look like it not subscribing each time… if I edit the piston and save, it subscribe and trigger perfectly… Since the timer event is an independant block it looks like its not recalculated at the same time as the piston…


#16

Thanks for the advice, I ll try that! Actually, the if is triggered perfectly, but the thing is: (here my piston )
as you can see, I try with an other every before the other to set the variable, but I think that it should be outside an every statment to works… So with the if statment,the entire piston run and all the timers inside every & on change event are reset, so if it start/stop raining, my variable is not set properly… I ll try maybe to put an exit action? The next step would be to have multiple every (1 for each time, but it duplicate a lot of coding …) Take a look at the pistn and maybe you ll see something else!


#17

Another thing I notice, in every loop, the if stays condition works like this: it start a timer and if the variable stays at the value for the time periode it ll trigger…

But inside if happen every day, the same condition check if the value of the variable was the same for the last periode of time…so its triggered directly, not after the delay…

I need the delay like in the every loop… As you said, it seems to keep the value of its first run to eveluate the next run. I tried with a variable that containing the time… The variable is updated, even inside the loop so before to cedule the next run… but it cedule it for the next day at old time. Its like the event really happen 1 time per day at a time…

I need to test with global if it will be the same or if it ll force it to recalculate… Also I can use the condition every day at to set a variable to 1 and reset it to 0 inside the every loop… and make the every loop run each hour with the condition of variable = 1 …

But its little messy … is there a way to suggest a change ?

Thanks!


#18

That isn’t how stays works. If the variable is equal to 1 (or whatever it needs to be equal to) an execution will be scheduled and the stays condition will return false immediately and the piston will continue.

If the stays condition is evaluated again and the variable is no longer 1 (or whatever), the scheduled execution will be ‘cancelled’ and the stays will again return false.

If the stays condition is evaluated again and the variable is still 1 (or whatever), the scheduled execution will be left alone and the stays will again return false.

If the scheduled execution time is reached without being cancelled the piston will execute and act like stays has returned true. This only means the stays condition has been met if the piston design allows it.

The two key things are:

  • stays always returns false when evaluated
  • stays only knows the variable has changed if it is evaluated again.

#19

yes, that exactly what I would mean (sorry if I was not clear) and it works perfectly like this inside the every event or inside other event since events are considered like a single block…

But if I use the same stays condition inside a simple if statment, it does not start a timer or a schedule to see if the variable stays to a value… it just check if the variable was at this value for the period specified… so let say a have a variable = 1 since few hour and the piston execute the stays (for 5 minutes) condition, it automatically execute the condition. If the variable is set to 1 only 2 minutes before executing the stays condition, it will not do anything because it check if the variable was at that value in the past 5 minutes…

I made some test and it looks like this to me, I was just wondering why the same condition is considered differently according if its in event or if statment…

That s also why using the if statment was causing some issue… The work around I found to this (still in test) is to use a global variable that is set to 0 and I use the ‘if happen every day at’ statment to turn this variable to 1 and to set the local variable to the time of the next execution. I changed the every event by a on change event with that global with the condition to be = 1. So inside this event I execute the same code as the every but at the end I set the global back to 0.

Looks great for now but it takes few days to test and be sure…

Let me know if you know why that stays act different in normal statment that in event… maybe I m doing something wrong! To test it I simply create a blank piston and add a every event at each 2 minutes and add inside the stays condition (1 minutes) and once triggered, 1 minutes later it send me the push notification I added. After that I changed the every event by the if happen every day at condition. The time of the execution is stored inside a variable and update (variable = addMinutes($now,2)) so the piston run every 2 minutes… and this way, the stays condition is always triggered directly at the same time of the piston… Should have an explanation, for now I simply think that is because the event is considered as a piston or as a separated block but not sure if it s the reason!

Thanks again!


#20

that works fine… I also realized that the if stays trigger, when used in an events, it act as supposed (start a timer and check state after that, if it stays for the period it trigger the action…) but when used inside piston directly , it run twice … one time when the piston gets triggered…so it check if the variable stays for the periode of time… but it will also act like inside an event if the variable change and stays for the periode of time…

A workaround is to add an exit action before the stays event when use outside an event!

Thanks again!