Files
swift-manual-s/Sources/ManualS/Internal/FurnaceInterpolation.swift
Michael Housh 5f6d2a7b6c
All checks were successful
CI / Ubuntu (push) Successful in 11m23s
feat: Adds furnace heating interpolations.
2025-03-13 11:49:32 -04:00

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)
}
}
}