Initial Commit
This commit is contained in:
14
Sources/TemperatureSensorClient/Interface.swift
Normal file
14
Sources/TemperatureSensorClient/Interface.swift
Normal 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
|
||||
}
|
||||
}
|
||||
51
Sources/TemperatureSensorClient/Live.swift
Normal file
51
Sources/TemperatureSensorClient/Live.swift
Normal 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))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user