跳到正文

REST API 与 MCP 集成

计算器 REST API:请求、结果与诊断

六种翅片盘管引擎、八条计算路由和两条查询/健康路由的当前契约,附本地纯内存验证的完整合成示例。

修订日期

1. 访问条件与路由清单

使用部署的 ExCoil 站点源地址和下列准确路径。POST 请求发送 Authorization: Bearer <REST_API_KEY> 和 Content-Type: application/json。REST 密钥以 exk_ 开头;仅在服务端保存,勿写入日志、仓库或浏览器代码。需要状态为 active 或 trialing 的 Enterprise 或 Manufacturer 订阅。Free/Professional 可在应用内计算,并不代表有 REST 权限。

密钥存在权限列表时,计算与 /refrigerants 检查 calc:read。null 列表不限制权限,空列表不授予权限,* 可通过检查。/health 需要身份验证但不检查 calc:read。所有这些请求都消耗密钥限额。本 API 不提供 Shell & Tube、湿空气计算、项目写入、PDF/CAD 或制造导出。MCP 使用独立令牌与 /api/mcp,且仅限 Manufacturer。

方法路径JSON 根字段
POST/api/v1/calculate/dx-evaporatorair, coil, ref, calib
POST/api/v1/calculate/dx-evaporator/balancedinputs, options?
POST/api/v1/calculate/dx-condenserair, coil, ref, calib
POST/api/v1/calculate/dx-condenser/balancedair, coil, ref, calib
POST/api/v1/calculate/chilled-waterair, water, coil, hydraulic, calib
POST/api/v1/calculate/hot-waterair, water, coil, hydraulic, calib
POST/api/v1/calculate/steam-coilair, steam, coil, hydraulic, calib
POST/api/v1/calculate/dry-coolerair, fluid, coil, hydraulic, calib
GET/api/v1/refrigerants—
GET/api/v1/health—

2. 使用 SI 输入,不要发送界面表单对象

下方示例分别列出 request 与 response;只发送 request 的内容,不发送外层对象或 response。数值是合成演示工况,不是推荐设计。每个示例均通过当前输入 schema 和纯内存引擎计算。REST 路由并不执行 tRPC/MCP 使用的 Zod schema,仅在浅层对象/制冷剂检查后把请求交给引擎。不要假定存在逐字段错误、自动单位换算或 schema 默认值填充。

除干冷器外,air 使用 Vdot_m3_s、T_in_C、RH_in、P_Pa,分别为 m³/s、干球 °C、0–1 相对湿度及当地绝对大气压 Pa。冷凝器 RH_in 可省略(引擎默认 0.5)。几何字段是 coil,而非 geometry:height_m、width_m、Pt_m、Pl_m、Do_m、wall_m、fin_m 均为米;rows 是正整数;fpi 仍为每英寸翅片数;tube_k/fin_k 为 W/(m·K),freeAreaRatio 为比例。尺寸与导热系数需为正,Do_m > 2·wall_m,管间距需大于 Do_m。DX 的 tubesPerRow 将有效高度固定为 tubesPerRow × Pt_m。水/蒸汽/干冷器的 hydraulic.tubeCountOverride 是每排管数,不是总管数。

finType 可为 plain、wavy、louver、slit,冷凝器仅接受前三项。水/蒸汽/干冷器 coil 还含 tubeMat、finMat;导热系数需明确提供。calib 按模块填写,不要放入 options。segments 是可选数值积分分辨率,不是实际管数。通常 schema 的 freeAreaRatio 范围为 0.1–0.9;冷凝器 schema 允许 0–1,但引擎要求 >0 且 ≤1。DX 的 f_maldistribution 要求 >0 且 ≤1。必须另行验证物理关系,schema 通过不等于工况可行。

可选 circuitryPD 在 DX 中位于 ref,其余模块位于 hydraulic。以下必填数组应以相同顺序描述同一组真实回路;计数为整数、长度为米、局部阻力系数无量纲、流量比例为 0–1。管线内径必须为正,长度、粗糙度与 localK 非负。可选系统编号和附件路径用于压降诊断,不会把热模型变成逐系统/逐回路精细仿真。无显式路径时附件损失采用近似。不要用任意计数虚构此结构。

text

// Optional: ref.circuitryPD (DX) or hydraulic.circuitryPD (water/steam/dry cooler)
{
  tubesPerCircuit: number[], returnBendsPerCircuit: number[],
  crossoversPerCircuit: number[], circuitLengths_m: number[],
  maxTubesPerCircuit: number, maxReturnBends: number, isUnbalanced: boolean,
  systemCount?: number, circuitSystemIds?: string[], feederLengths_m?: number[],
  localKPerCircuit?: number[], lengthImbalance_pct?: number,
  hydraulicPaths?: Array<{
    circuitId: number, systemId: string, systemFlowFraction: number,
    circuitFlowFraction: number, tubeLength_m: number, connectorLength_m: number,
    inletCommon: Line, inletBranch: Line, outletBranch: Line, outletCommon: Line
  }>
}
// Line = { length_m: number, innerDiameter_m: number, roughness_m: number, localK: number }

3. DX 蒸发器:固定流量性能计算

POST /api/v1/calculate/dx-evaporator 直接接收输入对象。ref 含 fluid、Tevap_C、superheat_K、circuits、mode;RATING 还需正值 mdot_ref_kg_s。x_in 是入口干度(默认 0.2);引擎要求 0 ≤ x_in < 1,虽然共享 schema 允许 1。Tevap_C 是吸气连接处的饱和温度;压力耦合可能使管入口饱和温度更高。fluid 必须准确匹配支持的属性表键名。

RATING 保留指定质量流量:出口干度和 achievedSuperheat_K 是结果,superheat_K 是目标。SIZING 需要 Q_target_W,根据目标负荷和设计焓升计算质量流量,再评估同一几何,不会自动扩大盘管。可选 fouling.R_ext/R_int 为非负 m²·K/W 热阻;引擎读取它们,但蒸发器共享 Zod schema 未列出。读取 outlet、perf、zones、htc、geometry 和 flags,重点检查 targetMet、hydraulicFeasible、pressureDropExcessive、notes,不能只看能量平衡。结霜和接近干涸的物理过程未解析。

json

