Smart Thermostat Raspberry PI - part modified remote boiler control function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def fcontroll(): | |
""" | |
Main boiler controll function. | |
Gets current and set temperature | |
uses 3 run levels to controll boiler. | |
run level 0 = initial, | |
run level 1 = determine how many mintues boier shoudl be on, | |
run level 2 = continuesly check of boier should be on for 10 minutes | |
Inserts message in sendmes table. | |
Runs as seprate thread. | |
""" | |
runScen = 0 | |
boilerStat = 0 | |
setBoiler = 0 | |
maxScen = (10*60) #maximum run for 1 hour long | |
scenLength = 0 | |
cursource = '40b5af01' #divice id used for logging purposses | |
logging.info("time sleep 10 started") | |
time.sleep(10) | |
logging.info("time sleep 10 complete") | |
bvepoch = 9999999999 | |
usettemp = -30000 | |
prevsettemp = -30000 | |
settemptime = -(60*60*24*5) | |
while True: | |
try: | |
fscurtime = time.time() | |
fsvepoch = int(fscurtime) | |
fsvsub = int(datetime.datetime.fromtimestamp(fscurtime).strftime('%f')) | |
fkepoch = bvepoch - fsvepoch | |
fsmintime = fsvepoch-5 | |
curtemp = -30000 #lower than 0 Kelvin | |
settemp = -30000 #lower than 0 Kelvin | |
curtempepoch = -(60*60*24*5) | |
settempepoch = -(60*60*24*5) | |
outtemp = 1500 #default outside temperature | |
#get current actual inside temperature form sensvals table | |
dbd8 = dbc.cursor() | |
dbd8.execute("SELECT vepoch,vvalue FROM sensvals where vsource = '40b5af01' and vport='rx000A04' order by vepoch desc, vkey asc LIMIT 1") | |
rows = dbd8.fetchall() | |
for row in rows: | |
curtempepoch = row[0] | |
curtemp = row[1] | |
dbd8.close() | |
#get current set temperature form sensvals table | |
dbd9 = dbc.cursor() | |
dbd9.execute("SELECT vepoch,vvalue FROM sensvals where vsource = '40b5af01' and vport='rx000A02' order by vepoch desc, vkey asc LIMIT 1") | |
rows = dbd9.fetchall() | |
for row in rows: | |
settempepoch = row[0] | |
settemp = row[1] | |
dbd9.close() | |
#get current outside temperature form curtemp table | |
dbcontr1 = dbc.cursor() | |
dbcontr1.execute("SELECT vvalue FROM curtemp ORDER BY vkey asc LIMIT 1") | |
rows = dbcontr1.fetchall() | |
for row in rows: | |
outtemp = row[0] | |
dbcontr1.close() | |
#only set usettemp if settemp has not ben changed for 5 seconds | |
#this is prevent the temperature scenrio to be based on a slightly higher settemp instead of waiting for the final set temp | |
#to be set by the user | |
if (prevsettemp != settemp): | |
settemptime = fsvepoch | |
elif (fsvepoch - settemptime > 5 ): | |
usettemp = settemp | |
prevsettemp = settemp | |
#devault variables | |
curtemptimediff = fsvepoch-curtempepoch #check how many seconds ago last current temperature has been received | |
settemptimediff = fsvepoch-settempepoch #check how many seconds ago last current temperature has been received | |
tempdif = (usettemp*10) - curtemp | |
outtempdif = (usettemp*10) - outtemp | |
#!!include if settemp is set and the other checsk if temp is actual | |
if(runScen == 0): #no scenario running | |
runScen = frunScen(curtemp,usettemp) | |
elif (runScen == 1): #start scenario | |
usedkey = 'failed' | |
usedkey,runminutes = getscen(tempdif,outtempdif) | |
if (usedkey <> 'failed'): #only use scenarios if a valid scenario has been retrieved | |
scenLength = runminutes[0] | |
maxrun = 6 | |
#insert used scenario and values used to determine this scenario to be uploaded to cloud server for scoring. | |
usscenpreky = cursource+'_'+str(fkepoch) | |
uscenkey = usscenpreky+'_'+ usedkey | |
dbdconsa5 = dbc.cursor() | |
dbdconsa5.execute("INSERT INTO usedscenario (vkey, vprekey, viepoch, scenariokey, vtempdif, vouttempdif, vtemp, vouttemp, vsettemp) values ('%s','%s',%i,'%s',%i,%i,%i,%i,%i)" % (uscenkey,usscenpreky,fsvepoch,usedkey,tempdif,outtempdif,curtemp,outtemp,settemp)) | |
dbdconsa5.close() | |
else: #otherwise determine number of seconds boiler should be on using fscenlengh() function | |
scenLength = fscenLength(curtemp,usettemp) | |
maxrun = 1 | |
logging.info(usedkey) | |
runnum = 0 | |
startScen = int(time.time()) | |
runScen = 2 | |
boilerStat = 1 | |
logging.info(str(maxrun)) | |
logging.info(str(runnum)) | |
logging.info(str(scenLength)) | |
elif(runScen == 2): #run scenario | |
runCurtime = int(time.time()) | |
if (boilerStat == 1 ): | |
boilerStat = fboilerStat(startScen,scenLength,runCurtime,curtemp,settemp) | |
if (boilerStat == 1 ): | |
setBoiler = 1 #send Arduino 1 for boilerstat | |
else: | |
setBoiler = 0 #send Arduino 0 for boilerstat | |
if(runCurtime - startScen > maxScen): | |
runScen = 3 | |
elif(runScen == 3): #check if scenario schould go to next interval of 10 minus or complete after 60 miutes | |
runnum = runnum + 1 | |
if (runnum < maxrun): #go to next iteration of 10 minutes | |
runScen = 2 | |
boilerStat = 1 | |
startScen = int(time.time()) | |
scenLength = runminutes[runnum] #get number of minutes to be on from scenario array | |
logging.info(str(maxrun)) | |
logging.info(str(runnum)) | |
logging.info(str(scenLength)) | |
else: #completed 60 minutes | |
runScen = 0 | |
scurhour = int(datetime.datetime.fromtimestamp(fscurtime).strftime('%H')) | |
scurminute = int(datetime.datetime.fromtimestamp(fscurtime).strftime('%M')) | |
#only send message if temperature readings are current and withint normal range | |
if (curtemp > -30000 and curtemptimediff < 20 and settemp > -30000 and settemptimediff < 20): | |
vchecksum = scurhour+scurminute+setBoiler+curtemp | |
sendstr = str(scurhour).zfill(2) + str(scurminute).zfill(2) + str(setBoiler) + str(curtemp).zfill(4)+str(vchecksum).zfill(4) | |
fins(fscurtime,cursource,'rx000B01',scenLength) #for logging purposses, insert in sensvals table | |
fins(fscurtime,cursource,'rx000B02',boilerStat) #for logging purposses, insert in sensvals table | |
fins(fscurtime,cursource,'rx000B03',setBoiler) #for logging purposses, insert in sensvals table | |
#insert message in sendmes table | |
dbd10 = dbc.cursor() | |
dbd10.execute("INSERT INTO sendmes(vepoch, vsub, vsendmes) VALUES(?,?,?)",(fsvepoch,fsvsub,sendstr)) | |
dbd10.close() | |
#delete older messages, keep messages of last 5 seconds | |
dbd13 = dbc.cursor() | |
dbd13.execute("DELETE from sendmes where vepoch < %i" % fsmintime) | |
dbd13.close() | |
except Exception: | |
logging.exception("fcontroll") | |
time.sleep(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment