A Python implementation of the MCS (Microgeneration Certification Scheme) Heat Pump Calculator for heat loss calculations and heat pump system design, based on BS EN 12831.
- Heat Loss Calculation: Room-by-room and whole building heat loss calculations following BS EN 12831
- Inter-Room Heat Transfer: Model heat loss/gain between adjacent rooms at different temperatures (compatible with heatlossjs)
- Degree Days Data: Built-in CIBSE degree days data for all UK postcode areas
- Hot Water Energy: Calculate domestic hot water energy requirements
- Heat Pump Sizing: Size heat pumps based on design heat loss and hot water demand
- Radiator Sizing: Calculate radiator sizing for low-temperature heat pump systems
- Annual Energy Consumption: Estimate annual energy consumption and costs
- U-Value Calculations: Floor U-value calculations for solid and suspended floors
- Flexible Modeling: Choose between MCS-style (independent rooms) or detailed inter-room thermal modeling
# Clone the repository
git clone <repository-url>
cd python_mcs_heatloss
# Create and activate conda environment
conda create -n python_mcs_heatloss python=3.12
conda activate python_mcs_heatloss
# Install dependencies
pip install -r requirements.txt
# Run tests
pytest tests/test_calculator.py -v
# Run example
python example_usage.py
pip install -r requirements.txt
from mcs_calculator import HeatPumpCalculator
from mcs_calculator import Wall, Window, Floor
# Initialize calculator for Manchester (M postcode)
calc = HeatPumpCalculator(postcode_area='M', building_category='B')
# Create building
building = calc.create_building('My House')
# Create a room
living_room = calc.create_room(
name='Living Room',
room_type='Lounge',
floor_area=25.0,
height=2.4
)
# Add fabric elements
living_room.walls.append(Wall('External Wall', area=15, u_value=0.3))
living_room.windows.append(Window('Window', area=4, u_value=1.4))
living_room.floors.append(Floor('Ground Floor', area=25, u_value=0.25))
living_room.thermal_bridging_factor = 0.15
building.add_room(living_room)
# Calculate heat loss
summary = calc.calculate_building_heat_loss()
print(f"Total Heat Loss: {summary['total_heat_loss']['watts']:.0f} W")
print(f"Annual Energy: {summary['total_heat_loss']['kwh']:.0f} kWh")
mcs_calculator/
├── __init__.py # Package initialization
├── calculator.py # Main HeatPumpCalculator class
├── room.py # Room, Building, Wall, Window, Floor classes
└── data_tables.py # Lookup tables (degree days, U-values, etc.)
tests/
└── test_calculator.py # Comprehensive test suite
example_usage.py # Complete example with detailed output
Main calculator class for heat pump system design.
calc = HeatPumpCalculator(postcode_area='SW', building_category='B')
# Get location information
location = calc.get_location_info()
# Create building and rooms
building = calc.create_building('House Name')
room = calc.create_room('Living Room', 'Lounge', floor_area=25)
# Calculate heat loss
summary = calc.calculate_building_heat_loss()
# Hot water energy
hw_energy = calc.calculate_hot_water_energy(num_occupants=4)
# Size heat pump
sizing = calc.size_heat_pump(design_heat_loss_kw=5.0, hot_water_demand_kw=3.0)
# Annual energy consumption
energy = calc.calculate_annual_energy_consumption(
space_heating_kwh=10000,
hot_water_kwh=4000,
cop=3.5
)
# Radiator sizing
rad_sizing = calc.calculate_radiator_sizing(
room_heat_loss_w=1500,
room_temp=21,
flow_temp=45,
return_temp=40
)
Represents a room with fabric elements and calculates heat loss.
from mcs_calculator import Room, Wall, Window, Floor
room = Room(
name='Bedroom',
room_type='Bedroom',
design_temp=18,
volume=36,
air_change_rate=1.0,
thermal_bridging_factor=0.15
)
# Add fabric elements
# External walls
room.walls.append(Wall('External Wall', area=12, u_value=0.3, boundary='external'))
# Party wall to adjacent room (for inter-room heat transfer)
room.walls.append(Wall('Party Wall to Hall', area=8, u_value=0.5, boundary='hall'))
# Unheated space
room.walls.append(Wall('Loft', area=15, u_value=0.2, boundary='unheated', boundary_temp=18))
room.windows.append(Window('Window', area=2, u_value=1.4))
room.floors.append(Floor('Floor', area=15, u_value=0.25, temperature_factor=0.5))
# Calculate heat loss
external_temp = -2.0
degree_days = 2033
# Without inter-room heat transfer
fabric_loss = room.fabric_heat_loss_watts(external_temp)
# With inter-room heat transfer (provide room temperatures)
room_temps = {'hall': 19, 'kitchen': 18}
fabric_loss_with_interroom = room.fabric_heat_loss_watts(external_temp, room_temps)
vent_loss = room.ventilation_heat_loss_watts(external_temp)
total_loss = room.total_heat_loss_watts(external_temp, room_temps)
annual_kwh = room.total_heat_loss_kwh(external_temp, degree_days)
Walls support different boundary types for flexible thermal modeling:
# External boundary (uses external temperature)
Wall('External Wall', area=10, u_value=0.3, boundary='external')
# Ground boundary (uses ground temperature)
Wall('Ground Contact', area=10, u_value=0.5, boundary='ground', boundary_temp=10.6)
# Unheated space (uses specified or default 18°C)
Wall('To Garage', area=8, u_value=0.4, boundary='unheated', boundary_temp=15)
# Adjacent room (uses room's design temperature for inter-room heat transfer)
Wall('Party Wall', area=12, u_value=0.5, boundary='kitchen')
Built-in lookup tables for UK-specific data.
from mcs_calculator import DegreeDays, RoomTemperatures, VentilationRates, FloorUValues
# Degree days
degree_days = DegreeDays.get_degree_days('M') # Manchester
design_temp = DegreeDays.get_design_temp('M')
location = DegreeDays.get_location('M')
# Room temperatures
temp = RoomTemperatures.get_temperature('Lounge') # 21°C
# Ventilation rates
ach = VentilationRates.get_rate('Kitchen', category='B') # 1.5 ACH
# Floor U-values
u_value = FloorUValues.calculate_floor_u_value(
floor_type='solid',
perimeter=20,
area=25,
insulation_thickness=0.1
)
The calculator follows BS EN 12831 for heat loss calculations:
Q_fabric = Σ (A × U × ΔT × f)
Where:
- A = area (m²)
- U = U-value (W/m²K)
- ΔT = temperature difference (K)
- f = temperature correction factor (e.g., 0.5 for ground floors)
For walls with adjacent room boundaries:
Q_inter_room = A × U × (T_room - T_adjacent)
This allows modeling heat loss/gain between rooms at different temperatures, providing more accurate thermal modeling for complex buildings.
Q_ventilation = 0.33 × n × V × ΔT
Where:
- 0.33 = specific heat capacity of air (Wh/m³K)
- n = air change rate (ACH)
- V = volume (m³)
- ΔT = temperature difference (K)
Additional 15% (typical for post-2006 buildings) added to fabric heat loss to account for thermal bridges.
kWh = Q × DD × 24 / 1000
Where:
- Q = heat loss per degree (W/K)
- DD = degree days
- 24 = hours per day
Room Type | Design Temp (°C) | Ventilation (ACH) |
---|---|---|
Lounge | 21 | 1.0 (Category B) |
Dining | 21 | 1.0 |
Bedroom | 18 | 1.0 |
Kitchen | 18 | 1.5 |
Bathroom | 22 | 1.5 |
Hall/Landing | 18 | 1.0 |
Building Categories:
- Category A: Higher ventilation (older/leakier buildings)
- Category B: Medium ventilation (standard)
- Category C: Lower ventilation (very tight/new buildings)
HEAT LOSS CALCULATION
================================================================================
Room Temp Fabric W Vent W Total W Annual kWh
--------------------------------------------------------------------------------
Living Room 21.0 460 477 937 2124
Kitchen/Dining 18.0 268 501 769 1990
Bedroom 1 18.0 201 251 451 1168
--------------------------------------------------------------------------------
TOTAL 2969 7259
HEAT PUMP SIZING
Required Heat Pump Capacity: 5.97 kW
ANNUAL ENERGY CONSUMPTION (COP = 3.5)
Space Heating Demand: 7,259 kWh/year
Hot Water Demand: 4,245 kWh/year
Total Heat Demand: 11,504 kWh/year
Electricity Consumption: 3,287 kWh/year
Estimated Annual Cost (@ £0.30/kWh): £986
This implementation has been validated against:
- MCS Excel Calculator - Exact match (within 0.001W precision)
- heatlossjs - 0.01% difference (0.12W out of 1179W on test case)
See VALIDATION_REPORT.md
and HEATLOSSJS_COMPARISON.md
for detailed validation results.
✅ 61/61 tests passing (100%)
- Formula accuracy: 4/4 ✓
- Excel MCS validation: 16/16 ✓
- Cross-validation: 18/18 ✓
- Core functionality: 20/20 ✓
- heatlossjs validation: 7/7 ✓ (including inter-room heat transfer)
The package includes comprehensive tests:
# Run all tests
pytest tests/test_calculator.py -v
# Run specific test class
pytest tests/test_calculator.py::TestRoom -v
# Run with coverage
pytest tests/test_calculator.py --cov=mcs_calculator
Test coverage includes:
- Degree days lookup
- Floor U-value calculations
- Room heat loss (fabric and ventilation)
- Thermal bridging
- Hot water energy
- Heat pump sizing
- Radiator sizing
- Complete building calculations
This Python implementation provides the same core functionality as the MCS Heat Pump Calculator Excel spreadsheet (Version 1.10), with the following advantages:
- Programmatic Access: Integrate calculations into your own applications
- Batch Processing: Calculate heat loss for multiple buildings efficiently
- Version Control: Track changes to building designs over time
- Automation: Automate repetitive calculations
- Testing: Comprehensive test suite ensures accuracy
- Extensibility: Easy to add custom calculations or modify existing ones
- Python 3.12+
- openpyxl >= 3.1.2 (for reading Excel files)
- pandas >= 2.0.0
- numpy >= 1.24.0
- pytest >= 7.4.0 (for testing)
This is a Python implementation of publicly available MCS heat loss calculation methods following BS EN 12831.
Contributions are welcome! Please ensure:
- All tests pass:
pytest tests/ -v
- Code follows PEP 8 style guidelines
- New features include tests
- Documentation is updated
For issues or questions, please open an issue on the GitHub repository.
- BS EN 12831-1:2017 - Energy performance of buildings - Method for calculation of the design heat load
- CIBSE Guide A - Environmental Design
- MCS Installation Standard MIS 3005
- MCS Heat Pump Calculator (Excel) Version 1.10
- Initial Python implementation
- Complete heat loss calculation engine
- Comprehensive test suite
- Example usage scripts
- Full documentation