{
  "request": {
    "air": {
      "Vdot_m3_s": 1.5,
      "T_in_C": 27,
      "RH_in": 0.5,
      "P_Pa": 101325
    },
    "coil": {
      "height_m": 0.508,
      "tubesPerRow": 20,
      "width_m": 1,
      "rows": 4,
      "fpi": 12,
      "Pt_m": 0.0254,
      "Pl_m": 0.022,
      "Do_m": 0.00952,
      "wall_m": 0.0003,
      "fin_m": 0.0001,
      "tube_k": 386,
      "fin_k": 200,
      "freeAreaRatio": 0.6,
      "finType": "plain"
    },
    "ref": {
      "fluid": "R410A",
      "Tevap_C": 5,
      "superheat_K": 5,
      "circuits": 10,
      "mode": "RATING",
      "mdot_ref_kg_s": 0.04,
      "x_in": 0.2
    },
    "calib": {
      "C_air": 1,
      "C_tp": 1,
      "C_sh": 1,
      "f_maldistribution": 1
    },
    "segments": 40
  },
  "response": {
    "success": true,
    "data": {
      "outlet": {
        "T_out_C": 23.49883696449892,
        "RH_out": 0.5951224553222765,
        "W_out": 0.01076357974635124,
        "h_out": 51029.9957183522,
        "Tdp_out_C": 15.165690704059124
      },
      "perf": {
        "Q_total_W": 7909.303263873674,
        "Q_sens_W": 6229.595529054708,
        "Q_lat_W": 1679.7077348189664,
        "SHR": 0.7876288620147928,
        "mcond_kg_s": 0.0006600788155553462,
        "v_face_m_s": 2.952755905511811,
        "dP_air_Pa": 83.01172194416893,
        "dP_ref_Pa": 1516.4350589804817,
        "Q_ref_W": 7909.303263873688,
        "balanceError_pct": 1.4948764421579912e-13,
        "mdot_ref_kg_s": 0.04,
        "x_out": 1,
        "achievedSuperheat_K": 21.745191335740323,
        "targetSuperheat_K": 5,
        "refrigerantOutlet": {
          "T_C": 26.745191335740323,
          "h_in_J_kg": 250687.86399999997,
          "h_out_J_kg": 448420.44559684215,
          "phase": "superheated"
        },
        "refrigerantPressure": {
          "P_in_Pa": 937723.0350589807,
          "P_out_Pa": 936206.6000000002,
          "T_sat_in_C": 5.0521987063866804,
          "T_sat_out_C": 5,
          "satDrop_K": 0.05219870638668045,
          "x_in_local": 0.19968718691574538,
          "dP_twoPhase_Pa": 520.582915294799,
          "dP_vapor_Pa": 995.8955933460854,
          "dP_accessoriesInlet_Pa": 0,
          "dP_accessoriesOutlet_Pa": 0,
          "massFlux_kg_m2s": 64.00890550459303,
          "hydraulicFeasible": true
        }
      },
      "geometry": {
        "A_face_m2": 0.508,
        "A_ext_m2": 39.10246205044688,
        "A_int_m2": 2.2418405176016765,
        "n_tubes": 80,
        "n_tubes_H": 20,
        "L_circuit_m": 8,
        "Di_m": 0.00892
      },
      "htc": {
        "h_air_avg": 66.80366999738932,
        "h_ref_avg": 507.4101139521869,
        "U_overall": 15.758299149814324,
        "eta_fin": 0.7703542918753953,
        "eta_surface": 0.7837297035150003
      },
      "flags": {
        "wetCoil": true,
        "superheated": true,
        "converged": true,
        "oversized": true,
        "targetMet": true,
        "hydraulicFeasible": true,
        "pressureDropExcessive": false,
        "notes": [
          "Refrigerant ΔP 1.5 kPa (G = 64 kg/m²s per circuit): saturation 5.05 °C at the tube inlets → 5.00 °C at the suction connection (drop 0.05 K, coupled into capacity).",
          "Warning: Liquid velocity (0.06 m/s) is too low (<0.3 m/s). Risk of poor oil return and flow stratification.",
          "Warning: Vapor velocity (1.78 m/s) is too low (<3 m/s). Risk of poor oil return.",
          "Refrigerant-limited: achieved superheat 21.7 K exceeds target by more than 2 K (66 % of area superheating vapour). A TXV would increase mass flow and capacity.",
          "Wet surface on 34 % of the coil area: SHR = 0.788, condensate 2.38 kg/h",
          "Model: mean-circuit crossflow moving boundary with pressure-coupled saturation (MSH friction, Domanski–Hermes bends, homogeneous momentum); Chen two-phase HTC does not model dryout near x → 1."
        ]
      },
      "zones": {
        "tp_fraction": 0.34306774086665626,
        "sh_fraction": 0.6569322591333437,
        "wet_fraction": 0.34306774086665626,
        "Q_tp_W": 6885.446862985299,
        "Q_sh_W": 1023.8564008883747
      },
      "timestamp": "2026-11-02T15:44:41.927Z",
      "engineVersion": "6.1.0"
    }
  }
}

4. DX 冷凝器:目标是排热量

POST /api/v1/calculate/dx-condenser 使用 ref.fluid、Tcond_C、Tin_gas_C、subcool_K、circuits、mode,以及 RATING 的 mdot_ref_kg_s。Tin_gas_C 是 °C 入口气体温度,不是排气过热度。要求 Tin_gas_C ≥ Tcond_C、subcool_K ≥ 0,Tcond_C 在该属性表的亚临界范围内。SIZING 中 Q_target_W 是冷凝器排热量,应包括上游计算的压缩机热量;流量由目标焓降推导,不会搜索更低的虚假负荷。

calib 含 C_air、C_dsh、C_cond、C_sc、f_maldistribution;可选 fouling 含 R_ext/R_int,单位 m²·K/W。结果使用 airOut、perf.Q_dsh_W/Q_cond_W/Q_sc_W、achievedSubcool_K、status、refrigerantOutlet.phase。zones 表示回路面积/长度比例,热量比例另见 heat_fractions。检查 capacityShortfall_pct、targetMet、pressureDropExcessive。热计算保持 Tcond 恒定,估计压降不会反馈到沿程饱和温度;不解析温度滑移及详细排间/回路相互作用。

json

{
  "request": {
    "air": {
      "Vdot_m3_s": 1.5,
      "T_in_C": 30,
      "RH_in": 0.5,
      "P_Pa": 101325
    },
    "coil": {
      "height_m": 0.508,
      "tubesPerRow": 20,
      "width_m": 1,
      "rows": 4,
      "fpi": 12,
      "Pt_m": 0.0254,
      "Pl_m": 0.022,
      "Do_m": 0.00952,
      "wall_m": 0.0003,
      "fin_m": 0.0001,
      "tube_k": 386,
      "fin_k": 200,
      "freeAreaRatio": 0.6,
      "finType": "plain"
    },
    "ref": {
      "fluid": "R410A",
      "Tcond_C": 45,
      "subcool_K": 5,
      "Tin_gas_C": 75,
      "circuits": 10,
      "mode": "RATING",
      "mdot_ref_kg_s": 0.04
    },
    "calib": {
      "C_air": 1,
      "C_dsh": 1,
      "C_cond": 1,
      "C_sc": 1,
      "f_maldistribution": 1
    },
    "fouling": {
      "R_ext": 0,
      "R_int": 0
    },
    "segments": 40
  },
  "response": {
    "success": true,
    "data": {
      "engineVersion": "dx-cond-6.1.0",
      "airOut": {
        "T_out_C": 34.905833102639996,
        "RH_out": 0.37920635932683405,
        "W_out": 0.01331020383863019,
        "h_out_J_kgda": 69268.25088365117
      },
      "perf": {
        "Q_total_W": 8646.863272072569,
        "Q_dsh_W": 1798.625303999998,
        "Q_cond_W": 5929.402399999996,
        "Q_sc_W": 918.8355680725742,
        "v_face_m_s": 2.952755905511811,
        "dP_air_Pa": 82.1050884443191,
        "dP_ref_Pa": 265.3632161326799,
        "mdot_ref_kg_s": 0.04,
        "achievedSubcool_K": 12.142056810891162,
        "status": "OK",
        "satDrop_K": 0.004153328462578543,
        "propertyModel": "coolprop_grid",
        "Q_ref_W": 8646.863272072569,
        "balanceError_pct": 1.8932766850595476e-13,
        "requiredHeatRejection_W": 8124.959035999998,
        "capacityShortfall_pct": 0,
        "refrigerantOutlet": {
          "T_C": 32.85794318910884,
          "h_in_J_kg": 469048.89259999996,
          "h_out_J_kg": 252877.31079818573,
          "quality": null,
          "phase": "subcooled"
        },
        "pressureDropBreakdown": {
          "vapor_Pa": 103.73388610449132,
          "liquid_Pa": 24.3684210978554,
          "condensationFriction_Pa": 158.1821536620547,
          "condensationBends_Pa": 8.76982049279011,
          "acceleration_Pa": -29.691065224511664,
          "accessories_Pa": 0
        }
      },
      "zones": {
        "dsh_fraction": 0.18317599713921148,
        "cond_fraction": 0.5251466837984806,
        "sc_fraction": 0.29167731906230787,
        "heat_fractions": {
          "dsh": 0.20800899093769123,
          "cond": 0.6857287103348375,
          "sc": 0.10626229872747119
        }
      },
      "htc": {
        "h_air_W_m2K": 66.77541103267734,
        "h_ref_avg_W_m2K": 600.8301332918751,
        "U_avg_W_m2K": 18.87836136527455,
        "U_fouled_W_m2K": 18.87836136527455,
        "eta_fin": 0.7704249008937955,
        "eta_surface": 0.7837962000041732,
        "h_dsh_W_m2K": 237.6991690054887,
        "h_cond_W_m2K": 904.9932282548654,
        "h_sc_W_m2K": 281.2531278597104
      },
      "geometry": {
        "A_face_m2": 0.508,
        "A_ext_m2": 39.10246205044688,
        "A_int_m2": 2.2418405176016765,
        "totalTubes": 80,
        "tubesH": 20,
        "L_circuit_m": 8,
        "Di_m": 0.00892
      },
      "flags": {
        "converged": true,
        "oversized": false,
        "targetMet": true,
        "pressureDropExcessive": false,
        "notes": [
          "Mean-circuit pure-crossflow moving-boundary model: uniform air and refrigerant flow; not a row-by-row circuit simulation.",
          "Single-phase enthalpies from the CoolProp superheated/subcooled property grid (piecewise cp = Δh/ΔT); temperature glide and saturation-pressure variation along the circuit are not resolved.",
          "Target duty is condenser heat rejection, not evaporator cooling capacity; compressor power must be included upstream.",
          "Multiple depth rows use a mean-crossflow approximation; row mixing and circuit/airflow interaction require independent validation.",
          "Refrigerant ΔP uses mean-circuit area lengths, MSH friction, homogeneous acceleration and distributed bend estimates; gravity and pressure/thermal coupling are not resolved.",
          "Warning: Liquid velocity (0.07 m/s) is too low (<0.3 m/s). Risk of poor oil return and flow stratification.",
          "Warning: Vapor velocity (0.53 m/s) is too low (<3 m/s). Risk of poor oil return."
        ]
      }
    }
  }
}

