Turn on Heater 3 (Loud Kicks!) if Temp Difference Between Heater 1 (quiet) and Heater 2 (quiet) is greater than 1 degree


#1

Total Noob and old, crusty guy to boot!

1) Give a description of the problem
I’m getting this error: This piston does not subscribe to any events. Unless executed by other means, it will never run on its own.

2) What is the expected behavior?
Heater Kicks to switch its heating setpoint to Heater Nook if the temperature difference between the Living Room and Dining Room is greater than 1 degree. Otherwise, shut off kicks (by turning setpoint to 10).

3) What is happening/not happening?
It’s giving me the not subscribed to events error.

**4) Post a Green Snapshot of the piston!!

**5) Attach any logs

2/11/2019, 9:14:25 PM +97ms
+1ms ╔Starting piston… (v0.3.109.20181207)
+226ms ║╔Subscribing to devices…
+318ms ║║Subscribing to Heater - Kitchen Kicks…
+320ms ║╚Finished subscribing (102ms)
+374ms ║Calculating (decimal) 22.2 - (decimal) 22.2 >> (decimal) 0.0
+386ms ║Comparison (decimal) 0.0 is_outside_of_range (integer) -1 … (integer) 1 = false (5ms)
+417ms ║Calculating (decimal) 22.2 - (decimal) 22.2 >> (decimal) 0.0
+430ms ║Comparison (decimal) 0.0 is_inside_of_range (integer) -1 … (integer) 1 = true (5ms)
+444ms ╚Piston successfully started (444ms)
2/11/2019, 9:14:09 PM +70ms
+1ms ╔Received event [Home].test = 1549948449069 with a delay of 0ms
+115ms ║RunTime Analysis CS > 25ms > PS > 59ms > PE > 31ms > CE
+119ms ║Runtime (39131 bytes) successfully initialized in 59ms (v0.3.109.20181207) (117ms)
+121ms ║╔Execution stage started
+146ms ║║Calculating (decimal) 22.2 - (decimal) 22.2 >> (decimal) 0.0
+156ms ║║Comparison (decimal) 0.0 is_outside_of_range (integer) -1 … (integer) 1 = false (3ms)
+159ms ║║Condition #2 evaluated false (30ms)
+161ms ║║Condition group #1 evaluated false (state did not change) (32ms)
+177ms ║║Calculating (decimal) 22.2 - (decimal) 22.2 >> (decimal) 0.0
+186ms ║║Comparison (decimal) 0.0 is_inside_of_range (integer) -1 … (integer) 1 = true (3ms)
+189ms ║║Condition #4 evaluated true (23ms)
+191ms ║║Condition group #3 evaluated true (state did not change) (27ms)
+195ms ║║Cancelling statement #5’s schedules…
+428ms ║║Executed physical command [Heater - Kitchen Kicks].setHeatingSetpoint([10.0]) (222ms)
+430ms ║║Executed [Heater - Kitchen Kicks].setHeatingSetpoint (225ms)
+437ms ║╚Execution stage complete. (317ms)
+439ms ╚Event processed successfully (439ms)
2/11/2019, 9:14:01 PM +926ms
+1ms ╔Starting piston… (v0.3.109.20181207)
+206ms ║╔Subscribing to devices…
+319ms ║║Subscribing to Heater - Kitchen Kicks…
+321ms ║╚Finished subscribing (123ms)
+362ms ║Calculating (decimal) 22.2 - (decimal) 22.2 >> (decimal) 0.0
+370ms ║Comparison (decimal) 0.0 is_outside_of_range (integer) -1 … (integer) 1 = false (4ms)
+395ms ║Calculating (decimal) 22.2 - (decimal) 22.2 >> (decimal) 0.0
+403ms ║Comparison (decimal) 0.0 is_inside_of_range (integer) -1 … (integer) 1 = true (3ms)
+416ms ╚Piston successfully started (415ms)
2/11/2019, 9:10:02 PM +296ms
+1ms ╔Received event [Home].test = 1549948202295 with a delay of 0ms
+99ms ║RunTime Analysis CS > 16ms > PS > 48ms > PE > 35ms > CE
+102ms ║Runtime (39191 bytes) successfully initialized in 48ms (v0.3.109.20181207) (100ms)
+104ms ║╔Execution stage started
+133ms ║║Calculating (decimal) 22.0 - (decimal) 21.9 >> (decimal) 0.10000000000000142
+145ms ║║Comparison (decimal) 0.10000000000000142 is_outside_of_range (integer) -1 … (integer) 1 = false (5ms)
+150ms ║║Condition #2 evaluated false (37ms)
+152ms ║║Condition group #1 evaluated false (state did not change) (41ms)
+173ms ║║Calculating (decimal) 22.0 - (decimal) 21.9 >> (decimal) 0.10000000000000142
+183ms ║║Comparison (decimal) 0.10000000000000142 is_inside_of_range (integer) -1 … (integer) 1 = true (4ms)
+186ms ║║Condition #4 evaluated true (29ms)
+188ms ║║Condition group #3 evaluated true (state did not change) (32ms)
+192ms ║║Cancelling statement #5’s schedules…
+602ms ║║Executed physical command [Heater - Kitchen Kicks].setHeatingSetpoint([22.0]) (234ms)
+604ms ║║Executed [Heater - Kitchen Kicks].setHeatingSetpoint (238ms)
+609ms ║╚Execution stage complete. (505ms)
+658ms ╚Event processed successfully (658ms)


