Set heatpoint X minutes before 4pm based on temperature (so it gets to y degrees by 4pm)


#1

1) Give a description of the problem
My main area heats up at a rate of about 6 degrees an hour. I can’t figure out how to get the heater to kick in X minutes before 4pm based on the temperature at that time.

2) What is the expected behavior?
I browbeat my kid into coming up with a code for me. I think she’s got it right: If Temperature [of thermostat] <21 [degrees], then set HeatingSetPoint to 21 10(21- Temperature) minutes before 4pm.

3) What is happening/not happening?
I’m too dumb to figure out if I’m dealing with an argument, expression or variable in Webcore in trying to run the formula.


#2

a simple one can be something like this:

Every day at 3.55pm (timer)
IF heater thermostat (or any other sensor that reads) IS X degrees or below
Then 
Do this do that

#3

There is one issue when using a variable in a scheduled time…

The piston only checks the variable when the piston executes.
It has no knowledge of the variable until after the piston runs.

In other words, if this variable has changed in the past 24 hours, it will not see the new variable until after the 24 hour schedule has executed.


You can get around this somewhat if the piston has two triggers.

  • One trigger fires before the earliest possible event. (checking temp & changing the variable)
  • The second trigger can then use the variable in the time, since it was recently updated.

For example, this piston fires at a different time each and every day.

temp

Lines 45-47 is simply to refresh the variable & timer (can be any time)
Lines 53 and onwards is the real part of the piston.


#4

I find this stuff tough to understand. I vow to spend some more time reading about the basics of Webcore (or better yet, tracaking down a video). I’ve tried, but it’s tough for me to absorb, although I realize I don’t even understand Webcore 101.

Two pistons has got to be correct, though, because the first piston needs to figure out what the temperature difference is earlier enough before 4pm (in my case) to do something about it. I’m thinking it won’t take more than 2 hours to heat up, because I set the “off” temperature at 10 Celsius. So I guess the first piston needs to execute at, say, 2pm to figure out what 10 x (21 - Temp) is? That would give me how many minutes before 4pm the second piston needs to execute. In other words, if the Temp is 11 degrees, then 21 - 11 = 10, so I need the second piston to fire 100 minutes before 4pm. Do I do that with a variable or an expression?

The next piston would, as you say, then simply have to execute [Variable?] minutes before 4pm to set the Heatingsetpoint to 21 if Temp < 21. But I can’t figure out how to do that. How would I input that “code” into Webcore?


#5

This is actually one of the occasions where I would use two triggers in the same piston.
(with both of them being time based)


Personally, I would use both. I would “Set variable to X”, and define X using an expression.


If you take my advice and make both triggers in the same piston, I would do it something like this:

define
    decimal temp  (not set)
    integer offset  (not set)
end define

Every day at 2pm
    Set variable {temp} = YourDevice's temperature
    Set variable {offset} = (21 - temp) * 10
END EVERY

Every day at {offset} minutes before 4pm
    IF {temp} is < 21
        Then do cool stuff
    END IF
END EVERY

Quick Note:
If your device only sees whole temperatures, then the variable {temp} can be an integer.

Also, the third line (Set variable offset) is the only expression here:
(21 - temp) * 10


Pro Tip:
If there is ever a 2PM where the temp is greater than 21 (let’s say 23 degrees), then that day the second trigger would fire after 4pm. (in this example, at 4:20) Of course, with the IF block in place, the “cool stuff” would not execute, since {temp} is greater than 21, but it is handy to be aware if you want different actions to take place in those cases.


#7

Thanks!!

Sorry, meant two triggers, not pistons.

I think I’ve almost got it, but I can’t figure out how you can provide for the second piston to fire {offset} minutes before 4pm in line 27.

If it’s not an “Expression” in the “At this time…” box, what is it? If I choose Value, I don’t get the offset box (but can put in 4:00pm), and if I choose Variable, they are all pre-determined? I tried to use a time expression, but I’m obviously missing something obvious?

image


#8

Try wrapping that expression in a set of ( )


#9

I forgot the offset is not shown with time. You can work around this by making 4pm a time variable up top

temp

Then on line 27, make it something like this:

temp


The one thing you will also have to change is line 25 needs to make sure {Lead_Time} is a negative number, so it triggers before 4pm. Something like:

Set variable {Lead_Time} = (Nook_Temp-21) * 10


#10

Thanks!! I think that did the trick…

