feat: Initial commit

This commit is contained in:
2025-03-12 16:59:10 -04:00
commit 5c684d0537
28 changed files with 1285 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
public enum BalancePoint {
public struct Request: Codable, Equatable, Sendable {
public let winterDesignTemperature: Int
public let heatLoss: Int
public let heatPumpCapacity: Capacity.HeatPumpHeating
public init(winterDesignTemperature: Int, heatLoss: Int, heatPumpCapacity: Capacity.HeatPumpHeating) {
self.winterDesignTemperature = winterDesignTemperature
self.heatLoss = heatLoss
self.heatPumpCapacity = heatPumpCapacity
}
}
public struct Response: Codable, Equatable, Sendable {
public let balancePointTemperature: Double
public init(balancePointTemperature: Double) {
self.balancePointTemperature = balancePointTemperature
}
}
}

View File

@@ -0,0 +1,12 @@
public struct AdjustmentMultiplier: Codable, Equatable, Sendable {
public let coolingTotal: Double?
public let coolingSensible: Double?
public let heating: Double
public init(coolingTotal: Double? = nil, coolingSensible: Double? = nil, heating: Double) {
self.coolingTotal = coolingTotal
self.coolingSensible = coolingSensible
self.heating = heating
}
}

View File

@@ -0,0 +1,104 @@
// A container / namespace for different capacity containers.
public enum Capacity {
public struct Cooling: Codable, Equatable, Sendable {
public let total: Int
public let sensible: Int
public var latent: Int
public init(
total: Int,
sensible: Int,
latent: Int? = nil
) {
self.total = total
self.sensible = sensible
self.latent = latent ?? total - sensible
}
}
public struct Heating: Codable, Equatable, Sendable {
public let total: Int
public init(total: Int) {
self.total = total
}
}
public struct HeatPumpHeating: Codable, Equatable, Sendable {
public let at47: Int
public let at17: Int
public init(at47: Int, at17: Int) {
self.at47 = at47
self.at17 = at17
}
}
public struct ManufacturersCooling: Codable, Equatable, Sendable {
public let airflow: Int
public let capacity: Container
public let otherCapacity: Container?
public init(
airflow: Int,
capacity: Capacity.ManufacturersCooling.Container,
otherCapacity: Capacity.ManufacturersCooling.Container? = nil
) {
self.airflow = airflow
self.capacity = capacity
self.otherCapacity = otherCapacity
}
public struct Container: Codable, Equatable, Sendable {
public let dryBulbTemperature: Int
public let wetBulbTemperature: Int
public let outdoorTemperature: Int
public let totalCapacity: Int
public let sensibleCapacity: Int
public let adjustmentMultipliers: AdjustmentMultiplier?
public var latentCapacity: Int { totalCapacity - sensibleCapacity }
public init(
dryBulbTemperature: Int,
wetBulbTemperature: Int,
outdoorTemperature: Int,
totalCapacity: Int,
sensibleCapacity: Int,
adjustmentMultipliers: AdjustmentMultiplier? = nil
) {
self.dryBulbTemperature = dryBulbTemperature
self.wetBulbTemperature = wetBulbTemperature
self.outdoorTemperature = outdoorTemperature
self.totalCapacity = totalCapacity
self.sensibleCapacity = sensibleCapacity
self.adjustmentMultipliers = adjustmentMultipliers
}
}
}
public struct ManufacturersContainer: Codable, Equatable, Sendable {
public let wetBulb: Int
public let totalCapacity: Int
public let sensibleCapacity: Int
public let adjustmentMultipliers: AdjustmentMultiplier?
public init(
wetBulb: Int,
totalCapacity: Int,
sensibleCapacity: Int,
adjustmentMultipliers: AdjustmentMultiplier? = nil
) {
self.wetBulb = wetBulb
self.totalCapacity = totalCapacity
self.sensibleCapacity = sensibleCapacity
self.adjustmentMultipliers = adjustmentMultipliers
}
}
}

View File

