Optimal Passive Cooling Solutions for Small Server Closets Without AC in Historic Buildings


2 views

When dealing with small server closets (2m x 1.3m in this case) in historic buildings without AC, we're typically looking at heat loads between 800W-2000W. Based on standard heat dissipation calculations:

// Basic heat calculation formula in Python
def calculate_temp_increase(heat_watts, room_volume_cubic_meters):
    # Constants for air properties at sea level
    air_density = 1.225  # kg/m³
    specific_heat = 1005  # J/(kg·K)
    volume_air = room_volume_cubic_meters
    mass_air = volume_air * air_density
    
    # Convert watts to joules per hour (3600 seconds)
    joules_per_hour = heat_watts * 3600
    
    # Temperature increase per hour in Celsius
    temp_increase = joules_per_hour / (mass_air * specific_heat)
    
    return temp_increase

# Example for 2m x 1.3m x 2.5m (height) room with 800W load
room_vol = 2 * 1.3 * 2.5
temp_rise = calculate_temp_increase(800, room_vol)
print(f"Temperature increase per hour: {temp_rise:.2f}°C")

The dual-fan approach (intake + exhaust) works best when properly balanced. Here's how to calculate required airflow:

// Calculating required airflow in CFM (Cubic Feet per Minute)
def calculate_required_cfm(heat_watts, max_temp_rise):
    # Conversion factors
    watts_to_btu = 3.41214
    cubic_meter_to_cubic_feet = 35.3147
    
    # Calculate BTU/h
    btu_per_hour = heat_watts * watts_to_btu
    
    # Required CFM (assuming 20°F/11°C temp rise is acceptable)
    required_cfm = btu_per_hour / (1.08 * max_temp_rise)
    
    return required_cfm

# For 800W load with 11°C (20°F) max temp rise
cfm_needed = calculate_required_cfm(800, 20)
print(f"Minimum required airflow: {cfm_needed:.2f} CFM")

For our London case study, we'd recommend:

  • 2 x 120mm AC Infinity AIRPLATE S7 exhaust fans (110 CFM each)
  • 1 x 120mm intake fan with dust filter (80 CFM)
  • Thermostat controller (AC Infinity CLOUDLINE T6)

Installation notes:

# Example Home Assistant automation for fan control
- alias: "Server Closet Fan Control"
  trigger:
    platform: numeric_state
    entity_id: sensor.server_closet_temperature
    above: 28
  action:
    service: fan.turn_on
    entity_id: fan.exhaust_fan_1, fan.exhaust_fan_2

- alias: "Server Closet Fan Off"
  trigger:
    platform: numeric_state
    entity_id: sensor.server_closet_temperature
    below: 25
  action:
    service: fan.turn_off
    entity_id: fan.exhaust_fan_1, fan.exhaust_fan_2

To maintain acoustic isolation while allowing airflow:

  • Install sound baffles in ventilation ducts
  • Use flexible acoustic ducting (Melinex or similar)
  • Place fans on vibration isolators

A basic Raspberry Pi monitoring solution with Grafana:

# Python script for temperature monitoring
import board
import adafruit_dht
import time
import psutil

dhtDevice = adafruit_dht.DHT22(board.D4)

while True:
    try:
        temp_c = dhtDevice.temperature
        humidity = dhtDevice.humidity
        cpu_temp = psutil.sensors_temperatures()['cpu_thermal'][0].current
        
        print(f"Ambient: {temp_c:.1f}°C, Humidity: {humidity:.1f}%, CPU: {cpu_temp:.1f}°C")
        
    except RuntimeError as error:
        print(error.args[0])
    
    time.sleep(30)

Based on your equipment list, let's calculate the approximate heat output:

// Sample thermal calculation in Python
equipment = {
    '24_port_switch': {'qty': 2, 'watts': 60},
    'router': {'qty': 1, 'watts': 30},
    'vsdl_modem': {'qty': 1, 'watts': 15},
    'dell_desktop': {'qty': 1, 'watts': 200},
    '4_bay_nas': {'qty': 1, 'watts': 80},
    'hp_microserver': {'qty': 1, 'watts': 150},
    'ups': {'qty': 1, 'watts': 50}
}

total_watts = sum(item['qty'] * item['watts'] for item in equipment.values())
btu_per_hour = total_watts * 3.412

print(f"Total heat output: {total_watts}W ({btu_per_hour:.0f} BTU/h)")

The standard formula for calculating required airflow:

/* C-style pseudo-code for ventilation calculation */
#define SPECIFIC_HEAT_AIR 0.018  // BTU/ft³·°F
#define MAX_TEMP_RISE 20  // °F (11°C) above ambient

float calculate_cfm(float btu_h, float temp_rise) {
    return btu_h / (temp_rise * SPECIFIC_HEAT_AIR * 60);
}

void main() {
    float required_cfm = calculate_cfm(btu_per_hour, MAX_TEMP_RISE);
    printf("Required airflow: %.1f CFM\n", required_cfm);
}

For your 2.6m² closet with ~800W load (2730 BTU/h):

  • Exhaust-only system: Install 150-200 CFM inline duct fan (6" diameter) with:
    # Example ESPHome config for automated fan control
    sensor:
      - platform: dht
        pin: D2
        temperature:
          name: "Server Closet Temperature"
        update_interval: 60s
    
    fan:
      - platform: speed
        output: gpio
        id: exhaust_fan
        speed_count: 3
        output:
          pin: D1
    
    automation:
      - trigger:
          platform: numeric_state
          entity_id: sensor.server_closet_temperature
          above: 28  # °C
        action:
          - fan.turn_on:
              id: exhaust_fan
              speed: 'high'
    
  • Push-pull system: Add 100 CFM intake fan near floor level with passive vents (acoustic foam lined)

Implementing a basic monitoring system with Raspberry Pi:

# Python script for thermal monitoring
import RPi.GPIO as GPIO
from w1thermsensor import W1ThermSensor
import time

GPIO.setmode(GPIO.BCM)
FAN_PIN = 18
GPIO.setup(FAN_PIN, GPIO.OUT)

sensor = W1ThermSensor()

def read_temp():
    return sensor.get_temperature()

def control_fan(temp):
    if temp > 30:  # °C
        GPIO.output(FAN_PIN, GPIO.HIGH)
    else:
        GPIO.output(FAN_PIN, GPIO.LOW)

while True:
    current_temp = read_temp()
    control_fan(current_temp)
    time.sleep(60)

For noise reduction in your setup:

  • Use centrifugal fans instead of axial fans for ducting (quieter at higher static pressure)
  • Install vibration isolators for all fans
  • Line the closet with 2" acoustic foam (NRC 0.8+)
  • Maintain at least 15cm air gap between equipment for proper airflow