import Foundation import Logging import OrderedCollections import Routes public extension RoomPressure.Request { static let pascalToIWCMultiplier = 0.004014 static let targetVelocity = 400.0 static let maxVelocity = 600.0 static let minGrilleFreeArea = 0.7 static let standardDuctSizes = OrderedSet([4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20]) static let standardGrilleHeights = OrderedSet([4, 6, 8, 10, 12, 14, 20]) static let standardGrilleSizes = [ 4: OrderedSet([8, 10, 12, 14]), 6: OrderedSet([8, 10, 12, 14]), 8: OrderedSet([10, 12, 14]), 10: OrderedSet([10]), 12: OrderedSet([12]), 14: OrderedSet([14]) ] // OrderedSet([ // (width: 8, height: 4), // (width: 10, height: 4), // (width: 12, height: 4), // (width: 14, height: 4), // (width: 8, height: 6), // (width: 10, height: 6), // (width: 12, height: 6), // (width: 14, height: 6), // (width: 10, height: 8), // (width: 12, height: 8), // (width: 14, height: 8), // (width: 10, height: 10), // (width: 12, height: 12), // (width: 14, height: 14) // ]) func respond(logger: Logger) async throws -> RoomPressure.Response { fatalError() } private func getStandardDuctSize(for calculatedSize: Int) -> Int { Self.standardDuctSizes.sorted() .first { $0 >= calculatedSize } ?? 20 } private func getStandardGrilleSize(requiredArea: Double, selectedHeight: Int) throws -> (width: Int, height: Int) { guard let availableSizes = Self.standardGrilleSizes[selectedHeight] else { throw RoomPressureError.invalidPreferredHeight } if let width = availableSizes.first(where: { Double($0) * Double(selectedHeight) * Self.minGrilleFreeArea >= (requiredArea / Self.minGrilleFreeArea) }) { return (width, selectedHeight) } // If no width matches return largest for the selectedHeight. if let largestSize = availableSizes.last { return (largestSize, selectedHeight) } return (14, selectedHeight) } // Calculate door leakage area in sq. ft. private func calculateDoorLeakageArea(doorWidth: Double, doorHeight: Double, doorUndercut: Double) -> Double { let doorLeakageArea = (doorWidth * doorUndercut) / 144.0 let doorPerimiterLeakage = ((2 * doorHeight + doorWidth) * 0.125) / 144.0 return doorLeakageArea + doorPerimiterLeakage } enum RoomPressureError: Error { case invalidPreferredHeight } }