@@ -0,0 +1,45 @@
import Foundation
public struct DesignInfo: Codable, Equatable, Sendable {
public let summer: Summer
public let winter: Winter
public let elevation: Int
public init(
summer: DesignInfo.Summer = .init(),
winter: DesignInfo.Winter = .init(),
elevation: Int = 0
) {
self.summer = summer
self.winter = winter
self.elevation = elevation
}
}
public extension DesignInfo {
struct Summer: Codable, Equatable, Sendable {
public let outdoorTemperature: Int
public let indoorTemperature: Int
public let indoorHumidity: Int
public init(
outdoorTemperature: Int = 90,
indoorTemperature: Int = 75,
indoorHumidity: Int = 50
) {
self.outdoorTemperature = outdoorTemperature
self.indoorTemperature = indoorTemperature
self.indoorHumidity = indoorHumidity
}
}
struct Winter: Codable, Equatable, Sendable {
public let outdoorTemperature: Int
public init(outdoorTemperature: Int = 5) {
self.outdoorTemperature = outdoorTemperature
}
}
}

View File

@@ -0,0 +1,18 @@
public struct HouseLoad: Codable, Equatable, Sendable {
public let coolingTotal: Int
public let coolingSensible: Int
public let heating: Int
public var coolingLatent: Int { coolingTotal - coolingSensible }
public init(
coolingTotal: Int,
coolingSensible: Int,
heating: Int
) {
self.coolingTotal = coolingTotal
self.coolingSensible = coolingSensible
self.heating = heating
}
}

View File

@@ -0,0 +1,27 @@
public enum SystemType: Codable, Equatable, Sendable {
case airToAir(type: EquipmentType, compressor: CompressorType, climate: ClimateType)
case heatingOnly(type: HeatingOnlyType)
public enum ClimateType: String, CaseIterable, Codable, Equatable, Sendable {
case mildWinterOrLatentLoad
case coldWinterOrNoLatentLoad
}
public enum CompressorType: String, CaseIterable, Codable, Equatable, Sendable {
case singleSpeed
case multiSpeed
case variableSpeed
}
public enum EquipmentType: String, CaseIterable, Codable, Equatable, Sendable {
case airConditioner
case heatPump
}
public enum HeatingOnlyType: String, CaseIterable, Codable, Equatable, Sendable {
case boiler
case electric
case furnace
}
}

View File

@@ -0,0 +1,15 @@
public enum Derating {
public struct Request: Codable, Equatable, Sendable {
public let elevation: Int
public let systemType: SystemType
public init(elevation: Int, systemType: SystemType) {
self.elevation = elevation
self.systemType = systemType
}
}
public typealias Response = AdjustmentMultiplier
}

View File

