feat: Begins more work on async integration
This commit is contained in:
7
.editorconfig
Normal file
7
.editorconfig
Normal file
@@ -0,0 +1,7 @@
|
||||
root = true
|
||||
|
||||
[*.swift]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
tab_width = 2
|
||||
trim_trailing_whitespace = true
|
||||
1
.swiftformat
Normal file
1
.swiftformat
Normal file
@@ -0,0 +1 @@
|
||||
--self init-only
|
||||
@@ -36,7 +36,7 @@ public struct Client {
|
||||
}
|
||||
|
||||
public enum SensorPublishRequest {
|
||||
case mixed(State.Sensors.TemperatureHumiditySensor<State.Sensors.Mixed>)
|
||||
case mixed(State.Sensors.TemperatureHumiditySensor<State.Sensors.MixedAir>)
|
||||
case postCoil(State.Sensors.TemperatureHumiditySensor<State.Sensors.PostCoil>)
|
||||
case `return`(State.Sensors.TemperatureHumiditySensor<State.Sensors.Return>)
|
||||
case supply(State.Sensors.TemperatureHumiditySensor<State.Sensors.Supply>)
|
||||
|
||||
@@ -61,7 +61,7 @@ public class AsyncClient {
|
||||
tlsConfiguration: nil,
|
||||
webSocketURLPath: nil
|
||||
)
|
||||
self.client = .init(
|
||||
self.client = MQTTClient(
|
||||
host: envVars.host,
|
||||
identifier: envVars.identifier,
|
||||
eventLoopGroupProvider: .shared(Self.eventLoopGroup),
|
||||
|
||||
@@ -24,13 +24,13 @@ public final class State {
|
||||
|
||||
public struct Sensors: Equatable {
|
||||
|
||||
public var mixedAirSensor: TemperatureHumiditySensor<Mixed>
|
||||
public var mixedAirSensor: TemperatureHumiditySensor<MixedAir>
|
||||
public var postCoilSensor: TemperatureHumiditySensor<PostCoil>
|
||||
public var returnAirSensor: TemperatureHumiditySensor<Return>
|
||||
public var supplyAirSensor: TemperatureHumiditySensor<Supply>
|
||||
|
||||
public init(
|
||||
mixedAirSensor: TemperatureHumiditySensor<Mixed> = .init(),
|
||||
mixedAirSensor: TemperatureHumiditySensor<MixedAir> = .init(),
|
||||
postCoilSensor: TemperatureHumiditySensor<PostCoil> = .init(),
|
||||
returnAirSensor: TemperatureHumiditySensor<Return> = .init(),
|
||||
supplyAirSensor: TemperatureHumiditySensor<Supply> = .init()
|
||||
@@ -97,7 +97,7 @@ extension State.Sensors {
|
||||
}
|
||||
|
||||
// MARK: - Temperature / Humidity Sensor Location Namespaces
|
||||
public enum Mixed { }
|
||||
public enum MixedAir { }
|
||||
public enum PostCoil { }
|
||||
public enum Return { }
|
||||
public enum Supply { }
|
||||
|
||||
65
Sources/Models/TemperatureAndHumiditySensor.swift
Normal file
65
Sources/Models/TemperatureAndHumiditySensor.swift
Normal file
@@ -0,0 +1,65 @@
|
||||
import Psychrometrics
|
||||
|
||||
public struct TemperatureAndHumiditySensor: Equatable, Identifiable {
|
||||
/// The identifier of the sensor, same as the location.
|
||||
public var id: Location { location }
|
||||
|
||||
public let altitude: Length
|
||||
|
||||
/// The location identifier of the sensor
|
||||
public let location: Location
|
||||
|
||||
/// The current temperature value of the sensor.
|
||||
@TrackedChanges
|
||||
public var temperature: Temperature?
|
||||
|
||||
/// The current humidity value of the sensor.
|
||||
@TrackedChanges
|
||||
public var humidity: RelativeHumidity?
|
||||
|
||||
/// The psychrometric units of the sensor.
|
||||
public let units: PsychrometricEnvironment.Units
|
||||
|
||||
public init(
|
||||
location: Location,
|
||||
altitude: Length = .feet(800.0),
|
||||
temperature: Temperature? = nil,
|
||||
humidity: RelativeHumidity? = nil,
|
||||
needsProcessed: Bool = false,
|
||||
units: PsychrometricEnvironment.Units = .imperial
|
||||
) {
|
||||
self.altitude = altitude
|
||||
self.location = location
|
||||
self._temperature = .init(wrappedValue: temperature, needsProcessed: needsProcessed)
|
||||
self._humidity = .init(wrappedValue: humidity, needsProcessed: needsProcessed)
|
||||
self.units = units
|
||||
}
|
||||
|
||||
/// The calculated dew-point temperature of the sensor.
|
||||
public var dewPoint: DewPoint? {
|
||||
guard let temperature = temperature,
|
||||
let humidity = humidity,
|
||||
!temperature.rawValue.isNaN,
|
||||
!humidity.rawValue.isNaN
|
||||
else { return nil }
|
||||
return .init(dryBulb: temperature, humidity: humidity, units: units)
|
||||
}
|
||||
|
||||
/// Check whether any of the sensor values have changed and need processed.
|
||||
public var needsProcessed: Bool {
|
||||
get { $temperature.needsProcessed || $humidity.needsProcessed }
|
||||
set {
|
||||
$temperature.needsProcessed = newValue
|
||||
$humidity.needsProcessed = newValue
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the different locations of a temperature and humidity sensor, which can
|
||||
/// be used to derive the topic to both listen and publish new values to.
|
||||
public enum Location: String, Equatable, Hashable {
|
||||
case mixedAir = "mixed-air"
|
||||
case postCoil = "post-coil"
|
||||
case `return`
|
||||
case supply
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
/// A container for all the different topics that are needed by the application.
|
||||
/// A container for all the different MQTT topics that are needed by the application.
|
||||
public struct Topics: Codable, Equatable {
|
||||
|
||||
/// The command topics the application can publish to.
|
||||
@@ -36,13 +36,13 @@ public struct Topics: Codable, Equatable {
|
||||
/// Represents the sensor topics.
|
||||
public struct Sensors: Codable, Equatable {
|
||||
|
||||
public var mixedAirSensor: TemperatureAndHumiditySensor<State.Sensors.Mixed>
|
||||
public var mixedAirSensor: TemperatureAndHumiditySensor<State.Sensors.MixedAir>
|
||||
public var postCoilSensor: TemperatureAndHumiditySensor<State.Sensors.PostCoil>
|
||||
public var returnAirSensor: TemperatureAndHumiditySensor<State.Sensors.Return>
|
||||
public var supplyAirSensor: TemperatureAndHumiditySensor<State.Sensors.Supply>
|
||||
|
||||
public init(
|
||||
mixedAirSensor: TemperatureAndHumiditySensor<State.Sensors.Mixed> = .default(location: "mixed=air"),
|
||||
mixedAirSensor: TemperatureAndHumiditySensor<State.Sensors.MixedAir> = .default(location: "mixed-air"),
|
||||
postCoilSensor: TemperatureAndHumiditySensor<State.Sensors.PostCoil> = .default(location: "post-coil"),
|
||||
returnAirSensor: TemperatureAndHumiditySensor<State.Sensors.Return> = .default(location: "return"),
|
||||
supplyAirSensor: TemperatureAndHumiditySensor<State.Sensors.Supply> = .default(location: "supply")
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
|
||||
/// A property wrapper that tracks changes of a property.
|
||||
///
|
||||
/// This allows values to only publish changes if they have changed since the
|
||||
/// last time they were recieved.
|
||||
@propertyWrapper
|
||||
public struct TrackedChanges<Value> {
|
||||
|
||||
/// The current tracking state.
|
||||
private var tracking: TrackingState
|
||||
|
||||
/// The current wrapped value.
|
||||
private var value: Value
|
||||
|
||||
/// Used to check if a new value is equal to an old value.
|
||||
private var isEqual: (Value, Value) -> Bool
|
||||
|
||||
/// Access to the underlying property that we are wrapping.
|
||||
public var wrappedValue: Value {
|
||||
get { value }
|
||||
set {
|
||||
@@ -17,6 +26,12 @@ public struct TrackedChanges<Value> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new property that tracks it's changes.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - wrappedValue: The value that we are wrapping.
|
||||
/// - needsProcessed: Whether this value needs processed (default = false).
|
||||
/// - isEqual: Method to compare old values against new values.
|
||||
public init(
|
||||
wrappedValue: Value,
|
||||
needsProcessed: Bool = false,
|
||||
@@ -27,11 +42,17 @@ public struct TrackedChanges<Value> {
|
||||
self.isEqual = isEqual
|
||||
}
|
||||
|
||||
/// Represents whether a wrapped value has changed and needs processed or not.
|
||||
enum TrackingState {
|
||||
|
||||
/// The state when nothing has changed and we've already processed the current value.
|
||||
case hasProcessed
|
||||
|
||||
/// The state when the value has changed and has not been processed yet.
|
||||
case needsProcessed
|
||||
}
|
||||
|
||||
/// Check whether the value needs processed.
|
||||
public var needsProcessed: Bool {
|
||||
get { tracking == .needsProcessed }
|
||||
set {
|
||||
@@ -55,6 +76,11 @@ extension TrackedChanges: Equatable where Value: Equatable {
|
||||
&& lhs.needsProcessed == rhs.needsProcessed
|
||||
}
|
||||
|
||||
/// Create a new property that tracks it's changes, using the default equality check.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - wrappedValue: The value that we are wrapping.
|
||||
/// - needsProcessed: Whether this value needs processed (default = false).
|
||||
public init(
|
||||
wrappedValue: Value,
|
||||
needsProcessed: Bool = false
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"name": "xcode build server",
|
||||
"version": "0.2",
|
||||
"bspVersion": "2.0",
|
||||
"languages": [
|
||||
"c",
|
||||
"cpp",
|
||||
"objective-c",
|
||||
"objective-cpp",
|
||||
"swift"
|
||||
],
|
||||
"argv": [
|
||||
"/opt/homebrew/bin/xcode-build-server"
|
||||
],
|
||||
"workspace": "/Volumes/michael/Repos/github.com/hvac-iot/swift-mqtt-dewPoint/.swiftpm/xcode/package.xcworkspace",
|
||||
"build_root": "/Volumes/michael/Repos/github.com",
|
||||
"scheme": "dewPoint-controller-Package",
|
||||
"kind": "xcode"
|
||||
}
|
||||
Reference in New Issue
Block a user