#2

The command “is outside of range” is a condition, which normally does not subscribe to anything. What usually happens when there are no triggers in the piston is the conditions become triggers. For some reason, in your case, they are not. I think it is because of the math you have embedded. SmartThings would have to query the device, and then do the math before it knows if it should run or not.


Just throwing an idea out there…

If I was doing this in my house, I would put your entire piston into a repeating block. Maybe something like:

The first four variables at the top can be changed to suit you. With the current coding, it will check every 45 minutes to see if there is a gap between temps. If so, it turns on the loud heater, and also sets the timer to check every ten minutes. Once this second check finds the two temperatures back near each other, it will basically turn off the loud heater, and turn the timer back to 45 minutes.


Also, just food for thought:
If you are using only one degree difference (which could end up being 1.1 degrees), I suspect that your obnoxious heater may turn on more often than you would like.

The example above has the added benefit of making sure the loud noise happens as infrequently as possible,


#3

Thanks!

Two things:

(1) I’m embarrassed to say I can’t figure out how to change ‘HeaterA’ to the name of my actual heater. When I did it with my code, it brought up a drop down menu up as soon as I started typing ‘Heater’ that I could then pick from. I can’t, for the life of me, figure out how to get that drop down menu back.

(2) Because I’m cheap and turn the heat down to 10 degrees when we’re sleeping or we leave, I realize I need the kicks to come on below a certain temperature, regardless of whether HeaterA and HeaterB are about the same temperatures or not. So, for example, if either of Heater A’s or Heater’s B temperature is below, say, 19 degrees, the kicks should come on. I can’t figure out how to layer that over top of the above code.

Sorry…I’m way out of my depth!


#4

Yeah, sorry, I had to use a generic name since I do not have the same devices as you. You should be able to manually type out exactly as you had before, and it should work.

(use your first post as reference)


Personally, I would create a new piston for this, so the logic doesn’t mess with what you have here.


#5

Appreciate it! I think that does the trick, and I can now play around with the numbers…thanks! I didn’t realize you could just cut and paste into the text box. I thought you had to use the drop down menus. [insert face slap here].

Screenshot of code:

And copy of log:

2/12/2019, 9:17:45 PM +222ms
+0ms ╔Received event [Home].test = 1550035065221 with a delay of 0ms
+115ms ║RunTime Analysis CS > 18ms > PS > 61ms > PE > 36ms > CE
+119ms ║Runtime (39055 bytes) successfully initialized in 61ms (v0.3.109.20181207) (116ms)
+121ms ║╔Execution stage started
+150ms ║║Calculating (decimal) 22.6 - (decimal) 21.0 >> (decimal) 1.6000000000000014
+163ms ║║Comparison (decimal) 1.6000000000000014 is_outside_of_range (integer) -1 … (integer) 1 = true (5ms)
+166ms ║║Condition #2 evaluated true (33ms)
+168ms ║║Condition group #1 evaluated true (state did not change) (35ms)
+172ms ║║Cancelling statement #7’s schedules…
+566ms ║║Executed physical command [Heater - Kitchen Kicks].setHeatingSetpoint([20.5]) (216ms)
+567ms ║║Executed [Heater - Kitchen Kicks].setHeatingSetpoint (218ms)
+571ms ║╚Execution stage complete. (451ms)
+658ms ╚Event processed successfully (658ms)