5. 冷水盘管:必须提供质量流量

POST /api/v1/calculate/chilled-water 要求 water.flowType(mass 或 volumetric)、mdot_kg_s、T_in_C、glycol_pct。Vdot_m3_s 在此契约中只是可选信息;引擎直接使用 mdot_kg_s,不会换算仅含体积流量的请求。glycol_pct 为 0–60 的乙二醇质量百分比,0 表示水。冷水入口必须低于空气入口温度。该路由没有 water.T_out_C 目标或 mode 字段。

hydraulic 含 circuits、passes,可选 tubeCountOverride/circuitryPD。calib 含 C_air、C_w、f_fouling、f_maldistribution、approach_K。approach_K 仅为兼容保留并被忽略,可填 0,不能用作出口温度约束。passes 不会再次乘入回路长度。引擎把总污垢和分配不均因子限制为 0.5–1。结果包含 airOutlet、waterOutlet、显热/潜热、凝水 kg/s、SHR、wetAreaFraction、rowProfile。dP_water_kPa 为 kPa,dP_air_Pa 为 Pa。检查 regime、notes、收敛以及湿空气/流速警告。

json

{
  "request": {
    "air": {
      "Vdot_m3_s": 1.5,
      "T_in_C": 27,
      "RH_in": 0.5,
      "P_Pa": 101325
    },
    "water": {
      "flowType": "mass",
      "mdot_kg_s": 0.8,
      "T_in_C": 7,
      "glycol_pct": 0
    },
    "coil": {
      "height_m": 0.508,
      "width_m": 1,
      "rows": 4,
      "fpi": 12,
      "Pt_m": 0.0254,
      "Pl_m": 0.022,
      "Do_m": 0.00952,
      "wall_m": 0.0003,
      "fin_m": 0.0001,
      "tube_k": 386,
      "fin_k": 200,
      "freeAreaRatio": 0.6,
      "finType": "plain",
      "tubeMat": "Cu",
      "finMat": "Al"
    },
    "hydraulic": {
      "circuits": 10,
      "passes": 1,
      "tubeCountOverride": 20
    },
    "calib": {
      "C_air": 1,
      "C_w": 1,
      "f_fouling": 1,
      "f_maldistribution": 1,
      "approach_K": 0
    },
    "segments": 40
  },
  "response": {
    "success": true,
    "data": {
      "airOutlet": {
        "T_out_C": 17.59280443908688,
        "RH_out": 0.7765505714650607,
        "W_out": 0.009740516735050291,
        "h_out": 42378.12881134521,
        "Tdp_out_C": 13.647149565122389
      },
      "waterOutlet": {
        "T_out_C": 13.83298923251135,
        "dT_K": 6.83298923251135
      },
      "perf": {
        "Q_total_W": 22902.7552948312,
        "Q_sens_W": 16738.15895260657,
        "Q_lat_W": 6164.596342224632,
        "SHR": 0.7308360385959376,
        "mcond_kg_s": 0.0024330194247277745,
        "v_face_m_s": 2.952755905511811,
        "v_water_m_s": 1.2806100545209298,
        "dP_air_Pa": 102.16101340852097,
        "dP_water_kPa": 31.131087580896573,
        "balanceError_pct": 1.588445914152848e-14
      },
      "geometry": {
        "A_face_m2": 0.508,
        "A_ext_m2": 39.10246205044688,
        "A_int_m2": 2.2418405176016765,
        "n_tubes": 80,
        "n_tubes_H": 20,
        "L_circuit_m": 8,
        "Di_m": 0.00892
      },
      "htc": {
        "h_air_avg": 66.82202962012009,
        "h_water_avg": 5727.92773098421,
        "U_overall": 45.13852142146351,
        "eta_fin": 0.7703084264602427,
        "eta_surface": 0.7836865094705112
      },
      "flags": {
        "wetCoil": true,
        "converged": true,
        "oversized": false,
        "regime": "Turbulent",
        "notes": [
          "Air ΔP includes a +30 % condensate allowance on the wet area (75 % wet); dry value 83 Pa.",
          "Wet coil: 75 % of the area condensing, SHR = 0.731, latent 6.16 kW",
          "Condensate rate: 8.76 kg/h"
        ],
        "wetAreaFraction": 0.75,
        "topology": "counter-cross-flow",
        "rowProfile": [
          {
            "row": 1,
            "Q_W": 5499.31813897424,
            "T_air_out_C": 23.90926813806179,
            "W_air_out": 0.011144473622459834,
            "T_w_mean_C": 13.026969682536295,
            "wetFraction": 0
          },
          {
            "row": 2,
            "Q_W": 5494.681101553189,
            "T_air_out_C": 21.71020036768415,
            "W_air_out": 0.010785290417758279,
            "T_w_mean_C": 11.3995916157579,
            "wetFraction": 1
          },
          {
            "row": 3,
            "Q_W": 5820.603392148445,
            "T_air_out_C": 19.617081166279927,
            "W_air_out": 0.010308018617014768,
            "T_w_mean_C": 9.711871818476336,
            "wetFraction": 1
          },
          {
            "row": 4,
            "Q_W": 6088.1526621553285,
            "T_air_out_C": 17.59280443908688,
            "W_air_out": 0.009740516735050291,
            "T_w_mean_C": 7.936579335221592,
            "wetFraction": 1
          }
        ]
      },
      "timestamp": "2026-11-02T15:44:41.973Z",
      "engineVersion": "6.0.0"
    }
  }
}

