Some webCoRE Basics for writing pistons - time triggers, every blocks

I regularly see questions of folks having trouble getting a piston to work properly, due to not understanding time triggers vs. every blocks.

A couple of overall points:

  • time trigger comparisons are used when something needs to happen on a schedule.

  • for reacting to device changes, you want to use device trigger comparisons (vs. polling with time triggers) if at all possible.


For time based triggers there is a choice of:

  • if statements (time happens daily, etc)

  • every blocks


If Statement

Few things to note from this piston:

  • when the timer occurs (each day at 8:30), the entire piston will run

    • the 'then' portion of the 'time happens daily' will be executed also
  • all the usual on how to use trigger comparisons properly apply:

    • In the if statement, there is one trigger comparison (unless using OR or FOLLOWED BY)

      • In the webCoRE IDE (dashboard, staging, or local) when you select an if statement and add comparison(s), comparisons are organized by triggers vs. conditions
    • All of the trigger comparison statements are at level 1 (looking left to right). ie trigger comparisons are not nested below then or else statements.

      • This is 'best practice' as it makes it clearer what will run the entire piston
  • if your hub is down for a while with pending time requests, webCoRE will run a recovery on missed timers to get the piston moving again

  • note this example is a bit strange in that

    • when the timer fires, the entire piston will run so both toggle commands will run

    • if you run the piston by 'test' in the IDE or 'execute piston' statement from another piston, only the 2nd toggle (Dimmer 4) would execute (ie the time happens daily is FALSE)


Every Statement:

Few things to note from this piston:

  • The best way to read this is there are two pistons in this example (note pink color lines on the async portion of the piston)

    • the EVERY block statements (btw, ON EVENTS FROM works this way also)

    • the rest of the piston excluding the every block(s) statements

  • When the piston runs (the entire piston on a 'test' from the IDE, or event (there is none in this piston))

    • it schedules the every block (but does not run the statements with in it)

      • this makes debugging statements in every blocks more difficult
    • it will execute the toggle for Dimmer 4

  • When a 1 minute time fires, it only runs the EVERY block statements.

    • you can think of the every block as having an EXIT at the end of the block

      • so the timer run will not execute the toggle (dimmer 4)
  • it is important to note

    • that every blocks should NOT (cannot) contain trigger or trigger comparisons in the code of the EVERY statements.

      • Ie the only thing that runs an every block is the timer on the EVERY statement.

      • Any if statements within the every block should only use condition comparisons. (webCoRE will not subscribe to trigger comparisons within an EVERY block, so using trigger comparisons will not do what you expect (they will all be false)).

    • There can be multiple every blocks in a single piston

      • each time you add another EVERY block, you added another mini-piston that only runs when that block's timer fires.
    • Every blocks should be at level 1 (looking left to right), ie they should not be nested below other statements)

    • The every block(s) can be anywhere in the piston (beginning, middle, end). When a time event occurs for an every block only the statements within that every block are executed.

      • so only the every block statements for the timer event are executed, and no other statements are executed for the timer event in the piston.
    • Normally a single piston processes events sequentially in the order they occurred. This means there is single execution of the piston at any instance in time as far as synchronization.

      • parallel piston execution can be enabled for a piston, but it can add a lot of overhead to the system - typically without much benefit. It can also make debugging a piston more challenging.
    • variables can be used to pass state between main piston and every blocks or between every blocks


  • This piston is likely not doing what the person expected, because there is no trigger for the main part of the piston, the toggle for Dimmer 4 would only run if one executed the piston via 'test' in the IDE or an 'execute piston' statement in another piston

References:

Installation and Tips for webCoRE on HE

Piston images shown from webCoRE forum

4 Likes

Thanks for posting this. I am sure this information is available at other locations, possibly scattered through the HE and Webcore forums. It's nice to have a concise explanation with an example piston.

1 Like