The data structure and update value function

This commit is contained in:
samuelbles07
2024-10-11 20:54:05 +07:00
parent 60d01c0d94
commit 9c09b82efd
2 changed files with 236 additions and 38 deletions

View File

@ -1,7 +1,6 @@
#include "AgValue.h"
#include "AgConfigure.h"
#include "AirGradient.h"
#include "Main/utils.h"
#include "Libraries/Arduino_JSON/src/Arduino_JSON.h"
#define json_prop_pmFirmware "firmware"
@ -37,6 +36,183 @@ String Measurements::pms5003FirmwareVersionBase(String prefix, int fwCode) {
return prefix + String("-") + String(fwCode);
}
String Measurements::agValueTypeStr(AgValueType type) {
String str;
switch (type) {
case AgValueType::Temperature:
str = "Temperature";
break;
case AgValueType::Humidity:
str = "Humidity";
break;
case AgValueType::CO2:
str = "CO2";
break;
case AgValueType::TVOC:
str = "TVOC";
break;
case AgValueType::TVOCRaw:
str = "TVOCRaw";
break;
case AgValueType::NOx:
str = "NOx";
break;
case AgValueType::NOxRaw:
str = "NOxRaw";
break;
case AgValueType::PM25:
str = "PM25";
break;
case AgValueType::PM01:
str = "PM01";
break;
case AgValueType::PM10:
str = "PM10";
break;
case AgValueType::PM03:
str = "PM03";
break;
default:
break;
};
return str;
}
void Measurements::updateValue(AgValueType type, int val) {
// Define data point source
IntegerValue *temporary = nullptr;
float invalidValue = 0;
switch (type) {
case AgValueType::CO2:
temporary = &_co2;
invalidValue = utils::getInvalidCO2();
break;
case AgValueType::TVOC:
temporary = &_tvoc;
invalidValue = utils::getInvalidVOC();
break;
case AgValueType::TVOCRaw:
temporary = &_tvoc_raw;
invalidValue = utils::getInvalidVOC();
break;
case AgValueType::NOx:
temporary = &_nox;
invalidValue = utils::getInvalidNOx();
break;
case AgValueType::NOxRaw:
temporary = &_nox_raw;
invalidValue = utils::getInvalidNOx();
break;
case AgValueType::PM25:
temporary = &_pm_25;
invalidValue = utils::getInvalidPmValue();
break;
case AgValueType::PM01:
temporary = &_pm_01;
invalidValue = utils::getInvalidPmValue();
break;
case AgValueType::PM10:
temporary = &_pm_10;
invalidValue = utils::getInvalidPmValue();
break;
case AgValueType::PM03:
temporary = &_pm_03_pc;
invalidValue = utils::getInvalidPmValue();
break;
default:
break;
};
// Sanity check if agvaluetype is defined for integer data type or not
if (temporary == nullptr) {
Serial.printf("%s is not defined for integer data type\n", agValueTypeStr(type));
// TODO: Just assert?
return;
}
// Update new value when value provided is not the invalid one
if (val != invalidValue) {
temporary->lastValue = val;
temporary->sumValues = temporary->sumValues + val;
temporary->read.success = temporary->read.success + 1;
}
// Increment read counter
temporary->read.counter = temporary->read.counter + 1;
// Calculate value average when maximum set is reached
if (temporary->read.counter >= temporary->read.max) {
// Calculate the average
temporary->avg = temporary->sumValues / temporary->read.success;
// This is just for notifying
int miss = temporary->read.max - temporary->read.success;
if (miss != 0) {
Serial.printf("%s reading miss %d out of %d update\n", agValueTypeStr(type), miss,
temporary->read.max);
}
// Resets the sum data and read variables
temporary->sumValues = 0;
temporary->read.counter = 0;
temporary->read.success = 0;
}
}
void Measurements::updateValue(AgValueType type, float val) {
// Define data point source
FloatValue *temporary = nullptr;
float invalidValue = 0;
switch (type) {
case AgValueType::Temperature:
temporary = &_temperature;
invalidValue = utils::getInvalidTemperature();
break;
case AgValueType::Humidity:
temporary = &_humidity;
invalidValue = utils::getInvalidHumidity();
break;
default:
break;
}
// Sanity check if agvaluetype is defined for float data type or not
if (temporary == nullptr) {
Serial.printf("%s is not defined for float data type\n", agValueTypeStr(type));
// TODO: Just assert?
return;
}
// Update new value when value provided is not the invalid one
if (val != invalidValue) {
temporary->lastValue = val;
temporary->sumValues = temporary->sumValues + val;
temporary->read.success = temporary->read.success + 1;
}
// Increment read counter
temporary->read.counter = temporary->read.counter + 1;
// Calculate value average when maximum set is reached
if (temporary->read.counter >= temporary->read.max) {
// Calculate the average
temporary->avg = temporary->sumValues / temporary->read.success;
// This is just for notifying
int miss = temporary->read.max - temporary->read.success;
if (miss != 0) {
Serial.printf("%s reading miss %d out of %d update\n", agValueTypeStr(type), miss,
temporary->read.max);
}
// Resets the sum data and read variables
temporary->sumValues = 0;
temporary->read.counter = 0;
temporary->read.success = 0;
}
}
String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
void *_ag, void *_config) {
AirGradient *ag = (AirGradient *)_ag;

View File

@ -1,14 +1,36 @@
#ifndef _AG_VALUE_H_
#define _AG_VALUE_H_
#include <Arduino.h>
#include "App/AppDef.h"
#include "Main/utils.h"
#include <Arduino.h>
class Measurements {
private:
String pms5003FirmwareVersion(int fwCode);
String pms5003TFirmwareVersion(int fwCode);
String pms5003FirmwareVersionBase(String prefix, int fwCode);
// Generic struct for reading indication for respective value
// TODO: Reading naming is confusing, because its not actually reading but updating with new value
struct Reading {
int counter; // How many reading attempts done
int success; // How many reading that success from each attempts
int max; // Maximum reading attempt
};
// Reading type for sensor value that outputs float
struct FloatValue {
float lastValue; // Last reading value
float sumValues; // Total value of each reading
float avg; // The last average calculation after maximum reading attempt reached
Reading read;
};
// Reading type for sensor value that outputs integer
struct IntegerValue {
int lastValue; // Last reading value
unsigned long sumValues; // Total value of each reading // TODO: explain why unsigned long
int avg; // The last average calculation after maximum reading attempt reached
Reading read;
};
public:
Measurements() {
pm25_1 = -1;
@ -35,40 +57,22 @@ public:
}
~Measurements() {}
// Generic struct for reading indication for respective value
struct Reading {
int counter; // How many reading attempts done
int success; // How many reading that success from each attempts
int max; // Maximum reading attempt
enum class AgValueType {
Temperature,
Humidity,
CO2,
TVOC,
TVOCRaw,
NOx,
NOxRaw,
PM25,
PM01,
PM10,
PM03,
};
// Reading type for sensor value that outputs float
struct FloatValue {
float lastValue; // Last reading value
float sumValues; // Total value of each reading
float avg; // The last average calculation after maximum reading attempt reached
Reading read;
};
// Reading type for sensor value that outputs integer
struct IntegerValue {
int lastValue; // Last reading value
unsigned long sumValues; // Total value of each reading
int avg; // The last average calculation after maximum reading attempt reached
Reading read;
};
FloatValue temperature;
FloatValue humidity;
IntegerValue co2;
IntegerValue tvoc;
IntegerValue tvoc_raw;
IntegerValue nox;
IntegerValue nox_raw;
IntegerValue pm_25;
IntegerValue pm_01;
IntegerValue pm_10;
IntegerValue pm_03_pc;
void updateValue(AgValueType type, int val);
void updateValue(AgValueType type, float val);
float Temperature;
int Humidity;
@ -108,7 +112,25 @@ public:
const int targetCount = 20;
int bootCount;
String toString(bool isLocal, AgFirmwareMode fwMode, int rssi, void* _ag, void* _config);
String toString(bool isLocal, AgFirmwareMode fwMode, int rssi, void *_ag, void *_config);
private:
FloatValue _temperature;
FloatValue _humidity;
IntegerValue _co2;
IntegerValue _tvoc;
IntegerValue _tvoc_raw;
IntegerValue _nox;
IntegerValue _nox_raw;
IntegerValue _pm_25;
IntegerValue _pm_01;
IntegerValue _pm_10;
IntegerValue _pm_03_pc; // particle count 0.3
String pms5003FirmwareVersion(int fwCode);
String pms5003TFirmwareVersion(int fwCode);
String pms5003FirmwareVersionBase(String prefix, int fwCode);
String agValueTypeStr(AgValueType type);
};
#endif /** _AG_VALUE_H_ */