feat: Begins room pressure calculations

This commit is contained in:
2025-02-28 22:45:59 -05:00
parent c1aa2a8ad1
commit af24ef3971
6 changed files with 132 additions and 6 deletions

View File

@@ -25,6 +25,8 @@ extension ApiController: DependencyKey {
@Dependency(\.psychrometricClient) var psychrometricClient
return .init(json: { route, logger in
logger.debug("API Route: \(route)")
switch route {
case let .calculateDehumidifierSize(request):
logger.debug("Calculating dehumidifier size: \(request)")
@@ -37,6 +39,11 @@ extension ApiController: DependencyKey {
case let .calculateMoldRisk(request):
logger.debug("Calculating mold risk: \(request)")
return try await psychrometricClient.respond(request, logger)
case let .calculateRoomPressure(request):
logger.debug("Calculating room pressure: \(request)")
// FIX:
fatalError()
}
})
}

View File

@@ -0,0 +1,76 @@
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
}
}