6. 热水盘管:显热加热

POST /api/v1/calculate/hot-water 与冷水使用相同的 water、coil、hydraulic、calib 字段,但要求 water.T_in_C > air.T_in_C。即使 flowType 为 volumetric,也必须给出正值 mdot_kg_s。glycol_pct 指乙二醇质量百分比;该路由没有选择丙二醇的 fluidType。

引擎按给定几何和流量计算,不控制水出口温度,也不自动选型扩大盘管。approach_K 被忽略,passes 不会重复增加长度。加热时空气含湿量 W_out 保持不变,相对湿度随温度变化。结果含 airOutlet、waterOutlet、perf.Q_total_W、dP_water_kPa 和逐排诊断,没有通用 sensibleCapacity_kW 或 coilCode 字段。选型前检查 regime、流速警告和 flags.converged。

json

{
  "request": {
    "air": {
      "Vdot_m3_s": 1.5,
      "T_in_C": 15,
      "RH_in": 0.5,
      "P_Pa": 101325
    },
    "water": {
      "flowType": "mass",
      "mdot_kg_s": 0.8,
      "T_in_C": 70,
      "glycol_pct": 0
    },
    "coil": {
      "height_m": 0.508,
      "width_m": 1,
      "rows": 4,
      "fpi": 12,
      "Pt_m": 0.0254,
      "Pl_m": 0.022,
      "Do_m": 0.00952,
      "wall_m": 0.0003,
      "fin_m": 0.0001,
      "tube_k": 386,
      "fin_k": 200,
      "freeAreaRatio": 0.6,
      "finType": "plain",
      "tubeMat": "Cu",
      "finMat": "Al"
    },
    "hydraulic": {
      "circuits": 10,
      "passes": 1,
      "tubeCountOverride": 20
    },
    "calib": {
      "C_air": 1,
      "C_w": 1,
      "f_fouling": 1,
      "f_maldistribution": 1,
      "approach_K": 0
    },
    "segments": 40
  },
  "response": {
    "success": true,
    "data": {
      "airOutlet": {
        "T_out_C": 45.761722198035464,
        "RH_out": 0.08548275287573397,
        "W_out": 0.0052785443390815584,
        "h_out": 59687.224743425075
      },
      "waterOutlet": {
        "T_out_C": 52.970971133489016,
        "dT_K": 17.029028866510984
      },
      "perf": {
        "Q_total_W": 56935.16608498108,
        "v_face_m_s": 2.952755905511811,
        "v_water_m_s": 1.3104547892703775,
        "dP_air_Pa": 82.60160250830555,
        "dP_water_kPa": 26.25240208261644,
        "balanceError_pct": 2.5558747306799374e-14
      },
      "geometry": {
        "A_face_m2": 0.508,
        "A_ext_m2": 39.10246205044688,
        "A_int_m2": 2.2418405176016765,
        "n_tubes": 80,
        "n_tubes_H": 20,
        "L_circuit_m": 8,
        "Di_m": 0.00892
      },
      "htc": {
        "h_air_avg": 66.7732116534083,
        "h_water_avg": 9792.613943179225,
        "U_overall": 47.844060775088444,
        "eta_fin": 0.7704303970347292,
        "eta_surface": 0.7838013760296212
      },
      "flags": {
        "converged": true,
        "oversized": false,
        "regime": "Turbulent",
        "notes": [],
        "topology": "counter-cross-flow",
        "rowProfile": [
          {
            "row": 1,
            "Q_W": 16668.64454630135,
            "T_air_out_C": 24.00596675498907,
            "T_w_mean_C": 55.41380080380971
          },
          {
            "row": 2,
            "Q_W": 14933.338963764221,
            "T_air_out_C": 32.07435851144329,
            "T_w_mean_C": 60.1476061140732
          },
          {
            "row": 3,
            "Q_W": 13369.768306539849,
            "T_air_out_C": 39.297962599714644,
            "T_w_mean_C": 64.38509129379582
          },
          {
            "row": 4,
            "Q_W": 11963.414268375656,
            "T_air_out_C": 45.761722198035464,
            "T_w_mean_C": 68.17579603667396
          }
        ]
      },
      "timestamp": "2026-11-02T15:44:41.983Z",
      "engineVersion": "6.0.0"
    }
  }
}

7. 蒸汽盘管:表压与排凝限制

POST /api/v1/calculate/steam-coil 使用 steam.P_steam_kPa,单位 kPa 表压,参照 air.P_Pa 的当地大气压。属性表要求入口绝压 >20 且 ≤2000 kPa,饱和温度必须比入口空气高出超过 1 °C。steam.controlType 为 modulating/on_off,不代表动态控制仿真。明确提供 mode RATING 或 SIZING,REST 不应用 schema 默认值。subcooling_K 可选(引擎默认 5 K)。没有 quality 输入,假定入口是干饱和蒸汽。

calib 含 C_air、C_steam、f_fouling、f_noncondensables。SIZING 需正值 steam.Q_target_W,尝试 1–4 排,返回满足负荷的最小可行排数;若均不满足,返回四排结果并设 targetMet false。检查 selectedRows、pressureDropLimited、notes、steamOutlet、dP_steam_kPa。steamTrapCapacity_kg_h 和 dP_steamAssemblies_kPa 仅为初步参考,不是疏水阀/排凝认证。凝水过冷区域不单独建模;重力排凝、水锤、疏水阀可用压差及机械承压需独立工程核查。

json

{
  "request": {
    "air": {
      "Vdot_m3_s": 1.5,
      "T_in_C": 15,
      "RH_in": 0.5,
      "P_Pa": 101325
    },
    "steam": {
      "P_steam_kPa": 100,
      "controlType": "modulating",
      "subcooling_K": 5,
      "mode": "RATING"
    },
    "coil": {
      "height_m": 0.508,
      "width_m": 1,
      "rows": 1,
      "fpi": 8,
      "Pt_m": 0.0254,
      "Pl_m": 0.022,
      "Do_m": 0.01588,
      "wall_m": 0.0008,
      "fin_m": 0.0001,
      "tube_k": 386,
      "fin_k": 200,
      "freeAreaRatio": 0.65,
      "finType": "plain",
      "tubeMat": "Cu",
      "finMat": "Al"
    },
    "hydraulic": {
      "circuits": 20,
      "passes": 1,
      "tubeCountOverride": 20
    },
    "calib": {
      "C_air": 1,
      "C_steam": 1,
      "f_fouling": 1,
      "f_noncondensables": 1
    },
    "segments": 40
  },
  "response": {
    "success": true,
    "data": {
      "airOutlet": {
        "T_out_C": 34.079225932632134,
        "RH_out": 0.15946330926782845,
        "W_out": 0.0052785443390815584,
        "h_out": 47819.933671807084
      },
      "steamOutlet": {
        "T_sat_C": 120.4008265,
        "T_condensate_C": 115.40022902366081,
        "mdot_steam_kg_s": 0.015890787995762996,
        "mdot_steam_kg_h": 57.206836784746784
      },
      "perf": {
        "Q_total_W": 35312.68146348002,
        "v_face_m_s": 2.952755905511811,
        "dP_air_Pa": 79.84088218559907,
        "dP_steamAssemblies_kPa": 0,
        "steamTrapCapacity_kg_h": 143.01709196186695,
        "dP_steam_kPa": 0.004148565054761704,
        "v_steam_in_m_s": 4.3669848655833485,
        "satTempDrop_K": 0.0005974763391805027,
        "balanceError_pct": 2.0604375857744306e-14,
        "effectiveness": 0.18101641744854888,
        "NTU": 0.19969124105470984,
        "UA_W_K": 369.59744652696935
      },
      "geometry": {
        "A_face_m2": 0.508,
        "A_ext_m2": 5.494324834912423,
        "A_int_m2": 0.8972388618652448,
        "n_tubes": 20,
        "n_tubes_H": 20,
        "L_circuit_m": 1,
        "Di_m": 0.014279999999999998
      },
      "htc": {
        "h_air_avg": 69.05378275896463,
        "h_steam_avg": 16452.208245445134,
        "U_overall": 67.26894707397848,
        "eta_fin": 0.9040208158032803,
        "eta_surface": 0.9208501857263931
      },
      "flags": {
        "converged": true,
        "oversized": false,
        "notes": [
          "In-tube condensation: max(Chato gravity-driven, Shah shear-driven) — governing: Chato (stratified); inlet vapour Re = 5474.",
          "Steam ΔP in governing circuit 0.00 kPa → T_sat drop 0.00 K; capacity uses T_sat at the mean circuit pressure (120.4 °C).",
          "Condensate hydrostatic head across the coil: 4.7 kPa (0 return bends per circuit). Ensure gravity drainage and trap differential.",
          "Steam use includes 5.0 K condensate subcooling (h_fg + cp·ΔT_sub); the subcooling area is not modelled separately."
        ],
        "pressureDropLimited": false,
        "condensationModel": "Chato (stratified)",
        "rowProfile": [
          {
            "row": 1,
            "Q_W": 35312.68146348002,
            "T_air_out_C": 34.079225932632134,
            "h_steam_W_m2K": 16452.208245445134
          }
        ]
      },
      "timestamp": "2026-11-02T15:44:41.989Z",
      "engineVersion": "5.0.0"
    }
  }
}

