diff --git a/src/Data/DataController.cpp b/src/Data/DataController.cpp index 2073bda..4db06f7 100644 --- a/src/Data/DataController.cpp +++ b/src/Data/DataController.cpp @@ -75,15 +75,15 @@ void DataController::setContainerHeight(int height) if (height <= HCSR04_MIN_MM) { _logger.log("sisis", "ERROR - Container height ", height, - "mm is less than the minimum measuring distance of ", - HCSR04_MIN_MM, "mm"); + "mm is less than the minimum measuring distance of ", + HCSR04_MIN_MM, "mm"); return; } if (height >= HCSR04_MAX_MM) { - _logger.log("sisis", "ERROR - Container height ", height, - "mm is more than the maximum measuring distance of ", - HCSR04_MAX_MM, "mm"); + _logger.log("sisis", "ERROR - Container height ", height, + "mm is more than the maximum measuring distance of ", + HCSR04_MAX_MM, "mm"); return; } _logger.log("sis", "Set container height to ", height, "mm"); @@ -135,18 +135,52 @@ void DataController::_sample() _ui->suspend(); // Take a sample. + Measurement m; switch (_sampleType) { case SAMPLE_TEMPERATURE: - _temperatureMeasurements.add(_sensors->readTemperature()); + m = _sensors->readTemperature(); + _temperatureMeasurements.add(m); + if (_temperatureLastPublished.ok && m.ok && _temperatureLastPublished.value != m.value) + { + if (m.value == _temperatureMeasurements.getAverage().value || + abs(_temperatureLastPublished.value - m.value) > TEMPERATURE_SIGNIFICANT_CHANGE) { + _publishTemperature(); + } + } + else if (_temperatureLastPublished.ok == false && m.ok) { + _publishTemperature(); + } _sampleType = SAMPLE_HUMIDITY; break; case SAMPLE_HUMIDITY: - _humidityMeasurements.add(_sensors->readHumidity()); + m = _sensors->readHumidity(); + _humidityMeasurements.add(m); + if (_humidityLastPublished.ok && m.ok && _humidityLastPublished.value != m.value) + { + if (m.value == _humidityMeasurements.getAverage().value || + abs(_humidityLastPublished.value - m.value) > HUMIDITY_SIGNIFICANT_CHANGE) { + _publishHumidity(); + } + } + else if (_humidityLastPublished.ok == false && m.ok) { + _publishHumidity(); + } _sampleType = SAMPLE_DISTANCE; break; case SAMPLE_DISTANCE: - _distanceMeasurements.add(_sensors->readDistance()); + m = _sensors->readDistance(); + _distanceMeasurements.add(m); + if (_distanceLastPublished.ok && m.ok && _distanceLastPublished.value != m.value) + { + if (m.value == _distanceMeasurements.getAverage().value || + abs(_distanceLastPublished.value - m.value) > DISTANCE_SIGNIFICANT_CHANGE) { + _publishDistance(); + } + } + else if (_distanceLastPublished.ok == false && m.ok) { + _publishDistance(); + } break; } @@ -166,14 +200,36 @@ void DataController::_publish() if (_lastPublish == 0 || millis() - _lastPublish > PUBLISH_INTERVAL) { _lastPublish = millis(); - - _mqtt->publish("temperature", _temperatureMeasurements.getLast()); - _mqtt->publish("temperature/average", _temperatureMeasurements.getAverage()); - _mqtt->publish("humidity", _humidityMeasurements.getLast()); - _mqtt->publish("humidity/average", _humidityMeasurements.getAverage()); - _mqtt->publish("distance", _distanceMeasurements.getLast()); - _mqtt->publish("distance/average", _distanceMeasurements.getAverage()); - + _publishTemperature(); + _publishHumidity(); + _publishDistance(); _ui->led1.dip()->fast(); } } + +void DataController::_publishTemperature() +{ + auto m = _temperatureMeasurements.getLast(); + _temperatureLastPublished.ok = m.ok; + _temperatureLastPublished.value = m.value; + _mqtt->publish("temperature", m); + _mqtt->publish("temperature/average", _temperatureMeasurements.getAverage()); +} + +void DataController::_publishHumidity() +{ + auto m = _humidityMeasurements.getLast(); + _humidityLastPublished.ok = m.ok; + _humidityLastPublished.value = m.value; + _mqtt->publish("humidity", _humidityMeasurements.getLast()); + _mqtt->publish("humidity/average", _humidityMeasurements.getAverage()); +} + +void DataController::_publishDistance() +{ + auto m = _distanceMeasurements.getLast(); + _distanceLastPublished.ok = m.ok; + _distanceLastPublished.value = m.value; + _mqtt->publish("distance", _distanceMeasurements.getLast()); + _mqtt->publish("distance/average", _distanceMeasurements.getAverage()); +} \ No newline at end of file diff --git a/src/Data/DataController.h b/src/Data/DataController.h index af6afde..ad78ec9 100644 --- a/src/Data/DataController.h +++ b/src/Data/DataController.h @@ -10,13 +10,19 @@ #define SAMPLE_CYCLE_LENGTH 30 // 1 temperature + 1 humidity + 28 distance samples // Two different values are published per sensor: a recent value and an average -// value. These definition define the number of measurements to include in the -// average computation. -#define TEMPERATURE_AVG_LOOKBACK 10 // making this a 5 minute average -#define HUMIDITY_AVG_LOOKBACK 10 // making this a 5 minute average +// value. These definition define the number of recent measurements to include +// in the average computation. +#define TEMPERATURE_AVG_LOOKBACK 6 // making this a 3 minute average +#define HUMIDITY_AVG_LOOKBACK 6 // making this a 3 minute average #define DISTANCE_AVG_LOOKBACK 28 * 2 * 5 // making this a 5 minute average -// The minimal interval at which to publish measurements to the MQTT broker. +// When significant changes occur in the sensor measurements, they are +// published to MQTT. These definitions specify what is considered significant. +#define TEMPERATURE_SIGNIFICANT_CHANGE 2 // to dampen flapping between two values on transition +#define HUMIDITY_SIGNIFICANT_CHANGE 2 // also to dampen flapping behavior. +#define DISTANCE_SIGNIFICANT_CHANGE 3 // based on the sensor specification of 3mm resolution + +// The minimal interval at which to forcibly publish measurements to the MQTT broker. // When significant changes occur in the measurements, then these will be published // to the MQTT broker at all times, independent from this interval. #define PUBLISH_INTERVAL 4000 @@ -57,8 +63,14 @@ private: DataController(); static DataController* _instance; Measurements _temperatureMeasurements; + Measurement _temperatureLastPublished; + void _publishTemperature(); Measurements _humidityMeasurements; + Measurement _humidityLastPublished; + void _publishHumidity(); Measurements _distanceMeasurements; + Measurement _distanceLastPublished; + void _publishDistance(); DoughLogger _logger; DoughUI* _ui; DoughSensors* _sensors; diff --git a/src/config_local.example.h b/src/config_local.example.h index 6e78a45..b6dc75b 100644 --- a/src/config_local.example.h +++ b/src/config_local.example.h @@ -9,7 +9,7 @@ #define MQTT_PASSWORD "" // The prefix to use for the MQTT publishing topic. -#define MQTT_TOPIC_PREFIX "sensors/doughboy" +//#define MQTT_TOPIC_PREFIX "sensors/doughboy" // Define this one to not use the WiFi MAC address as the device ID // in the publish topics (sensors/doughboy//...)