For testing purposes, I changed the target time (when I get home) to 230pm, and to check for the offset at 2:29pm. I also had to monkey with the temps so I assumed I wanted it at 25 degrees by 2:30pm.

The log seems to confirm it’s working, although it’s setting the heaters to kick in at 2:04pm tomorrow, presumably because there’s no time machine built into Webcore!

Unless you see something I don’t, thanks!!!

Logs

3/2/2019, 2:28:59 PM +110ms
+1ms ╔Received event [Home].time = 1551565740000 with a delay of -891ms
+126ms ║RunTime Analysis CS > 23ms > PS > 76ms > PE > 27ms > CE
+128ms ║Runtime (38470 bytes) successfully initialized in 76ms (v0.3.10a.20190223) (126ms)
+130ms ║╔Execution stage started
+147ms ║║Cancelling statement #2’s schedules…
+161ms ║║Executed virtual command setVariable (3ms)
+169ms ║║Calculating (decimal) 22.3 - (decimal) 25.0 >> (decimal) -2.6999999999999993
+175ms ║║Calculating (decimal) -2.6999999999999993 * (decimal) 10.0 >> (decimal) -26.999999999999993
+182ms ║║Executed virtual command setVariable (3ms)
+186ms ║╚Execution stage complete. (57ms)
+189ms ║Setting up scheduled job for Sun, Mar 3 2019 @ 2:04:00 PM PST (in 84900.702s), with 1 more job pending
+201ms ╚Event processed successfully (201ms)


#11

Well, there is one more tweak if you want reliability.

The time at line 23 must be before the very earliest possible time, or the second trigger (set heating point) will never trigger.

In other words, with your current wording, it will not know until 2:29 what {Lead_Time} is, so it is impossible for it to trigger the second block at 2:30 - {Lead_Time} since that time would have already passed. This error will repeat each and every day.

So either make a wider gap between the two times…
OR
Make a new math formula on line 26 that adds an offset (positive number) to take place after 2:30.


Basically:
If {Lead_Time} is a negative number, it will trigger before {Target_Time}
If {Lead_Time} is a positive number, it will trigger after {Target_Time}

…and {Lead_Time} must be set before the second block is supposed to trigger.


#12

Thanks!!

To match my intellect, I went with the KISS method and put a 2 1/2 hour gap in between figuring out the Lead_Time before the Target_Time. Here’s the final code…Thanks again WCmore!


#13

That should do it! :+1:

You should see a wakeup scheduled for 1:30, and once that executes, the next wakeup schedule will be 4PM minus {Lead_Time}


#14

Really appreciate it Monsieur WC!!!


#15

Hmmm, are you seeing something I’m not? It looks like the calculation is somehow wrong in line 28? The heaters came on at 3:34pm, or 26 minutes before 4pm (the TargetTime), but they should have come on at 2:23pm, being 97 minutes (the calculation determined in Lead_Time) before the TargetTime.

Logs

3/4/2019, 3:33:59 PM +366ms
+0ms ╔Received event [Home].time = 1551742440000 with a delay of -635ms
+256ms ║RunTime Analysis CS > 38ms > PS > 192ms > PE > 26ms > CE
+259ms ║Runtime (38500 bytes) successfully initialized in 192ms (v0.3.10a.20190223) (257ms)
+260ms ║╔Execution stage started
+308ms ║║Comparison (decimal) 11.1 is_less_than (integer) 18 = true (3ms)
+311ms ║║Cancelling condition #8’s schedules…
+312ms ║║Condition #8 evaluated true (18ms)
+314ms ║║Cancelling condition #6’s schedules…
+315ms ║║Condition group #6 evaluated true (state changed) (21ms)
+317ms ║║Cancelling statement #6’s schedules…
+709ms ║║Executed physical command [Heater - Kitchen Nook And Front Door].setHeatingSetpoint([21.0]) (386ms)
+711ms ║║Executed [Heater - Kitchen Nook And Front Door].setHeatingSetpoint (388ms)
+718ms ║╚Execution stage complete. (458ms)
+722ms ║Setting up scheduled job for Tue, Mar 5 2019 @ 1:30:00 PM PST (in 78959.914s), with 1 more job pending
+732ms ╚Event processed successfully (733ms)