8. 干冷器:REST 仅执行单盘管性能计算

POST /api/v1/calculate/dry-cooler 的 air 不同:T_db_C、RH、altitude_m,以及 Vdot_m3_s 或 v_face_m_s。同时提供时正值 v_face_m_s 优先。fluid 使用 fluidType water/eg/pg、glycolPct(质量百分比 0–60)、T_in_C、正值 mdot_kg_s 或 Vdot_m3_s;质量流量优先。流体入口必须比空气更热。calib 使用 C_air、C_fluid、f_fouling_air、f_fouling_fluid、可选 R_fouling_air_m2KW/R_fouling_fluid_m2KW(m²·K/W)、f_maldistribution、approach_K;approach_K 被忽略。

此 REST 路由只调用 solveDryCooler。共享类型虽列有 fluid.T_out_C、vShape、vAngle_deg,但这些字段不会在此启用目标出口温度求解或 V 形求解器。这里没有 /dry-cooler/balanced 路由。响应是单盘管结果,含 airOutlet、fluidOutlet、Q_total_W、LMTD_K、F_correction、effectiveness、NTU 和冻结诊断。此排热模型 Q_lat_W 为 0、wetCoil 为 false;不是喷淋绝热/蒸发冷却器。检查 nearFreezing、freezingMargin_K、regime、收敛和 notes。

json

{
  "request": {
    "air": {
      "T_db_C": 30,
      "RH": 0.5,
      "altitude_m": 0,
      "Vdot_m3_s": 1.5
    },
    "fluid": {
      "fluidType": "eg",
      "glycolPct": 30,
      "T_in_C": 45,
      "mdot_kg_s": 0.8
    },
    "coil": {
      "height_m": 0.508,
      "width_m": 1,
      "rows": 4,
      "fpi": 10,
      "Pt_m": 0.0254,
      "Pl_m": 0.022,
      "Do_m": 0.01588,
      "wall_m": 0.0005,
      "fin_m": 0.0002,
      "tube_k": 386,
      "fin_k": 200,
      "freeAreaRatio": 0.55,
      "finType": "plain",
      "tubeMat": "Cu",
      "finMat": "Al"
    },
    "hydraulic": {
      "circuits": 10,
      "passes": 1,
      "tubeCountOverride": 20
    },
    "calib": {
      "C_air": 1,
      "C_fluid": 1,
      "f_fouling_air": 1,
      "f_fouling_fluid": 1,
      "R_fouling_air_m2KW": 0,
      "R_fouling_fluid_m2KW": 0,
      "f_maldistribution": 1,
      "approach_K": 0
    },
    "segments": 40
  },
  "response": {
    "success": true,
    "data": {
      "airOutlet": {
        "T_out_C": 37.963588732151216,
        "RH_out": 0.32077369527978405,
        "W_out": 0.01331020383863019,
        "h_out": 72420.05383927401
      },
      "fluidOutlet": {
        "T_out_C": 40.1532216213745,
        "dT_K": 4.846778378625501
      },
      "perf": {
        "Q_total_W": 14036.364768477986,
        "Q_sens_W": 14036.364768477986,
        "Q_lat_W": 0,
        "v_face_m_s": 2.952755905511811,
        "v_fluid_m_s": 0.44169081528152904,
        "dP_air_Pa": 220.66091438182707,
        "dP_fluid_kPa": 3.170390159951273,
        "balanceError_pct": 2.2030504600253869e-13,
        "LMTD_K": 8.499786553833324,
        "F_correction": 0.9964684620436388,
        "effectiveness": 0.530905915476746,
        "NTU": 0.9402368011687094
      },
      "geometry": {
        "A_face_m2": 0.508,
        "A_ext_m2": 26.353776660889263,
        "A_int_m2": 3.7397518948332893,
        "n_tubes": 80,
        "n_tubes_H": 20,
        "L_circuit_m": 8,
        "Di_m": 0.014879999999999997
      },
      "htc": {
        "h_air_avg": 158.41035024054196,
        "h_fluid_avg": 784.605812708763,
        "U_overall": 62.88400693514512,
        "UA_W_K": 1657.2310743106261,
        "eta_fin": 0.8992749036562225,
        "eta_surface": 0.9133028338448336
      },
      "flags": {
        "wetCoil": false,
        "wetFraction": 0,
        "converged": true,
        "oversized": false,
        "regime": "Transitional",
        "nearFreezing": false,
        "freezingPoint_C": -13.544999999999998,
        "freezingMargin_K": 53.6982216213745,
        "notes": [
          "Warning: Glycol mixture velocity (0.44 m/s) below 0.5 m/s. Glycol mixtures need higher velocity for adequate heat transfer.",
          "Notice: Fluid flow is transitional (Re = 2798). Results may have higher uncertainty.",
          "Dry cooler: the fin surface is warmer than the air, so no condensation can occur (latent capacity = 0)."
        ],
        "topology": "counter-cross-flow",
        "rowProfile": [
          {
            "row": 1,
            "Q_W": 3885.8246219918224,
            "T_air_out_C": 32.20463842919675,
            "T_w_mean_C": 40.80778501827438
          },
          {
            "row": 2,
            "Q_W": 3634.220318092688,
            "T_air_out_C": 34.266528131601234,
            "T_w_mean_C": 42.10730054946271
          },
          {
            "row": 3,
            "Q_W": 3382.1877594860885,
            "T_air_out_C": 36.18542613516059,
            "T_w_mean_C": 43.31977794477613
          },
          {
            "row": 4,
            "Q_W": 3134.1320689073873,
            "T_air_out_C": 37.963588732151216,
            "T_w_mean_C": 44.445822404284186
          }
        ]
      },
      "timestamp": "2026-11-02T15:44:42.006Z",
      "engineVersion": "2.0.0"
    }
  }
}

