Dec-14-2019, 11:05 AM
Hello all,
I am quite new to Python and I am training myself on the internet. So please excuse me if my code is wrong/not very readable. I have also posted this on the RaspberryPi forums.
As I travel a lot I wanted to control my heater remotely and some time ago I built a basic "ON OFF" switch which I could access via VNC remotely. I also bought a temperature sensor but never made time to make a proper program to control the temperature.
I've finally come up with something but I have some questions I cannot answer myself.
I'm using tkinter and I made a simple interface. The base control actually works - I'm impressed - but I am struggling with a few things.
Question 1.
I do not understand how the "window_name.mainloop()" works. I understand it's to keep the graphic elements running but then I do not understand where I should write my other code - the code that decides whether it's time to switch the heating off based on the temperature etc.
I ended up putting everything into different functions. I am not sure it's the correct way of doing it, particularly when I call the main function from the main function itself to make it run all the time. I'm sure some of you would shiver!
Question 2.
Do I understand correctly or variables in functions only live in that function? I am struggling to have the "bypass" button to work - it would set a flag which would prevent the boiler from starting if set to TRUE - but if I understand correctly variables only live into each function independently?
In the end I wonder if you could tell me if my approach is correct - I doubt it. Again, apologies for the messy code - it's still working in progress. The lots of "print" are there for debug purposes! :)
Thanks for your help!

