From 7181476aafbea185eb8205bcb2db299aa6a847a2 Mon Sep 17 00:00:00 2001 From: Michael Housh Date: Sat, 30 Oct 2021 22:57:32 -0400 Subject: [PATCH] Cleaned up publish sensor and fixed default sensor topics. --- Sources/ClientLive/Live.swift | 106 +++++++++++++++++++--------------- Sources/Models/Topics.swift | 54 +++++++---------- 2 files changed, 81 insertions(+), 79 deletions(-) diff --git a/Sources/ClientLive/Live.swift b/Sources/ClientLive/Live.swift index 60ef19a..4b5d459 100644 --- a/Sources/ClientLive/Live.swift +++ b/Sources/ClientLive/Live.swift @@ -55,58 +55,17 @@ extension Client2 { topics: Topics ) -> Self { .init( - // TODO: Fix adding listeners in a more generic way. addListeners: { -// state.addSensorListeners(to: client, topics: topics) - client.addPublishListener(named: topics.sensors.returnAirSensor.temperature) { result in - let topic = topics.sensors.returnAirSensor.temperature - result.logIfFailure(client: client, topic: topic) - .parse(as: Temperature.self) - .map { temperature -> () in - state.sensors.returnAirSensor.temperature = temperature - } - } - client.addPublishListener(named: topics.sensors.returnAirSensor.humidity) { result in - let topic = topics.sensors.returnAirSensor.humidity - result.logIfFailure(client: client, topic: topic) - .parse(as: RelativeHumidity.self) - .map { humidity -> () in - state.sensors.returnAirSensor.humidity = humidity - } - } + state.addSensorListeners(to: client, topics: topics) }, connect: { client.connect() .map { _ in } }, publishSensor: { request in - guard let (dewPoint, topic) = request.dewPointData(topics: topics, units: state.units) - else { - client.logger.debug("No dew point for sensor.") - return client.eventLoopGroup.next().makeSucceededVoidFuture() - } - client.logger.debug("Publishing dew-point: \(dewPoint), to: \(topic)") - return client.publish( - to: topic, - payload: ByteBufferAllocator().buffer(string: "\(dewPoint.rawValue)"), - qos: .atLeastOnce - ) - .flatMap { - guard let (enthalpy, topic) = request.enthalpyData(altitude: state.altitude, topics: topics, units: state.units) - else { - client.logger.debug("No enthalpy for sensor.") - return client.eventLoopGroup.next().makeSucceededVoidFuture() - } - client.logger.debug("Publishing enthalpy: \(enthalpy), to: \(topic)") - return client.publish( - to: topic, - payload: ByteBufferAllocator().buffer(string: "\(enthalpy.rawValue)"), - qos: .atLeastOnce - ) - } - .map { - request.setHasProcessed(state: state) - } + client.publishDewPoint(request: request, state: state, topics: topics) + .publishEnthalpy() + .setHasProcessed() }, shutdown: { client.disconnect() @@ -164,6 +123,7 @@ struct TemperatureAndHumiditySensorKeyPathEnvelope { func addListener(to client: MQTTNIO.MQTTClient, topics: Topics, state: State) { let temperatureTopic = topics.sensors[keyPath: temperatureTopic] + client.logger.trace("Adding listener for topic: \(temperatureTopic)") client.addPublishListener(named: temperatureTopic) { result in result.logIfFailure(client: client, topic: temperatureTopic) .parse(as: Temperature.self) @@ -173,6 +133,7 @@ struct TemperatureAndHumiditySensorKeyPathEnvelope { } let humidityTopic = topics.sensors[keyPath: humidityTopic] + client.logger.trace("Adding listener for topic: \(humidityTopic)") client.addPublishListener(named: humidityTopic) { result in result.logIfFailure(client: client, topic: humidityTopic) .parse(as: RelativeHumidity.self) @@ -287,3 +248,58 @@ extension Client2.SensorPublishRequest { } } } + +extension MQTTNIO.MQTTClient { + + func publishDewPoint( + request: Client2.SensorPublishRequest, + state: State, + topics: Topics + ) -> EventLoopFuture<(MQTTNIO.MQTTClient, Client2.SensorPublishRequest, State, Topics)> { + guard let (dewPoint, topic) = request.dewPointData(topics: topics, units: state.units) + else { + logger.trace("No dew point for sensor.") + return eventLoopGroup.next().makeSucceededFuture((self, request, state, topics)) + } + logger.debug("Publishing dew-point: \(dewPoint), to: \(topic)") + return publish( + to: topic, + payload: ByteBufferAllocator().buffer(string: "\(dewPoint.rawValue)"), + qos: .atLeastOnce + ) + .map { (self, request, state, topics) } + } +} + +extension EventLoopFuture where Value == (Client2.SensorPublishRequest, State) { + func setHasProcessed( +// request: Client2.SensorPublishRequest, state: State + ) -> EventLoopFuture { + map { request, state in + request.setHasProcessed(state: state) + } + } +} + +extension EventLoopFuture where Value == (MQTTNIO.MQTTClient, Client2.SensorPublishRequest, State, Topics) { + func publishEnthalpy( +// request: Client2.SensorPublishRequest, +// state: State, +// topics: Topics + ) -> EventLoopFuture<(Client2.SensorPublishRequest, State)> { + flatMap { client, request, state, topics in + guard let (enthalpy, topic) = request.enthalpyData(altitude: state.altitude, topics: topics, units: state.units) + else { + client.logger.trace("No enthalpy for sensor.") + return client.eventLoopGroup.next().makeSucceededFuture((request, state)) + } + client.logger.debug("Publishing enthalpy: \(enthalpy), to: \(topic)") + return client.publish( + to: topic, + payload: ByteBufferAllocator().buffer(string: "\(enthalpy.rawValue)"), + qos: .atLeastOnce + ) + .map { (request, state) } + } + } +} diff --git a/Sources/Models/Topics.swift b/Sources/Models/Topics.swift index f274c48..e5efc09 100644 --- a/Sources/Models/Topics.swift +++ b/Sources/Models/Topics.swift @@ -41,12 +41,11 @@ public struct Topics: Codable, Equatable { public var returnAirSensor: TemperatureAndHumiditySensor public var supplyAirSensor: TemperatureAndHumiditySensor - // TODO: Fix defaults. public init( - mixedAirSensor: TemperatureAndHumiditySensor = .init(), - postCoilSensor: TemperatureAndHumiditySensor = .init(), - returnAirSensor: TemperatureAndHumiditySensor = .init(), - supplyAirSensor: TemperatureAndHumiditySensor = .init() + mixedAirSensor: TemperatureAndHumiditySensor = .default(location: "mixed=air"), + postCoilSensor: TemperatureAndHumiditySensor = .default(location: "post-coil"), + returnAirSensor: TemperatureAndHumiditySensor = .default(location: "return"), + supplyAirSensor: TemperatureAndHumiditySensor = .default(location: "supply") ) { self.mixedAirSensor = mixedAirSensor self.postCoilSensor = postCoilSensor @@ -54,31 +53,6 @@ public struct Topics: Codable, Equatable { self.supplyAirSensor = supplyAirSensor } -// /// The temperature sensor topic. -// public var temperature: String -// -// /// The humidity sensor topic. -// public var humidity: String -// -// /// The dew point topic (we write / publish this data from the application). -// public var dewPoint: String -// -// /// Create a new sensor topic container. -// /// -// /// - Parameters: -// /// - temperature: The temperature sensor topic. -// /// - humidity: The humidity sensor topic. -// /// - dewPoint: The dew point sensor topic. -// public init( -// temperature: String = "sensors/temperature", -// humidity: String = "sensors/humidity", -// dewPoint: String = "sensors/dew_point" -// ) { -// self.temperature = temperature -// self.humidity = humidity -// self.dewPoint = dewPoint -// } - public struct TemperatureAndHumiditySensor: Codable, Equatable { public var temperature: String public var humidity: String @@ -92,10 +66,10 @@ public struct Topics: Codable, Equatable { /// - humidity: The humidity sensor topic. /// - dewPoint: The dew point sensor topic. public init( - temperature: String = "sensors/temperature", - humidity: String = "sensors/humidity", - dewPoint: String = "sensors/dew_point", - enthalpy: String = "sensors/enthalpy" + temperature: String, + humidity: String, + dewPoint: String, + enthalpy: String ) { self.temperature = temperature self.humidity = humidity @@ -281,3 +255,15 @@ public struct Topics: Codable, Equatable { } } } + +// MARK: Helpers +extension Topics.Sensors.TemperatureAndHumiditySensor { + public static func `default`(location: String) -> Self { + .init( + temperature: "sensors/\(location)/temperature", + humidity: "sensors/\(location)/humidity", + dewPoint: "sensors/\(location)/dew-point", + enthalpy: "sensors/\(location)/enthalpy" + ) + } +}