#!/usr/bin/python3
import math
def sin(a):
""" Sin of angle in degrees. """
return math.sin(math.radians(a))
def makeModel(p_outside):
class Temps:
""" Area temperatures """
main = 21
bedrooms = 18
loft = 18
outside = p_outside
class House:
""" General house dimensions """
U = 0.1
base = 7.852 # Overall house width to eaves.
roofSlope = 7.816 # Eaves to roof peak.
groundfloorRoofSlope = 3.532 # Eaves to roof point level with loft floor
height = roofSlope * sin(60)
groundfloorHeight = groundfloorRoofSlope * sin(60)
loftHeight = height - groundfloorHeight
loftBase = base - 2 * sin(30) * groundfloorRoofSlope
loftOutsideLength = 2 * (roofSlope - groundfloorRoofSlope)
groundfloorOutsideLength = 2 * groundfloorRoofSlope + base
gableArea = 0.5 * base * height
loftGableArea = 0.5 * loftBase * loftHeight
groundfloorGableArea = gableArea - loftGableArea
class FrontDoor:
""" Front door """
h = 2.0
w = 0.8
U = 1.0
class MainWindow:
""" Main window (Velux GPL M08 -65) """
w = 0.780
h = 1.398
U = 1.1
# Allow for not being vertical - exact increment needs checking.
MainWindow.U += 0.1
class BedroomWindow:
""" Bedroom window (Velux GL M06 -65) """
w = 0.780
h = 1.178
U = 1.0
openings = (FrontDoor, MainWindow, BedroomWindow)
for o in openings:
o.area = o.w * o.h
o.conductance = o.area * o.U
gable = object()
cathederal = object()
class GuestBedroom:
""" Guest bedroom and hall to its north. """
width = 2.7
attributes = { gable }
openings = (FrontDoor, MainWindow)
temp = Temps.bedrooms
class Bathroom:
""" Bathroom and hall to its north. """
width = 2.4
attributes = {}
openings = { MainWindow }
temp = Temps.main
class Kitchen:
""" Bathroom and hall to its north. """
width = 2.4
attributes = {}
openings = { MainWindow }
temp = Temps.main
class LivingRoom:
""" Living room. """
width = 3.0
attributes = { cathederal }
openings = { MainWindow }
temp = Temps.main
class Study:
""" Office/study. """
width = 3.0
attributes = { cathederal }
openings = { MainWindow }
temp = Temps.main
class MainBedroom:
""" Main bedroom. """
width = 3.3
attributes = { gable }
openings = { MainWindow, BedroomWindow }
temp = Temps.bedrooms
rooms = (GuestBedroom, Bathroom, Kitchen, LivingRoom, Study, MainBedroom)
for r in rooms:
r.outsideLength = House.groundfloorOutsideLength
r.gableArea = House.groundfloorGableArea if gable in r.attributes else 0
def Loft(room):
""" Create a loft object for the room below it. """
class Loft:
""" Loft """
width = room.width
attributes = { gable } if gable in room.attributes else {}
openings = {}
temp = Temps.main if cathederal in room.attributes else Temps.loft
outsideLength = House.loftOutsideLength
gableArea = House.loftGableArea if gable in attributes else 0
return Loft
rooms += tuple(map(Loft, rooms))
for r in rooms:
r.area = (r.width * r.outsideLength + r.gableArea -
sum(o.area for o in r.openings))
r.lossCoeff = r.area * House.U + sum(o.conductance for o in r.openings)
r.loss = r.lossCoeff * (r.temp - Temps.outside)
class Conduction:
""" Conductive heat losses. """
loss = sum(r.loss for r in rooms)
class Ventilation:
""" Ventilation heat losses. """
rate = 120 # m³/h
efficiency = 0.8
massRate = rate * 1.3 / 3600 # kg/s
heatOut = massRate * 1e3 * (Temps.main - Temps.outside) # Heat out in watts
loss = heatOut * (1 - efficiency) # Net heat actually lost
class Overall:
""" Overall results. """
totalLoss = Conduction.loss + Ventilation.loss
things = (Temps, House) + openings + rooms + (Conduction, Ventilation, Overall)
class Model:
@classmethod
def printModel(self):
for i, c in enumerate(things):
if i > 0: print()
print(c.__doc__.strip())
for k in sorted(k for k in dir(c) if not k.startswith('_')):
print(' ', k + ':', getattr(c, k))
for t in things:
setattr(Model, t.__name__, t)
return Model
if __name__ == '__main__':
model = makeModel(-1)
model.printModel()
print()
print(model.Conduction.loss)