I didn’t realize you could have multiple pistons doing different things with the same device, but, of course, that makes sense now that I think about it. Right now, I control my living room, dining room and nook with my nook thermostat. In other words, all the wife (or me!) has to do is worry about the nook thermostat for our “main” area–all other thermostats will then use the nook’s setpoint as their own. Now that I’ve dealt with the kicks “kicking” in to keep the temperature stable (in our main area), I can just run another piston that basically says set the kicks at the same setpoint as the nook setpoint, but only if the nook temperature is less than–say–19–degrees, otherwise if the nook’s temperature is 19 degrees or more set the kick’s setpoint for 10? But wouldn’t that conflict with the instructions in the code you gave me if the kicks piston’s conditions are met in your code? In other words, assume the temperature difference is greater than 1 (in my example using your code), but the temperatures are all above 19 (in my new example), would the kicks shut off or kick in?

I appreciate all the handholding…I’ve been trying to figure this out on my own–unsuccessfully- for a long time! I know it’s probably intuitive to you, but it’s all completely foreign to me.


#6

Sorry, now I’m spamming my own thread.

Not sure if it’s running properly. For starters, the Kicks are set for 20.5 when the temperature varied by 1 degree, but not sure why it set it at 20.5? I originally hardwired 20.0 in as the setpoint when the conditions were met, but why 20.5? Then I changed it so that the kicks would set their setpoint to the setpoint of the Nook, but–after hitting test–the setpoint is still 20.5. Is that because of the timer maybe?

I guess, similar to the timer, now that the temperature is within 1 degree, if I hit “test”, the kicks don’t shut off…again, maybe the timer? I notice there’s “heating point” for the command vs. “heatingsetpoint” for the variable, but there was no “heatingsetpoint” in the command. Just a bit odd the terms used are different…

Logs

2/12/2019, 9:54:38 PM +31ms
+1ms ╔Received event [Home].test = 1550037278030 with a delay of 0ms
+122ms ║RunTime Analysis CS > 25ms > PS > 58ms > PE > 39ms > CE
+125ms ║Runtime (40021 bytes) successfully initialized in 58ms (v0.3.109.20181207) (122ms)
+126ms ║╔Execution stage started
+170ms ║║Comparison (integer) 30 is_outside_of_range (integer) 1 … (integer) 500 = false (4ms)
+173ms ║║Condition #11 evaluated false (10ms)
+174ms ║║Condition group #10 evaluated false (state did not change) (13ms)
+191ms ║╚Execution stage complete. (65ms)
+196ms ║Setting up scheduled job for Tue, Feb 12 2019 @ 10:22:45 PM PST (in 1687.274s)
+301ms ╚Event processed successfully (301ms)
2/12/2019, 9:52:44 PM +969ms
+2ms ╔Starting piston… (v0.3.109.20181207)
+348ms ║╔Subscribing to devices…
+478ms ║║Subscribing to Heater - Kitchen Kicks…
+479ms ║╚Finished subscribing (146ms)
+570ms ║Calculating (decimal) 21.8 - (decimal) 20.9 >> (decimal) 0.9000000000000021
+584ms ║Comparison (decimal) 0.9000000000000021 is_outside_of_range (decimal) -1.0 … (decimal) 1.0 = false (4ms)
+587ms ║Cancelling condition #3’s schedules…
+589ms ║Cancelling condition #2’s schedules…
+609ms ║Comparison (integer) 30 is_outside_of_range (integer) 1 … (integer) 500 = false (4ms)
+618ms ║Setting up scheduled job for Tue, Feb 12 2019 @ 10:22:45 PM PST (in 1799.915s)
+633ms ╚Piston successfully started (633ms)

Now that I look more carefully, this isn’t right is it?? Isn’t 0.9 inside the range of -1 to 1, such that the kicks should turn off once the timer is hit?

+570ms ║Calculating (decimal) 21.8 - (decimal) 20.9 >> (decimal) 0.9000000000000021
+584ms ║Comparison (decimal) 0.9000000000000021 is_outside_of_range (decimal) -1.0 … (decimal) 1.0 = false (4ms)

Thanks!!


#7

Somehow, you deleted the two lines
Set variable {timer}
as seen in my “9pmk” piston above. (lines 33 & 36)

