Files
swift-manual-s/Sources/ManualS/Internal/Derating.swift
2025-03-12 16:59:10 -04:00

102 lines
3.9 KiB
Swift

import Models
extension Derating.Request {
func respond() async throws -> Derating.Response {
switch systemType {
case .airToAir:
return .init(
coolingTotal: totalWetDerating(elevation: elevation),
coolingSensible: sensibleWetDerating(elevation: elevation),
heating: totalDryDerating(elevation: elevation)
)
case let .heatingOnly(type: type):
switch type {
case .boiler, .furnace:
return .init(heating: furnaceDerating(elevation: elevation))
case .electric:
return .init(heating: 1)
}
}
}
}
// swiftlint:disable cyclomatic_complexity
private func furnaceDerating(elevation: Int) -> Double {
guard elevation > 0 else { return 1 }
if (0 ..< 1000).contains(elevation) { return 1 }
if (1000 ..< 2000).contains(elevation) { return 0.96 }
if (2000 ..< 3000).contains(elevation) { return 0.92 }
if (3000 ..< 4000).contains(elevation) { return 0.88 }
if (4000 ..< 5000).contains(elevation) { return 0.84 }
if (5000 ..< 6000).contains(elevation) { return 0.8 }
if (6000 ..< 7000).contains(elevation) { return 0.76 }
if (7000 ..< 8000).contains(elevation) { return 0.72 }
if (8000 ..< 9000).contains(elevation) { return 0.68 }
if (9000 ..< 10000).contains(elevation) { return 0.64 }
if (10000 ..< 11000).contains(elevation) { return 0.6 }
if (11000 ..< 12000).contains(elevation) { return 0.56 }
// greater than 12,000 feet in elevation.
return 0.52
}
private func totalWetDerating(elevation: Int) -> Double {
guard elevation > 0 else { return 1 }
if (0 ..< 1000).contains(elevation) { return 1 }
if (1000 ..< 2000).contains(elevation) { return 0.99 }
if (2000 ..< 3000).contains(elevation) { return 0.98 }
if (3000 ..< 4000).contains(elevation) { return 0.98 }
if (4000 ..< 5000).contains(elevation) { return 0.97 }
if (5000 ..< 6000).contains(elevation) { return 0.96 }
if (6000 ..< 7000).contains(elevation) { return 0.95 }
if (7000 ..< 8000).contains(elevation) { return 0.94 }
if (8000 ..< 9000).contains(elevation) { return 0.94 }
if (9000 ..< 10000).contains(elevation) { return 0.93 }
if (10000 ..< 11000).contains(elevation) { return 0.92 }
if (11000 ..< 12000).contains(elevation) { return 0.91 }
// greater than 12,000 feet in elevation.
return 0.9
}
private func sensibleWetDerating(elevation: Int) -> Double {
guard elevation > 0 else { return 1 }
if (0 ..< 1000).contains(elevation) { return 1 }
if (1000 ..< 2000).contains(elevation) { return 0.97 }
if (2000 ..< 3000).contains(elevation) { return 0.94 }
if (3000 ..< 4000).contains(elevation) { return 0.91 }
if (4000 ..< 5000).contains(elevation) { return 0.88 }
if (5000 ..< 6000).contains(elevation) { return 0.85 }
if (6000 ..< 7000).contains(elevation) { return 0.82 }
if (7000 ..< 8000).contains(elevation) { return 0.8 }
if (8000 ..< 9000).contains(elevation) { return 0.77 }
if (9000 ..< 10000).contains(elevation) { return 0.74 }
if (10000 ..< 11000).contains(elevation) { return 0.71 }
if (11000 ..< 12000).contains(elevation) { return 0.68 }
// greater than 12,000 feet in elevation.
return 0.65
}
private func totalDryDerating(elevation: Int) -> Double {
guard elevation > 0 else { return 1 }
if (0 ..< 1000).contains(elevation) { return 1 }
if (1000 ..< 2000).contains(elevation) { return 0.98 }
if (2000 ..< 3000).contains(elevation) { return 0.97 }
if (3000 ..< 4000).contains(elevation) { return 0.95 }
if (4000 ..< 5000).contains(elevation) { return 0.94 }
if (5000 ..< 6000).contains(elevation) { return 0.92 }
if (6000 ..< 7000).contains(elevation) { return 0.9 }
if (7000 ..< 8000).contains(elevation) { return 0.89 }
if (8000 ..< 9000).contains(elevation) { return 0.87 }
if (9000 ..< 10000).contains(elevation) { return 0.86 }
if (10000 ..< 11000).contains(elevation) { return 0.84 }
if (11000 ..< 12000).contains(elevation) { return 0.82 }
// greater than 12,000 feet in elevation.
return 0.81
}
// swiftlint:enable cyclomatic_complexity