@@ -0,0 +1,148 @@
public enum Interpolate {
public struct Request: Codable, Equatable, Sendable {
public let designInfo: DesignInfo
public let houseLoad: HouseLoad
public let systemType: SystemType
public let manufacturersCapacity: Capacity.ManufacturersCooling
public init(
designInfo: DesignInfo,
houseLoad: HouseLoad,
systemType: SystemType,
manufacturersCapacity: Capacity.ManufacturersCooling
) {
self.designInfo = designInfo
self.houseLoad = houseLoad
self.systemType = systemType
self.manufacturersCapacity = manufacturersCapacity
}
}
public struct Response: Codable, Equatable, Sendable {
public let failed: Bool
public let failures: [String]?
public let interpolationType: InterpolationType
public let interpolatedCapacity: Capacity.Cooling
public let excessLatent: Int
public let finalCapacityAtDesign: Capacity.Cooling
public let altitudeDerating: AdjustmentMultiplier?
public let capacityAsPercentOfLoad: Capacity.Cooling
public let sizingLimits: SizingLimits.Response
public init(
failures: [String]? = nil,
interpolationType: InterpolationType,
interpolatedCapacity: Capacity.Cooling,
excessLatent: Int,
finalCapacityAtDesign: Capacity.Cooling,
altitudeDerating: AdjustmentMultiplier? = nil,
capacityAsPercentOfLoad: Capacity.Cooling,
sizingLimits: SizingLimits.Response
) {
self.failed = failures != nil ? failures!.count > 0 : false
self.failures = failures
self.interpolationType = interpolationType
self.interpolatedCapacity = interpolatedCapacity
self.excessLatent = excessLatent
self.finalCapacityAtDesign = finalCapacityAtDesign
self.altitudeDerating = altitudeDerating
self.capacityAsPercentOfLoad = capacityAsPercentOfLoad
self.sizingLimits = sizingLimits
}
}
public enum InterpolationType2: Codable, Equatable, Sendable {
case noInterpolation(Capacity.ManufacturersCooling)
case oneWayIndoor(OneWayIndoor)
case oneWayOutdoor(OneWayOutdoor)
}
public struct OneWayIndoor: Codable, Equatable, Sendable {
public let airflow: Int
public let outdoorTemperature: Int
public let capacities: Capacities
public let adjustmentMultipliers: AdjustmentMultiplier?
public init(
airflow: Int,
outdoorTemperature: Int,
capacities: Interpolate.OneWayIndoor.Capacities,
adjustmentMultipliers: AdjustmentMultiplier? = nil
) {
self.airflow = airflow
self.outdoorTemperature = outdoorTemperature
self.capacities = capacities
self.adjustmentMultipliers = adjustmentMultipliers
}
public struct Capacities: Codable, Equatable, Sendable {
public let aboveDewpoint: Capacity.ManufacturersContainer
public let belowDewpoint: Capacity.ManufacturersContainer
public init(aboveDewpoint: Capacity.ManufacturersContainer, belowDewpoint: Capacity.ManufacturersContainer) {
self.aboveDewpoint = aboveDewpoint
self.belowDewpoint = belowDewpoint
}
}
}
public struct OneWayOutdoor: Codable, Equatable, Sendable {
public let airflow: Int
public let wetBulb: Int
public let capacities: Capacities
public let adjustmentMultipliers: AdjustmentMultiplier?
public init(
airflow: Int,
wetBulb: Int,
capacities: Interpolate.OneWayOutdoor.Capacities,
adjustmentMultipliers: AdjustmentMultiplier? = nil
) {
self.airflow = airflow
self.wetBulb = wetBulb
self.capacities = capacities
self.adjustmentMultipliers = adjustmentMultipliers
}
public struct Capacities: Codable, Equatable, Sendable {
public let aboveOutdoor: Capacity
public let belowOutdoor: Capacity
public init(
aboveOutdoor: Interpolate.OneWayOutdoor.Capacities.Capacity,
belowOutdoor: Interpolate.OneWayOutdoor.Capacities.Capacity
) {
self.aboveOutdoor = aboveOutdoor
self.belowOutdoor = belowOutdoor
}
public struct Capacity: Codable, Equatable, Sendable {
public let outdoorTemperature: Int
public let totalCapacity: Int
public let sensibleCapacity: Int
public init(outdoorTemperature: Int, totalCapacity: Int, sensibleCapacity: Int) {
self.outdoorTemperature = outdoorTemperature
self.totalCapacity = totalCapacity
self.sensibleCapacity = sensibleCapacity
}
}
}
}
public enum InterpolationType: String, CaseIterable, Codable, Equatable, Sendable {
case noInterpolation
case oneWayIndoor
case oneWayOutdoor
case twoWay
}
}

View File

@@ -0,0 +1,22 @@
public enum RequiredKW {
public struct Request: Codable, Equatable, Sendable {
public let capacityAtDesign: Int?
public let heatLoss: Int
public init(capacityAtDesign: Int? = nil, heatLoss: Int) {
self.capacityAtDesign = capacityAtDesign
self.heatLoss = heatLoss
}
}
public struct Response: Codable, Equatable, Sendable {
public let requiredKW: Double
public init(requiredKW: Double) {
self.requiredKW = requiredKW
}
}
}

View File

@@ -0,0 +1,44 @@
public enum SizingLimits {
public struct Request: Codable, Equatable, Sendable {
public let systemType: SystemType
public let houseLoad: HouseLoad?
public init(systemType: SystemType, houseLoad: HouseLoad? = nil) {
self.systemType = systemType
self.houseLoad = houseLoad
}
}
public struct Response: Codable, Equatable, Sendable {
public let oversizing: SizingLimits.Limits
public let undersizing: SizingLimits.Limits
public init(oversizing: SizingLimits.Limits, undersizing: SizingLimits.Limits) {
self.oversizing = oversizing
self.undersizing = undersizing
}
}
public struct Limits: Codable, Equatable, Sendable {
public let heating: Int
public let coolingTotal: Int
public let coolingSensible: Int?
public let coolingLatent: Int?
public init(
heating: Int,
coolingTotal: Int,
coolingSensible: Int? = nil,
coolingLatent: Int? = nil
) {
self.heating = heating
self.coolingTotal = coolingTotal
self.coolingSensible = coolingSensible
self.coolingLatent = coolingLatent
}
}
}