The timer will not change with those two lines missing.


This is true, but a good rule of thumb is trying to make sure only one fires at any given moment. In this case, it sounds OK because one piston will be firing at one temperature range, and another piston will be firing at a (mostly) different temperature.

The logic behind this is if too many commands are trying to be sent out simultaneously, there may be occasions where some commands do not reach the destination.


I might hold off a few days on the second piston until you get this one working. No need to get all tangled up in two webs at once. In general though, you want to make sure the two codes do not step on each other’s toes.


#8

This piston does nothing when pressing TEST.
You just have to let it run to see if it’s working.
(well, that plus put back in those two missing lines)


#9

This looks right to me.
“Outside = false” is the same as saying “inside = true”


#10

Thank goodness for anonymity. Clearly what little grey matter I had has fossilized! My brain didn’t even process the “= false” part of the equation. My daughter–who I’m encouraging to take up coding(!)–had a good laugh at your flipping the statement around to “inside=true”!

To continue with the stupid train, I can’t figure out how to keep the variable as something separate from turning on the kicks. I reloaded your code, but for the life of me can’t figure out how to say “turn on kicks” AND “set variable”, since I assume the variable is not a “new task” under the “turn on kicks” action? Put another way, I can’t seem to “insert” a line of code after “Heater - Kitchen Kicks” that says “set heatingpoint to X”, and then have a statement following that that says AND “set variable”. Which is–I’m guessing–how I ended up deleting it in the first place.

image

I fear I’m missing the obvious…


#11

Just “add a new statement” for the heater commands, and make sure it happens right before the variable set.


Pro Tip:
Once that block is created, you can drag the set variable into the same block. (but it won’t work in reverse)

This is because “Location” is a generic block


Observation :

It looks like your original post used the device “Thermostat 3” to send that command.

temp


One way to think of this:
“Set variable” lines can be inside ANY block of code, but “set heating” can only be in blocks that have that capability. (Thermostats etc)


#12

I didn’t see that “add a new statement” box at the end of the block. I added the necessary statement to the end of the block, and then figured out how to drag it up.

I’ll spend some time tonight trying to figure out the basics of Webcore so I at least have some sense of the structure before posting again. It’s daunting to try and figure out in isolation without a real-world (more bitesize) example to start with.

In the interim, it sounds like it’s fine to set the variable under the “heater” command, like below, because Webcore is smart enough to know a variable doesn’t just tie into the “heater” that it’s under?


#13

That is correct. A “Set variable” command can be anywhere in your code. It is one of the “built-in” commands that work inside any old block.


#14

Got it, thanks. I think this is the final product, which I’ll test tonight and run for a while before adding any additional commands in a separate piston…thanks again WCmore!!

2/13/2019, 2:18:35 PM +855ms
+1ms ╔Starting piston... (v0.3.109.20181207)
+303ms ║╔Subscribing to devices...
+421ms ║║Subscribing to Heater - Kitchen Kicks...
+425ms ║╚Finished subscribing (135ms)
+496ms ║Calculating (decimal) 11.9 - (decimal) 12.2 >> (decimal) -0.29999999999999893
+508ms ║Comparison (decimal) -0.29999999999999893 is_outside_of_range (decimal) -1.0 .. (decimal) 1.0 = false (3ms)
+531ms ║Comparison (integer) 30 is_outside_of_range (integer) 1 .. (integer) 500 = false (4ms)
+535ms ║Cancelling condition #11's schedules...
+537ms ║Cancelling condition #10's schedules...
+545ms ║Setting up scheduled job for Wed, Feb 13 2019 @ 2:48:36 PM PST (in 1799.922s)
+556ms ╚Piston successfully started (556ms)

#15

Sorry to be such a PITA, but the temperature of the two thermostats has NEVER been outside the range of 1 degree, so I can’t test the piston. That said, I need to turn the kicks on to get the temperature up where there WILL start to be a variation. But I don’t think I can run a separate piston, because this one keeps shutting off the kicks (because the temp is within 1 degree).

I tried to add an “or” condition to deal with this in line 31, but it doesn’t seem to be working:

It correctly identifies the first condition (temp outside of 1 degree range) as being false and the second condition as being true (all the thermostats temps below the main thermostat’s setpoint), but it doesn’t seem to be picking it up that I want it to kick in the kicks if either one of those conditions are met (ie, the “or” I tried to add). I’m only sheepishly posting this, but I feel like I’m so close!