9. 两条 balanced 路由并不相同

POST /api/v1/calculate/dx-evaporator/balanced 要求 {inputs: <完整蒸发器输入>, options?: {tolPct?, maxIt?}}。它搜索达到目标出口过热度的制冷剂质量流量,即膨胀阀工作点;能力是结果,不只是让空气/制冷剂热量相等。内部改用 RATING,缺省流量时使用正初值。maxIt 默认 60。原始输入为 SIZING 时,tolPct(默认 1)检查能力缺口,而不是过热度求解误差;引擎过热度接受误差为 0.05 K。即使返回结果,targetMet/converged 也可能为 false,不会调整校准。

POST /api/v1/calculate/dx-condenser/balanced 直接接收冷凝器输入,不接受 {inputs, options} 包装。它调用普通冷凝器引擎,保留 RATING 流量,设 iterations 为 1,并在 SIZING 下检查负荷、液态出口和过冷度。REST 不传第三个 options 参数,因此发送 options 不会开放内部流量边界、maxIt 或容差。不能描述为搜索更低冷凝器流量来掩盖能力不足。两者都使用各自普通模块的结果结构。

json

[
  {
    "method": "POST",
    "path": "/api/v1/calculate/dx-evaporator/balanced",
    "request": {
      "inputs": {
        "air": {
          "Vdot_m3_s": 1.5,
          "T_in_C": 27,
          "RH_in": 0.5,
          "P_Pa": 101325
        },
        "coil": {
          "height_m": 0.508,
          "tubesPerRow": 20,
          "width_m": 1,
          "rows": 4,
          "fpi": 12,
          "Pt_m": 0.0254,
          "Pl_m": 0.022,
          "Do_m": 0.00952,
          "wall_m": 0.0003,
          "fin_m": 0.0001,
          "tube_k": 386,
          "fin_k": 200,
          "freeAreaRatio": 0.6,
          "finType": "plain"
        },
        "ref": {
          "fluid": "R410A",
          "Tevap_C": 5,
          "superheat_K": 5,
          "circuits": 10,
          "mode": "RATING",
          "mdot_ref_kg_s": 0.04,
          "x_in": 0.2
        },
        "calib": {
          "C_air": 1,
          "C_tp": 1,
          "C_sh": 1,
          "f_maldistribution": 1
        },
        "segments": 40
      },
      "options": {
        "tolPct": 1,
        "maxIt": 60
      }
    },
    "response": {
      "success": true,
      "data": {
        "outlet": {
          "T_out_C": 16.37866583468195,
          "RH_out": 0.7700295163271693,
          "W_out": 0.008931554267298955,
          "h_out": 39086.848765679584,
          "Tdp_out_C": 12.341546239274933
        },
        "perf": {
          "Q_total_W": 28606.45485650264,
          "Q_sens_W": 18898.46749721315,
          "Q_lat_W": 9707.987359289491,
          "SHR": 0.660636474949893,
          "mcond_kg_s": 0.0038349295656768378,
          "v_face_m_s": 2.952755905511811,
          "dP_air_Pa": 83.4970954841905,
          "dP_ref_Pa": 18853.52619300515,
          "Q_ref_W": 28606.45485650279,
          "balanceError_pct": 5.214107509615256e-13,
          "mdot_ref_kg_s": 0.1606828269347608,
          "x_out": 1,
          "achievedSuperheat_K": 5.013566038697411,
          "targetSuperheat_K": 5,
          "refrigerantOutlet": {
            "T_C": 10.01356603869741,
            "h_in_J_kg": 250687.86399999997,
            "h_out_J_kg": 428718.4314365398,
            "phase": "superheated"
          },
          "refrigerantPressure": {
            "P_in_Pa": 955060.1261930054,
            "P_out_Pa": 936206.6000000002,
            "T_sat_in_C": 5.648975814871859,
            "T_sat_out_C": 5,
            "satDrop_K": 0.648975814871859,
            "x_in_local": 0.19609440443287166,
            "dP_twoPhase_Pa": 17333.776101730764,
            "dP_vapor_Pa": 1524.1357220685973,
            "dP_accessoriesInlet_Pa": 0,
            "dP_accessoriesOutlet_Pa": 0,
            "massFlux_kg_m2s": 257.12829713694947,
            "hydraulicFeasible": true
          }
        },
        "geometry": {
          "A_face_m2": 0.508,
          "A_ext_m2": 39.10246205044688,
          "A_int_m2": 2.2418405176016765,
          "n_tubes": 80,
          "n_tubes_H": 20,
          "L_circuit_m": 8,
          "Di_m": 0.00892
        },
        "htc": {
          "h_air_avg": 66.82588196002244,
          "h_ref_avg": 3152.8354872556492,
          "U_overall": 39.48790359750422,
          "eta_fin": 0.7702988035387852,
          "eta_surface": 0.7836774470234328
        },
        "flags": {
          "wetCoil": true,
          "superheated": true,
          "converged": true,
          "oversized": false,
          "targetMet": true,
          "hydraulicFeasible": true,
          "pressureDropExcessive": false,
          "notes": [
            "Refrigerant ΔP 18.9 kPa (G = 257 kg/m²s per circuit): saturation 5.65 °C at the tube inlets → 5.00 °C at the suction connection (drop 0.65 K, coupled into capacity).",
            "Warning: Liquid velocity (0.22 m/s) is too low (<0.3 m/s). Risk of poor oil return and flow stratification.",
            "Wet surface on 93 % of the coil area: SHR = 0.661, condensate 13.81 kg/h",
            "Model: mean-circuit crossflow moving boundary with pressure-coupled saturation (MSH friction, Domanski–Hermes bends, homogeneous momentum); Chen two-phase HTC does not model dryout near x → 1.",
            "TXV: mdot_ref = 0.16068 kg/s gives 5.01 K superheat (12 evaluations)."
          ],
          "iterations": 12
        },
        "zones": {
          "tp_fraction": 0.9259358677567262,
          "sh_fraction": 0.0740641322432738,
          "wet_fraction": 0.9259358677567262,
          "Q_tp_W": 27660.548469301222,
          "Q_sh_W": 945.9063872014204
        },
        "timestamp": "2026-11-02T15:44:42.158Z",
        "engineVersion": "6.1.0"
      }
    }
  },
  {
    "method": "POST",
    "path": "/api/v1/calculate/dx-condenser/balanced",
    "request": {
      "air": {
        "Vdot_m3_s": 1.5,
        "T_in_C": 30,
        "RH_in": 0.5,
        "P_Pa": 101325
      },
      "coil": {
        "height_m": 0.508,
        "tubesPerRow": 20,
        "width_m": 1,
        "rows": 4,
        "fpi": 12,
        "Pt_m": 0.0254,
        "Pl_m": 0.022,
        "Do_m": 0.00952,
        "wall_m": 0.0003,
        "fin_m": 0.0001,
        "tube_k": 386,
        "fin_k": 200,
        "freeAreaRatio": 0.6,
        "finType": "plain"
      },
      "ref": {
        "fluid": "R410A",
        "Tcond_C": 45,
        "subcool_K": 5,
        "Tin_gas_C": 75,
        "circuits": 10,
        "mode": "RATING",
        "mdot_ref_kg_s": 0.04
      },
      "calib": {
        "C_air": 1,
        "C_dsh": 1,
        "C_cond": 1,
        "C_sc": 1,
        "f_maldistribution": 1
      },
      "fouling": {
        "R_ext": 0,
        "R_int": 0
      },
      "segments": 40
    },
    "response": {
      "success": true,
      "data": {
        "engineVersion": "dx-cond-6.1.0",
        "airOut": {
          "T_out_C": 34.905833102639996,
          "RH_out": 0.37920635932683405,
          "W_out": 0.01331020383863019,
          "h_out_J_kgda": 69268.25088365117
        },
        "perf": {
          "Q_total_W": 8646.863272072569,
          "Q_dsh_W": 1798.625303999998,
          "Q_cond_W": 5929.402399999996,
          "Q_sc_W": 918.8355680725742,
          "v_face_m_s": 2.952755905511811,
          "dP_air_Pa": 82.1050884443191,
          "dP_ref_Pa": 265.3632161326799,
          "mdot_ref_kg_s": 0.04,
          "achievedSubcool_K": 12.142056810891162,
          "status": "OK",
          "satDrop_K": 0.004153328462578543,
          "propertyModel": "coolprop_grid",
          "Q_ref_W": 8646.863272072569,
          "balanceError_pct": 1.8932766850595476e-13,
          "requiredHeatRejection_W": 8124.959035999998,
          "capacityShortfall_pct": 0,
          "refrigerantOutlet": {
            "T_C": 32.85794318910884,
            "h_in_J_kg": 469048.89259999996,
            "h_out_J_kg": 252877.31079818573,
            "quality": null,
            "phase": "subcooled"
          },
          "pressureDropBreakdown": {
            "vapor_Pa": 103.73388610449132,
            "liquid_Pa": 24.3684210978554,
            "condensationFriction_Pa": 158.1821536620547,
            "condensationBends_Pa": 8.76982049279011,
            "acceleration_Pa": -29.691065224511664,
            "accessories_Pa": 0
          }
        },
        "zones": {
          "dsh_fraction": 0.18317599713921148,
          "cond_fraction": 0.5251466837984806,
          "sc_fraction": 0.29167731906230787,
          "heat_fractions": {
            "dsh": 0.20800899093769123,
            "cond": 0.6857287103348375,
            "sc": 0.10626229872747119
          }
        },
        "htc": {
          "h_air_W_m2K": 66.77541103267734,
          "h_ref_avg_W_m2K": 600.8301332918751,
          "U_avg_W_m2K": 18.87836136527455,
          "U_fouled_W_m2K": 18.87836136527455,
          "eta_fin": 0.7704249008937955,
          "eta_surface": 0.7837962000041732,
          "h_dsh_W_m2K": 237.6991690054887,
          "h_cond_W_m2K": 904.9932282548654,
          "h_sc_W_m2K": 281.2531278597104
        },
        "geometry": {
          "A_face_m2": 0.508,
          "A_ext_m2": 39.10246205044688,
          "A_int_m2": 2.2418405176016765,
          "totalTubes": 80,
          "tubesH": 20,
          "L_circuit_m": 8,
          "Di_m": 0.00892
        },
        "flags": {
          "converged": true,
          "oversized": false,
          "targetMet": true,
          "pressureDropExcessive": false,
          "notes": [
            "Mean-circuit pure-crossflow moving-boundary model: uniform air and refrigerant flow; not a row-by-row circuit simulation.",
            "Single-phase enthalpies from the CoolProp superheated/subcooled property grid (piecewise cp = Δh/ΔT); temperature glide and saturation-pressure variation along the circuit are not resolved.",
            "Target duty is condenser heat rejection, not evaporator cooling capacity; compressor power must be included upstream.",
            "Multiple depth rows use a mean-crossflow approximation; row mixing and circuit/airflow interaction require independent validation.",
            "Refrigerant ΔP uses mean-circuit area lengths, MSH friction, homogeneous acceleration and distributed bend estimates; gravity and pressure/thermal coupling are not resolved.",
            "Warning: Liquid velocity (0.07 m/s) is too low (<0.3 m/s). Risk of poor oil return and flow stratification.",
            "Warning: Vapor velocity (0.53 m/s) is too low (<3 m/s). Risk of poor oil return."
          ],
          "iterations": 1
        }
      }
    }
  }
]

