Files
swift-estimated-pressures-core/Sources/SharedModels/FlaggedEquipmentMeasurement.swift

191 lines
5.6 KiB
Swift

import Foundation
// TODO: Needs updated for when forms are using `minmal` values.
public struct FlaggedEquipmentMeasurement: Equatable {
public var airflow: Flagged
public var coilPressureDrop: Flagged
public var externalStaticPressure: Flagged
public var filterPressureDrop: Flagged
public var returnPlenumPressure: Flagged
public var supplyPlenumPressure: Flagged
public init(
airflow: Flagged,
coilPressureDrop: Flagged,
externalStaticPressure: Flagged,
filterPressureDrop: Flagged,
returnPlenumPressure: Flagged,
supplyPlenumPressure: Flagged
) {
self.airflow = airflow
self.coilPressureDrop = coilPressureDrop
self.externalStaticPressure = externalStaticPressure
self.filterPressureDrop = filterPressureDrop
self.returnPlenumPressure = returnPlenumPressure
self.supplyPlenumPressure = supplyPlenumPressure
}
public init(
budgets: BudgetedPercentEnvelope,
measurement: EquipmentMeasurement,
ratedPressures: RatedStaticPressures,
tons: CoolingCapacity?
) {
switch measurement {
case let .airHandler(airHandler):
self = .airHandler(
budgets: budgets,
measurement: airHandler,
ratedPressures: ratedPressures,
tons: tons
)
case let .furnaceAndCoil(furnaceAndCoil):
self = .furnaceAndCoil(
budgets: budgets,
measurement: furnaceAndCoil,
ratedPressures: ratedPressures,
tons: tons
)
}
}
public static func airHandler(
budgets: BudgetedPercentEnvelope,
measurement: EquipmentMeasurement.AirHandler,
ratedPressures: RatedStaticPressures,
tons: CoolingCapacity?
) -> Self {
.init(
airflow: checkAirflow(value: measurement.airflow, tons: tons),
coilPressureDrop: .init(
wrappedValue: (measurement.$postCoilPressure.positiveValue - measurement.$postFilterPressure.positiveValue) ?? 0,
.result(.good())
),
externalStaticPressure: checkExternalStaticPressure(
value: measurement.externalStaticPressure,
ratedPressures: ratedPressures
),
filterPressureDrop: .init(
value: measurement.$postFilterPressure.positiveValue - measurement.$returnPlenumPressure.positiveValue,
budget: budgets.filterBudget,
ratedPressures: ratedPressures
),
returnPlenumPressure: .init(
value: measurement.$returnPlenumPressure.positiveValue,
budget: budgets.returnPlenumBudget,
ratedPressures: ratedPressures
),
supplyPlenumPressure: .init(
value: measurement.$supplyPlenumPressure.positiveValue ?? 0,
budget: budgets.supplyPlenumBudget,
ratedPressures: ratedPressures
)
)
}
public static func furnaceAndCoil(
budgets: BudgetedPercentEnvelope,
measurement: EquipmentMeasurement.FurnaceAndCoil,
ratedPressures: RatedStaticPressures,
tons: CoolingCapacity?
) -> Self {
.init(
airflow: checkAirflow(value: measurement.airflow, tons: tons),
coilPressureDrop: .init(
value: measurement.$preCoilPressure.positiveValue - measurement.$supplyPlenumPressure.positiveValue,
budget: budgets.coilBudget,
ratedPressures: ratedPressures
),
externalStaticPressure: checkExternalStaticPressure(
value: measurement.externalStaticPressure,
ratedPressures: ratedPressures
),
filterPressureDrop: .init(
value: measurement.$postFilterPressure.positiveValue - measurement.$returnPlenumPressure.positiveValue,
budget: budgets.filterBudget,
ratedPressures: ratedPressures,
ignoreMinimum: true
),
returnPlenumPressure: .init(
value: measurement.$returnPlenumPressure.positiveValue,
budget: budgets.returnPlenumBudget,
ratedPressures: ratedPressures
),
supplyPlenumPressure: .init(
value: measurement.$supplyPlenumPressure.positiveValue,
budget: budgets.supplyPlenumBudget,
ratedPressures: ratedPressures
)
)
}
}
// MARK: - Helpers
#if DEBUG
extension FlaggedEquipmentMeasurement {
public static func mock(type equipmentType: EquipmentType) -> Self {
.init(
budgets: .init(equipmentType: equipmentType, fanType: .variableSpeed),
measurement: .mock(type: equipmentType),
ratedPressures: .init(),
tons: .default
)
}
}
#endif
fileprivate extension Flagged {
init(
value: Double,
budget: Percentage,
ratedPressures: RatedStaticPressures,
ignoreMinimum: Bool = false
) {
let minimum = ignoreMinimum ? 0 : ratedPressures.minimum * budget.fraction
let maximum = ratedPressures.maximum * budget.fraction
let rated = ratedPressures.rated * budget.fraction
self.init(
wrappedValue: value,
.using(maximum: maximum, minimum: minimum, rated: rated)
)
}
init(
value: Double?,
budget: Percentage,
ratedPressures: RatedStaticPressures,
ignoreMinimum: Bool = false
) {
guard let value else {
self = .error(message: "Value is not set.")
return
}
self.init(
value: value,
budget: budget,
ratedPressures: ratedPressures,
ignoreMinimum: ignoreMinimum
)
}
}
fileprivate func checkExternalStaticPressure(
value: Double,
ratedPressures: RatedStaticPressures
) -> Flagged {
.init(
wrappedValue: value,
.rated(ratedPressures)
)
}
fileprivate func checkAirflow(
value: Double?,
tons: CoolingCapacity?
) -> Flagged {
guard let value, let tons else {
return .init(wrappedValue: value ?? 0, .result(.good()))
}
return .init(wrappedValue: value, .airflow(tons: tons))
}