2/14/2019, 5:22:35 PM +13ms
+1ms ╔Starting piston... (v0.3.109.20181207)
+251ms ║╔Subscribing to devices...
+401ms ║║Subscribing to Heater - Kitchen Nook And Front Door...
+403ms ║║Subscribing to Heater - Kitchen Kicks...
+404ms ║╚Finished subscribing (164ms)
+470ms ║Calculating (decimal) 19.1 - (decimal) 19.5 >> (decimal) -0.3999999999999986
+483ms ║Comparison (decimal) -0.3999999999999986 is_outside_of_range (decimal) -1.0 .. (decimal) 1.0 = false (3ms)
+517ms ║Comparison (decimal) 19.5 is_less_than (decimal) 20.5 = true (3ms)
+522ms ║Comparison (decimal) 18.2 is_less_than (decimal) 20.5 = true (3ms)
+526ms ║Comparison (decimal) 19.1 is_less_than (decimal) 20.5 = true (2ms)
+552ms ║Comparison (integer) 30 is_outside_of_range (integer) 1 .. (integer) 500 = false (3ms)
+573ms ║Setting up scheduled job for Thu, Feb 14 2019 @ 5:52:35 PM PST (in 1799.866s)
+588ms ╚Piston successfully started (587ms)

#16

Do you realize how fortunate you are? It means your house temperature is stable and uniform, so this safety net of a piston is not needed to run!! Well done!!

(Remember the goal was to balance the house, with as few loud kicks as possible)

For what it’s worth, I would likely remove the new OR lines you added.

If you really want to test it, why not raise or lower one of your other heaters for an hour or two. (Living room or dining room) This trick would likely create a larger difference between the two, so the piston here can kick on.

All that being said, I think you are good to go without any tweaks.
(although testing is usually the right choice when it comes to programming)


#17

Ha ha! True! But my wife’s nose is still running without the kicks boosting the temp!

Duh…that’s a good point. I have those on another piston to hinge off the “main” thermostat", so they kept turning back on, but I realize I can just pause that piston for testing. FACK!

BTW, I think it’s working. They just “kicked” on. I think it had something to do with the timer function. We’re heading out for V-Day dinner, and will be asleep by 830pm, but who knows what might happen if I can get the heat above 20 Celsius when we get home! Really, really appreciate all the help!

2/14/2019, 5:52:35 PM +253ms
+1ms ╔Received event [Home].time = 1550195555450 with a delay of -198ms
+468ms ║RunTime Analysis CS > 43ms > PS > 381ms > PE > 44ms > CE
+471ms ║Runtime (41721 bytes) successfully initialized in 381ms (v0.3.109.20181207) (468ms)
+472ms ║╔Execution stage started
+505ms ║║Calculating (decimal) 19.6 - (decimal) 19.8 >> (decimal) -0.1999999999999993
+519ms ║║Comparison (decimal) -0.1999999999999993 is_outside_of_range (decimal) -1.0 .. (decimal) 1.0 = false (3ms)
+523ms ║║Condition #3 evaluated false (34ms)
+552ms ║║Comparison (decimal) 19.8 is_less_than (decimal) 20.5 = true (3ms)
+555ms ║║Comparison (decimal) 18.4 is_less_than (decimal) 20.5 = true (2ms)
+560ms ║║Comparison (decimal) 19.6 is_less_than (decimal) 20.5 = true (3ms)
+562ms ║║Condition #18 evaluated true (37ms)
+564ms ║║Condition group #17 evaluated true (state did not change) (39ms)
+566ms ║║Condition group #2 evaluated true (state did not change) (78ms)
+569ms ║║Cancelling statement #4's schedules...
+651ms ║║Executed physical command [Heater - Kitchen Kicks].setHeatingSetpoint([20.5]) (71ms)
+653ms ║║Executed [Heater - Kitchen Kicks].setHeatingSetpoint (74ms)
+665ms ║║Executed virtual command [Heater - Kitchen Kicks].setVariable (4ms)
+669ms ║╚Execution stage complete. (198ms)
+671ms ║Setting up scheduled job for Thu, Feb 14 2019 @ 6:22:35 PM PST (in 1799.527s)
+681ms ╚Event processed successfully (681ms)