10. 成功响应与查询结果

计算成功返回 HTTP 200,格式 {success:true,data:<引擎结果>},没有统一能力改名、coilCode、分页或保存项目。能力为 W;制冷剂/凝水流量通常为 kg/s,明确 kg_h 的字段除外;空气/DX 压降为 Pa,液体/蒸汽以 kPa 结尾的字段为 kPa。示例给出完整合成响应。下面的紧凑字段表还列出条件字段;它是字段记法,不是可执行 TypeScript 或 JSON 请求。可选字段可能缺失。

HTTP 成功仅表示引擎返回,不证明满足负荷或可安全制造。检查 flags.converged、flags.notes、适用时的 targetMet、实际过热/过冷度、出口相态、水力及冻结诊断。很小的 balanceError_pct 只是内部守恒残差,不是独立实验室验证。冷凝器返回 engineVersion,但不含 timestamp;不要假设元数据完全一致。

GET /api/v1/refrigerants 仅返回 data 中的准确制冷剂名称数组,不含 GWP、ODP、安全等级或属性表。GET /api/v1/health 直接返回 status、version、ISO timestamp,不带 success/data;version 是 API 版本,不是各引擎版本。两条 GET 均需身份验证。列出某制冷剂不代表支持跨临界或无限温度范围。

text

// HTTP 200 calculators: { success: true, data: Result }
// A trailing ? marks an optional field; names and units are literal API keys.
Air = {T_out_C, RH_out, W_out, h_out}; // numbers: °C, fraction, kg/kg dry air, J/kg dry air
Geometry = {A_face_m2, A_ext_m2, A_int_m2, n_tubes, n_tubes_H, L_circuit_m, Di_m};
HTC = {h_air_avg, U_overall, eta_fin, eta_surface}; // W/(m²·K), efficiencies 0–1
Row = {row, Q_W, T_air_out_C, T_w_mean_C};

