[OBSOLETE] [BETA MILESTONE 1] CoRE (Community's own Rules Engine)

UPDATE 8/12/2016: CoRE has moved on to Beta Milestone 2. Please kindly follow us here.

In an attempt to fill the huge void left by the withdrawal of Rule Machine, a few brave community members started their journey to creating a new rule engine to rule them all. We’ve decided to call it CoRE, an abbreviation that stands for “Community’s own Rule Engine”, courtesy of @SBDOBRESCU (his idea, really).

WARNING: This SmartApp is in an alpha BETA development stage and may be quirky. It may also change rapidly and drastically, involving a full reset of the app in order to upgrade.

It is not recommend to install this SmartApp in a “production” environment, but we encourage people to try it out.

IMPORTANT: This topic is here for general information and peer assistance. If you want to point out errors, omissions, or ask for features, please do so at CoRE and Piston Rules Engine, first design steps

We have @BoSTon who has volunteered to write documentation on how the CoRE works, from beginners to advanced, to power users. If anyone wants to help, please don’t hesitate. It’s a community’s effort, after all.

The SmartApp can be installed via GitHub integration into your IDE or can be found here

To install the SmartApp using GitHub integration, go to your IDE, go to SmartApps, tap on Settings and Add new repository with ady624 / CoRE / master in the three fields. Then use the Update from Repo button. Make sure you either tick the Publish option while updating from the repository, or publish the app after each update.

NOTE: It is not required, nor necessary to donate to use this SmartApp. This is a free open source software and it is my way to pay my dues to those before me. But if you feel like it, you can donate here. Thank you.

UPDATE 6/13/2016: 45 days into development, finally reached the 1st beta milestone! :wink:

UPDATE 7/26/2016: As a result of the ST issues with lost state information on 7/25/2016, some pistons might have been corrupted. The first sign of such a corruption is an empty dashboard. CoRE is able to revive them, but as of today, this process is manual (once this process is deemed worthy, CoRE may automatically rebuild pistons when it needs to). You can find the rebuild option under Advanced Options in each piston’s main page. If you are affected, the easiest way to determine which pistons are faulty is to open the Live logging in the IDE and then attempt to view the dashboard. Each affected piston will output an error about a null object. Visit each of them in the CoRE UI and tap on the Rebuild this CoRE piston under the Advanced Options section. Then repeat the process until the dashboard works again. Sorry for the trouble, I will get them to automatically rebuild in the near future, should such a rare event happen again.

UPDATE 7/26/2016: Official wiki is here. It’s still a work in progress, but it’s a good starting point.

Thank you

56 Likes

So far I ran this to run a virtual switch to turn on a set of dimmers to a requested level and then when the virtual switch is turned off it turns off the dimmers. Worked like a charm! This is amazingly fun, thank you for the hard work

3 Likes

Hi… a total Rules Machine/Smart Rules/CoRE NooBee here with an ask for guidance. I have no idea where to begin with CoRE…

I’d like to set up two pistons:

Smart Room Light

  • Room light turns on when someone enters a room (door opens, or door is already open and motion is detected in the room). Room has both motion and door open/close sensors
  • Room light stays on as long as someone is in the room - even if the door closes (motion sensor timeout is 4 minutes, I think)
  • After 15 minutes of “someone is in the room”, the light is left on indefinitely, even if motion stops or the door is opened
  • Once the door is opened, light stays on until a) no motion is detected (person left the room, but left the door open), OR the door is closed AND no more motion is detected (person left and closed the door behind themselves).
  • Note that the person may choose to turn off the light once in the room, whether the door is opened or closed.
  • note also we don’t want to turn the light on if the person is “inside” the room and opens the door (to go to the bathroom in the middle of the night).

I’ve tried Smart Lighting for this, but I can’t make it work because there’s no way for two separate automations to know what each other knows.

The second one is also tricky:

Lock the Door When Wife Comes Home

  • Generally, when I’m home, we tend to leave the door to the basement unlocked (it has a Z-Wave Kwikset lock).
  • I have the lock autolock on both Goodnight! and Goodby! routines, and auto-unlock on I’m Back! routine. I also use Do’t Lock Me Out if I open the door for any reason - keeps us from getting locked out when we get in the car and realize our sunglasses are inside.
  • Wife wants the door to lock behind her when she comes home and I’m not there; I don’t care, so long as I don’t get locked out when I am there
  • House knows that she is home by her iPhone (reliable enough)
  • Door has lock & close sensors
  • Light inside the door turns on when I’m Back is run because wife arrived
  • She has to go through another door to get into the house (also has open/close sensors)

So it seems that one logic approach is:

  • When wife arrives and hubby isn’t home, wait for her to close the Upstairs Door, then Lock the Garage Door behind her

Suggestions, guidance, and links to documentation that would help me figure this out most welcome!

TIA!.

1 Like

Hi, @storageanarchy,

