Hvac Condensate Calculator

import React, { useState } from 'react'; // HVAC Condensate Calculator - Single-file React component // TailwindCSS classes used for styling (requires Tailwind in the parent project) // - Default export is the React component export default function HvacCondensateCalculator() { const [units, setUnits] = useState('imperial'); // 'imperial' or 'metric' const [cfm, setCfm] = useState(1200); const [tIn, setTIn] = useState(78); // inlet dry bulb (°F or °C) const [rhIn, setRhIn] = useState(60); // % const [tOut, setTOut] = useState(55); // coil outlet dry bulb const [rhOut, setRhOut] = useState(95); // % (if coil leaves saturated near 100% may be >) const [hoursPerDay, setHoursPerDay] = useState(24); const [safetyFactor, setSafetyFactor] = useState(1.1); // helper: convert units const toF = (c) => (c * 9) / 5 + 32; const toC = (f) => ((f - 32) * 5) / 9; const toCFM = (m3h) => m3h / 1.699; // approximate const toM3h = (cfm) => cfm * 1.699; // Psychrometric helper functions (approximate using Magnus-Tetens) // All calculations assume standard atmospheric pressure (101325 Pa) // saturation vapor pressure (Pa) over liquid water using Magnus formula function satVaporPressurePa(T_C) { // T_C in deg C // Magnus constants for water const a = 17.62; const b = 243.12; // deg C const es = 610.94 * Math.exp((a * T_C) / (T_C + b)); return es; // Pa } function humidityRatio(T_C, RH_percent) { // returns humidity ratio (kg water / kg dry air) // p = 101325 Pa const P = 101325; const es = satVaporPressurePa(T_C); const pv = (RH_percent / 100) * es; const w = 0.622 * pv / (P - pv); // kg/kg return w; } function densityAir(T_C) { // approximate density of moist air (kg/m3) at 101325 Pa // use ideal gas: rho = P / (R_specific * T_kelvin) * correction for humidity (small) const R_d = 287.05; // J/(kg·K) const T_k = T_C + 273.15; const rho = 101325 / (R_d * T_k); return rho; // kg/m3 dry air approx } // Main calculation function compute() { // Convert inputs to consistent units (metric internally) const T_in_C = units === 'imperial' ? toC(tIn) : tIn; const T_out_C = units === 'imperial' ? toC(tOut) : tOut; const Q_cfm = units === 'imperial' ? Number(cfm) : Number(cfm) / 1.699; // if metric input given as m3/h, convert to CFM equivalent // Convert CFM to m3/s const CFM = Number(Q_cfm); const m3_per_min = CFM * 0.0283168466; // 1 CFM = 0.0283168466 m3/min const m3_per_s = m3_per_min / 60; // Air mass flow (kg/s) = volumetric * density const rho = densityAir(T_in_C); const massFlowAir = m3_per_s * rho; // kg dry air / s // humidity ratios const w_in = humidityRatio(T_in_C, Number(rhIn)); const w_out = humidityRatio(T_out_C, Number(rhOut)); // water mass removed (kg/s) = massFlowAir * (w_in - w_out) let w_removed = w_in - w_out; if (w_removed < 0) w_removed = 0; // no negative condensate const waterKgPerSec = massFlowAir * w_removed; // kg/s const waterKgPerHour = waterKgPerSec * 3600; const waterLPerHour = waterKgPerHour; // 1 kg water ≈ 1 L const waterLPerDay = waterLPerHour * Number(hoursPerDay) * Number(safetyFactor); // imperial conversions const lbPerHour = waterKgPerHour * 2.2046226218; const gallonsPerHour = waterKgPerHour * 0.2641720524; const gallonsPerDay = gallonsPerHour * hoursPerDay * safetyFactor; return { waterKgPerSec, waterKgPerHour, waterLPerHour, waterLPerDay, lbPerHour, gallonsPerHour, gallonsPerDay, massFlowAir, w_in, w_out, }; } const results = compute(); function downloadCSV() { const rows = [ ['Input', 'Value', 'Units'], ['Units system', units, ''], ['Airflow', cfm, units === 'imperial' ? 'CFM' : 'm3/h (approx)'], ['Inlet Temp', tIn, units === 'imperial' ? '°F' : '°C'], ['Inlet RH', rhIn, '%'], ['Outlet Temp', tOut, units === 'imperial' ? '°F' : '°C'], ['Outlet RH', rhOut, '%'], ['Hours per day', hoursPerDay, 'h/day'], ['Safety factor', safetyFactor, 'x'], [], ['Result', 'Value', 'Units'], ['Condensate (kg/hr)', results.waterKgPerHour.toFixed(3), 'kg/hr'], ['Condensate (L/day)', results.waterLPerDay.toFixed(2), 'L/day'], ['Condensate (lb/hr)', results.lbPerHour.toFixed(3), 'lb/hr'], ['Condensate (gal/day)', results.gallonsPerDay.toFixed(3), 'gal/day'], ]; const csv = rows.map((r) => r.map((c) => `"${c}"`).join(',')).join('\n'); const blob = new Blob([csv], { type: 'text/csv' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'hvac-condensate-calculation.csv'; document.body.appendChild(a); a.click(); a.remove(); URL.revokeObjectURL(url); } return (

HVAC Condensate Calculator

Responsive web tool — approximate psychrometric method. Good for quick sizing & estimates.

setCfm(Number(e.target.value))} className="mt-1 w-full border rounded px-3 py-2" />
{units === 'imperial' ? 'CFM' : 'm³/h (enter approximate)'}
setHoursPerDay(Number(e.target.value))} className="mt-1 w-full border rounded px-3 py-2" />
setTIn(Number(e.target.value))} className="mt-1 w-full border rounded px-3 py-2" />
{units === 'imperial' ? '°F' : '°C'}
setRhIn(Number(e.target.value))} className="mt-1 w-full border rounded px-3 py-2" />
setTOut(Number(e.target.value))} className="mt-1 w-full border rounded px-3 py-2" />
{units === 'imperial' ? '°F' : '°C'}
setRhOut(Number(e.target.value))} className="mt-1 w-full border rounded px-3 py-2" />
setSafetyFactor(Number(e.target.value))} className="mt-1 w-40 border rounded px-3 py-2" />
Multiply daily condensate for safety / contingency
Built with care • Copy this file into a React + Tailwind project (Create React App, Vite, or Next.js). No external libraries required.
); }

Post a Comment

0 Comments