import CoreFoundation import Models extension SizingLimits.Request { func respond() async throws -> SizingLimits.Response { return try .init( oversizing: .oversizingLimit(systemType: systemType, houseLoad: coolingLoad), undersizing: .undersizingLimits ) } } private extension SizingLimits.Limits { static let undersizingLimits = Self( heating: 90, coolingTotal: 90, coolingSensible: 90, coolingLatent: 90 ) static func oversizingLimit( systemType: SystemType, houseLoad: Capacity.Cooling? ) throws -> Self { switch systemType { case let .heatingOnly(type: type): return .init(heating: type.oversizingLimit(), coolingTotal: 115) case let .airToAir(type: _, compressor: compressor, climate: climate): return try .init( heating: 140, coolingTotal: coolingTotalOversizingLimit( houseLoad: houseLoad, compressorType: compressor, climateType: climate ), coolingSensible: nil, coolingLatent: 150 ) } } } private extension SystemType.HeatingOnlyType { func oversizingLimit() -> Int { switch self { case .boiler, .furnace: return 140 case .electric: return 175 } } } private func coolingTotalOversizingLimit( houseLoad: Capacity.Cooling?, compressorType: SystemType.CompressorType, climateType: SystemType.ClimateType ) throws -> Int { switch (compressorType, climateType) { case (.singleSpeed, .mildWinterOrLatentLoad): return 115 case (.multiSpeed, .mildWinterOrLatentLoad): return 120 case (.variableSpeed, .mildWinterOrLatentLoad): return 130 default: guard let houseLoad else { throw HouseLoadError() } let decimal = Double(houseLoad.total + 15000) / Double(houseLoad.total) return Int(round(decimal * 100)) } } public struct HouseLoadError: Error, Equatable { public let message = "House load not supplied." public init() {} }