feat: Completes hvac-system-performance views and api call.
This commit is contained in:
@@ -32,7 +32,7 @@ extension ApiController: DependencyKey {
|
||||
|
||||
case let .calculateHVACSystemPerformance(request):
|
||||
logger.debug("Calculating hvac system performance: \(request)")
|
||||
fatalError()
|
||||
return try await request.respond(logger: logger)
|
||||
|
||||
case let .calculateMoldRisk(request):
|
||||
logger.debug("Calculating mold risk: \(request)")
|
||||
|
||||
92
Sources/ApiController/Extensions/HVACSystemPerformance.swift
Normal file
92
Sources/ApiController/Extensions/HVACSystemPerformance.swift
Normal file
@@ -0,0 +1,92 @@
|
||||
import Dependencies
|
||||
import Foundation
|
||||
import Logging
|
||||
import PsychrometricClient
|
||||
import Routes
|
||||
|
||||
public extension HVACSystemPerformance.Request {
|
||||
|
||||
// TODO: Check if we should use psychrometrics for the request conditions instead
|
||||
private static let airDensity = 0.075 // lb/ft^3 at standard conditions.
|
||||
private static let specificHeat = 0.24 // BTU/lb at standard conditions (imperial).
|
||||
|
||||
func respond(logger: Logger) async throws -> HVACSystemPerformance.Response {
|
||||
@Dependency(\.psychrometricClient) var psychrometricClient
|
||||
|
||||
try validate()
|
||||
|
||||
let altitude = parseAltitude()
|
||||
let temperatureSplit = returnAirTemperature - supplyAirTemperature
|
||||
|
||||
let returnAirProperties = try await psychrometricClient.psychrometricProperties(.dryBulb(
|
||||
.init(.init(returnAirTemperature)),
|
||||
relativeHumidity: returnAirHumidity%,
|
||||
altitude: altitude
|
||||
))
|
||||
|
||||
let supplyAirProperties = try await psychrometricClient.psychrometricProperties(.dryBulb(
|
||||
.init(.init(supplyAirTemperature)),
|
||||
relativeHumidity: supplyAirHumidity%,
|
||||
altitude: altitude
|
||||
))
|
||||
|
||||
let airMassFlow = airflow * 60 * Self.airDensity
|
||||
logger.debug("Air mass flow: \(airMassFlow)")
|
||||
let condensationRate = airMassFlow * (
|
||||
returnAirProperties.humidityRatio.value - supplyAirProperties.humidityRatio.value
|
||||
) // lb/hr
|
||||
let sensibleCapacity = airMassFlow * Self.specificHeat * temperatureSplit
|
||||
logger.debug("Return enthalpy: \(returnAirProperties.enthalpy.value)")
|
||||
logger.debug("Supply enthalpy: \(supplyAirProperties.enthalpy.value)")
|
||||
let deltaEnthalpy = returnAirProperties.enthalpy.value - supplyAirProperties.enthalpy.value
|
||||
logger.debug("Delta enthalpy: \(deltaEnthalpy)")
|
||||
let totalCapacity = airMassFlow * deltaEnthalpy
|
||||
|
||||
let capacity = HVACSystemPerformance.Capacity(
|
||||
total: totalCapacity,
|
||||
sensible: sensibleCapacity,
|
||||
latent: totalCapacity - sensibleCapacity
|
||||
)
|
||||
|
||||
let systemMetrics = HVACSystemPerformance.SystemMetrics(
|
||||
cfmPerTon: airflow / systemSize,
|
||||
targetTemperatureSplit: (systemSize * 12000 * 0.75) / (1.08 * airflow),
|
||||
actualTemperatureSplit: temperatureSplit,
|
||||
condensationRatePoundsPerHour: condensationRate
|
||||
)
|
||||
|
||||
return .init(
|
||||
returnAirProperties: returnAirProperties,
|
||||
supplyAirProperties: supplyAirProperties,
|
||||
capacity: capacity,
|
||||
systemMetrics: systemMetrics
|
||||
)
|
||||
}
|
||||
|
||||
private func parseAltitude() -> Length {
|
||||
guard let altitude, altitude > 0 else { return .seaLevel }
|
||||
return .init(altitude)
|
||||
}
|
||||
|
||||
private func validate() throws {
|
||||
guard returnAirTemperature > 0 else {
|
||||
throw ValidationError(message: "Return air temperature should be greater than 0.")
|
||||
}
|
||||
guard returnAirHumidity > 0 else {
|
||||
throw ValidationError(message: "Return air humidity should be greater than 0.")
|
||||
}
|
||||
guard supplyAirTemperature > 0 else {
|
||||
throw ValidationError(message: "Supply air temperature should be greater than 0.")
|
||||
}
|
||||
guard supplyAirHumidity > 0 else {
|
||||
throw ValidationError(message: "Supply air humidity should be greater than 0.")
|
||||
}
|
||||
guard systemSize > 0 else {
|
||||
throw ValidationError(message: "System size should be greater than 0.")
|
||||
}
|
||||
}
|
||||
|
||||
struct ValidationError: Error {
|
||||
let message: String
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user