Toggle Navigation
Hatchery
Eggs
Thermostat
__init__.py
Users
Badges
Login
Register
MCH2022 badge?
go to mch2022.badge.team
__init__.py
raw
Content
import gc,socket import urequests as requests import time, badge, _thread, ugfx, wifi, appglue, onewire, ds18x20, machine, json, esp gc.collect() #try to maintain targettemp settings=json.loads('{"settings":{"mqtt_broker":"","mqtt_port":"1883","mqtt_user":"","mqtt_password":"","mqtt_clientid":"thermostat","offset":"-0.5","margin":"0.5","loglevel":"0","default_screen":"0","store_data":"0","openweatherkey":""}}') message="Have a nice day!" message2="" message3="" readings=bytearray(50) #readingcounter=0 storecount=29 # eerste 2 waardes kunnen onzin zijn lasttime=0 uptime=0 ctemp=20.0 ttemp=20.0 itemp=0 pc=4 screen=0 burn=0 buitentemp=0.0 windsnelheid=0.0 tempsensor=0 # 0=internal,1=DS18B20,2=BME280 description="wacht op data" zonop=0 zonneer=0 dotw=('','Zondag','Maandag','Dinsdag','Woensdag','Donderdag','Vrijdag','Zaterdag') schedule='' default_reply = """\ HTTP/1.0 200 OK Server: SHA2017 Badge Content-Type: text/html """ default_cookie_reply="HTTP/1.0 200 OK\nServer: SHA2017 Badge\nCookie: ThermostatKey=%s\nContent-Type: text/html\n\n" notfound_reply = """\ HTTP/1.0 404 Not Found Server: SHA2017 Badge Content-Type: text/html """ def store_settings(): global settings for p in settings['settings']: badge.nvs_set_str('thermostat',p,settings['settings'][p]) def read_settings(): global settings settings['settings']['offset']=badge.nvs_get_str('thermostat','offset',settings['settings']['offset']) settings['settings']['margin']=badge.nvs_get_str('thermostat','margin',settings['settings']['margin']) settings['settings']['openweatherkey']=badge.nvs_get_str('thermostat','openweatherkey') settings['settings']['default_screen']= badge.nvs_get_str('thermostat','screen',settings['settings']['default_screen']) settings['settings']['loglevel']=badge.nvs_get_str('thermostat','loglevel',settings['settings']['loglevel']) settings['settings']['mqtt_broker']=badge.nvs_get_str('thermostat','mqtt_broker',settings['settings']['mqtt_broker']) settings['settings']['mqtt_port']=badge.nvs_get_str('thermostat','mqtt_port',settings['settings']['mqtt_port']) settings['settings']['mqtt_user']=badge.nvs_get_str('thermostat','mqtt_user',settings['settings']['mqtt_user']) settings['settings']['mqtt_password']=badge.nvs_get_str('thermostat','mqtt_user',settings['settings']['mqtt_password']) def init_hw(): global p33, ds, roms, uptime,bme,tempsensor bme=0 badge.init() ugfx.init() #ugfx.input_init() ugfx.clear(ugfx.BLACK) ugfx.flush() ugfx.clear(ugfx.WHITE) ugfx.string(40, 30, "Initializing!" , "DejaVuSans20", ugfx.BLACK) ugfx.string(40, 70, "THERMOSTAT!" , "DejaVuSans20", ugfx.BLACK) ugfx.flush() #p33 for relay switch #p12 for temp sensor badge.power_sdcard_enable() p33=machine.Pin(33,machine.Pin.OUT) p33.value(0) # create the onewire object dat = machine.Pin(4) ds = ds18x20.DS18X20(onewire.OneWire(dat)) # scan for DS18B20 devices on onewire the bus roms = ds.scan() if roms: tempsensor=1 print("Onewire ROM 0 Serial:%s"%( roms[0])) ds.read_temp(roms[0]) time.sleep(0.75) ds.read_temp(roms[0]) else: print("Couldn't init temp sensor, using internal cpu temp") # scan for BME280 devices on I2C bus i2c=machine.I2C(sda=machine.Pin(26), scl=machine.Pin(27)) slaves=i2c.scan() if 144 in slaves: import bme280 print("BME280 sensor found on I2C bus!") bme = bme280.BME280(i2c=i2c) tempsensor=2 #init reading array for x in range(50): readings[x]=0 uptime=time.time() def wifi_up(): while not wifi.sta_if.isconnected(): time.sleep(0.1) pass print(wifi.sta_if.ifconfig()[0]) return wifi.sta_if.ifconfig()[0] def init_web(): global s #init webserver stuff try: del s except: s=0 wifi.init() ai = socket.getaddrinfo(wifi_up(),80) addr = ai[0][4] s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.bind(addr) except: print("Whatever, cannot bind 80, continuing to see what happends...") s.listen(5) def init_mqtt(): global mqtt port=1883 mqtt=0 user="None" password="None" if len(settings['settings']['mqtt_port'])>0: port=settings['settings']['mqtt_port'] if len(settings['settings']['mqtt_user'])>0 and len(settings['settings']['mqtt_password'])>0: user=settings['settings']['mqtt_password'] password=settings['settings']['mqtt_port'] if len(settings['settings']['mqtt_broker'])>0: from umqtt.simple import MQTTClient mqtt = MQTTClient(settings['settings']['mqtt_clientid'], settings['settings']['mqtt_broker'],port=port,user=user,password=password) mqtt.set_callback(mqtt_cb) try: mqtt.connect() mqtt.subscribe(b"thermostat/#") except: print("Could not connect to MQTT Broker %s:%s with user %s!"%(settings['settings']['mqtt_broker'],port,user)) def mqtt_cb(topic, msg): global ttemp,message #global leds print((topic, msg)) #lets strip all the extra characters mqttmessage = (msg.decode('utf-8')) mqttmessage = mqttmessage.replace('\x08', '') mqttmessage = mqttmessage.replace('\x05', '') if(topic.decode('utf-8')=='thermostat/targettemp'): ttemp = mqttmessage if(topic.decode('utf-8')=='thermostat/message'): message = mqttmessage def mqtt_publish(): global itemp,ctemp,burn,mqtt if mqtt: try: mqtt.publish("/temperature/cpu", itemp) mqtt.publish("/temperature/sensor", ctemp) mqtt.publish("/pressure/sensor","998") mqtt.publish("/humidty/sensor","12.34") mqtt.publish("/temperature/type", tempsensor) mqtt.publish("/uptime", uptime) mqtt.publish("/burner", burn) except: #did we lose our mqtt connection! let's try to connect again init_mqtt() def main_target_temp(): global ctemp,ttemp,burn,p33, ds, roms, settings,itemp,bme print("Target temp thread started!") ugfx.input_init() ugfx.flush() while True: if bme: print(bme.values) itemp=(esp.temperature_sens_read()-32)/1.8 if roms: ds.convert_temp() ctemp=float(ds.read_temp(roms[0]))+float(settings['settings']['offset']) else: ctemp=itemp store_reading() if ctemp<(ttemp-float(settings['settings']['margin'])): burn=1 else: burn=0 mqtt_publish() p33.value(burn) #do screen stuff ugfx.input_attach(ugfx.BTN_START, lambda pushed: ugfx.flush() if pushed else False) ugfx.input_attach(ugfx.BTN_SELECT, lambda pushed: ugfx.flush() if pushed else False) ugfx.input_attach(ugfx.JOY_UP, lambda pushed: new_temp(0.5) if pushed else False) ugfx.input_attach(ugfx.JOY_DOWN, lambda pushed: new_temp(-0.5) if pushed else False) ugfx.input_attach(ugfx.JOY_LEFT, lambda pushed: switch_screen(-1) if pushed else False) ugfx.input_attach(ugfx.JOY_RIGHT, lambda pushed: switch_screen(1) if pushed else False) ugfx.input_attach(ugfx.BTN_A, lambda pushed: get_TIL() if pushed else False) ugfx.flush() show_set_screen() time.sleep(10) gc.collect() def show_set_screen(): global screen if screen==1: show_graph_screen() elif screen==2: show_settings_screen() elif screen==3: show_schedule_screen() elif screen==4: show_reboot_screen() else: show_main_screen() def show_main_screen(): global ctemp,ttemp,burn,message,dotw global buitentemp,windsnelheid,description,zonop,zonneer,itemp #tstatus=('idleing','burning') tstatus=('.zZ','!!!') moty=('','Jan','Feb','Mar','Apr','Mei','Jun','Jul','Aug','Sep','Oct','Nov','Dec') now=time.localtime() #0year,1 month,2 day,3 hour,4 minute,5 sec,6 dayoftheweek,7 dayoftheyear if now[4]<10: mytime="%d:0%d"%(now[3],now[4]) else: mytime="%d:%d"%(now[3],now[4]) ugfx.clear(ugfx.WHITE) ugfx.string(4, 0, "Huidige temperatuur is %.1f, Gewenste temperatuur is %.1f" % (ctemp,ttemp) , "Roboto_BlackItalic12", ugfx.BLACK) ugfx.string(4, 14, "De CPU is %.1f. Buiten temperatuur is %s, Windsnelheid %.1f " % (itemp,buitentemp,float(windsnelheid)) , "Roboto_BlackItalic12", ugfx.BLACK) ugfx.string(4, 28, "Het is %s %d %s %d en buiten is het %s" % (dotw[now[6]],now[2],moty[now[1]],now[0],description) , "Roboto_BlackItalic12", ugfx.BLACK) ugfx.string(4, 42, "Het is donker %s en de zon komt op om %s" % (zonneer,zonop) , "Roboto_BlackItalic12", ugfx.BLACK) ugfx.string(30, 62, "%.1f C %s [|||]=%s" %(ctemp,mytime,tstatus[burn]), "Roboto_Black22", ugfx.BLACK) ugfx.string(4, 90, " %s" % (message) , "Roboto_BlackItalic12", ugfx.BLACK) ugfx.string(4, 104, " %s" % (message2) , "Roboto_BlackItalic12", ugfx.BLACK) ugfx.string(4, 118, " %s" % (message3) , "Roboto_BlackItalic12", ugfx.BLACK) ugfx.flush() def show_graph_screen(): global readings t=263 #height 128 #width 296 # de graph moet tussen y=24 en y=268 liggen # de graph moet tussen x=0 en x=112 liggen ugfx.clear(ugfx.WHITE) ugfx.line(14,0,14,128,ugfx.BLACK) ugfx.line(0,114,296,114,ugfx.BLACK) ugfx.string(0, 12, "30", "Roboto_BlackItalic12", ugfx.BLACK) ugfx.string(0, 46, "20", "Roboto_BlackItalic12", ugfx.BLACK) ugfx.string(0, 80, "10", "Roboto_BlackItalic12", ugfx.BLACK) ugfx.string(16, 116, "-4u", "Roboto_BlackItalic12", ugfx.BLACK) ugfx.string(77, 116, "-3u", "Roboto_BlackItalic12", ugfx.BLACK) ugfx.string(137, 116, "-2u", "Roboto_BlackItalic12", ugfx.BLACK) ugfx.string(198, 116, "-1u", "Roboto_BlackItalic12", ugfx.BLACK) ugfx.string(260, 116, "nu", "Roboto_BlackItalic12", ugfx.BLACK) #y=len(readings)-1 r=1 while r<48: y=storecount-r if y<0: y=48 #readings.append(int(ctemp*10.0)) #ugfx.line(t,114-int(readings[y-1]*0.32),t+5,114-int(readings[y]*0.32),ugfx.BLACK) ugfx.line(t,114-int(readings[y-1]/255*112),t+5,114-int(readings[y]/255*112),ugfx.BLACK) #ugfx.pixel(t,114-int(readings[y]*0.32),ugfx.BLACK) #print("x:%d y:%d"%(t,114-int(readings[y]*0.32))) t-=5 r+=1 ugfx.flush() def show_settings_screen(): global settings,uptime now=time.localtime(uptime) uptimestring=("%d:%d %d-%d-%d %d"%(now[3],now[4],now[2],now[1],now[0],time.time()-uptime)) ugfx.clear(ugfx.WHITE) ugfx.string(4, 0, "Settings Screen" , "Roboto_BlackItalic12", ugfx.BLACK) ugfx.string(4,14,"IP: %s"%(wifi.sta_if.ifconfig()[0]), "Roboto_BlackItalic12", ugfx.BLACK) l=28 for p in settings['settings']: ugfx.string(4,l,"%s: %s"%(p,settings['settings'][p]), "Roboto_BlackItalic12", ugfx.BLACK) l+=14 ugfx.string(4,l,"Mem free: %d Uptime: %s Seconds"%(gc.mem_free(),uptimestring), "Roboto_BlackItalic12", ugfx.BLACK) ugfx.flush() def show_schedule_screen(): global schedule now=time.localtime() ugfx.clear(ugfx.WHITE) ugfx.string(4, 0, "Schedule Screen" , "Roboto_BlackItalic12", ugfx.BLACK) l=28 ugfx.string(4,l,"%s"%(dotw[now[6]]), "Roboto_BlackItalic12", ugfx.BLACK) l+=14 ugfx.string(4,l,"Schakeltijd Gewenste Temperatuur", "Roboto_BlackItalic12", ugfx.BLACK) l+=14 try: if len(schedule['schedule'][dotw[now[6]]])>0: for s in schedule['schedule'][dotw[now[6]]]: if int(s['hour'])<now[3] and int(s['min'])<now[4]: ugfx.string(4,l,"%s:%s %.1f C"%(s['hour'],s['min'],float(s['temp'])/10), "Roboto_BlackItalic12", ugfx.BLACK) l+=14 except Exception as e: print("Error in current_schedule: %s"%(str(e))) ugfx.string(4,l,"Fout in schedule: %s"%(str(e)), "Roboto_BlackItalic12", ugfx.BLACK) ugfx.flush() def show_reboot_screen(): ugfx.clear(ugfx.WHITE) ugfx.input_attach(ugfx.BTN_START, lambda pushed: appglue.start_app('launcher') if pushed else False) ugfx.input_attach(ugfx.BTN_SELECT, lambda pushed: machine.reset() if pushed else False) ugfx.string(40, 30, "[START]: Launcher" , "DejaVuSans20", ugfx.BLACK) ugfx.string(40, 50, "[SELECT]: Reboot" , "DejaVuSans20", ugfx.BLACK) ugfx.flush() def switch_screen(dir): global settings,screen maxscreen=4 screen+=int(dir) if screen<0: screen=maxscreen if screen>maxscreen: screen=0 show_set_screen() def new_temp(delta): global ttemp #print("Temp is %.1f en delta is %.1f"%(ttemp,delta)) ttemp+=float(delta) #ttemp=round(ttemp,1) ugfx.clear(ugfx.WHITE) ugfx.string(80, 35, "%.1f" %(ttemp), "DejaVuSans20", ugfx.BLACK) if ttemp>24.0: if ttemp<26.0: ugfx.string(80, 55, "Een beetje warm???", "DejaVuSans20", ugfx.BLACK) else: ugfx.string(80, 55, "Doe niet zo gek!!", "DejaVuSans20", ugfx.BLACK) ugfx.flush() time.sleep_ms(200) def main_scheduler(): global schedule,ttemp print("Scheduler thread started!") while True: #now=time.localtime() #year, month,day,hour,minute,sec,dayoftheweek,dayoftheyear #print("Day of the week is %d" % (now[6])) sleep=current_schedule() print("Target temperature set to %.1f, sleeping for %d minutes" % (ttemp,sleep ) ) time.sleep(sleep*60) def current_schedule(): global ttemp,schedule,dotw #dotw=('','Zaterdag','Zondag','Maandag','Dinsdag','Woensdag','Donderdag','Vrijdag') now=time.localtime() #year, month,day,hour,minute,sec,dayoftheweek,dayoftheyear t=0 try: if len(schedule['schedule'][dotw[now[6]]])>0: for s in schedule['schedule'][dotw[now[6]]]: if int(s['hour'])<now[3] and int(s['min'])<now[4]: ttemp=round(float(s['temp'])/10,1) t+=1 except Exception as e: print("Error in current_schedule: %s"%(str(e))) ttemp=18.0 return 300 # wait for 5 minutes if t==len(schedule['schedule'][dotw[now[6]]]): return((23-now[3])*60+60-now[4]) else: return((int(schedule['schedule'][dotw[now[6]]][t]['hour'])-int(s['hour']))*60+abs((int(schedule['schedule'][dotw[now[6]]][t]['hour'])-now[4]))) return 60 def main_handle_web(): print("Handle web thread started!") global s,message,dotw global burn, ttemp,ctemp,buitentemp while True: try: print("Listening for connections!") res = s.accept() client_s = res[0] client_ip = str(res[1][0]) print("Connection from ",client_ip) request = client_s.recv(512) request = str(request) ref=request.find('eferer') if ref>0: #sloop de referer eruit request=request[:ref] print("Request was : %s" % request) except: print("Can't handle the heat, not accepting web stuff!!!!") time.sleep(1) return if request.find('/favicon.ico')>0 or len(request)==0: client_s.send(notfound_reply) client_s.close() else: if request.find('/?message=')>0: rl=request.split(' ') arg=rl[1].split('=') message=arg[1].replace('%20',' ') message=message.replace('%22','') print("change current message to %s" % message) elif request.find('/?ctemp=')>0: rl=request.split(' ') arg=rl[1].split('=') ctemp=round(float(arg[1])/10,1) print("change current temp to %s" % ctemp) elif request.find('/?ttemp=')>0: rl=request.split(' ') arg=rl[1].split('=') ttemp=round(float(arg[1])/10,1) elif request.find('/?tempup')>0: ttemp+=0.5 elif request.find('/?tempdown')>0: ttemp-=0.5 elif request.find('/?schedule')>0: get_schedule() elif request.find('/chgsettings?')>0: #GET /chgsettings?offset=-0.5&loglevel=0&store_data=0&margin=0.5&openweatherkey=e8d05fb1070a4eeee6ce99f689fa1aef&default_screen=0 HTTP/1.1\r\n ss=request.find('?') ss+=1 se=request[ss:].find(' ')+ss+1 args=request[ss:se].split('&') for a in args: t=a.split('=') settings['settings'][t[0]]=t[1] store_settings() # send back html client_s.send(default_reply) try: file = open("/lib/thermostat/bootstrap.html", "r") for line in file: client_s.send(line) client_s.send("<div class=\"container\"><div class=\"starter-template\">") if request.find('/settings')>0: client_s.send("<h1>Instellingen:</h1><p class=\"lead\">\n") client_s.send("<form action=\"/chgsettings\" method=\"GET\">\n") for p in settings['settings']: client_s.send("<div class=\"form-group row\">\n<label class=\"col-sm-2 col-form-label\">%s</label>\n<div class=\"col-sm-10\">\n<input type=\"text\" class=\"form-control\" name=\"%s\" value=\"%s\"></div></div>\n"%(p,p,settings['settings'][p])) #client_s.send("%s <input type=\"text\" name=\"%s\" value=\"%s\"><br>\n"%(p,p,settings['settings'][p])) client_s.send("<input class=\"btn btn-lg btn-success\" role=\"button\" type=\"submit\" value=\"Sla op\"></form>") elif request.find('/schema')>0: client_s.send("<div id=\"schema\"></div>\n<script>\ntxt=\"<h1>Schema:</h1><br>\";\nscheduleObj=%s;\n\nfor (d in scheduleObj['schedule'])\n\t{\n\ttxt+=\"<h1>\"+d+\"</h1><br>\";\n\tfor (s in scheduleObj['schedule'][d])\n\t\t{\n\t\ttxt+=scheduleObj['schedule'][d][s].hour+\":\"+scheduleObj['schedule'][d][s].min+\" \"+scheduleObj['schedule'][d][s].temp/10+\"°C<br>\";\n\n\t}\n}\ndocument.getElementById(\"schema\").innerHTML = txt;\n</script>\n"%(schedule)) else: client_s.send("<h1>Status:</h1><p class=\"lead\">") if(burn==0): client_s.send("Niet") else: client_s.send("Wel") client_s.send(" verwarmen!<br>\nGewenste temperatuur %.1f °C<br> Huidige temperatuur %.1f °C<br> Buiten temperatuur %.1f °C<br></p>\n" % (float(ttemp),float(ctemp),float(buitentemp))) client_s.send("<a class=\"btn btn-lg btn-success\" role=\"button\" href=\"/?tempup\">Warmer</a> ") client_s.send("<a class=\"btn btn-lg btn-primary\" role=\"button\" href=\"/?tempdown\">Kouder</a><br>") client_s.send("</div></div><script>\n$(document).ready(function() {\n$('a[href=\"' + this.location.pathname + '\"]').parent().addClass('active');\n});\n</script></body></html>\n") except Exception as e: print("Where is my socket and bootstrap file? %s"%(str(e))) file.close() client_s.close() gc.collect() def get_weather(): global buitentemp,windsnelheid,description,zonop,zonneer,settings #get the weather if len(settings['settings']['openweatherkey'])<10: description="Set Openweather Key" return openweatherUrl="http://api.openweathermap.org/data/2.5/weather?q=Breda,nl&lang=nl&units=metric&appid=%s"%(settings['settings']['openweatherkey']) try: rw = requests.get(openweatherUrl) w=rw.json() rw.close() buitentemp=w['main']['temp'] windsnelheid=float(w['wind']['speed']) description=w['weather'][0]['description'] zonop="%d:%d" %(time.localtime(w['sys']['sunrise'])[3],time.localtime(w['sys']['sunrise'])[4]) zonneer="%d:%d" %(time.localtime(w['sys']['sunset'])[3],time.localtime(w['sys']['sunset'])[4]) except: ugfx.string(10, 10, "Could not get the weather", "Roboto_Regular12", 0) ugfx.flush() print('openweather fail') time.sleep(5) return def get_TIL(): global message,message2,message3,TIL #get top post reddit TIL #redditUrl="https://www.reddit.com/r/todayilearned/new.json?limit=1" redditUrl="https://www.reddit.com/r/worldnews/new.json?limit=1" try: rw = requests.get(redditUrl) TIL=rw.json() rw.close() except: ugfx.string(10, 10, "Could not get the top post from reddit", "Roboto_Regular12", 0) ugfx.flush() print('reddit fail') time.sleep(5) return message=TIL['data']['children'][0]['data']['title'] message2="" message3="" if len(message)>55: message2=message[55:] message=message[:55] if len(message2)>55: message3=message2[55:] message2=message2[:55] def get_schedule(): global schedule print("Getting schedule!") #get schedule scheduleUrl="http://192.168.2.11/tempsense/index.cgi?action=schedule" try: rw = requests.get(scheduleUrl) schedule=rw.json() rw.close() except: ugfx.string(10, 10, "Could not get the schedule", "Roboto_Regular12", 0) ugfx.flush() print('schedule fail') schedule=json.loads('{"schedule": {"Maandag": [{"hour": "00", "min": "00", "temp":"160"}]}}') time.sleep(5) return print(schedule) def store_temp(): global ctemp webUrl="http://192.168.2.11/tempsense/index.cgi?action=new&reading=%.1f&type=1" % (ctemp) try: rw = requests.get(webUrl) rw.close() except: print("Could not store reading!") def main_internet_info(): print("Internet info thread started!\n") while True: time.sleep(1800) get_weather() get_TIL() store_temp() gc.collect() def store_reading_old(): #dit wordt elke 10 seconden aangeroepen #sla een waarde elke 5 minuten op dus 5*60=300/10=30 #sla maximaal 12*4=48 waardes op global readings,ctemp,storecount if storecount>29: storecount=0 if len(readings)>48: del readings[0] readings.append(int(ctemp*10.0)) storecount+=1 def store_reading(): #dit wordt elke 10 seconden aangeroepen #sla een waarde elke 5 minuten op dus 5*60=300/10=30 #sla maximaal 12*4=48 waardes op global readings,ctemp,storecount,lasttime if (time.time()-lasttime)<300: return lasttime=time.time() if storecount>48: storecount=0 readings[storecount]=int(ctemp/35*255) # so max temp is 35 degrees we can store and we scale to max byte size #print("Storing %.1f as %d"%(ctemp,readings[storecount])) storecount+=1 def progress(): global pc ugfx.string(pc,100, '#', "Roboto_BlackItalic12", ugfx.BLACK) ugfx.flush() pc+=10 try: gc.collect() print("Free mem: %d" %(gc.mem_free())) print("Initializing") init_hw() progress()#1 init_mqtt() progress()#2 read_settings() progress()#3 except Exception as e: #probably a bug: ugfx.string(50, 50,str(e), "Roboto_BlackItalic12", ugfx.BLACK) print("Picked up an error inp phase 1 : %s"%(str(e))) ugfx.flush() try: #init_web() progress()#4 print("Done, starting up!\n") time.sleep(1) progress()#5 get_schedule() progress()#6 get_weather() except Exception as e: #probably a bug: ugfx.string(50, 50,str(e), "Roboto_BlackItalic12", ugfx.BLACK) print("Picked up an error in phase 2 : %s"%(str(e))) ugfx.flush() try: gc.collect() progress()#7 get_TIL() progress()#8 _thread.start_new_thread(main_target_temp,()) _thread.start_new_thread(main_scheduler,()) _thread.start_new_thread(main_internet_info,()) #_thread.start_new_thread(main_handle_web,()) print("All systems go!") time.sleep(5) gc.collect() print("Free mem: %d" %(gc.mem_free())) except Exception as e: #probably a bug: ugfx.string(50, 50,str(e), "Roboto_BlackItalic12", ugfx.BLACK) print("Picked up an error phase 3 : %s"%(str(e))) ugfx.flush()