I only looked at your first rule so far, there is a conflict between your first condition and your last note. Door opens > light on, but not at night? Perhaps consider making time part of the equation? You need to figure out the exact conditions that would turn the light on and the exact conditions that would turn the light off. Then implementation becomes easy. You may need to use triggers as you’re looking for certain events and preexisting conditions (motion is active, while door is already open). Try and write down the conditions that turn the light on and the ones that turn the light off and then I can give this a shot. The 15 minutes >>> indefinite on will be possible when variables are finished. You can “save” the date at which the light turned on and then use that as a condition to not turn off the light. Not there yet.

Thanks for the suggestion - I will try to write down the conditions.

But I don’t think there is a conflict as you describe. The difference is that the door is being opened from the INSIDE while it is nighttime - I’m trying to capture the fact that there is someone inside the room who is sleeping (most likely having manually turned off the light in the room without leaving the room), and then said person needs to go to the bathroom. If he/she wants a light, they probably turn the bedside light on manually, or they turn on the room light…again, probably before they open the (door from the inside).

I had hoped that the 15 minute thing could be as simple as:

  • (motion event)
  • how long since the door was opened (foo = doorDevice.lastOnEvent(); if foo > 15 minutes, ignore motion events until person leaves the room)
1 Like

So then what turns the light on would be:

(
    Door changes to 'open'
    AND
    Motion is 'inactive'
)
OR
(
    Motion changes to 'active'
    AND
    Door is 'open'
)

Is that right? And who provides the device.lastOnEvent() ? Is that a custom command you have in the DTH? I can save the date of the last event that triggered a condition. I don’t yet have the variable > 15 minutes implemented. It can also be done with a Wait 15 minutes, but you’re still missing the Set Variable (working on it) and the Variable capability under conditions (coming soon).

With Light…

Set Variable “canTurnLightOff” = true
Turn on
Wait 15 minutes
Set Variable “canTurnLightOff” = false

and then use the variable canTurnLightOff in the off part of the logic.
Wait

I was hoping to parse the event history for the device to get the last time it was turned on by the door opening or motion. I know I can get that when writing a SmartApp, but I understand that you can’t expose the entire device attributes through CoRE. Will have to wait for variables then…

1 Like

If you modify the DTH to have an attribute, I can use that attribute. But how will the attribute change? Every one minute? CoRE can read custom attributes and make conditions on them. It can also execute custom commands (though right now I’m missing the ability to define the parameters - but it’s planned for). It cannot however execute a custom command and get the data into a variable. Or use a custom command as a condition. Not yet, at least.

Variables seem the way to go, although the attribute we need already exists, it’s just stashed in an inconvenient place:

foo = device.statesSince(“switch”, (fifteen minutes ago))

So, we could (in theory):

  • detect motion and turn on the light, and start a 5 minute timer.
  • Each time we see motion, we restart the 5 minute timer (but don’t turn the light on again).
  • We also check if it’s been more than 15 minutes since we turned on the light thusly - If there is NOT a switch.on event in the returned set of events,
  • If so, then we stop watching for movement and leave the light alone (covers the case where the person has turned it off manually since entering the room also). We also disable the 5 minute timer…
  • If the 5 minute timer ever times out before we see more motion (within the first 15 minutes), we shut off the light…if outside the 15 minutes, we do nothing…

At least, I think that would work. If it was easy to get at that list of past events, that is. Rather complicated for what probably isn’t a hugely important feature…

1 Like

Just need some guidance re variables. Just messing with a simple piston that will send an SMS if battery level of any sensors in the condition drops below 30%.

In the trigger group I’ve named a variable in the ‘save matching device list’ called ‘batterylow’

Can this ‘batterylow’ variable be then used to fill the sms message with name of device that is low. How is the syntax for the sms message set…

“{batterylow} has low battery”

do i need to use @ or $ symbols anywhere??

1 Like

You got it right. Use any name for the “Save matching device list to variable” and then use that name between { } in the SMS message.

When saving the info to a variable you can use @ to make that variable global. This means other pistons will have access to it as well. You don’t have to, unless you need that info in other pistons. You won’t be able to set any variable starting with $ as those are reserved system variables - they change on their own :slight_smile: The example you showed should work.

1 Like

Just a note here. Using a trigger will only provide one device at a time in your list, because only the device that triggerred the evaluation actually dropped below 30% at that time.

Dropped below is different from is below. This is because Dropped below involves transition. It senses the transition of a value past a threshold. So you won’t get all devices in your list, because only one “transitions” past the 30% threshold at any given time.

Use a condition instead. IF [devices].battery is below 30% … this will still happen every time a battery level changes, but all devices below 30% would match true. But be advised, every time a battery level changes, you’ll get an SMS, if any is below 30%. So if you have a chatty device that keeps reporting battery changes (should not happen in real life as they are supposed to conserve their battery, not waste it on reporting that battery is going down) you’ll definitely see a lot of SMSs coming your way. You can fix this with a time trigger and the condition on battery. This way you can make the time trigger happen daily at whatever time you want it, so you only get up to one SMS a day…

