mirror of
https://github.com/airgradienthq/arduino.git
synced 2025-08-01 09:54:28 +02:00
The data structure and update value function
This commit is contained in:
178
src/AgValue.cpp
178
src/AgValue.cpp
@@ -1,7 +1,6 @@
|
|||||||
#include "AgValue.h"
|
#include "AgValue.h"
|
||||||
#include "AgConfigure.h"
|
#include "AgConfigure.h"
|
||||||
#include "AirGradient.h"
|
#include "AirGradient.h"
|
||||||
#include "Main/utils.h"
|
|
||||||
#include "Libraries/Arduino_JSON/src/Arduino_JSON.h"
|
#include "Libraries/Arduino_JSON/src/Arduino_JSON.h"
|
||||||
|
|
||||||
#define json_prop_pmFirmware "firmware"
|
#define json_prop_pmFirmware "firmware"
|
||||||
@@ -37,6 +36,183 @@ String Measurements::pms5003FirmwareVersionBase(String prefix, int fwCode) {
|
|||||||
return prefix + String("-") + String(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,
|
String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
|
||||||
void *_ag, void *_config) {
|
void *_ag, void *_config) {
|
||||||
AirGradient *ag = (AirGradient *)_ag;
|
AirGradient *ag = (AirGradient *)_ag;
|
||||||
|
@@ -1,14 +1,36 @@
|
|||||||
#ifndef _AG_VALUE_H_
|
#ifndef _AG_VALUE_H_
|
||||||
#define _AG_VALUE_H_
|
#define _AG_VALUE_H_
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include "App/AppDef.h"
|
#include "App/AppDef.h"
|
||||||
|
#include "Main/utils.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
class Measurements {
|
class Measurements {
|
||||||
private:
|
private:
|
||||||
String pms5003FirmwareVersion(int fwCode);
|
// Generic struct for reading indication for respective value
|
||||||
String pms5003TFirmwareVersion(int fwCode);
|
// TODO: Reading naming is confusing, because its not actually reading but updating with new value
|
||||||
String pms5003FirmwareVersionBase(String prefix, int fwCode);
|
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:
|
public:
|
||||||
Measurements() {
|
Measurements() {
|
||||||
pm25_1 = -1;
|
pm25_1 = -1;
|
||||||
@@ -35,40 +57,22 @@ public:
|
|||||||
}
|
}
|
||||||
~Measurements() {}
|
~Measurements() {}
|
||||||
|
|
||||||
// Generic struct for reading indication for respective value
|
enum class AgValueType {
|
||||||
struct Reading {
|
Temperature,
|
||||||
int counter; // How many reading attempts done
|
Humidity,
|
||||||
int success; // How many reading that success from each attempts
|
CO2,
|
||||||
int max; // Maximum reading attempt
|
TVOC,
|
||||||
|
TVOCRaw,
|
||||||
|
NOx,
|
||||||
|
NOxRaw,
|
||||||
|
PM25,
|
||||||
|
PM01,
|
||||||
|
PM10,
|
||||||
|
PM03,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Reading type for sensor value that outputs float
|
void updateValue(AgValueType type, int val);
|
||||||
struct FloatValue {
|
void updateValue(AgValueType type, float val);
|
||||||
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;
|
|
||||||
|
|
||||||
float Temperature;
|
float Temperature;
|
||||||
int Humidity;
|
int Humidity;
|
||||||
@@ -108,7 +112,25 @@ public:
|
|||||||
const int targetCount = 20;
|
const int targetCount = 20;
|
||||||
int bootCount;
|
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_ */
|
#endif /** _AG_VALUE_H_ */
|
||||||
|
Reference in New Issue
Block a user