Let me try a quick answer to each
Questions:
- When should you use a local variable vs. a global variable?
You use a local variable when its value is not needed outside of that piston. If you need to share data between pistons (set the value in one or more pistons, get the value in a different piston, etc.) then you need to use a global variable.
- When a variable is global, does that mean it is available to all Pistons?
Yes, a global variable set by a piston can be read by any other pistons.
- When entering the name of a global variable, do I place a @ or $ before it? Is there a difference?
@ signifies a global variable, while $ signifies a system variable - system variables are read-only (you cannot set them) and provide information about the environment. For instance, $time gives you the current time. $sunrise gives you the time of today’s sunrise. $random gives you a random decimal number between 0 and 1, $randomLevel gives you a random level between 0 and 100, $nextSunrise gives you the date and time of the following sunrise (either today - if asked of very early - or tomorrow). For example, when a minimote button is pushed, $currentEventDeviceIndex gives you the button number that was pressed. You can find a list of all the variables, including their current values, if you open any piston in the dashboard and scroll just below the actual piston - the local variables are that piston’s own variables, so they’re relevant for that piston only.
- Where do you print the result of a variable? i.e. which screen shows the output of a variable for testing?
There is no print per se, but you can send it in a notification, or to other services by using http requests. Most text fields in CoRE support variables. To use a variable in a text, you need to use curly brackets { } around the variable name. For example Send Notification “This is a random number: {$random}
”. You can see the list of all available variables in the dashboard, under any piston you open.
- Must you set the name and initialize a global variable under Global Variables on the main page? If not, what is the Global Variables on the main page meant for?
No. That page is there because it quickly became apparent that people were confused about how to create a variable. CoRE was designed in such a way that all you need to do is just use a Set Variable (or other fields that request a variable name) in any piston and provide a name for the variable - that variable would be automatically created. So no, you don’t have to initialize it, but you can if you want to. Or you can change the value manually, I guess that is where that page comes in handy.
Q) Can you create a variable with the same name of another local or global and if so does the most current setting over-ride the last?
Global variables are unique. You can’t have two global variables with the same name, placing a value into an existing variable obviously overrides the old value and saves the new one. Local variables are unique within any given piston. Two pistons can both use the same variable name, though the two variables are distinct, each having its own value. Also, each piston can only see its own variable.
Q) So far, I am familiar with Boolean, Number, String and Time. Have no idea what decimal is used for…
When setting a variable value, you get to choose what kind of data you want to store in it. Boolean can store true or false, Number can store an integer number (no decimals), String can hold any text, including all of the other type’s data (i.e. “false”, “12”), Time is a long number (similar to a unix timestamp) that contains the number of milliseconds since Jan 1st 1970. Current values hover around 1,488,460,769,000 - CoRE knows to format these into a readable date/time when used in a text field. Decimal is able to hold numbers that can or do have decimal places (i.e. 2.34).
Q) I’ve been wondering how “Execute during validation stage” can / should be used.
In order to avoid as many timeouts as possible (SmartApps are only awarded 20s to finish their execution, after which they are forcefully terminated), CoRE implements what I called stages: it has an evaluation stage and an execution stage. Evaluation happens first and it’s where CoRE is comparing conditions, deciding what needs to be done and what not. It queues all the decisions and then saves the list (in case it times out) and moves on to the execution stage, where it actually performs the tasks. The “execute during evaluation stage” will do just what it says. It will force that “Set Variable” to be executed during the evaluation (it will again be performed during the execution stage, later on). The one reason you need this for is if you alter the value of a variable (using a when true/false action) and then further down the piston code you have an IF that uses that variable. IF (Door is open) >> when true Set variable x = 1 THEN IF x == 1 THEN… Had you not enable that “execute during evaluation stage”, the second IF would still see the old value of x, not the 1 you just set. Hope it clarifies things a bit.
NOTE: CoRE (SE) (name is not final) is underway and it will sport a full HTML interface, taking the pain away from editing pistons (pfew). There will be several very important changes in there. For example, in CoRE {name} represents the value of a variable named “name”. In CoRE (SE) the { } signify an expression is included between the brackets. Expressions bring in several benefits, one being the ability to use calculations inside the { }, not just a single variable (i.e. {@test + 3 * (anotherVariable - 1)}
), the ability to use predefined functions (like avg(values)
, min(values)
, sum(values)
, stdev(values)
, format(format, values)
, round(decimal, precision)
, floor(decimal, precision)
, sqr(decimal)
, sqrt(decimal)
, power(decimal, power)
, etc.) and also the ability to reference device attribute values by using [name:attribute] where name is the name of a device, or the name of a variable referencing a device, i.e. [$currentEventDevice:contact]
. This may render variables useless (though I’d still use them here and there). For example,
IF { avg( [Kitchen:temperature], [Living Room:temperature], [Bedroom:temperature] ) } exits range {@minTemp} … {@maxTemp} THEN do something
In other words, the condition is able to calculate the average of the temperatures in the three rooms I selected and compare them to two global variables that I can modify in other pistons. You can also use conversions in your notifications:
Send Notification “The outside temperature is { format(‘%.1f’, [Outside Sensor:temperature]) }°F or { format(‘%.1f’, celsius([Outside Sensor:temperature])) }°C”
This would always format the temperatures with one decimal place (because of the %.1f
- see more formats here) Notice how it can even convert the temperature to Celsius on the fly
Or here’s another one, to know when any two doors are open:
IF { count( [Front Door:contact], [Back Door:contact], [Patio Door:contact], [Sliding Door:contact] ) } is greater than 1 THEN do something
For those who don’t really fancy expressions, you can also do this in the UI:
Also, CoRE (SE) will allow multiple installation instances (there is a hack people are using to install CoRE multiple times) and I am considering even adding super global variables (@@) which will even work across instances of CoRE (SE). He he
Enough with the show off for now, sorry, had to do it LOL