I am quite new to Python and I am training myself on the internet. So please excuse me if my code is wrong/not very readable. I have also posted this on the RaspberryPi forums.
As I travel a lot I wanted to control my heater remotely and some time ago I built a basic "ON OFF" switch which I could access via VNC remotely. I also bought a temperature sensor but never made time to make a proper program to control the temperature.
I've finally come up with something but I have some questions I cannot answer myself.
I'm using tkinter and I made a simple interface. The base control actually works - I'm impressed - but I am struggling with a few things.
Question 1.
I do not understand how the "window_name.mainloop()" works. I understand it's to keep the graphic elements running but then I do not understand where I should write my other code - the code that decides whether it's time to switch the heating off based on the temperature etc.
I ended up putting everything into different functions. I am not sure it's the correct way of doing it, particularly when I call the main function from the main function itself to make it run all the time. I'm sure some of you would shiver!
Question 2.
Do I understand correctly or variables in functions only live in that function? I am struggling to have the "bypass" button to work - it would set a flag which would prevent the boiler from starting if set to TRUE - but if I understand correctly variables only live into each function independently?
In the end I wonder if you could tell me if my approach is correct - I doubt it. Again, apologies for the messy code - it's still working in progress. The lots of "print" are there for debug purposes! :)
Thanks for your help!
from tkinter import * import tkinter as tk import time import board import busio import adafruit_mcp9808 import RPi.GPIO as GPIO deltaplus = 0.2 #offset before heating status is changed deltaminus = 0.5 #offset before heating status is changed #Setting up GPIOs GPIO.setup(21, GPIO.OUT) GPIO.output(21, GPIO.LOW) GPIO.setup(20, GPIO.OUT) GPIO.output(20, GPIO.HIGH) #Setting up temperature sensor i2c_bus = busio.I2C(board.SCL, board.SDA) mcp = adafruit_mcp9808.MCP9808(i2c_bus) actualtempC = round(mcp.temperature,1) # To increase set temperature by one degree def increase_temp(): value = int(entry_set_temp.get()) value = value + 1 entry_set_temp.delete(0,2) entry_set_temp.insert(0, value) # To decrease set temperature by one degree def decrease_temp(): value = int(entry_set_temp.get()) value = value - 1 entry_set_temp.delete(0,2) entry_set_temp.insert(0, value) #Heating bypass enable - when BYPASS button is pressed def bypassOn(): print("bypassON running") bypassFlag = 1 print("BypassFlag from bypassOn",bypassFlag) heatingOff() #def bypassOff(): # bypassFlag = 0 #Variable initialisation - not working as variables only live in each DEF section? def variableinit(): bypassFlag = 0 #Switch heating off def heatingOff(): GPIO.output(21,GPIO.HIGH) boilerStatus = 0 print("Boilerstatus into heatingoff", boilerStatus) #Switch heating on IF bypass is not on def heatingOn(): print("BypassFlag from heatingOn before IF",bypassFlag) if bypassFlag==0: GPIO.output(21,GPIO.LOW) boilerStatus = 1 print("BypassFlag from heatingOn",bypassFlag) #Main section - I'm sure there's a better way to do this! def thermostat(): print("Bypass beginning of THERMOSTAT:",bypassFlag) actualtempC = round(mcp.temperature,1) setTemp = int(entry_set_temp.get()) #read variable from user set temp field label_actual_temp = tk.Label(master, text = actualtempC, font=("Helvetica", 28)) #Display actual sensor temp label_actual_temp.place(relx = 0.5, rely = 0.1, anchor=N) print("Sensor temperature: ",actualtempC) print("Set temperature: ", int(entry_set_temp.get())) print("Bypass before main IF:",bypassFlag) #thermostat algoritm if actualtempC < setTemp - deltaminus: #if temp is below set temp, minus offset, then switch heating on heatingOn() print("one") if actualtempC > setTemp + deltaplus: #if temp is above set temp, plus offset, then switch heating off heatingOff() print("two") # print("BoilerStatus", boilerStatus) # label_heatingStatus = tk.Label(master, textvariable = boilerStatus, font=("Helvetica", 28)) # label_heatingStatus.place(relx = 0.2, rely = 0.8, anchor=N) print("Bypass:",bypassFlag) print("END") master.after(3000,thermostat) #repeat this section? I'm sure, again, there's a better way to do this! #Variable initialisation variableinit() #define tkinter window master = tk.Tk() master.geometry("800x480") #CURRENT TEMP label label_current_temp = tk.Label(master, text="CURRENT TEMP °C", font=("Helvetica", 28)) label_current_temp.place(relx = 0.5, rely = 0.0, anchor=N) #SET TEMP label label_set_temp = tk.Label(master, text="SET TEMP °C", font=("Helvetica", 28)) label_set_temp.place(relx = 0.5, rely = 0.34, anchor = CENTER) #label_set_temp = tk.Label(master, text="SET TEMP °C", font=("Helvetica", 28)) #label_set_temp.place(relx = 0.5, rely = 0.34, anchor = CENTER) #BYPASS button button_bypass = tk.Button(master, text="BYPASS", width=15, font=("Helvetica", 28), command=bypassOn) button_bypass.place(relx = 0.5, rely = 0.68, anchor = CENTER) #Winter Protection checkbox winter_protection = IntVar() check_winter_protection = Checkbutton(master, text="Winter Protection?", variable = winter_protection, font=("Helvetica", 18)) check_winter_protection.place(relx = 0.5, rely = 0.88, anchor = CENTER) #label_actual_temp = tk.Label(master, text = actualtempC, font=("Helvetica", 28)) #label_actual_temp.place(relx = 0.5, rely = 0.1, anchor=N) #SET TEMP field default_temp = StringVar(master, value="19") # Set field to a default of 19 when programme starts entry_set_temp = tk.Entry(master, font=("Helvetica", 28), width = 7, justify = CENTER, textvariable = default_temp) entry_set_temp.place(relx = 0.5, rely = 0.44, anchor = CENTER) # PLUS button for Set Temp field button_plus = tk.Button(master, text="+", width=1, font=("Helvetica", 8), command=increase_temp) button_plus.place(relx = 0.62, rely = 0.405, anchor = CENTER) #MINUS button for Set Temp field button_minus = tk.Button(master, text="-", width=1, font=("Helvetica", 8), command=decrease_temp) button_minus.place(relx = 0.62, rely = 0.475, anchor = CENTER) # main programme thermostat() master.mainloop()