CoRE

The Unofficial SmartThings Blog
Jump to: navigation, search

CoRE-logo.jpg

logo courtesy of @chickwebb

For indexed notes from the developer and the SmartThings community, see CoREnotes [1] For indexed samples of working CoRE Pistons submitted by the SmartThings community, see CoREsamples [2]

!!!This document is still under construction!!!

Summary

CoRE (Community's own Rules Engine) - is a rule engine that takes events and states as input and executes actions based on the relationships between these events and states. CoRE is the main application that hosts Pistons. The piston is a decisional unit in CoRE that does the heavy lifting of subscribing to events, performing conditional evaluation, and executing required actions. There can be as many pistons as you need inside CoRE.


Piston State

Pistons have a boolean state that can be used to affect how actions are performed or cancelled. This state is decided during the EVALUATION cycle of the piston. For details on how the state is determined, please see Piston modes.


Piston Cycles

In CoRE, each piston has 4 cycles:

IDLE:
The piston is waiting for events that can put it in motion.
EVALUATION:
The piston has received an event is now looking at all conditions the user has layed out, evaluating each as an individual and also all as a whole. The piston state is decided at this time.
SCHEDULING:
The piston has figured out which actions need to be executed as a result of the evaluation and is adding them all to an execution queue.
EXECUTION:
The piston is now done with evaluation and scheduling, so it now executes all queued actions that are due.

Piston Types

Do

This piston type is not self triggering, it must be triggered by another event (piston, SmartApp, ...). It executes an action or set of actions specified in the piston.

Format:
WHEN run (actions)
State:
The state of the do piston is always FALSE. There is never a state change for this type of piston, as it has no conditionals. It rides the ELSE set of actions of a simple piston.
Actions:
The (actions) are always executed when the piston is called.


Basic

This is the simplest piston in CoRE. It allows for one conditional set and one action set that is executed when the conditional set is evaluated as true

Format:
IF (conditions) THEN (actions)
State:
The state of the basic piston is deemed TRUE if (conditions) evaluates as true, or FALSE otherwise
Actions:
The (actions) are executed if (conditions) is true

Simple

This is the very similar to the basic piston, but with a twist. It allows for one conditional set and two action sets, one that is executed when the conditional set is evaluated as true, and another that is executed when the conditional set is evaluated as false. Only one of the two is executed during any given run.

Format:
IF (conditions) THEN (actions1) ELSE (actions2)
State:
The state of the simple piston is deemed TRUE if (conditions) evaluates as true, or FALSE otherwise
Actions:
The (actions1) are executed if (conditions) is true, otherwise (actions2) are executed if (conditions) is false

Latching

This is the most complex piston in CoRE. It acts as a bi-stable (or flip-flop), flipping it's state based on two independent conditional sets.

Format:
IF (conditions1) THEN (actions1) BUT IF (conditions2) THEN (actions2)
State:
The state of the latching piston is a bit more complex. It only changes under certain circumstances. It will change to FALSE when and only if it is TRUE and (conditions2) is true. It will change to TRUE when and only if it is :FALSE and (conditions1) is true. If both (conditions1) and (conditions2) are true, the state flips. If neither of (conditions1) nor (conditions2) is true, the state remains unchanged.
Actions:
The (actions1) are executed if (conditions1) is true, (actions2) are executed if (conditions2) is true

And-If

This is a dual piston, because it supports two conditional sets, with a logical AND between them

Format:
IF (conditions1) THEN (actions1) AND IF (conditions2) THEN (actions2) ELSE (actions3)
State:
The state of the And-If piston is deemed TRUE if both (conditions1) and (conditions2) evaluate as true, or FALSE otherwise
Actions:
The (actions1) are executed if (conditions1) is true, (actions2) are executed if (conditions2) is true, (actions3) are executed if either (conditions1) or (conditions2) is false

Or-If

This is a dual piston, because it supports two conditional sets, with a logical OR between them

Format:
IF (conditions1) THEN (actions1) OR IF (conditions2) THEN (actions2) ELSE (actions3)
State:
The state of the Or-If piston is deemed TRUE if any of (conditions1) or (conditions2) evaluate as true, or FALSE otherwise
Actions:
The (actions1) are executed if (conditions1) is true, (actions2) are executed if (conditions2) is true, (actions3) are executed if both (conditions1) and (conditions2) are false

Then-If

This is a dual piston, because it supports two conditional sets. It allows for one conditional set to allow a second conditional set to be evaluated only if the first one was true.

Format:
IF (conditions1) THEN (actions1) THEN IF (conditions2) THEN (actions2) ELSE (actions3)
State:
The state of the Then-If piston is deemed TRUE if both (conditions1) and (conditions2) evaluate as true, or FALSE otherwise
Actions:
The (actions1) are executed if (conditions1) is true, (actions2) are executed if both (conditions1) and (conditions2) are true, (actions3) are executed if either (conditions1) or (conditions2) is false

Else-If

This is a dual piston, because it supports two conditional sets. It allows for one conditional set to allow a second conditional set to be evaluated only if the first one was false.

Format:
IF (conditions1) THEN (actions1) ELSE IF (conditions2) THEN (actions2) ELSE (actions3)
State:
The state of the Else-If piston is deemed TRUE if either (conditions1) or (conditions2) evaluates as true, or FALSE otherwise
Actions:
The (actions1) are executed if (conditions1) is true, (actions2) are executed if (conditions1) is false and (conditions2) is true, (actions3) are executed if both (conditions1) and (conditions2) are false

Follow-Up

This is a simple piston, with a catch. It never gets evaluated on its own, it can only run when requested to run by an external source, such as other pistons, an Ask Alexa CoRE Trigger Macro, or an IFTTT request.

Format:
IF (conditions) THEN (actions1) ELSE (actions2)
State:
The state of the Follow-Up piston is deemed TRUE if (conditions1) evaluates as true, or FALSE otherwise
Actions:
The (actions1) are executed if (conditions1) is true, (actions2) are executed if (conditions1) is false

Conditions & Triggers

There are two kind of conditional units in a Piston.

Conditions:
Compare the current state of a device to a given value, using a selected comparison, and determines whether that comparison is true or false.
Triggers:
Evaluate an event that has just occurred, so it has one big limitation: within one conditional set, only one device/attribute pair trigger can be true at any given time, because events are processed one by one, :in the order they were received. This means you should never use (trigger) AND (trigger) as this construction will always evaluate as false, unless the two triggers involve the same device and attribute (i.e. (Light.level :changes to greater than 50) AND (Light.level changes to odd) would work and return true only if level is an odd number above 50)
Using conditions only:
When no trigger is used, all conditions are allowed to subscribe to events and act upon receiving such events. This is the typical use of a piston, where the user builds a conditional set and when anything used in that conditional set changes, the piston will fire. All time conditions will fire their own events twice a day, when the time passes the two time points used in the condition. For instance, time is after 5pm has two time points, 5pm :and midnight, as it is the equivalent of time is between 5pm and midnight.
Mixing conditions with triggers:
When mixing conditions with triggers, conditions will take a secondary role of filtering out triggered events. Triggers will subscribe to device events, while conditions will not. So the construction (Door contact changes to open) AND (Time is between 5pm and midnight) will only be evaluated when the door "contact" attribute changes. It is worth noting that this construction will listen to "contact" changes, regardless of whether the door opens or :closes. This is to allow your piston to have an ELSE statement and fire it once in a while. A good example on when to mix conditions and triggers is the "if I come home after 5pm, do this". The conditional set would be(presence :changes to present) AND (time is after 5pm) and it would only be true the user arrived home after 5pm. If we were to use a condition only construction, say (presence is present) AND (time is after 5pm), then the piston would :fire whenever the user arrives/leaves home, at 5pm and at midnight. If the user was home at 5pm, the actions would execute. If the user arrived between 5pm and midnight, the actions would execute. If the user was home at :midnight, the actions would execute. That is where a trigger helps, because it allows the user to specify which events can trigger actions, while still using other conditions to achieve their goal.

Grouping Modes

Conditions and/or triggers can be "grouped" into condition groups. When a condition group contains two or more conditions/triggers, the condition group needs to know how to evaluate the bunch, so that's where the grouping method comes in. There are currently six grouping methods in CoRE:

OR:
All conditions/triggers are evaluated and the result is true if any of the conditions in the group is true
AND:
All conditions/triggers are evaluated and the result is true only if all of the conditions in the group are true
XOR:
All conditions/triggers are evaluated and combined together using eXclusive OR
THEN IF:
All conditions/triggers are evaluated in a sequence. Each action is evaluated only if the previous one was true. The group is true when all conditions are true
ELSE IF
All conditions/triggers are evaluated in a sequence. Each action is evaluated only if the previous one was false. The group is true when any one condition is true. The following :conditions are ignored once a condition is found as true, providing an effective SWITCH-CASE logical block.
FOLLOWED BY:
This is a ladder type evaluation, where each piston evaulation may advance the ladder to the next step, if that step is true. If the current step the ladder is at evaluates as false, :the whole ladder is reset and the result is false. The result will be true only when the last condition is reached and that evaluates true, at which point the ladder is again reset :and ready for the next cycle.

Latest Version

The latest version of the CoRE SmartApp code can be found in this GitHub location.

Open Source License

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or(at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

CoRE SmartApp Installation

GitHub Installation

The recommended approach for installation is through the integration of your SmartThings IDE and GitHub. This manual will not go into detail about setting up your SmartThings IDE with GitHub. SmartThings has provided instructions on how to accomplish this and they can be found here, SmartThings GitHub Documentation.

SmartThings IDE Links

After configuring your SmartThings IDE with GitHub follow the steps below:

  • Find the My SmartApps link on the top of the page.
CoRE-MySmartApps.png
  • Find the Settings button at the upper-right corner of your SmartThings IDE page (this will only appear after you have configured with GitHub).
CoRE-Settings2.png
  • Clicking this button will open the GitHub Repository Integration page. To find the CoRE SmartApp code, enter the information below:
    • Owner: ady624
    • Name: CoRE
    • Branch: master
  • Close the GitHub Repository Integration page by clicking the Save button.
GitRepoInt.png
  • Click the Update from Repo button at the upper-right corner of your SmartThings IDE and select CoRE (master) from the list.
CoRE-UpdateRepo.png
  • In the right-hand column you will see smartapps/ady624/core.src/core.groovy, select this using the checkbox.
  • At the bottom-right corner of the Update from Repo page, select Publish using the checkbox and then click Execute Update.
CoRE-ExecuteUpdate.png
  • When done syncing, the new SmartApp should now appear in your IDE.
CoRE-AppList.png
  • If they ever change color, that indicates a new version is available.
  • For the CoRE Dashboard to work properly you with need to enable OAuth, directions can be found further down in this document.

Manual Installation

  • Click the Raw button to load a non-formatted version of the code.
CoRE-CopyCode1.png
  • Select all of the code (typically CTRL-A) and copy it (typically CTRL-C).
  • Next you will want to log into the SmartThings IDE.
  • Find the My SmartApps link on the top of the page.
CoRE-MySmartApps.png
  • Click on the +New SmartApp in the upper-right corner.
CoRE-CopyCode2.png
  • Select the From Code tab along the top section.
CoRE-CopyCode3.png
  • Paste (typically CTRL-C) the code you copied from GitHub.
  • Click the Create button in the bottom left corner.
CoRE-CopyCode4.png
  • This will bring up another page with the code now formatted within the SmartThings IDE.
CoRE-CopyCode5.png
  • Click the Save button at the upper-right corner.
CoRE-OAuthUpdate3.png
  • Finally click-on the Publish button and select For Me at the upper-right corner of the screen.
CoRE-OAuthUpdate4.png
  • For the CoRE Dashboard to work properly you with need to enable OAuth, directions can be found further down in this document.

Enabling OAuth

In order for the CoRE Dashboard to viewed you will need to enable OAuth. To enable OAuth follow the steps below:

  • Find the My SmartApps link on the top of the page.
CoRE-MySmartApps.png
  • From the list of SmartApps click on the icon for Edit Properties in the first column on the left side.
CoRE-EditProp.png
  • The OAuth section is towards the bottom of the page, select it by clicking on the OAuth section.
CoRE-EditApp.png
  • Click the Enable OAuth in SmartApp button.
CoRE-EnableOAuth.png
  • The screen will change, providing you with a unique code for you OAuth Client ID and OAuth Client Secret.
CoRE-OAuth.png
  • These are the foundations of the security of your app and should be kept secret.
  • You do not need to memorize or write these codes down.
  • You do not need to add any additional information to this page.
  • Click-on the Update button at the bottom left corner of the screen.
CoRE-OAuthUpdate.png
  • Open the code for your SmartApp by clicking the name.
CoRE-OAuthUpdate2.png
  • Click the Save button at the upper-right corner.
CoRE-OAuthUpdate3.png
  • Finally click-on the Publish button and select For Me at the upper-right corner of the screen.
CoRE-OAuthUpdate4.png