CoRE - Get peer assistance here with setting up Pistons

@alanrosesf I changed things a bit… Maybe this will show someone else who has a Centralite Pearl thermostat and Android phones how to save money on home energy costs and simultaneously stay comfortable.

Software required/configured: Centralite Pearl running on SmartThings (I’m using the Zigbee HA 1.2 model), IFTTT configured linked to Google Calendar & SmartThings (among a bunch of other stuff), and both my wife’s phone and my phone linked to SmartThings, and, of course, CoRE working great.

A. IFTTT reads my Google Calendar looking for an event string in the event title. I have three thermostatic “modes” - Mode A, Mode B & Mode C. The Event Description in each one contains a JSON string. All three modes are for “all year,” contain both a heat point and cool point (both a desired setpoint for the thermostat, and a buffer 2-3 degrees higher/lower that triggers a mode change (the Centralite Pearl does not have “auto-changeover” built in, but CoRE can totally do it for you. It worked perfectly last night for instance.)

My “Mode A” JSON in the Event Description is: {“low_t”:“68”;“low_s”:“70”;“high_t”:“74”;“high_s”:“72”} (B is cooler for nighttime, and C is damn near “off” - allowing things to get really cold in the winter or really hot in the summer, but not enough to cause damage to things in the house)

B. I have six virtual switches too; ScheduleA, ScheduleB, ScheduleC, VirtualA, VirtualB, and VirtualC. There’s also very simple event based trigger pistons for this; if ScheduleA switches on, do the following: turn off ScheduleB & C, and take the results of the LOCAL variable low_t and set the GLOBAL ModeAHeatTrigger to it, low_s goes to ModeAHeatSetpoint, high_t becomes ModeACoolTrigger and high_s becomes ModeACoolSetpoint. The things to remember: have the four local variables (low_t, low_s, high_t, high_s) in the three pistons (Schedule A/B/C) initialized, and have “Import Data Event on True” turned on.

The ScheduleA/B/C modes always correspond to the actual schedule (not necessarily what the thermostat is set to do) and always update the temperatures associated with that mode from what is taken from the Google Schedule, so if the wife decides the next time we go to bed to lower the temp, she can do that from Google Calendar without having to know any code.

The VirtualA/B/C switches actually trigger the modes though. There’s a myriad of pistons.

C. Each VirtualA/B/C switch has two pistons associated with it (though with other thermostats, I’m sure you could distill the whole thing down to probably three or maybe even less pistons. I have to split the mode change logic out from the setpoint logic due to the thermostat itself). So, SetModeAExec and SetModeATemp are two different pistons. SetModeATemp looks at VirtualA and if it is switched on, and CURRENTLY, it takes HARDCODED setpoint values (heatpoint at 70, coolpoint at 72) and loads them into the thermostat. I would love to use the “Load attribute from variable” and use ModeAHeatSetpoint and ModeACoolSetpoint, respectively. As it is right now, to set the temperature, the “disable command optimizations” has to be OFF (use command optimizations) to get the setpoints loaded. What does work fine is the triggers for changeover in the other piston, SetModeAExec. It’s an Else-If that, if VirtualA is on, and thermostat’s reported room temperature is less than ModeAHeatTrigger, it sets the thermostat’s MODE to Heat. The Else-If is to do the same for cool. The Else is to flip a dummy switch. Command optimizations have to be OFF for the mode change logic to work.

D. Then there’s another couple pistons that are Else-If’s that examine what mode we’ve switched into, and where the phones are. If either my wife or I are present, and the Schedule is A, it does Mode A. If either my wife or I are present and the Schedule is B, it does Mode B. If the Schedule is C and either of us are present, it does Mode A (this is so if either of us are home when not scheduled to be home (home during a Schedule C) it won’t let the temperature get crazy). If the Schedule is B and neither of us are present it does C (this is so if we forget to turn the schedule off while gone for the night, it doesn’t bother trying to get the house in sleeping conditions). However, if the mode switches to A but no one is home, we want it to do that anyway - it means one of us is scheduled to come home, and we want it to be nice when we walk in the door.

All that logic just flips (and turns off the other two) the appropriate VirtualA/B/C switch.

I’m sure there’s way better ways to do all of this stuff, but it’s been trial and error to get my logic structures to work to be both comfortable and efficient and to find the bugs with my thermostat.

My big goal, and the last step in all thermostatic control for me, will be getting the load attribute from variable function to work.

1 Like

Thank you kindly for the time put into this response. It is appreciated.

Cheers.

I always look for cohesive posts like this because maybe when I’m googling an answer, I can find it and quickly get that data together without having to try so many things on my own.

I know verbose comments make people with tiny attention spans wig out, but I find that details tend to make for more contextual information and learning easier than the contrary.

I just figured out where url is for an Mp3 is.

how do I play this mp3 file when a sensor is triggered?

million thanks in advance.

So, I thought I knew the answer to this issue but it doesn’t seem to work. Let’s say I have a piston such as the following:

IF motion sensor=active
THEN turn on light
BUT IF motion sensor=inactive
THEN wait 2 minutes
turn off light

What seems to be happening is that during the 2 minute wait in the BUT IF clause, if motion is detected, it doesn’t matter - the lights will turn off and then come right back on since motion is active. I’m looking to figure out a way so that if additional motion is detected in that 2 minute waiting period, the light won’t turn off - in other words, the piston will cancel or start from the beginning again. I THOUGHT by setting Task Cancellation Policy in the Advanced Options to “Cancel on condition or piston state change” that it would solve the issue, but it doesn’t - the light flickers off and then comes right back on. Thoughts?

Check out NightlightPro.

change your but if section to STAYS inactive for 2 minutes. Remove the wait and just have it turn off.

As you currently have it I would guess: BUT IF motion sensor is inactive then…

The reason the light is still turning off is because once that motion sensor stops reporting active it will report inactive. Depending on the type of motion sensor varies in the length it will take to report that. ST brand motion sensor will report inactive relatively quickly compared to others. Anyway once that reports inactive your timer kicks off. You could add in a cancel on condition state change but that just adds more work. Simpler to just have it as STAYS inactive.

1 Like

Thanks - that makes perfect sense.

1 Like

Also could try cancel on state change. The timer will start when there if no motion but if it sees motion within the 2 min, it will restart the timer

Can I do this in CoRe easily?

IF Door Changes to Open
THEN
Using Nest Thermostat
var ThemoStatmode = NestThermostatMode
Eco()
BUT IF Door = Closed
AND Motion Sensor = Triggered
THEN
Using Nest Thermostat
(If ThermoStatmode = “off” THEN off())
(If ThermostaMode = “heat” THEN heat())

I’m using Nest Manager so cannot use Save Device State.

I know I could do this with multiple pistons, but would be much easier to do it with multiple if/switch statements within the THEN if possible.

Doesn’t work - already tried that. c1arkbar’s solution seems to be the best approach, though I have to do more testing. I have one use case in particular where I have 3 motion sensors in my office which I’m using as a single virtual motion sensor in CoRE and the “stays inactive for x minutes” didn’t seem to work in powering them off, but I need to do more testing. It will works great for my other application though.

I tried the same thing for one of my pistons, I’ve read up and it seems it SHOULD work but I believe there’s a bug/issue with CoRe cancelling. I could give you a convoluted way to get it working using global variables and “execute piston” but it looks like you’re good now?

I set up a piston that runs my evening lights. I did this with an or-if piston.

If at sunset
Then turn on XXXX
Or if at 2300
Then turn off XXXX

It works perfectly. I was reading up on Core though and it looks like the Or-If piston is very similar to a latching piston (But-If) and this scenario can work with that.

What is the difference between a latching piston and an Or-If piston?

Both pulled from the wiki here http://thingsthataresmart.wiki/index.php?title=CoRE

Thanks, I’ve read that but it’s still unclear how in use they would be different.

Both have Condition 1 fires Action 1 (OR… BUT) Condition 2 fires Action 2.

The only difference I see is Or/If has an Else addition. Would that be the only difference? In my piston I simply left the else blank.

The but if should be used as either it will be this or it will be that.

Or can be this or that but doesn’t have to be either

So but-if would be like a switch.

If switch on
Then xxxx
But if switch off
Then xxx

Where or-if would allow an additional category (neither).

If temp above 80
Then cool
Or if temp below 65
Then heat
Else do xxxx (or leave blank for nothing)

It seems to my untrained eye that all these types of pistons simply add additional sections. I think too much is being made of the names and selecting before design seems counterintuitive to me. Just starting with a basic piston and then being able to add an “or”, “but”, “else” section during the design would make more sense.

But I know webCore is on its way so it’ll be interesting to see how that will play out.

Thanks for the info!

Hey eibyer,

Sorry for the late reply, I’ve been travelling and a bit out of pocket.

Your logic helped me out a lot, and got me thinking in the right form. Although it’s not verbatim what you wrote, it’s pretty close. I did have to make two rules, though, one for weekdays and then one for the weekend.

Thanks!

1 Like

WebCoRE fixes the issue of piston types. It’s loads of fun to play with. Complex pistons can be whipped up in moments.

Hey there, could anyone help me set a variable to equal a device attribute? I’m using the updated GCal search, in which the developer maintaining the code has kindly added device attributes that reflect time offset from when the contact is scheduled to go open and closed - which he has named startMsgTime and endMsgTime. I’m looking to use those times to control a thermostat, but am a little stuck as to how to achieve this.

Originally, I intended to make a piston that compared the global variable $now, with the times stated in those device attributes. Specifically, I wanted to be able to do something like this:

IF $now is inside range {deviceName}:startMsgTime AND {deviceName}:endMsgTime, THEN using {Themostat1} set cooling setpoint to 76.

But I can’t seem to figure out how to compare $now with a device attribute - I see the options to compare it with a raw value or with another variable, but the option for comparing to a device says “you can’t currently add this.”

I do have Expert Mode enabled.

The other idea presented to me, was to make a piston that looked for startMsgTime or endMsgTime changing, and using that change to immediately set a custom variable to something…however, i can only figure out how to set the time in the custom variable to the current time, not the time listed in the device attribute. Ideas?