Skip to content

Tennis Playability Index (TMI) v2 — Specification

Status: Reference — Current Date: 2026-04-05 Code: src/domain/utils/playability.ts (canonical), fetch-weather/index.ts (Deno duplicate)


Formula (v2)

Veto gate: if any factor = 0 → score = 0  (safety-critical)

Otherwise: score = weighted_geometric_mean(
  heat^0.25,       ← Heat Index or KMA sensible temp (May-Sep)
  cold^0.20,       ← Raw temperature
  rain^0.20,       ← Precipitation probability + active rain
  humidity^0.10,   ← NEW: Dew point comfort
  air^0.10,        ← PM2.5 (환경부 thresholds)
  wind^0.10,       ← Wind speed
  uv^0.05,         ← NEW: UV Index (informational, no veto)
)

Why Weighted Geometric Mean (not min())

v1 used min(all factors) — one bad factor vetoed the entire score. This was too harsh: wind at 35 km/h shouldn't make the score 30 when everything else is perfect.

v2 uses weighted geometric mean (same formula as UN HDI, OECD Better Life Index):

  • Bad factors still pull the score down (more than arithmetic mean)
  • But one moderate factor doesn't tank an otherwise great day
  • Hard veto preserved at 0 (active rain, extreme heat) for safety

Source: Composite indicator methodology (Springer, 2017)

Why Piecewise Linear (not step functions)

v1 used hard steps: Heat Index 26°C = 100, 27°C = 80 (instant -20 jump). v2 interpolates linearly between breakpoints, producing smoother, more defensible transitions.


Thresholds (piecewise linear, peer-reviewed anchors)

Heat (체감온도 / Heat Index)

Input (°C)ScoreSource
≤26100UTCI comfort zone
3080UTCI moderate heat stress
3260KOSHA mandatory cooling
3430폭염주의보, KOSHA mandatory rest
≥350폭염경보, ACSM Black Flag

Heat source priority:

  1. KMA sensible temp (getSenTaIdxV4) — May-Sep only, includes solar radiation
  2. NWS Heat Index (Rothfusz regression) — fallback, temp + humidity only

Cold

Input (°C)ScoreSource
≤-100Extreme cold
-510Injury risk, ball hardness
040UTCI moderate cold stress
570UTCI slight cold stress
≥10100Comfortable

Air Quality (PM2.5 µg/m³)

InputScoreSource
≤15100환경부 "좋음"
3580환경부 "보통"
7530환경부 "나쁨"
≥1000환경부 "매우나쁨"

Wind (km/h)

InputScoreSource
≤15100No effect on ball
3070Noticeable drift
5030Ball trajectory seriously affected
≥650Impractical

Rain

ConditionScore
Active rain (PTY > 0)0 (hard veto — wet court unsafe)
POP 0%100
POP 30%85
POP 60%40
POP 80%15
POP 100%0

Humidity (Dew Point °C) — NEW in v2

Captures "muggy but not hot" discomfort that Heat Index misses at moderate temps.

Dew PointScoreSource
≤13100Dry/comfortable (NWS)
1690Slightly humid
1870Humid
2150Very humid (oppressive)
2420Extremely muggy
≥270Tropical, unsafe for sport

Dew point is a better comfort metric than RH%: 50% humidity feels different at 20°C vs 35°C, but dew point 20°C always feels the same. Source: NWS: Dew Point vs Humidity

UV Index — NEW in v2

Informational factor with low weight (0.05). No hard veto — UV doesn't make tennis unplayable but affects long-term health.

UV IndexScoreLevel
0-2100낮음 (Low)
3-590보통 (Moderate)
6-770높음 (High)
8-1050매우높음 (Very High)
≥1130위험 (Extreme)

Source: Tennis players receive median 7.5 SED/day UV exposure — Photoprotection in Outdoor Sports (PMC)


Display (5 levels)

ScoreLevelKoreanColorTip
80-100Excellent최적#22C55E테니스 하기 딱 좋아요
60-79Good좋음#3B82F6충분한 수분 섭취 권장
40-59Fair보통#EAB308주의하며 플레이하세요
20-39Poor나쁨#F97316실내 코트를 추천해요
0-19Unplayable불가#EF4444오늘은 쉬는 게 좋겠어요

Additional Display Data

DataWhere ShownSource
Estimated WBGTWeatherDetailSheetComputed from temp + humidity
Dew pointWeatherDetailSheetMagnus-Tetens from temp + humidity
UV IndexWeatherDetailSheetKMA 생활기상지수 getUVIdxV4
ATP heat referenceWeatherDetailSheet (WBGT > 28°C)ATP 2026 extreme heat rule

Data Sources

InputAPIStatus
Temperature (TMP)기상청 단기예보Active
Humidity (REH)기상청 단기예보Active
Wind speed (WSD)기상청 단기예보Active
Precipitation (POP, PTY)기상청 단기예보Active
PM2.5 / PM10에어코리아Active
UV Index기상청 생활기상지수 getUVIdxV4Active (deployed)
Sensible Temperature기상청 생활기상지수 getSenTaIdxV4Active (May-Sep only)
Medium-range forecast기상청 중기예보Active
Weather warnings기상청 기상특보 getPwnStatusActive

References

  • ACSM Heat Guidelines — Black Flag at WBGT 28°C+
  • ATP 2026 Extreme Heat Rule — WBGT 30.1°C breaks, 32.2°C suspension
  • KOSHA — Mandatory cooling at 31°C, rest at 33°C
  • 환경부 — PM2.5 air quality grades
  • NWS — Heat Index (Rothfusz regression), Dew point vs humidity
  • UTCI — Comfort zone boundaries (26°C upper, 9°C lower)
  • UN HDI — Weighted geometric mean methodology for composite indices

Markdown remains the source of truth. Run yarn docs:check before handoff.