3/4/2019, 1:29:59 PM +50ms
+1ms ╔Received event [Home].time = 1551735000000 with a delay of -950ms
+99ms ║RunTime Analysis CS > 17ms > PS > 49ms > PE > 32ms > CE
+103ms ║Runtime (38496 bytes) successfully initialized in 49ms (v0.3.10a.20190223) (100ms)
+105ms ║╔Execution stage started
+131ms ║║Cancelling statement #2’s schedules…
+144ms ║║Executed virtual command setVariable (4ms)
+154ms ║║Calculating (decimal) 11.3 - (decimal) 21.0 >> (decimal) -9.7
+160ms ║║Calculating (decimal) -9.7 * (decimal) 10.0 >> (decimal) -97.0
+167ms ║║Executed virtual command setVariable (4ms)
+172ms ║╚Execution stage complete. (67ms)
+174ms ║Setting up scheduled job for Mon, Mar 4 2019 @ 3:34:00 PM PST (in 7440.777s), with 1 more job pending
+183ms ╚Event processed successfully (182ms)


#16

The code in piston “pue9” looks real good, but for some reason, the scheduled wakeup was incorrect.

I would try adding a 1 second WAIT after line 26. This small delay is just to make sure the new variable has enough time to be written before the wakeup is scheduled.

(I suspect that yesterday the variable was -26, and the new variable was in the process of being written when this schedule was set)


Here is your identical piston with the WAIT added, as well as two log to console commands that will help with any future troubleshooting.


#17

Ahhh…there’s no way I would have figured that one out! From the log below, I’m betting you’re right. Thanks (again x 2!). Your code is uploaded to my Webcore and will check again tomorrow. :+1:

3/2/2019, 2:28:59 PM +110ms
+1ms ╔Received event [Home].time = 1551565740000 with a delay of -891ms
+126ms ║RunTime Analysis CS > 23ms > PS > 76ms > PE > 27ms > CE
+128ms ║Runtime (38470 bytes) successfully initialized in 76ms (v0.3.10a.20190223) (126ms)
+130ms ║╔Execution stage started
+147ms ║║Cancelling statement #2’s schedules…
+161ms ║║Executed virtual command setVariable (3ms)
+169ms ║║Calculating (decimal) 22.3 - (decimal) 25.0 >> (decimal) -2.6999999999999993
+175ms ║║Calculating (decimal) -2.6999999999999993 * (decimal) 10.0 >> (decimal) -26.999999999999993
+182ms ║║**Executed virtual command setVariable (**3ms)
+186ms ║╚Execution stage complete. (57ms)
+189ms ║Setting up scheduled job for Sun, Mar 3 2019 @ 2:04:00 PM PST (in 84900.702s), with 1 more job pending
+201ms ╚Event processed successfully (201ms)


#18

Hmmm, I can’t figure out why this time it fired at 4pm when the variables seem to be correctly set…

Local variables
decimalNook_Temp 11.5
integerLead_Time -95
timeTarget_Time4:00:00 PM

and the offset seems to be correct…

