Initial Commit

This commit is contained in:
2021-10-16 15:01:47 -04:00
commit 42c46d9d84
18 changed files with 553 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
import Foundation
import CoreUnitTypes
import Models
import NIO
public struct TemperatureSensorClient {
public var state: (TemperatureSensor, PsychrometricEnvironment.Units?) -> EventLoopFuture<Temperature>
public init(
state: @escaping (TemperatureSensor, PsychrometricEnvironment.Units?) -> EventLoopFuture<Temperature>
) {
self.state = state
}
}

View File

@@ -0,0 +1,51 @@
import CoreUnitTypes
import Foundation
import MQTTNIO
extension TemperatureSensorClient {
public static func live(client: MQTTClient) -> TemperatureSensorClient {
.init(
state: { sensor, units in
client.logger.debug("Adding listener for temperature sensor...")
let subscription = MQTTSubscribeInfoV5.init(topicFilter: sensor.topic, qos: .atLeastOnce)
return client.v5.subscribe(to: [subscription])
.flatMap { _ in
let promise = client.eventLoopGroup.next().makePromise(of: Temperature.self)
client.addPublishListener(named: "temperature-sensor", { result in
switch result.temperature() {
case let .success(celsius):
let userUnits = units ?? PsychrometricEnvironment.shared.units
let temperatureUnits = Temperature.Units.defaultFor(units: userUnits)
promise.succeed(.init(celsius[temperatureUnits], units: temperatureUnits))
case let .failure(error):
promise.fail(error)
}
})
return promise.futureResult
}
}
)
}
}
public enum TemperatureError: Error {
case invalidTemperature
}
// MARK: - Helpers
extension Result where Success == MQTTPublishInfo, Failure == Error {
fileprivate func temperature() -> Result<Temperature, Error> {
flatMap { info in
var buffer = info.payload
guard let string = buffer.readString(length: buffer.readableBytes),
let temperatureValue = Double(string)
else {
return .failure(TemperatureError.invalidTemperature)
}
return .success(.celsius(temperatureValue))
}
}
}