Some steps towards only publishing measurements when significant changes occur.

This commit is contained in:
Maurice Makaay 2020-07-11 18:47:15 +02:00
parent 10f8fc2290
commit cebbe092e9
3 changed files with 90 additions and 22 deletions

View File

@ -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());
}

View File

@ -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;

View File

@ -9,7 +9,7 @@
#define MQTT_PASSWORD "<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/<MQTT_DEVICE_ID>/...)