DXEvaporator = {
 outlet: Air & {Tdp_out_C}, geometry: Geometry, htc: HTC & {h_ref_avg},
 perf: {Q_total_W,Q_sens_W,Q_lat_W,SHR,mcond_kg_s,v_face_m_s,dP_air_Pa,dP_ref_Pa,
  Q_ref_W,balanceError_pct,mdot_ref_kg_s,x_out,achievedSuperheat_K?,targetSuperheat_K?,
  targetCapacity_W?,capacityShortfall_pct?,
  refrigerantOutlet?: {T_C,h_in_J_kg,h_out_J_kg,phase},
  refrigerantPressure?: {P_in_Pa,P_out_Pa,T_sat_in_C,T_sat_out_C,satDrop_K,x_in_local,
   dP_twoPhase_Pa,dP_vapor_Pa,dP_accessoriesInlet_Pa,dP_accessoriesOutlet_Pa,massFlux_kg_m2s,hydraulicFeasible}},
 zones?: {tp_fraction,sh_fraction,wet_fraction,Q_tp_W,Q_sh_W},
 flags: {wetCoil,superheated,converged,oversized,targetMet?,hydraulicFeasible?,pressureDropExcessive?,iterations?,notes},
 timestamp, engineVersion
};
DXCondenser = {
 airOut: {T_out_C,RH_out,W_out,h_out_J_kgda},
 perf: {Q_total_W,Q_dsh_W,Q_cond_W,Q_sc_W,v_face_m_s,dP_air_Pa,dP_ref_Pa?,
  mdot_ref_kg_s,achievedSubcool_K,status,satDrop_K?,propertyModel?,Q_ref_W,balanceError_pct,
  targetCapacity_W?,targetError_pct?,requiredHeatRejection_W?,capacityShortfall_pct?,
  refrigerantOutlet?: {T_C,h_in_J_kg,h_out_J_kg,quality,phase},
  pressureDropBreakdown?: {vapor_Pa,liquid_Pa,condensationFriction_Pa,condensationBends_Pa,acceleration_Pa,accessories_Pa}},
 zones: {dsh_fraction,cond_fraction,sc_fraction,heat_fractions?:{dsh,cond,sc}},
 htc: {h_air_W_m2K,h_ref_avg_W_m2K,U_avg_W_m2K,U_fouled_W_m2K?,eta_fin,eta_surface,h_dsh_W_m2K?,h_cond_W_m2K?,h_sc_W_m2K?},
 geometry: {A_face_m2,A_ext_m2,A_int_m2,totalTubes,tubesH?,L_circuit_m?,Di_m?},
 flags: {converged,iterations?,oversized,targetMet?,pressureDropExcessive?,notes}, engineVersion?
};
ChilledWater = {
 airOutlet: Air & {Tdp_out_C}, waterOutlet:{T_out_C,dT_K}, geometry:Geometry,
 htc:HTC & {h_water_avg},
 perf:{Q_total_W,Q_sens_W,Q_lat_W,SHR,mcond_kg_s,v_face_m_s,v_water_m_s?,dP_air_Pa,dP_water_kPa,balanceError_pct},
 flags:{wetCoil,converged,oversized,regime,notes,wetAreaFraction?,topology?,
  rowProfile?: Array<Row & {W_air_out,wetFraction}>}, timestamp,engineVersion
};
HotWater = {
 airOutlet:Air,waterOutlet:{T_out_C,dT_K},geometry:Geometry,htc:HTC & {h_water_avg},
 perf:{Q_total_W,v_face_m_s,v_water_m_s?,dP_air_Pa,dP_water_kPa,balanceError_pct},
 flags:{converged,oversized,regime,notes,topology?,rowProfile?:Row[]},timestamp,engineVersion
};
Steam = {
 airOutlet:Air,steamOutlet:{T_sat_C,T_condensate_C,mdot_steam_kg_s,mdot_steam_kg_h},
 geometry:Geometry,htc:HTC & {h_steam_avg},
 perf:{Q_total_W,v_face_m_s,dP_air_Pa,dP_steamAssemblies_kPa,steamTrapCapacity_kg_h,
  dP_steam_kPa?,v_steam_in_m_s?,satTempDrop_K?,balanceError_pct?,effectiveness?,NTU?,UA_W_K?},
 flags:{converged,oversized,notes,targetMet?,selectedRows?,pressureDropLimited?,condensationModel?,
  rowProfile?:Array<{row,Q_W,T_air_out_C,h_steam_W_m2K}>},timestamp,engineVersion
};
DryCooler = {
 airOutlet:Air,fluidOutlet:{T_out_C,dT_K},geometry:Geometry,htc:HTC & {h_fluid_avg,UA_W_K},
 perf:{Q_total_W,Q_sens_W,Q_lat_W,v_face_m_s,v_fluid_m_s,dP_air_Pa,dP_fluid_kPa,
  balanceError_pct,LMTD_K,F_correction,effectiveness,NTU},
 flags:{wetCoil,wetFraction,converged,oversized,regime,nearFreezing,freezingPoint_C,freezingMargin_K,
  notes,topology?,rowProfile?:Row[],targetMet?},timestamp,engineVersion
};
// Numbers unless named otherwise: flags booleans; notes string[]; rowProfile arrays.
// timestamp: ISO string; engineVersion/regime/topology/propertyModel/status/phase/condensationModel: strings.
// Condenser refrigerantOutlet.quality: number | null. No condenser timestamp is returned.
// Evaporator phase: two_phase | saturated_vapor | superheated.
// Condenser phase: superheated | two_phase | saturated_liquid | subcooled.
// Condenser status type: OK | NO_CONDENSE | NO_SUBCOOL | LIMITED_UA | PARTIAL.
// Current condenser solver emits OK, NO_CONDENSE, NO_SUBCOOL or PARTIAL.
// propertyModel: coolprop_grid | constant_cp_fallback; topology: counter-cross-flow.
// condensationModel: Chato (stratified) | Shah (annular).
// GET /api/v1/health: {status:"ok",version:"1.0.0",timestamp:"<ISO>"}
// GET /api/v1/refrigerants: {success:true,data:["R32","R410A","R134a","R22","R290","R1234yf","R404A","R507A","R407C","R1234ze(E)","R717","R744","R600a","R1270","R123","R245fa"]}

11. 错误、限流与安全排查

路由 JSON 错误格式为 {error:<代码>,message:<文本>},没有 success:false 或逐字段错误数组。以下为原始消息模板,尖括号内容可变。普通 DX 的缺少制冷剂和未知制冷剂消息不同;蒸发器 balanced 先检查 inputs,两条 balanced 均返回较短 Unknown refrigerant 消息。缺失嵌套字段也可能抛异常转为 422。对象检查很浅,JavaScript 数组也算对象,不能依赖它完成输入验证。

401 检查 Bearer、exk_ 格式和密钥有效性,勿泄露密钥。403 检查吊销、到期、订阅状态和 calc:read。400 修正格式或制冷剂键名。422 按引擎消息核对单位、必填项、流量/温度顺序、几何及属性范围,不要盲目重试。未捕获的认证/存储错误不由 wrapSolver 规范化。畸形 JSON 或超大请求可能在进入 REST 前被 Express 拒绝;应用 JSON parser 限额为 50mb,这类错误不保证上述 JSON 格式。

限流按密钥保存在进程内存,60 秒窗口从首次通过认证的请求开始。使用密钥配置值,值为假值时回退到每分钟 100 次;这不是统一套餐配额,也不是分布式限流。认证/限流通过后及 429 响应设置 X-RateLimit-Limit、X-RateLimit-Remaining、X-RateLimit-Reset(Unix 秒),并非每个 401/403 都有。认证后的权限/输入失败消耗限额。遇到 429 等待 reset 并采用有界退避,不保证 Retry-After。日志只记录路径、合成/脱敏输入、HTTP 状态和诊断,不记录秘密。

text

HTTP 401: {"error":"unauthorized","message":"Missing or invalid Authorization header. Use: Bearer exk_your_api_key"}
HTTP 401: {"error":"unauthorized","message":"Invalid API key format. Keys start with 'exk_'."}
HTTP 401: {"error":"unauthorized","message":"Invalid API key."}
HTTP 403: {"error":"forbidden","message":"API key has been revoked."}
HTTP 403: {"error":"forbidden","message":"API key has expired."}
HTTP 403: {"error":"forbidden","message":"API access requires an active Enterprise or Manufacturer subscription."}
HTTP 403: {"error":"forbidden","message":"This API key does not have the 'calc:read' permission."}
HTTP 429: {"error":"rate_limit_exceeded","message":"Rate limit of <limit> requests per minute exceeded. Try again later."}
HTTP 400: {"error":"bad_request","message":"Request body must be a JSON object with calculation inputs."}
HTTP 400: {"error":"bad_request","message":"Missing refrigerant in input. Provide ref.fluid (or legacy ref.refrigerant)."}
HTTP 400: {"error":"bad_request","message":"Unknown refrigerant '<name>'. Available: <keys>"}
HTTP 400: {"error":"bad_request","message":"Request body must contain 'inputs' and optional 'options' fields."}
HTTP 400: {"error":"bad_request","message":"Unknown refrigerant '<name>'."}
HTTP 422: {"error":"calculation_error","message":"<engine error>"}
// Non-Error fallbacks: normal routes = Calculation failed; balanced routes = Balanced solve failed.

文档所述功能取决于订阅等级以及计算中可用的数据。尺寸图不代表制造批准。

全部指南