diff --git a/Sources/ManualDClient/Live.swift b/Sources/ManualDClient/Live.swift index 9088598..5cce168 100644 --- a/Sources/ManualDClient/Live.swift +++ b/Sources/ManualDClient/Live.swift @@ -13,7 +13,7 @@ extension ManualDClient: DependencyKey { let finalSize = try roundSize(ductulatorSize) let flexSize = try flexSize(request) return .init( - ductulatorSize: ductulatorSize, + calculatedSize: ductulatorSize, finalSize: finalSize, flexSize: flexSize, velocity: velocity(cfm: request.designCFM, roundSize: finalSize) @@ -30,13 +30,13 @@ extension ManualDClient: DependencyKey { let frictionRate = availableStaticPressure * 100.0 / Double(request.totalEffectiveLength) return .init(availableStaticPressure: availableStaticPressure, frictionRate: frictionRate) }, - totalEffectiveLength: { request in + totalEquivalentLength: { request in let trunkLengths = request.trunkLengths.reduce(0) { $0 + $1 } let runoutLengths = request.runoutLengths.reduce(0) { $0 + $1 } let groupLengths = request.effectiveLengthGroups.totalEffectiveLength return trunkLengths + runoutLengths + groupLengths }, - equivalentRectangularDuct: { request in + rectangularSize: { request in let width = (Double.pi * (pow(Double(request.roundSize) / 2.0, 2.0))) / Double(request.height) return .init(height: request.height, width: Int(width.rounded(.toNearestOrEven))) } diff --git a/Sources/ManualDClient/ManualDClient.swift b/Sources/ManualDClient/ManualDClient.swift index 79ef91c..f03813c 100644 --- a/Sources/ManualDClient/ManualDClient.swift +++ b/Sources/ManualDClient/ManualDClient.swift @@ -10,163 +10,16 @@ extension DependencyValues { } } +/// Performs manual-d duct sizing calculations. +/// +/// @DependencyClient public struct ManualDClient: Sendable { public var ductSize: @Sendable (DuctSizeRequest) async throws -> DuctSizeResponse public var frictionRate: @Sendable (FrictionRateRequest) async throws -> FrictionRateResponse - public var totalEffectiveLength: @Sendable (TotalEffectiveLengthRequest) async throws -> Int - public var equivalentRectangularDuct: - @Sendable (EquivalentRectangularDuctRequest) async throws -> EquivalentRectangularDuctResponse - - // TODO: add (Project.ID) async throws -> ProjectResponse - - // TODO: Move to helpers. - // public func calculateSizes( - // rooms: [Room], - // trunks: [DuctSizing.TrunkSize], - // equipmentInfo: EquipmentInfo, - // maxSupplyLength: EffectiveLength, - // maxReturnLength: EffectiveLength, - // designFrictionRate: Double, - // projectSHR: Double, - // logger: Logger? = nil - // ) async throws -> ProjectResponse { - // try await .init( - // rooms: calculateRoomSizes( - // rooms: rooms, - // equipmentInfo: equipmentInfo, - // maxSupplyLength: maxSupplyLength, - // maxReturnLength: maxReturnLength, - // designFrictionRate: designFrictionRate, - // projectSHR: projectSHR - // ), - // trunks: calculateTrunkSizes( - // rooms: rooms, - // trunks: trunks, - // equipmentInfo: equipmentInfo, - // maxSupplyLength: maxSupplyLength, - // maxReturnLength: maxReturnLength, - // designFrictionRate: designFrictionRate, - // projectSHR: projectSHR - // ) - // ) - // } - // - // func calculateRoomSizes( - // rooms: [Room], - // equipmentInfo: EquipmentInfo, - // maxSupplyLength: EffectiveLength, - // maxReturnLength: EffectiveLength, - // designFrictionRate: Double, - // projectSHR: Double, - // logger: Logger? = nil - // ) async throws -> [DuctSizing.RoomContainer] { - // - // var retval: [DuctSizing.RoomContainer] = [] - // let totalHeatingLoad = rooms.totalHeatingLoad - // let totalCoolingSensible = rooms.totalCoolingSensible(shr: projectSHR) - // - // for room in rooms { - // let heatingLoad = room.heatingLoadPerRegister - // let coolingLoad = room.coolingSensiblePerRegister(projectSHR: projectSHR) - // let heatingPercent = heatingLoad / totalHeatingLoad - // let coolingPercent = coolingLoad / totalCoolingSensible - // let heatingCFM = heatingPercent * Double(equipmentInfo.heatingCFM) - // let coolingCFM = coolingPercent * Double(equipmentInfo.coolingCFM) - // let designCFM = DuctSizing.DesignCFM(heating: heatingCFM, cooling: coolingCFM) - // let sizes = try await self.ductSize( - // .init(designCFM: Int(designCFM.value), frictionRate: designFrictionRate) - // ) - // - // for n in 1...room.registerCount { - // - // var rectangularWidth: Int? = nil - // let rectangularSize = room.rectangularSizes? - // .first(where: { $0.register == nil || $0.register == n }) - // - // if let rectangularSize { - // let response = try await self.equivalentRectangularDuct( - // .init(round: sizes.finalSize, height: rectangularSize.height) - // ) - // rectangularWidth = response.width - // } - // - // retval.append( - // .init( - // roomID: room.id, - // roomName: "\(room.name)-\(n)", - // roomRegister: n, - // heatingLoad: heatingLoad, - // coolingLoad: coolingLoad, - // heatingCFM: heatingCFM, - // coolingCFM: coolingCFM, - // designCFM: designCFM, - // roundSize: sizes.ductulatorSize, - // finalSize: sizes.finalSize, - // velocity: sizes.velocity, - // flexSize: sizes.flexSize, - // rectangularSize: rectangularSize, - // rectangularWidth: rectangularWidth - // ) - // ) - // } - // } - // - // return retval - // } - // - // func calculateTrunkSizes( - // rooms: [Room], - // trunks: [DuctSizing.TrunkSize], - // equipmentInfo: EquipmentInfo, - // maxSupplyLength: EffectiveLength, - // maxReturnLength: EffectiveLength, - // designFrictionRate: Double, - // projectSHR: Double, - // logger: Logger? = nil - // ) async throws -> [DuctSizing.TrunkContainer] { - // - // var retval = [DuctSizing.TrunkContainer]() - // let totalHeatingLoad = rooms.totalHeatingLoad - // let totalCoolingSensible = rooms.totalCoolingSensible(shr: projectSHR) - // - // for trunk in trunks { - // let heatingLoad = trunk.totalHeatingLoad - // let coolingLoad = trunk.totalCoolingSensible(projectSHR: projectSHR) - // let heatingPercent = heatingLoad / totalHeatingLoad - // let coolingPercent = coolingLoad / totalCoolingSensible - // let heatingCFM = heatingPercent * Double(equipmentInfo.heatingCFM) - // let coolingCFM = coolingPercent * Double(equipmentInfo.coolingCFM) - // let designCFM = DuctSizing.DesignCFM(heating: heatingCFM, cooling: coolingCFM) - // let sizes = try await self.ductSize( - // .init(designCFM: Int(designCFM.value), frictionRate: designFrictionRate) - // ) - // var width: Int? = nil - // if let height = trunk.height { - // let rectangularSize = try await self.equivalentRectangularDuct( - // .init(round: sizes.finalSize, height: height) - // ) - // width = rectangularSize.width - // } - // - // retval.append( - // .init( - // trunk: trunk, - // ductSize: .init( - // designCFM: designCFM, - // roundSize: sizes.ductulatorSize, - // finalSize: sizes.finalSize, - // velocity: sizes.velocity, - // flexSize: sizes.flexSize, - // height: trunk.height, - // width: width - // ) - // ) - // ) - // } - // - // return retval - // } + public var totalEquivalentLength: @Sendable (TotalEquivalentLengthRequest) async throws -> Int + public var rectangularSize: + @Sendable (RectangularSizeRequest) async throws -> RectangularSizeResponse } @@ -174,25 +27,6 @@ extension ManualDClient: TestDependencyKey { public static let testValue = Self() } -// MARK: Project Response -// extension ManualDClient { -// -// public struct ProjectResponse: Codable, Equatable, Sendable { -// public let rooms: [DuctSizing.RoomContainer] -// public let trunks: [DuctSizing.TrunkContainer] -// -// public init( -// rooms: [DuctSizing.RoomContainer], -// trunks: [DuctSizing.TrunkContainer] -// ) { -// self.rooms = rooms -// self.trunks = trunks -// } -// } -// -// } - -// MARK: Duct Size extension ManualDClient { public struct DuctSizeRequest: Codable, Equatable, Sendable { @@ -210,27 +44,24 @@ extension ManualDClient { public struct DuctSizeResponse: Codable, Equatable, Sendable { - public let ductulatorSize: Double + public let calculatedSize: Double public let finalSize: Int public let flexSize: Int public let velocity: Int public init( - ductulatorSize: Double, + calculatedSize: Double, finalSize: Int, flexSize: Int, velocity: Int ) { - self.ductulatorSize = ductulatorSize + self.calculatedSize = calculatedSize self.finalSize = finalSize self.flexSize = flexSize self.velocity = velocity } } -} -// MARK: - Friction Rate -extension ManualDClient { public struct FrictionRateRequest: Codable, Equatable, Sendable { public let externalStaticPressure: Double @@ -258,11 +89,8 @@ extension ManualDClient { self.frictionRate = frictionRate } } -} -// MARK: Total Effective Length -extension ManualDClient { - public struct TotalEffectiveLengthRequest: Codable, Equatable, Sendable { + public struct TotalEquivalentLengthRequest: Codable, Equatable, Sendable { public let trunkLengths: [Int] public let runoutLengths: [Int] @@ -278,11 +106,8 @@ extension ManualDClient { self.effectiveLengthGroups = effectiveLengthGroups } } -} -// MARK: Equivalent Rectangular Duct -extension ManualDClient { - public struct EquivalentRectangularDuctRequest: Codable, Equatable, Sendable { + public struct RectangularSizeRequest: Codable, Equatable, Sendable { public let roundSize: Int public let height: Int @@ -292,7 +117,7 @@ extension ManualDClient { } } - public struct EquivalentRectangularDuctResponse: Codable, Equatable, Sendable { + public struct RectangularSizeResponse: Codable, Equatable, Sendable { public let height: Int public let width: Int diff --git a/Sources/ManualDCore/DuctSizes.swift b/Sources/ManualDCore/DuctSizes.swift index 94c932c..e4b1c8a 100644 --- a/Sources/ManualDCore/DuctSizes.swift +++ b/Sources/ManualDCore/DuctSizes.swift @@ -105,9 +105,6 @@ extension DuctSizes { } } } -} - -extension DuctSizes { // Represents the database model that the duct sizes have been calculated // for. diff --git a/Sources/ProjectClient/Internal/ManualDClient+calculateDuctSizes.swift b/Sources/ProjectClient/Internal/ManualDClient+calculateDuctSizes.swift index effc1e0..4b54d2c 100644 --- a/Sources/ProjectClient/Internal/ManualDClient+calculateDuctSizes.swift +++ b/Sources/ProjectClient/Internal/ManualDClient+calculateDuctSizes.swift @@ -62,7 +62,7 @@ extension ManualDClient { .first(where: { $0.register == nil || $0.register == n }) if let rectangularSize { - let response = try await self.equivalentRectangularDuct( + let response = try await self.rectangularSize( .init(round: sizes.finalSize, height: rectangularSize.height) ) rectangularWidth = response.width @@ -115,7 +115,7 @@ extension ManualDClient { ) var width: Int? = nil if let height = trunk.height { - let rectangularSize = try await self.equivalentRectangularDuct( + let rectangularSize = try await self.rectangularSize( .init(round: sizes.finalSize, height: height) ) width = rectangularSize.width @@ -149,7 +149,7 @@ extension DuctSizes.SizeContainer { self.init( rectangularID: nil, designCFM: designCFM, - roundSize: sizes.ductulatorSize, + roundSize: sizes.calculatedSize, finalSize: sizes.finalSize, velocity: sizes.velocity, flexSize: sizes.flexSize, @@ -167,7 +167,7 @@ extension DuctSizes.SizeContainer { self.init( rectangularID: rectangularSize?.id, designCFM: designCFM, - roundSize: sizes.ductulatorSize, + roundSize: sizes.calculatedSize, finalSize: sizes.finalSize, velocity: sizes.velocity, flexSize: sizes.flexSize, diff --git a/Tests/ManualDClientTests/ManualDClientTests.swift b/Tests/ManualDClientTests/ManualDClientTests.swift index 8af9ae5..b2d02d4 100644 --- a/Tests/ManualDClientTests/ManualDClientTests.swift +++ b/Tests/ManualDClientTests/ManualDClientTests.swift @@ -27,7 +27,7 @@ struct ManualDClientTests { let response = try await manualD.ductSize( .init(designCFM: 88, frictionRate: 0.06) ) - #expect(numberFormatter.string(for: response.ductulatorSize) == "6.07") + #expect(numberFormatter.string(for: response.calculatedSize) == "6.07") #expect(response.finalSize == 7) #expect(response.flexSize == 7) #expect(response.velocity == 329) @@ -61,7 +61,7 @@ struct ManualDClientTests { @Test func totalEffectiveLength() async throws { - let response = try await manualD.totalEffectiveLength( + let response = try await manualD.totalEquivalentLength( .init( trunkLengths: [25], runoutLengths: [10], @@ -79,7 +79,7 @@ struct ManualDClientTests { @Test func equivalentRectangularDuct() async throws { - let response = try await manualD.equivalentRectangularDuct(.init(round: 7, height: 8)) + let response = try await manualD.rectangularSize(.init(round: 7, height: 8)) #expect(response.height == 8) #expect(response.width == 5) }