feat: Adds thermal balance point, still need to implement economic balance point.

This commit is contained in:
2025-03-04 12:46:44 -05:00
parent d22beb9375
commit 6c31a9db09
11 changed files with 362 additions and 40 deletions

View File

@@ -1,3 +1,5 @@
import CoreModels
public enum HeatingBalancePoint {
public static let description: String = """
@@ -17,21 +19,24 @@ public enum HeatingBalancePoint {
public let systemSize: Double
public let capacityAt47: Double?
public let capacityAt17: Double?
public let heatingDesignTemperature: Double
public let heatingDesignTemperature: Double?
public let buildingHeatLoss: HeatingBalancePoint.HeatLoss
public let climateZone: ClimateZone?
public init(
systemSize: Double,
capacityAt47: Double? = nil,
capacityAt17: Double? = nil,
heatingDesignTemperature: Double,
buildingHeatLoss: HeatingBalancePoint.HeatLoss
heatingDesignTemperature: Double? = nil,
buildingHeatLoss: HeatingBalancePoint.HeatLoss,
climateZone: ClimateZone? = nil
) {
self.systemSize = systemSize
self.capacityAt47 = capacityAt47
self.capacityAt17 = capacityAt17
self.heatingDesignTemperature = heatingDesignTemperature
self.buildingHeatLoss = buildingHeatLoss
self.climateZone = climateZone
}
}
}
@@ -44,11 +49,27 @@ public enum HeatingBalancePoint {
public let capacityAt47: Double
public let capacityAt17: Double
public let balancePointTemperature: Double
public let heatLoss: Double
public let heatLossMode: HeatLoss.Mode
public let heatingDesignTemperature: Double
public let warnings: [String]
public init(capacityAt47: Double, capacityAt17: Double, balancePointTemperature: Double) {
public init(
capacityAt47: Double,
capacityAt17: Double,
balancePointTemperature: Double,
heatLoss: Double,
heatLossMode: HeatLoss.Mode,
heatingDesignTemperature: Double,
warnings: [String]
) {
self.capacityAt47 = capacityAt47
self.capacityAt17 = capacityAt17
self.balancePointTemperature = balancePointTemperature
self.heatLoss = heatLoss
self.heatLossMode = heatLossMode
self.heatingDesignTemperature = heatingDesignTemperature
self.warnings = warnings
}
}
}
@@ -62,5 +83,36 @@ public enum HeatingBalancePoint {
case known(btu: Double)
case estimated(squareFeet: Double)
public var mode: Mode {
switch self {
case .known: return .known
case .estimated: return .estimated
}
}
}
}
#if DEBUG
public extension HeatingBalancePoint.Response {
static func mock(mode: HeatingBalancePoint.Mode) -> Self {
switch mode {
case .economic:
fatalError()
case .thermal:
return .thermal(.init(
capacityAt47: 24600,
capacityAt17: 15100,
balancePointTemperature: 38.5,
heatLoss: 49667,
heatLossMode: .known,
heatingDesignTemperature: 5,
warnings: [
"Design temperature is estimated based on climate zone."
]
))
}
}
}
#endif

View File

@@ -286,7 +286,10 @@ public extension SiteRoute {
}
public enum HeatingBalancePoint: Equatable, Sendable {
case index(mode: Routes.HeatingBalancePoint.Mode? = nil, heatLossMode: Routes.HeatingBalancePoint.HeatLoss.Mode? = nil)
case index(
mode: Routes.HeatingBalancePoint.Mode? = nil,
heatLossMode: Routes.HeatingBalancePoint.HeatLoss.Mode? = nil
)
case heatLossFields(mode: Routes.HeatingBalancePoint.HeatLoss.Mode)
case submit(Routes.HeatingBalancePoint.Request)
@@ -317,15 +320,16 @@ public extension SiteRoute {
OneOf {
FormData {
Field("systemSize") { Double.parser() }
Optionally { Field("capcityAt47") { Double.parser() } }
Optionally { Field("capcityAt17") { Double.parser() } }
Field("heatingDesignTemperature") { Double.parser() }
Optionally { Field("capacityAt47") { Double.parser() } }
Optionally { Field("capacityAt17") { Double.parser() } }
Optionally { Field("heatingDesignTemperature") { Double.parser() } }
OneOf {
Field("knownHeatLoss") { Double.parser() }
.map(.case(Routes.HeatingBalancePoint.HeatLoss.known))
Field("simplifiedHeatLoss") { Double.parser() }
.map(.case(Routes.HeatingBalancePoint.HeatLoss.estimated))
}
Optionally { Field("climateZone") { ClimateZone.parser() } }
}
.map(.memberwise(Routes.HeatingBalancePoint.Request.Thermal.init))
.map(.case(Routes.HeatingBalancePoint.Request.thermal))

View File

@@ -1,17 +1,10 @@
import Foundation
private let numberFormatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.maximumFractionDigits = 2
return formatter
}()
public extension String.StringInterpolation {
mutating func appendInterpolation(double: Double, fractionDigits: Int = 2) {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.maximumFractionDigits = fractionDigits
appendInterpolation(numberFormatter.string(from: NSNumber(value: double))!)
appendInterpolation(formatter.string(from: NSNumber(value: double))!)
}
}