Most “smart” homes spin a ceiling fan when the room feels warm — usually based on a single temperature threshold. That’s crude. If you want comfort and efficiency, you should drive the fan from a thermal comfort model, not a basic if-temp-then-fan rule.
This post shows how to implement PMV/PPD-based logic (with a lightweight fallback heuristic) so your automation decides when a ceiling fan should actually run. Along the way, remember: a fan doesn’t always improve airflow or comfort in a meaningful way. Here’s a practical explanation of Will a ceiling fan improve air flow?
What Are PMV and PPD?
PMV (Predicted Mean Vote) estimates how people feel about thermal conditions on a -3 (cold) to +3 (hot) scale.
PPD (Predicted Percentage Dissatisfied) converts that into a dissatisfaction percentage.
Inputs typically include:
- Air temperature (°C)
- Mean radiant temperature (°C)
- Relative humidity (%)
- Air speed (m/s)
- Metabolic rate (met)
- Clothing insulation (clo)
In residential settings, reasonable defaults for unknowns:
-
met = 1.1
(sitting/standing indoors) -
clo = 0.6
(short sleeves, light pants)
A Minimal Python Implementation of PMV/PPD
This is a lightweight Python function you can integrate into Home Assistant, Node-RED, or a custom automation stack:
`import math
def pmv_ppd(tdb, tr, vr, rh, met=1.1, clo=0.6, wme=0.0):
pa = rh * 10 * math.exp(16.6536 - 4030.183 / (tdb + 235))
icl = 0.155 * clo
m = met * 58.15
w = wme * 58.15
mw = m - w
if icl <= 0.078:
f_cl = 1 + 1.29 * icl
else:
f_cl = 1.05 + 0.645 * icl
hcf = 12.1 * math.sqrt(vr)
taa = tdb + 273
tra = tr + 273
t_cla = taa + (35.5 - tdb) / (3.5 * icl + 0.1)
p1 = icl * f_cl
p2 = p1 * 3.96
p3 = p1 * 100
p4 = p1 * taa
p5 = 308.7 - 0.028 * mw + p2 * (tra / 100) ** 4
xn = t_cla
eps = 0.00015
for _ in range(150):
xf = xn
hcn = 2.38 * abs(100 * xf - taa) ** 0.25
hc = max(hcf, hcn)
xn = (p5 + p4 * hc - p2 * (xf / 100) ** 4) / (100 + p3 * hc)
if abs(xn - xf) <= eps:
break
tcl = xn - 273
hl1 = 3.05 * 0.001 * (5733 - 6.99 * mw - pa)
hl2 = 0.42 * (mw - 58.15) if mw > 58.15 else 0
hl3 = 1.7e-5 * m * (5867 - pa)
hl4 = 0.0014 * m * (34 - tdb)
hl5 = 3.96 * f_cl * ((xn / 100) ** 4 - (tra / 100) ** 4)
hl6 = f_cl * hc * (tcl - tdb)
ts = 0.303 * math.exp(-0.036 * m) + 0.028
pmv = ts * (mw - hl1 - hl2 - hl3 - hl4 - hl5 - hl6)
ppd = 100 - 95 * math.exp(-0.03353 * pmv ** 2 - 0.2179 * pmv ** 2)
return pmv, ppd`
Turning PMV Into a Fan Control Rule
Once you compute PMV and PPD, you can implement a decision rule like this:
def should_run_fan(pmv, rh, fan_air_speed, max_ppd=20):
if rh > 70:
return False
return pmv > 0.5 and fan_air_speed < 0.5 # 0.5 m/s ~ medium speed
In plain terms: if it feels too warm and humidity isn’t too high, run the fan before adjusting the thermostat.
Home Assistant YAML Automation Example
`alias: Fan Comfort Control
trigger:
- platform: state
entity_id:
- sensor.living_temp
- sensor.living_humidity
- sensor.living_air_speed action:
- service: python_script.compute_pmv data: temp: "{{ states('sensor.living_temp') | float }}" rh: "{{ states('sensor.living_humidity') | float }}" air_speed: "{{ states('sensor.living_air_speed') | float }}"
- choose:
- conditions:
- condition: numeric_state entity_id: sensor.living_pmv above: 0.5
- condition: numeric_state entity_id: sensor.living_rh below: 70 sequence:
- service: fan.turn_on target: entity_id: fan.living_ceiling data: percentage: 60 default:
- service: fan.turn_off target: entity_id: fan.living_ceiling `
- conditions:
Can't Use PMV? Use This Heuristic
If you don’t want to implement full PMV logic, use this pragmatic fallback:
if temp > 24.5 and 40 <= rh <= 60:
run_fan()
elif temp > 26.0 and rh < 70:
run_fan()
else:
keep_fan_off()
Be sure to add hysteresis (e.g. don't turn off unless temp < 24.0°C) and time thresholds to prevent flip-flopping.
What to Track
To verify your logic is working:
- Energy Use: Compare HVAC runtime before and after fan-first logic
- Comfort Score: Track average PMV or temp/RH band compliance
- Fan Events: Log toggles to detect unnecessary oscillations
Wrap-Up
Thermal comfort is measurable. PMV/PPD gives you a smarter foundation than simple temperature triggers. And before you assume fans always help, make sure to understand when they don’t:
Will a ceiling fan improve air flow?
Good automation comes from accurate sensing and smart thresholds — not guesswork.
Top comments (0)