3/5/2019, 3:59:59 PM +130ms
+1ms ╔Received event [Home].time = 1551830400000 with a delay of -871ms
+154ms ║RunTime Analysis CS &gt; 34ms &gt; PS &gt; 91ms &gt; PE &gt; 29ms &gt; CE
+158ms ║Runtime (39997 bytes) successfully initialized in 91ms (v0.3.10a.20190223) (155ms)
+161ms ║╔Execution stage started
+234ms ║║Comparison (decimal) 11.6 is_less_than (integer) 18 = true (5ms)
+238ms ║║Cancelling condition #8's schedules...
+240ms ║║Condition #8 evaluated true (24ms)
+243ms ║║Cancelling condition #6's schedules...
+245ms ║║Condition group #6 evaluated true (state changed) (31ms)
+248ms ║║Cancelling statement #6's schedules...
+343ms ║║Executed physical command [Heater - Kitchen Nook And Front Door].setHeatingSetpoint([21.0]) (85ms)
+344ms ║║Executed [Heater - Kitchen Nook And Front Door].setHeatingSetpoint (88ms)
+368ms ║║Calculating (string) Set Heating point @ + (string) 3:59 P.M. &gt;&gt; (string) Set Heating point @ 3:59 P.M.
+376ms ║║Calculating (string) Set Heating point @ 3:59 P.M. + (string) ( &gt;&gt; (string) Set Heating point @ 3:59 P.M. (
+384ms ║║Calculating (string) Set Heating point @ 3:59 P.M. ( + (string) 4:00:00 PM PST &gt;&gt; (string) Set Heating point @ 3:59 P.M. (4:00:00 PM PST
+390ms ║║Calculating (string) Set Heating point @ 3:59 P.M. (4:00:00 PM PST + (string) - &gt;&gt; (string) Set Heating point @ 3:59 P.M. (4:00:00 PM PST -
+396ms ║║Calculating (string) Set Heating point @ 3:59 P.M. (4:00:00 PM PST - + (string) -95 &gt;&gt; (string) Set Heating point @ 3:59 P.M. (4:00:00 PM PST - -95
+401ms ║║Calculating (string) Set Heating point @ 3:59 P.M. (4:00:00 PM PST - -95 + (string) mins) &gt;&gt; (string) Set Heating point @ 3:59 P.M. (4:00:00 PM PST - -95 mins)
+408ms ║║Set Heating point @ 3:59 P.M. (4:00:00 PM PST - -95 mins)
+410ms ║║Executed virtual command [Heater - Kitchen Nook And Front Door].log (2ms)
+416ms ║╚Execution stage complete. (256ms)
+419ms ║Setting up scheduled job for Wed, Mar 6 2019 @ 1:30:00 PM PST (in 77400.452s), with 1 more job pending
+429ms ╚Event processed successfully (429ms)


3/5/2019, 1:29:59 PM +78ms
    +1ms ╔Received event [Home].time = 1551821400000 with a delay of -923ms
    +86ms ║RunTime Analysis CS &gt; 20ms &gt; PS &gt; 52ms &gt; PE &gt; 14ms &gt; CE
    +89ms ║Runtime (39992 bytes) successfully initialized in 52ms (v0.3.10a.20190223) (87ms)
    +91ms ║╔Execution stage started
    +117ms ║║Cancelling statement #2's schedules...
    +133ms ║║Executed virtual command setVariable (4ms)
    +144ms ║║Calculating (decimal) 11.5 - (decimal) 21.0 &gt;&gt; (decimal) -9.5
    +152ms ║║Calculating (decimal) -9.5 * (decimal) 10.0 &gt;&gt; (decimal) -95.0
    +160ms ║║Executed virtual command setVariable (4ms)
    +168ms ║║Executed virtual command wait (1ms)
    +170ms ║║Requesting a wake up for Tue, Mar 5 2019 @ 1:30:00 PM PST (in 1.0s)
    +179ms ║║Fast executing schedules, waiting for 992ms to sync up
    +1222ms ║║Calculating (string) ( + (string) 11.5 &gt;&gt; (string) (11.5
    +1230ms ║║Calculating (string) (11.5 + (string) - 21) * 10 = &gt;&gt; (string) (11.5 - 21) * 10 =
    +1238ms ║║Calculating (string) (11.5 - 21) * 10 = + (string) -95 &gt;&gt; (string) (11.5 - 21) * 10 = -95
    +1250ms ║║(11.5 - 21) * 10 = -95
    +1252ms ║║Executed virtual command log (4ms)
    +1282ms ║╚Execution stage complete. (1191ms)
    +1286ms ║Setting up scheduled job for Tue, Mar 5 2019 @ 4:00:00 PM PST (in 8999.638s), with 1 more job pending
    +1300ms ╚Event processed successfully (1299ms)

#20

I used the “zypf” piston above, and changed a few numbers for faster testing…
IE: During testing, I switched to seconds for Target_Time - Lead_Time (Line 30)

I ran six tests, and I thought they all worked perfectly, but upon closer inspection, it was always using the previous Lead_Time.

Doing a bit more testing now.


#21

Wow, this one was a doozy. (I spent way too much time on this)

It seems that once a scheduled job is pending, webCoRE does not want to change it if the offset changes.

I finally got it to work with a few changes.

  • Changed “Every day” to “Time happens daily at
  • Added a “Cancel all pending tasks

Also important to note, that when I first tried this, it still failed. But when I recreated the same piston from scratch it worked. (There may have been some corruption in the earlier piston)

My freetime is up for the day, but hopefully you can use this structure to make your (new) piston work!

It is currently set at {offset} seconds to make testing much quicker, but once you are happy with it, it should also work once it is changed back to minutes.


#22

I promise I wasn’t trying to drag you down the rabbit hole!! I’ll test it out tonight and report back–although I might give it a couple of days to give you a bit of a break!

Can’t thank you enough for your perseverance!