Building Energy Boot Camp 2018 - Unofficial Day 6
Today is an “Unofficial Day 6” because I spent quite a lot of time working on my project while still on vacation. Essentially, there was no meeting, but I still worked for just as long as I would’ve if there were a meeting, as I need to catch up with the others. Anyways, I worked on creating the Air Data Displaying Dashboard I discussed on Day 4. As I had no idea how to make GUI with Python, I first researched the Tkinter library, which is very commonly used for GUI and is fairly simple. With time, I set up the layout that you see below, which consists of Tkinter Labels and Radiobuttons. I decided to use Labels because the user cannot edit them. As I do not have access to town WiFi, my program currently gets its data from two CSVs.
The following is the code that I wrote to display the window above. It currently doesn’t use wings or the first floor, as I am still learning which rooms are in which wing, and which rooms are actually considered to be a part of the first floor.
# -*- coding: utf-8 -*-
from tkinter import *
import pandas as pd
CO2_PATH = '2018 Q1Q2 - AHS CO2 (07300-1530).csv'
TEMP_PATH = '2018 Q1Q2 - AHS Temps (07300-1530).csv'
UNITS = ['ppm', '°F']
root = Tk()
root.title("AHS Air Data")
root.configure(background='white')
root.resizable(False, False)
wing = StringVar(root, value='A') # The selected wing
floor = IntVar(root, value=1) # The selected floor
measurement = IntVar(root, value=1) # The selected measurement
def set_wing():
fill_fields(floor.get(), str(wing.get()), measurement.get())
def set_floor():
fill_fields(floor.get(), str(wing.get()), measurement.get())
def set_measurement():
fill_fields(floor.get(), str(wing.get()), measurement.get())
# Setup table layout
COLUMN_TITLES = ['Floor', 'Wing', 'Measurement', 'Average Value', 'Maximum Value', 'Room Number With Maximum Value']
col_number = 0
row_labels = []
def set_field_data(avg, max_avg, room_number, unit):
# Change room number from something like "RM260 ZN11 ZN-T" to "260"
room_number = room_number.split(' ', 1)[0][2:]
row_labels[0].config(text=(str(round(avg, 2)) + ' ' + unit))
row_labels[1].config(text=(str(round(max_avg, 2)) + ' ' + unit))
row_labels[2].config(text=room_number)
def fill_fields(floor, wing, measure):
df = 0 # Set a default value to keep scope
if measure == 0:
# CO2
df = pd.read_csv(CO2_PATH, skipfooter=3, engine='python')
else:
# Temperature
df = pd.read_csv(TEMP_PATH, skipfooter=3, engine='python')
if floor != 1:
# Get all rooms on floor 2 by getting all columns starting with RM2
filtered_cols = [col for col in df if col.startswith('RM' + str(floor))]
df = df[filtered_cols]
avgs = df.mean()
max_avg = 0
max_room_num = ''
for column in df:
if df[column].mean() > max_avg:
max_avg = df[column].mean()
max_room_num = column
avg = avgs.mean()
set_field_data(avg, max_avg, max_room_num, UNITS[measure])
for col in COLUMN_TITLES:
label = Label(text=col, fg="Blue", bg="White", width="30")
label.grid(row=0, column=col_number, pady=(10, 0), sticky='we', ipady="2")
# Add floor options
if col_number == 0:
FLOOR_NUMBERS = ['1st', '2nd', '3rd']
current_row = 1
for floor_letter in FLOOR_NUMBERS:
Radiobutton(text=floor_letter, fg="Black", bg="White", variable=floor, value=int(floor_letter[0]),
command=set_floor).grid(row=current_row, column=col_number, sticky='we')
current_row += 1
# Add wing options
elif col_number == 1:
WING_LETTERS = ['A', 'B', 'C', 'D']
current_row = 1
for index, wing_letter in enumerate(WING_LETTERS):
if index == len(WING_LETTERS) - 1:
Radiobutton(text=wing_letter, fg="Black", bg="White", variable=wing, value=wing_letter,
command=set_wing).grid(row=current_row, column=col_number, sticky='we',
pady=(0, 10))
else:
Radiobutton(text=wing_letter, fg="Black", bg="White", variable=wing, value=wing_letter,
command=set_wing).grid(row=current_row, column=col_number, sticky='we')
current_row += 1
# Add measurement options
elif col_number == 2:
MEASUREMENTS = ['CO2', 'Temperature']
current_row = 1
for index, measure in enumerate(MEASUREMENTS):
Radiobutton(text=measure, fg="Black", bg="White", variable=measurement, value=index,
command=set_measurement).grid(row=current_row, column=col_number, sticky='we')
current_row += 1
else:
# Create empty cell for value
row_label = Label(bg="White", fg="Black", relief=RIDGE, width="30")
row_labels.append(row_label)
row_label.grid(row=1, column=col_number, sticky='we', ipady="2", padx=5)
col_number += 1
root.grid_columnconfigure(0, weight=1)
fill_fields(floor.get(), str(wing.get()), measurement.get())
root.mainloop()
I will continue to work on this project and hopefully finish it within the next day or two.