feat: Initial commit
This commit is contained in:
225
Sources/SharedModels/FlaggedEquipmentMeasurement.swift
Normal file
225
Sources/SharedModels/FlaggedEquipmentMeasurement.swift
Normal file
@@ -0,0 +1,225 @@
|
||||
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: - Key
|
||||
extension FlaggedEquipmentMeasurement {
|
||||
// NOTE: These need to be kept in display order.
|
||||
public enum Key: Equatable, CaseIterable {
|
||||
case returnPlenum
|
||||
case filterDrop
|
||||
case coilDrop
|
||||
case supplyPlenum
|
||||
case staticPressure
|
||||
case airflow
|
||||
|
||||
public var title: String {
|
||||
switch self {
|
||||
case .returnPlenum:
|
||||
return "Return Plenum"
|
||||
case .filterDrop:
|
||||
return "Filter Pressure Drop"
|
||||
case .coilDrop:
|
||||
return "Coil Pressure Drop"
|
||||
case .supplyPlenum:
|
||||
return "Supply Plenum"
|
||||
case .staticPressure:
|
||||
return "External Static Pressure"
|
||||
case .airflow:
|
||||
return "System Airflow"
|
||||
}
|
||||
}
|
||||
|
||||
public var flaggedKeyPath: KeyPath<FlaggedEquipmentMeasurement, Flagged> {
|
||||
switch self {
|
||||
case .returnPlenum:
|
||||
return \.returnPlenumPressure
|
||||
case .filterDrop:
|
||||
return \.filterPressureDrop
|
||||
case .coilDrop:
|
||||
return \.coilPressureDrop
|
||||
case .supplyPlenum:
|
||||
return \.supplyPlenumPressure
|
||||
case .staticPressure:
|
||||
return \.externalStaticPressure
|
||||
case .airflow:
|
||||
return \.airflow
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
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))
|
||||
}
|
||||
Reference in New Issue
Block a user