Cleaned up publish sensor and fixed default sensor topics.

This commit is contained in:
2021-10-30 22:57:32 -04:00
parent e971db67b8
commit 7181476aaf
2 changed files with 81 additions and 79 deletions

View File

@@ -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<Void> {
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) }
}
}
}

View File

@@ -41,12 +41,11 @@ public struct Topics: Codable, Equatable {
public var returnAirSensor: TemperatureAndHumiditySensor<State.Sensors.Return>
public var supplyAirSensor: TemperatureAndHumiditySensor<State.Sensors.Supply>
// TODO: Fix defaults.
public init(
mixedAirSensor: TemperatureAndHumiditySensor<State.Sensors.Mixed> = .init(),
postCoilSensor: TemperatureAndHumiditySensor<State.Sensors.PostCoil> = .init(),
returnAirSensor: TemperatureAndHumiditySensor<State.Sensors.Return> = .init(),
supplyAirSensor: TemperatureAndHumiditySensor<State.Sensors.Supply> = .init()
mixedAirSensor: TemperatureAndHumiditySensor<State.Sensors.Mixed> = .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")
) {
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<Location>: 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"
)
}
}