Page 1 of 1
HOw do I check if code was run less then 5 min ago?
Posted: Tue Dec 08, 2015 9:26 pm
by Mastiff
In my house the 14 heating zones with Nexa plugs runs constantly this time of year, and of course something has to go wrong. What happens is that if somebody plugs out the Nexa and then plugs it back in, and the temp sensor fires about then and tells EG that it's more than the set temp, it will send a "turn off" signal. But if the plug has been in for less than 15 seconds or so it will take this as a command to remove that code from the programming. So the room gets cold and won't heat up again. I have had this happen twice in a month now (teenage daughter, coguh, chough). So I figured the best way to avoid that would be to "declutter" the radio space and not send off and on signals as often as before. I do read the time when a sensor is read, so I should be able to put that into one table for off and one table for on signals without any problems and then have some code that checked if it's less than five minutes since the same signal (off or on) was sent and only send the next if it's more than five minutes or the signal has changed. But I have no idea how to code the comparishment, and I don't know if the time has to be converted in some way to see if it's less than five minutes. I could probably do it if I went on minutes alone, but that would be so messy when the hour changes. Can somebody tell me a smart way to do this?
Re: HOw do I check if code was run less then 5 min ago?
Posted: Wed Dec 09, 2015 7:30 am
by krambriw
Well, the script below takes a datetime object and compares with now. If it helps is doubtful since your teenager can still be lucky or unlucky to insert the device in the wrong moment. Maybe consider this device instead:
http://www.nexa.se/vara-produkter/syste ... wmr-3500-2 and make a separate outlet for the heater ?
Code: Select all
import datetime
# somehow fetch the date & time string that you will compare with
date_string = "2015-12-09 06:30"
# create a datetime object from this string
date_start = datetime.datetime.strptime(date_string, "%Y-%m-%d %H:%M")
# get current date & time in the same format
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
# do the same for current date & time
date_now = datetime.datetime.strptime(now, "%Y-%m-%d %H:%M")
print date_start
print date_now
# calculate the time difference in minutes
delta = int((date_now-date_start).seconds/60)
print delta
if delta > 5:
print "do your stuff"
Re: HOw do I check if code was run less then 5 min ago?
Posted: Wed Dec 09, 2015 7:54 am
by Mastiff
Thanks a lot, Walter! I'll implement that one!
As for the "teenage daughter bug syndrome", yeah. It's possible. But since last winter there were none of these things, and this will only send 1/5 of the current signals, I think the statistics should be with me.

I use a lot of the ones you link to (in my cabin the control a lot of circuits directly out of the fuses) but to be legal they have to be put in by an electrician, and besides there are too few wall sockets in most rooms here (house from the 80's), so it would be a problem.
Re: HOw do I check if code was run less then 5 min ago?
Posted: Wed Dec 09, 2015 2:53 pm
by Mastiff
God... Sometimes I wish I could actually code! I have spent half an hour getting nowhere here. I think I was overcomplicating. I already have the time for each room (the table [Rom] , with Norwegian formatting in the script, in this line:
Code: Select all
eg.globals.Tid[Rom] = eg.Utils.time.strftime("Kl. %H:%M, den %d.%m.", eg.Utils.time.localtime())
So this gives the variable content "Kl. 15:47, den 09.12." Instead of trying to make that fit into the datetime object, it would probably be better to strip it into hours and minutes, divide the hours with 60 and add the minutes. That variable I can call SignalTime. Then I can subtract the value in the table PreviousSignal[Rom] (which is updated after each run of the signal, but not when the code finds that it's less than five minutes since the signal) from that. So I just need to split "Kl. 15:47, den 09.12." into a format that lets me run 15*60 + 47. Right? Would that be easy to do?
Re: HOw do I check if code was run less then 5 min ago?
Posted: Wed Dec 09, 2015 4:50 pm
by krambriw
Provided the format you create is consistent
Code: Select all
s = "Kl. 15:47, den 09.12."
m = s.replace(',','').split(' ')[1].split(':')
start_time = int(m[0])*60+int(m[1])
print start_time
Re: HOw do I check if code was run less then 5 min ago?
Posted: Wed Dec 09, 2015 5:42 pm
by Mastiff
Yep, that works perfectly! Thanks! So now the code is like this (indentations because it comes after a few if's:
Code: Select all
m = eg.globals.Tid[Rom].replace(',','').split(' ')[1].split(':')
signaltidspunkt = int(m[0])*60+int(m[1])
print signaltidspunkt
# calculate the time difference in minutes
delta = int(signaltidspunkt-eg.globals.ForrigeAv[Rom])
print ("The number of minutes since the last signal:")
print delta
if delta > 5:
print "Now the signal is being sent"
eg.globals.ForrigeAv[Rom] = signaltidspunkt
I really didn't need an action when it was less than five minutes, so I trimmed that out. So only one problem left: If EG has started up, there will be no eg.globals.ForrigeAv (previous off) (or ForrigePaa, which I'm going to implement next). That means that it fails with a KeyError for the room number that doesn't have the value. In that case it should sendt the signal and set the previuos signal value to now. Sort of like what I would do in LUA:
Code: Select all
if not ForrigeAv[Rom]
then eg.globals.ForrigeAv[Rom] = signaltidspunkt
end
I think I have done something similar to this before (something about expect erorr or something), but I just can't remember how and where. Could you please remind me how that is done?
Re: HOw do I check if code was run less then 5 min ago?
Posted: Thu Dec 10, 2015 6:30 am
by krambriw
That means that it fails with a KeyError
I see two alternatives, some say one is better than the other. The first uses the try-catch clause:
Code: Select all
try:
delta = int(signaltidspunkt-eg.globals.ForrigeAv[Rom])
print ("The number of minutes since the last signal:")
print delta
if delta > 5:
print "Now the signal is being sent"
eg.globals.ForrigeAv[Rom] = signaltidspunkt
except KeyError:
eg.globals.ForrigeAv[Rom] = signaltidspunkt
print "Send the initial signal due to EG startup"
The second alternative uses an ordinary if-else clause:
Code: Select all
if eg.globals.ForrigeAv.has_key(Rom):
delta = int(signaltidspunkt-eg.globals.ForrigeAv[Rom])
print ("The number of minutes since the last signal:")
print delta
if delta > 5:
print "Now the signal is being sent"
eg.globals.ForrigeAv[Rom] = signaltidspunkt
else:
eg.globals.ForrigeAv[Rom] = signaltidspunkt
print "Send the initial signal due to EG startup"
From a performance standpoint, it depends on whether you expect your key to be there most of the time (An if statement is a bit slower, but an exception is a lot slower when it's raised)
Re: HOw do I check if code was run less then 5 min ago?
Posted: Thu Dec 10, 2015 7:24 am
by Mastiff
Thanks! I expect it to always be there execpt for the first run of each zone after a reboot, so the exception it is!

Re: HOw do I check if code was run less then 5 min ago?
Posted: Thu Dec 10, 2015 12:11 pm
by Mastiff
Ticking away nicely here. But I just realized something: I think I will have a problem past midnight. Because then the previous minute will be much larger than the current signal time! So I will have negative numbers, which is of course less than 5!

But I think I solved that, and even removed a bit of code by using this:
Code: Select all
if 0 < delta < 6:
print "Det er mindre enn fem minutter siden forrige signal"
else:
print "Det er mer enn fem minutter siden forrige signal"
eg.globals.ForrigeAv[Rom] = signaltidspunkt
I can't say how proud I will be if it actually words at midnight too!