56 lines
1.6 KiB
Swift
56 lines
1.6 KiB
Swift
import Models
|
|
import Validations
|
|
|
|
extension FurnaceInterpolation.Request {
|
|
private static let undersizingLimit = 90
|
|
private static let oversizingLimit = 140
|
|
|
|
func respond() async throws -> FurnaceInterpolation.Response {
|
|
try await validate()
|
|
let altitudeDerating = try await altitudeDerating()
|
|
let outputCapacity = Int(
|
|
(Double(inputRating) * (altitudeDerating ?? 1.0))
|
|
* (afue / 100)
|
|
)
|
|
let capacityAsPercentOfLoad = normalizePercentage(outputCapacity, heatLoss)
|
|
|
|
var failures = [String]()
|
|
if capacityAsPercentOfLoad < Self.undersizingLimit {
|
|
failures.append("Undersizing failure.")
|
|
}
|
|
if capacityAsPercentOfLoad > Self.oversizingLimit {
|
|
failures.append("Oversizing failure.")
|
|
}
|
|
|
|
return .init(
|
|
failures: failures.isEmpty ? nil : failures,
|
|
altitudeAdjustmentMultiplier: altitudeDerating,
|
|
capacityAsPercentOfLoad: capacityAsPercentOfLoad,
|
|
oversizingLimit: Self.oversizingLimit,
|
|
undersizingLimit: Self.undersizingLimit,
|
|
outputCapacity: outputCapacity
|
|
)
|
|
}
|
|
|
|
func altitudeDerating() async throws -> Double? {
|
|
guard let elevation else { return nil }
|
|
let response = try await Derating.Request(
|
|
elevation: elevation,
|
|
systemType: .heatingOnly(type: .furnace)
|
|
).respond()
|
|
return response.heating
|
|
}
|
|
|
|
}
|
|
|
|
extension FurnaceInterpolation.Request: AsyncValidatable {
|
|
public var body: some AsyncValidation<Self> {
|
|
AsyncValidator.accumulating {
|
|
AsyncValidator.greaterThan(\.heatLoss, 0)
|
|
AsyncValidator.greaterThan(\.inputRating, 0)
|
|
AsyncValidator.greaterThan(\.afue, 0)
|
|
AsyncValidator.lessThan(\.afue, 100)
|
|
}
|
|
}
|
|
}
|