1 Like

Perfect, works like a dream!!

1 Like

Edit: I’ve updated this as a Latching Piston to make sure motion active keeps things in the right state if the motion sensor doesn’t got out of active state due to constant motion, which a simple piston will do.

Just wanted to post a more complex but still pretty simple example that can help others get a quick understanding of the complexity you can easily achieve without going full tilt with variables and groups.

Previously this worked in a backward manner with RM, it’s easier to read here but works the same with the added “flash” notification that a light is about to turn off, without using flash…

Scenario: Walk into bathroom, light turns on. Leave in under 3 minutes, light will flash after 2 minutes of inactivity, stay on for one more minute, then turn off. So if you’re in the tub falling asleep, the flash will let you wave your arm to keep the light on. If you are in the bathroom for 2 minutes (minimum of activity) the fan will come on, assuming you are in the shower. After no motion from that scenario, the light will still wait it’s two minutes, flash, one minute, turn off, the fan will wait 10 minutes to finish venting the room, then shut off.

Piston Mode: Latching

If…

–Bathroom Motion Sensor -> motion is active

Then…

–Using Bathroom Light

  • Turn on

–With Bathroom Fan

  • Wait 2 minutes
  • Turn on

But If…

–Bathroom motion Sensor -> motion is inactive

Then…

–Using Bathroom Light (Cancel on piston state change)

  • Wait 2 minutes
  • Turn off
  • Turn on after 1000ms
  • Wait 1 minutes
  • Turn off

–With Bathroom Fan (Cancel on piston state change)

  • Wait 10 minutes
  • Turn off
8 Likes

Edit: I’ve updated this as a Latching Piston to make sure motion active keeps things in the right state if the motion sensor doesn’t got out of active state due to constant motion, which a simple piston will do.

Here’s another that uses motion, lux, power, and lights.

Scenario: Dining room is dark when light outside isn’t cloud free…so turn it on when lux is low, unless watching TV or other lights in the Living Room/Dining Room are already on.

Piston Mode: Latching

If…

–Living Room Motion Sensor -> motion is active

And

–Living Room Theater Outlet -> power is less than 30W

And

–Bloomsky -> illuminance is less than 3600lux (yes my BS is working fine with this!)

And

– Each of Dining Room Light, Living Room Light or Kitchen Sink Light -> switch is off

Then…

–With Dining Room Light

  • Turn on

But if…

Living Room Motion Sensor -> motion is inactive

Then…

–With Dining Room Light (Cancel on piston state change)

  • Wait 5 minutes
  • Turn off
  • Turn on after 1000ms
  • Wait 1 minute
  • Turn off
3 Likes

Don’t forget to vote for CoRE’s own icon

1 Like

I’m trying to execute the following, and I’m having a hard time understanding where to put limitations.

This is what I want: I have motion sensors at the top and bottom of my stairs. I want to turn on the upstairs lights when walking up the stairs and have them turn off when walking down the stairs, given that these actions happen within a certain time range of the day, in a certain mode and given a certain light is already turned off. That is, if it’s NOT that time range OR NOT in that mode OR that certain light is NOT off, nothing should happen.

I’m trying to use a time frame, mode and a light as conditions to limit the piston from running.

What I’ve written, which, I don’t think will work, is the following AND-IF:

IF
Bottom motion sensor becomes active
and
Top motion sensor is inactive

THEN
nothing

AND
Time is between x and y
and
Mode is Home
and
My Light is off

THEN
Using Master Bedroom light and Office Area light, turn on

ELSE
Using Master Bedroom light and Office Area light, turn off

My questions is how do I add conditions to allow operation of the piston, and at the same time have conditions that create THEN/ELSE actions?

Am I making any sense at all here…?

I’m have set up the following using Or-If.

IF
lux less than 11
AND
Between 7:45am and 11:55pm
THEN
Turn On

OR IF
motion sensor active
time between 11:54pm and sunrise
THEN
turn on

ELSE
wait 5 minutes
turn off

My issue is that when the light turns on in the first IF, the lux value goes above 11 and thus the ELSE parameter becomes active.
Apart from setting the lux value to turn the light on to a value that is above lux value when the light is on, I don’t know how to get round this.
Any ideas anybody?

I used “Cancel on piston state change” to prevent something like this, you’d apply it to the Else statement I believe. Then when motion state changes on/off during the Or If, you get a clean slate, I think…I’m still trying to get mine to work more reliably, turns out it flashes on/off as per the Else statement if there is CONSTANT motion for the duration. Doesn’t hurt to give it a try!

Thanks for the reply.
Wouldn’t that mean that if I am away then there will be no motion then the light would stay on?