mirror of
https://github.com/airgradienthq/arduino.git
synced 2025-07-16 10:12:09 +02:00
Apply for other monitor series
This commit is contained in:
@ -49,9 +49,8 @@ CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License
|
|||||||
#define SENSOR_TVOC_UPDATE_INTERVAL 1000 /** ms */
|
#define SENSOR_TVOC_UPDATE_INTERVAL 1000 /** ms */
|
||||||
#define SENSOR_CO2_UPDATE_INTERVAL 4000 /** ms */
|
#define SENSOR_CO2_UPDATE_INTERVAL 4000 /** ms */
|
||||||
#define SENSOR_PM_UPDATE_INTERVAL 2000 /** ms */
|
#define SENSOR_PM_UPDATE_INTERVAL 2000 /** ms */
|
||||||
#define SENSOR_TEMP_HUM_UPDATE_INTERVAL 2000 /** ms */
|
#define SENSOR_TEMP_HUM_UPDATE_INTERVAL 6000 /** ms */
|
||||||
#define DISPLAY_DELAY_SHOW_CONTENT_MS 2000 /** ms */
|
#define DISPLAY_DELAY_SHOW_CONTENT_MS 2000 /** ms */
|
||||||
#define FIRMWARE_CHECK_FOR_UPDATE_MS (60 * 60 * 1000) /** ms */
|
|
||||||
|
|
||||||
static AirGradient ag(DIY_BASIC);
|
static AirGradient ag(DIY_BASIC);
|
||||||
static Configuration configuration(Serial);
|
static Configuration configuration(Serial);
|
||||||
@ -68,7 +67,6 @@ static LocalServer localServer(Serial, openMetrics, measurements, configuration,
|
|||||||
wifiConnector);
|
wifiConnector);
|
||||||
static MqttClient mqttClient(Serial);
|
static MqttClient mqttClient(Serial);
|
||||||
|
|
||||||
static int getCO2FailCount = 0;
|
|
||||||
static AgFirmwareMode fwMode = FW_MODE_I_BASIC_40PS;
|
static AgFirmwareMode fwMode = FW_MODE_I_BASIC_40PS;
|
||||||
|
|
||||||
static String fwNewVersion;
|
static String fwNewVersion;
|
||||||
@ -90,6 +88,8 @@ static void wdgFeedUpdate(void);
|
|||||||
static bool sgp41Init(void);
|
static bool sgp41Init(void);
|
||||||
static void wifiFactoryConfigure(void);
|
static void wifiFactoryConfigure(void);
|
||||||
static void mqttHandle(void);
|
static void mqttHandle(void);
|
||||||
|
static int calculateMaxPeriod(int updateInterval);
|
||||||
|
static void setMeasurementMaxPeriod();
|
||||||
|
|
||||||
AgSchedule dispLedSchedule(DISP_UPDATE_INTERVAL, oledDisplaySchedule);
|
AgSchedule dispLedSchedule(DISP_UPDATE_INTERVAL, oledDisplaySchedule);
|
||||||
AgSchedule configSchedule(SERVER_CONFIG_SYNC_INTERVAL,
|
AgSchedule configSchedule(SERVER_CONFIG_SYNC_INTERVAL,
|
||||||
@ -130,6 +130,10 @@ void setup() {
|
|||||||
|
|
||||||
/** Init sensor */
|
/** Init sensor */
|
||||||
boardInit();
|
boardInit();
|
||||||
|
setMeasurementMaxPeriod();
|
||||||
|
|
||||||
|
// Uncomment below line to print every measurements reading update
|
||||||
|
// measurements.setDebug(true);
|
||||||
|
|
||||||
/** Connecting wifi */
|
/** Connecting wifi */
|
||||||
bool connectToWifi = false;
|
bool connectToWifi = false;
|
||||||
@ -230,17 +234,16 @@ void loop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void co2Update(void) {
|
static void co2Update(void) {
|
||||||
|
if (!configuration.hasSensorS8) {
|
||||||
|
// Device don't have S8 sensor
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int value = ag.s8.getCo2();
|
int value = ag.s8.getCo2();
|
||||||
if (utils::isValidCO2(value)) {
|
if (utils::isValidCO2(value)) {
|
||||||
measurements.CO2 = value;
|
measurements.update(Measurements::CO2, value);
|
||||||
getCO2FailCount = 0;
|
|
||||||
Serial.printf("CO2 (ppm): %d\r\n", measurements.CO2);
|
|
||||||
} else {
|
} else {
|
||||||
getCO2FailCount++;
|
measurements.update(Measurements::CO2, utils::getInvalidCO2());
|
||||||
Serial.printf("Get CO2 failed: %d\r\n", getCO2FailCount);
|
|
||||||
if (getCO2FailCount >= 3) {
|
|
||||||
measurements.CO2 = utils::getInvalidCO2();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,8 +316,7 @@ static void mqttHandle(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mqttClient.isConnected()) {
|
if (mqttClient.isConnected()) {
|
||||||
String payload = measurements.toString(true, fwMode, wifiConnector.RSSI(),
|
String payload = measurements.toString(true, fwMode, wifiConnector.RSSI(), ag, configuration);
|
||||||
&ag, &configuration);
|
|
||||||
String topic = "airgradient/readings/" + ag.deviceId();
|
String topic = "airgradient/readings/" + ag.deviceId();
|
||||||
if (mqttClient.publish(topic.c_str(), payload.c_str(), payload.length())) {
|
if (mqttClient.publish(topic.c_str(), payload.c_str(), payload.length())) {
|
||||||
Serial.println("MQTT sync success");
|
Serial.println("MQTT sync success");
|
||||||
@ -490,46 +492,27 @@ static void oledDisplaySchedule(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void updateTvoc(void) {
|
static void updateTvoc(void) {
|
||||||
measurements.TVOC = ag.sgp41.getTvocIndex();
|
if (!configuration.hasSensorSGP) {
|
||||||
measurements.TVOCRaw = ag.sgp41.getTvocRaw();
|
return;
|
||||||
measurements.NOx = ag.sgp41.getNoxIndex();
|
}
|
||||||
measurements.NOxRaw = ag.sgp41.getNoxRaw();
|
|
||||||
|
|
||||||
Serial.println();
|
measurements.update(Measurements::TVOC, ag.sgp41.getTvocIndex());
|
||||||
Serial.printf("TVOC index: %d\r\n", measurements.TVOC);
|
measurements.update(Measurements::TVOCRaw, ag.sgp41.getTvocRaw());
|
||||||
Serial.printf("TVOC raw: %d\r\n", measurements.TVOCRaw);
|
measurements.update(Measurements::NOx, ag.sgp41.getNoxIndex());
|
||||||
Serial.printf("NOx index: %d\r\n", measurements.NOx);
|
measurements.update(Measurements::NOxRaw, ag.sgp41.getNoxRaw());
|
||||||
Serial.printf("NOx raw: %d\r\n", measurements.NOxRaw);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updatePm(void) {
|
static void updatePm(void) {
|
||||||
if (ag.pms5003.connected()) {
|
if (ag.pms5003.connected()) {
|
||||||
measurements.pm01_1 = ag.pms5003.getPm01Ae();
|
measurements.update(Measurements::PM01, ag.pms5003.getPm01Ae());
|
||||||
measurements.pm25_1 = ag.pms5003.getPm25Ae();
|
measurements.update(Measurements::PM25, ag.pms5003.getPm25Ae());
|
||||||
measurements.pm10_1 = ag.pms5003.getPm10Ae();
|
measurements.update(Measurements::PM10, ag.pms5003.getPm10Ae());
|
||||||
measurements.pm03PCount_1 = ag.pms5003.getPm03ParticleCount();
|
measurements.update(Measurements::PM03_PC, ag.pms5003.getPm03ParticleCount());
|
||||||
|
|
||||||
Serial.println();
|
|
||||||
Serial.printf("PM1 ug/m3: %d\r\n", measurements.pm01_1);
|
|
||||||
Serial.printf("PM2.5 ug/m3: %d\r\n", measurements.pm25_1);
|
|
||||||
Serial.printf("PM10 ug/m3: %d\r\n", measurements.pm10_1);
|
|
||||||
Serial.printf("PM0.3 Count: %d\r\n", measurements.pm03PCount_1);
|
|
||||||
Serial.printf("PM firmware version: %d\r\n", ag.pms5003.getFirmwareVersion());
|
|
||||||
ag.pms5003.resetFailCount();
|
|
||||||
} else {
|
} else {
|
||||||
ag.pms5003.updateFailCount();
|
measurements.update(Measurements::PM01, utils::getInvalidPmValue());
|
||||||
Serial.printf("PMS read failed %d times\r\n", ag.pms5003.getFailCount());
|
measurements.update(Measurements::PM25, utils::getInvalidPmValue());
|
||||||
if (ag.pms5003.getFailCount() >= PMS_FAIL_COUNT_SET_INVALID) {
|
measurements.update(Measurements::PM10, utils::getInvalidPmValue());
|
||||||
measurements.pm01_1 = utils::getInvalidPmValue();
|
measurements.update(Measurements::PM03_PC, utils::getInvalidPmValue());
|
||||||
measurements.pm25_1 = utils::getInvalidPmValue();
|
|
||||||
measurements.pm10_1 = utils::getInvalidPmValue();
|
|
||||||
measurements.pm03PCount_1 = utils::getInvalidPmValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ag.pms5003.getFailCount() >= ag.pms5003.getFailCountMax()) {
|
|
||||||
Serial.printf("PMS failure count reach to max set %d, restarting...", ag.pms5003.getFailCountMax());
|
|
||||||
ESP.restart();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,8 +523,7 @@ static void sendDataToServer(void) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String syncData = measurements.toString(false, fwMode, wifiConnector.RSSI(),
|
String syncData = measurements.toString(false, fwMode, wifiConnector.RSSI(), ag, configuration);
|
||||||
&ag, &configuration);
|
|
||||||
if (apiClient.postToServer(syncData)) {
|
if (apiClient.postToServer(syncData)) {
|
||||||
Serial.println();
|
Serial.println();
|
||||||
Serial.println(
|
Serial.println(
|
||||||
@ -552,26 +534,54 @@ static void sendDataToServer(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void tempHumUpdate(void) {
|
static void tempHumUpdate(void) {
|
||||||
delay(100);
|
|
||||||
if (ag.sht.measure()) {
|
if (ag.sht.measure()) {
|
||||||
measurements.Temperature = ag.sht.getTemperature();
|
float temp = ag.sht.getTemperature();
|
||||||
measurements.Humidity = ag.sht.getRelativeHumidity();
|
float rhum = ag.sht.getRelativeHumidity();
|
||||||
|
|
||||||
Serial.printf("Temperature in C: %0.2f\r\n", measurements.Temperature);
|
measurements.update(Measurements::Temperature, temp);
|
||||||
Serial.printf("Relative Humidity: %d\r\n", measurements.Humidity);
|
measurements.update(Measurements::Humidity, rhum);
|
||||||
Serial.printf("Temperature compensated in C: %0.2f\r\n",
|
|
||||||
measurements.Temperature);
|
|
||||||
Serial.printf("Relative Humidity compensated: %d\r\n",
|
|
||||||
measurements.Humidity);
|
|
||||||
|
|
||||||
// Update compensation temperature and humidity for SGP41
|
// Update compensation temperature and humidity for SGP41
|
||||||
if (configuration.hasSensorSGP) {
|
if (configuration.hasSensorSGP) {
|
||||||
ag.sgp41.setCompensationTemperatureHumidity(measurements.Temperature,
|
ag.sgp41.setCompensationTemperatureHumidity(temp, rhum);
|
||||||
measurements.Humidity);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
measurements.update(Measurements::Temperature, utils::getInvalidTemperature());
|
||||||
|
measurements.update(Measurements::Humidity, utils::getInvalidHumidity());
|
||||||
Serial.println("SHT read failed");
|
Serial.println("SHT read failed");
|
||||||
measurements.Temperature = utils::getInvalidTemperature();
|
|
||||||
measurements.Humidity = utils::getInvalidHumidity();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set max period for each measurement type based on sensor update interval*/
|
||||||
|
void setMeasurementMaxPeriod() {
|
||||||
|
/// Max period for S8 sensors measurements
|
||||||
|
measurements.maxPeriod(Measurements::CO2, calculateMaxPeriod(SENSOR_CO2_UPDATE_INTERVAL));
|
||||||
|
/// Max period for SGP sensors measurements
|
||||||
|
measurements.maxPeriod(Measurements::TVOC, calculateMaxPeriod(SENSOR_TVOC_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::TVOCRaw, calculateMaxPeriod(SENSOR_TVOC_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::NOx, calculateMaxPeriod(SENSOR_TVOC_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::NOxRaw, calculateMaxPeriod(SENSOR_TVOC_UPDATE_INTERVAL));
|
||||||
|
/// Max period for PMS sensors measurements
|
||||||
|
measurements.maxPeriod(Measurements::PM25, calculateMaxPeriod(SENSOR_PM_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::PM01, calculateMaxPeriod(SENSOR_PM_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::PM10, calculateMaxPeriod(SENSOR_PM_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::PM03_PC, calculateMaxPeriod(SENSOR_PM_UPDATE_INTERVAL));
|
||||||
|
// Temperature and Humidity
|
||||||
|
if (configuration.hasSensorSHT) {
|
||||||
|
/// Max period for SHT sensors measurements
|
||||||
|
measurements.maxPeriod(Measurements::Temperature,
|
||||||
|
calculateMaxPeriod(SENSOR_TEMP_HUM_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::Humidity,
|
||||||
|
calculateMaxPeriod(SENSOR_TEMP_HUM_UPDATE_INTERVAL));
|
||||||
|
} else {
|
||||||
|
/// Temp and hum data retrieved from PMS5003T sensor
|
||||||
|
measurements.maxPeriod(Measurements::Temperature,
|
||||||
|
calculateMaxPeriod(SENSOR_PM_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::Humidity, calculateMaxPeriod(SENSOR_PM_UPDATE_INTERVAL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int calculateMaxPeriod(int updateInterval) {
|
||||||
|
// 0.5 is 50% reduced interval for max period
|
||||||
|
return (SERVER_SYNC_INTERVAL - (SERVER_SYNC_INTERVAL * 0.5)) / updateInterval;
|
||||||
|
}
|
@ -53,9 +53,8 @@ void LocalServer::_GET_metrics(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LocalServer::_GET_measure(void) {
|
void LocalServer::_GET_measure(void) {
|
||||||
server.send(
|
String toSend = measure.toString(true, fwMode, wifiConnector.RSSI(), *ag, config);
|
||||||
200, "application/json",
|
server.send(200, "application/json", toSend);
|
||||||
measure.toString(true, fwMode, wifiConnector.RSSI(), ag, &config));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalServer::setFwMode(AgFirmwareMode fwMode) { this->fwMode = fwMode; }
|
void LocalServer::setFwMode(AgFirmwareMode fwMode) { this->fwMode = fwMode; }
|
||||||
|
@ -73,19 +73,30 @@ String OpenMetrics::getPayload(void) {
|
|||||||
int pm03PCount = utils::getInvalidPmValue();
|
int pm03PCount = utils::getInvalidPmValue();
|
||||||
int atmpCompensated = utils::getInvalidTemperature();
|
int atmpCompensated = utils::getInvalidTemperature();
|
||||||
int ahumCompensated = utils::getInvalidHumidity();
|
int ahumCompensated = utils::getInvalidHumidity();
|
||||||
|
int tvoc = utils::getInvalidVOC();
|
||||||
|
int tvoc_raw = utils::getInvalidVOC();
|
||||||
|
int nox = utils::getInvalidNOx();
|
||||||
|
int nox_raw = utils::getInvalidNOx();
|
||||||
|
|
||||||
if (config.hasSensorSHT) {
|
if (config.hasSensorSHT) {
|
||||||
_temp = measure.Temperature;
|
_temp = measure.getFloat(Measurements::Temperature);
|
||||||
_hum = measure.Humidity;
|
_hum = measure.getFloat(Measurements::Humidity);
|
||||||
atmpCompensated = _temp;
|
atmpCompensated = _temp;
|
||||||
ahumCompensated = _hum;
|
ahumCompensated = _hum;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.hasSensorPMS1) {
|
if (config.hasSensorPMS1) {
|
||||||
pm01 = measure.pm01_1;
|
pm01 = measure.get(Measurements::PM01);
|
||||||
pm25 = measure.pm25_1;
|
pm25 = measure.get(Measurements::PM25);
|
||||||
pm10 = measure.pm10_1;
|
pm10 = measure.get(Measurements::PM10);
|
||||||
pm03PCount = measure.pm03PCount_1;
|
pm03PCount = measure.get(Measurements::PM03_PC);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.hasSensorSGP) {
|
||||||
|
tvoc = measure.get(Measurements::TVOC);
|
||||||
|
tvoc_raw = measure.get(Measurements::TVOCRaw);
|
||||||
|
nox = measure.get(Measurements::NOx);
|
||||||
|
nox_raw = measure.get(Measurements::NOxRaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.hasSensorPMS1) {
|
if (config.hasSensorPMS1) {
|
||||||
@ -120,33 +131,33 @@ String OpenMetrics::getPayload(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (config.hasSensorSGP) {
|
if (config.hasSensorSGP) {
|
||||||
if (utils::isValidVOC(measure.TVOC)) {
|
if (utils::isValidVOC(tvoc)) {
|
||||||
add_metric("tvoc_index",
|
add_metric("tvoc_index",
|
||||||
"The processed Total Volatile Organic Compounds (TVOC) index "
|
"The processed Total Volatile Organic Compounds (TVOC) index "
|
||||||
"as measured by the AirGradient SGP sensor",
|
"as measured by the AirGradient SGP sensor",
|
||||||
"gauge");
|
"gauge");
|
||||||
add_metric_point("", String(measure.TVOC));
|
add_metric_point("", String(tvoc));
|
||||||
}
|
}
|
||||||
if (utils::isValidVOC(measure.TVOCRaw)) {
|
if (utils::isValidVOC(tvoc_raw)) {
|
||||||
add_metric("tvoc_raw",
|
add_metric("tvoc_raw",
|
||||||
"The raw input value to the Total Volatile Organic Compounds "
|
"The raw input value to the Total Volatile Organic Compounds "
|
||||||
"(TVOC) index as measured by the AirGradient SGP sensor",
|
"(TVOC) index as measured by the AirGradient SGP sensor",
|
||||||
"gauge");
|
"gauge");
|
||||||
add_metric_point("", String(measure.TVOCRaw));
|
add_metric_point("", String(tvoc_raw));
|
||||||
}
|
}
|
||||||
if (utils::isValidNOx(measure.NOx)) {
|
if (utils::isValidNOx(nox)) {
|
||||||
add_metric("nox_index",
|
add_metric("nox_index",
|
||||||
"The processed Nitrous Oxide (NOx) index as measured by the "
|
"The processed Nitrous Oxide (NOx) index as measured by the "
|
||||||
"AirGradient SGP sensor",
|
"AirGradient SGP sensor",
|
||||||
"gauge");
|
"gauge");
|
||||||
add_metric_point("", String(measure.NOx));
|
add_metric_point("", String(nox));
|
||||||
}
|
}
|
||||||
if (utils::isValidNOx(measure.NOxRaw)) {
|
if (utils::isValidNOx(nox_raw)) {
|
||||||
add_metric("nox_raw",
|
add_metric("nox_raw",
|
||||||
"The raw input value to the Nitrous Oxide (NOx) index as "
|
"The raw input value to the Nitrous Oxide (NOx) index as "
|
||||||
"measured by the AirGradient SGP sensor",
|
"measured by the AirGradient SGP sensor",
|
||||||
"gauge");
|
"gauge");
|
||||||
add_metric_point("", String(measure.NOxRaw));
|
add_metric_point("", String(nox_raw));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,9 +49,8 @@ CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License
|
|||||||
#define SENSOR_TVOC_UPDATE_INTERVAL 1000 /** ms */
|
#define SENSOR_TVOC_UPDATE_INTERVAL 1000 /** ms */
|
||||||
#define SENSOR_CO2_UPDATE_INTERVAL 4000 /** ms */
|
#define SENSOR_CO2_UPDATE_INTERVAL 4000 /** ms */
|
||||||
#define SENSOR_PM_UPDATE_INTERVAL 2000 /** ms */
|
#define SENSOR_PM_UPDATE_INTERVAL 2000 /** ms */
|
||||||
#define SENSOR_TEMP_HUM_UPDATE_INTERVAL 2000 /** ms */
|
#define SENSOR_TEMP_HUM_UPDATE_INTERVAL 6000 /** ms */
|
||||||
#define DISPLAY_DELAY_SHOW_CONTENT_MS 2000 /** ms */
|
#define DISPLAY_DELAY_SHOW_CONTENT_MS 2000 /** ms */
|
||||||
#define FIRMWARE_CHECK_FOR_UPDATE_MS (60 * 60 * 1000) /** ms */
|
|
||||||
|
|
||||||
static AirGradient ag(DIY_PRO_INDOOR_V3_3);
|
static AirGradient ag(DIY_PRO_INDOOR_V3_3);
|
||||||
static Configuration configuration(Serial);
|
static Configuration configuration(Serial);
|
||||||
@ -68,7 +67,6 @@ static LocalServer localServer(Serial, openMetrics, measurements, configuration,
|
|||||||
wifiConnector);
|
wifiConnector);
|
||||||
static MqttClient mqttClient(Serial);
|
static MqttClient mqttClient(Serial);
|
||||||
|
|
||||||
static int getCO2FailCount = 0;
|
|
||||||
static AgFirmwareMode fwMode = FW_MODE_I_33PS;
|
static AgFirmwareMode fwMode = FW_MODE_I_33PS;
|
||||||
|
|
||||||
static String fwNewVersion;
|
static String fwNewVersion;
|
||||||
@ -90,6 +88,8 @@ static void wdgFeedUpdate(void);
|
|||||||
static bool sgp41Init(void);
|
static bool sgp41Init(void);
|
||||||
static void wifiFactoryConfigure(void);
|
static void wifiFactoryConfigure(void);
|
||||||
static void mqttHandle(void);
|
static void mqttHandle(void);
|
||||||
|
static int calculateMaxPeriod(int updateInterval);
|
||||||
|
static void setMeasurementMaxPeriod();
|
||||||
|
|
||||||
AgSchedule dispLedSchedule(DISP_UPDATE_INTERVAL, oledDisplaySchedule);
|
AgSchedule dispLedSchedule(DISP_UPDATE_INTERVAL, oledDisplaySchedule);
|
||||||
AgSchedule configSchedule(SERVER_CONFIG_SYNC_INTERVAL,
|
AgSchedule configSchedule(SERVER_CONFIG_SYNC_INTERVAL,
|
||||||
@ -130,6 +130,10 @@ void setup() {
|
|||||||
|
|
||||||
/** Init sensor */
|
/** Init sensor */
|
||||||
boardInit();
|
boardInit();
|
||||||
|
setMeasurementMaxPeriod();
|
||||||
|
|
||||||
|
// Uncomment below line to print every measurements reading update
|
||||||
|
// measurements.setDebug(true);
|
||||||
|
|
||||||
/** Connecting wifi */
|
/** Connecting wifi */
|
||||||
bool connectToWifi = false;
|
bool connectToWifi = false;
|
||||||
@ -228,17 +232,16 @@ void loop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void co2Update(void) {
|
static void co2Update(void) {
|
||||||
|
if (!configuration.hasSensorS8) {
|
||||||
|
// Device don't have S8 sensor
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int value = ag.s8.getCo2();
|
int value = ag.s8.getCo2();
|
||||||
if (utils::isValidCO2(value)) {
|
if (utils::isValidCO2(value)) {
|
||||||
measurements.CO2 = value;
|
measurements.update(Measurements::CO2, value);
|
||||||
getCO2FailCount = 0;
|
|
||||||
Serial.printf("CO2 (ppm): %d\r\n", measurements.CO2);
|
|
||||||
} else {
|
} else {
|
||||||
getCO2FailCount++;
|
measurements.update(Measurements::CO2, utils::getInvalidCO2());
|
||||||
Serial.printf("Get CO2 failed: %d\r\n", getCO2FailCount);
|
|
||||||
if (getCO2FailCount >= 3) {
|
|
||||||
measurements.CO2 = utils::getInvalidCO2();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,8 +373,7 @@ static void mqttHandle(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mqttClient.isConnected()) {
|
if (mqttClient.isConnected()) {
|
||||||
String payload = measurements.toString(true, fwMode, wifiConnector.RSSI(),
|
String payload = measurements.toString(true, fwMode, wifiConnector.RSSI(), ag, configuration);
|
||||||
&ag, &configuration);
|
|
||||||
String topic = "airgradient/readings/" + ag.deviceId();
|
String topic = "airgradient/readings/" + ag.deviceId();
|
||||||
if (mqttClient.publish(topic.c_str(), payload.c_str(), payload.length())) {
|
if (mqttClient.publish(topic.c_str(), payload.c_str(), payload.length())) {
|
||||||
Serial.println("MQTT sync success");
|
Serial.println("MQTT sync success");
|
||||||
@ -542,46 +544,27 @@ static void oledDisplaySchedule(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void updateTvoc(void) {
|
static void updateTvoc(void) {
|
||||||
measurements.TVOC = ag.sgp41.getTvocIndex();
|
if (!configuration.hasSensorSGP) {
|
||||||
measurements.TVOCRaw = ag.sgp41.getTvocRaw();
|
return;
|
||||||
measurements.NOx = ag.sgp41.getNoxIndex();
|
}
|
||||||
measurements.NOxRaw = ag.sgp41.getNoxRaw();
|
|
||||||
|
|
||||||
Serial.println();
|
measurements.update(Measurements::TVOC, ag.sgp41.getTvocIndex());
|
||||||
Serial.printf("TVOC index: %d\r\n", measurements.TVOC);
|
measurements.update(Measurements::TVOCRaw, ag.sgp41.getTvocRaw());
|
||||||
Serial.printf("TVOC raw: %d\r\n", measurements.TVOCRaw);
|
measurements.update(Measurements::NOx, ag.sgp41.getNoxIndex());
|
||||||
Serial.printf("NOx index: %d\r\n", measurements.NOx);
|
measurements.update(Measurements::NOxRaw, ag.sgp41.getNoxRaw());
|
||||||
Serial.printf("NOx raw: %d\r\n", measurements.NOxRaw);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updatePm(void) {
|
static void updatePm(void) {
|
||||||
if (ag.pms5003.connected()) {
|
if (ag.pms5003.connected()) {
|
||||||
measurements.pm01_1 = ag.pms5003.getPm01Ae();
|
measurements.update(Measurements::PM01, ag.pms5003.getPm01Ae());
|
||||||
measurements.pm25_1 = ag.pms5003.getPm25Ae();
|
measurements.update(Measurements::PM25, ag.pms5003.getPm25Ae());
|
||||||
measurements.pm10_1 = ag.pms5003.getPm10Ae();
|
measurements.update(Measurements::PM10, ag.pms5003.getPm10Ae());
|
||||||
measurements.pm03PCount_1 = ag.pms5003.getPm03ParticleCount();
|
measurements.update(Measurements::PM03_PC, ag.pms5003.getPm03ParticleCount());
|
||||||
|
|
||||||
Serial.println();
|
|
||||||
Serial.printf("PM1 ug/m3: %d\r\n", measurements.pm01_1);
|
|
||||||
Serial.printf("PM2.5 ug/m3: %d\r\n", measurements.pm25_1);
|
|
||||||
Serial.printf("PM10 ug/m3: %d\r\n", measurements.pm10_1);
|
|
||||||
Serial.printf("PM0.3 Count: %d\r\n", measurements.pm03PCount_1);
|
|
||||||
Serial.printf("PM firmware version: %d\r\n", ag.pms5003.getFirmwareVersion());
|
|
||||||
ag.pms5003.resetFailCount();
|
|
||||||
} else {
|
} else {
|
||||||
ag.pms5003.updateFailCount();
|
measurements.update(Measurements::PM01, utils::getInvalidPmValue());
|
||||||
Serial.printf("PMS read failed %d times\r\n", ag.pms5003.getFailCount());
|
measurements.update(Measurements::PM25, utils::getInvalidPmValue());
|
||||||
if (ag.pms5003.getFailCount() >= PMS_FAIL_COUNT_SET_INVALID) {
|
measurements.update(Measurements::PM10, utils::getInvalidPmValue());
|
||||||
measurements.pm01_1 = utils::getInvalidPmValue();
|
measurements.update(Measurements::PM03_PC, utils::getInvalidPmValue());
|
||||||
measurements.pm25_1 = utils::getInvalidPmValue();
|
|
||||||
measurements.pm10_1 = utils::getInvalidPmValue();
|
|
||||||
measurements.pm03PCount_1 = utils::getInvalidPmValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ag.pms5003.getFailCount() >= ag.pms5003.getFailCountMax()) {
|
|
||||||
Serial.printf("PMS failure count reach to max set %d, restarting...", ag.pms5003.getFailCountMax());
|
|
||||||
ESP.restart();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -592,8 +575,7 @@ static void sendDataToServer(void) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String syncData = measurements.toString(false, fwMode, wifiConnector.RSSI(),
|
String syncData = measurements.toString(false, fwMode, wifiConnector.RSSI(), ag, configuration);
|
||||||
&ag, &configuration);
|
|
||||||
if (apiClient.postToServer(syncData)) {
|
if (apiClient.postToServer(syncData)) {
|
||||||
Serial.println();
|
Serial.println();
|
||||||
Serial.println(
|
Serial.println(
|
||||||
@ -604,26 +586,54 @@ static void sendDataToServer(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void tempHumUpdate(void) {
|
static void tempHumUpdate(void) {
|
||||||
delay(100);
|
|
||||||
if (ag.sht.measure()) {
|
if (ag.sht.measure()) {
|
||||||
measurements.Temperature = ag.sht.getTemperature();
|
float temp = ag.sht.getTemperature();
|
||||||
measurements.Humidity = ag.sht.getRelativeHumidity();
|
float rhum = ag.sht.getRelativeHumidity();
|
||||||
|
|
||||||
Serial.printf("Temperature in C: %0.2f\r\n", measurements.Temperature);
|
measurements.update(Measurements::Temperature, temp);
|
||||||
Serial.printf("Relative Humidity: %d\r\n", measurements.Humidity);
|
measurements.update(Measurements::Humidity, rhum);
|
||||||
Serial.printf("Temperature compensated in C: %0.2f\r\n",
|
|
||||||
measurements.Temperature);
|
|
||||||
Serial.printf("Relative Humidity compensated: %d\r\n",
|
|
||||||
measurements.Humidity);
|
|
||||||
|
|
||||||
// Update compensation temperature and humidity for SGP41
|
// Update compensation temperature and humidity for SGP41
|
||||||
if (configuration.hasSensorSGP) {
|
if (configuration.hasSensorSGP) {
|
||||||
ag.sgp41.setCompensationTemperatureHumidity(measurements.Temperature,
|
ag.sgp41.setCompensationTemperatureHumidity(temp, rhum);
|
||||||
measurements.Humidity);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
measurements.update(Measurements::Temperature, utils::getInvalidTemperature());
|
||||||
|
measurements.update(Measurements::Humidity, utils::getInvalidHumidity());
|
||||||
Serial.println("SHT read failed");
|
Serial.println("SHT read failed");
|
||||||
measurements.Temperature = utils::getInvalidTemperature();
|
|
||||||
measurements.Humidity = utils::getInvalidHumidity();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set max period for each measurement type based on sensor update interval*/
|
||||||
|
void setMeasurementMaxPeriod() {
|
||||||
|
/// Max period for S8 sensors measurements
|
||||||
|
measurements.maxPeriod(Measurements::CO2, calculateMaxPeriod(SENSOR_CO2_UPDATE_INTERVAL));
|
||||||
|
/// Max period for SGP sensors measurements
|
||||||
|
measurements.maxPeriod(Measurements::TVOC, calculateMaxPeriod(SENSOR_TVOC_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::TVOCRaw, calculateMaxPeriod(SENSOR_TVOC_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::NOx, calculateMaxPeriod(SENSOR_TVOC_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::NOxRaw, calculateMaxPeriod(SENSOR_TVOC_UPDATE_INTERVAL));
|
||||||
|
/// Max period for PMS sensors measurements
|
||||||
|
measurements.maxPeriod(Measurements::PM25, calculateMaxPeriod(SENSOR_PM_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::PM01, calculateMaxPeriod(SENSOR_PM_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::PM10, calculateMaxPeriod(SENSOR_PM_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::PM03_PC, calculateMaxPeriod(SENSOR_PM_UPDATE_INTERVAL));
|
||||||
|
// Temperature and Humidity
|
||||||
|
if (configuration.hasSensorSHT) {
|
||||||
|
/// Max period for SHT sensors measurements
|
||||||
|
measurements.maxPeriod(Measurements::Temperature,
|
||||||
|
calculateMaxPeriod(SENSOR_TEMP_HUM_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::Humidity,
|
||||||
|
calculateMaxPeriod(SENSOR_TEMP_HUM_UPDATE_INTERVAL));
|
||||||
|
} else {
|
||||||
|
/// Temp and hum data retrieved from PMS5003T sensor
|
||||||
|
measurements.maxPeriod(Measurements::Temperature,
|
||||||
|
calculateMaxPeriod(SENSOR_PM_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::Humidity, calculateMaxPeriod(SENSOR_PM_UPDATE_INTERVAL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int calculateMaxPeriod(int updateInterval) {
|
||||||
|
// 0.5 is 50% reduced interval for max period
|
||||||
|
return (SERVER_SYNC_INTERVAL - (SERVER_SYNC_INTERVAL * 0.5)) / updateInterval;
|
||||||
|
}
|
@ -53,9 +53,8 @@ void LocalServer::_GET_metrics(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LocalServer::_GET_measure(void) {
|
void LocalServer::_GET_measure(void) {
|
||||||
server.send(
|
String toSend = measure.toString(true, fwMode, wifiConnector.RSSI(), *ag, config);
|
||||||
200, "application/json",
|
server.send(200, "application/json", toSend);
|
||||||
measure.toString(true, fwMode, wifiConnector.RSSI(), ag, &config));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalServer::setFwMode(AgFirmwareMode fwMode) { this->fwMode = fwMode; }
|
void LocalServer::setFwMode(AgFirmwareMode fwMode) { this->fwMode = fwMode; }
|
||||||
|
@ -73,19 +73,30 @@ String OpenMetrics::getPayload(void) {
|
|||||||
int pm03PCount = utils::getInvalidPmValue();
|
int pm03PCount = utils::getInvalidPmValue();
|
||||||
int atmpCompensated = utils::getInvalidTemperature();
|
int atmpCompensated = utils::getInvalidTemperature();
|
||||||
int ahumCompensated = utils::getInvalidHumidity();
|
int ahumCompensated = utils::getInvalidHumidity();
|
||||||
|
int tvoc = utils::getInvalidVOC();
|
||||||
|
int tvoc_raw = utils::getInvalidVOC();
|
||||||
|
int nox = utils::getInvalidNOx();
|
||||||
|
int nox_raw = utils::getInvalidNOx();
|
||||||
|
|
||||||
if (config.hasSensorSHT) {
|
if (config.hasSensorSHT) {
|
||||||
_temp = measure.Temperature;
|
_temp = measure.getFloat(Measurements::Temperature);
|
||||||
_hum = measure.Humidity;
|
_hum = measure.getFloat(Measurements::Humidity);
|
||||||
atmpCompensated = _temp;
|
atmpCompensated = _temp;
|
||||||
ahumCompensated = _hum;
|
ahumCompensated = _hum;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.hasSensorPMS1) {
|
if (config.hasSensorPMS1) {
|
||||||
pm01 = measure.pm01_1;
|
pm01 = measure.get(Measurements::PM01);
|
||||||
pm25 = measure.pm25_1;
|
pm25 = measure.get(Measurements::PM25);
|
||||||
pm10 = measure.pm10_1;
|
pm10 = measure.get(Measurements::PM10);
|
||||||
pm03PCount = measure.pm03PCount_1;
|
pm03PCount = measure.get(Measurements::PM03_PC);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.hasSensorSGP) {
|
||||||
|
tvoc = measure.get(Measurements::TVOC);
|
||||||
|
tvoc_raw = measure.get(Measurements::TVOCRaw);
|
||||||
|
nox = measure.get(Measurements::NOx);
|
||||||
|
nox_raw = measure.get(Measurements::NOxRaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.hasSensorPMS1) {
|
if (config.hasSensorPMS1) {
|
||||||
@ -120,33 +131,33 @@ String OpenMetrics::getPayload(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (config.hasSensorSGP) {
|
if (config.hasSensorSGP) {
|
||||||
if (utils::isValidVOC(measure.TVOC)) {
|
if (utils::isValidVOC(tvoc)) {
|
||||||
add_metric("tvoc_index",
|
add_metric("tvoc_index",
|
||||||
"The processed Total Volatile Organic Compounds (TVOC) index "
|
"The processed Total Volatile Organic Compounds (TVOC) index "
|
||||||
"as measured by the AirGradient SGP sensor",
|
"as measured by the AirGradient SGP sensor",
|
||||||
"gauge");
|
"gauge");
|
||||||
add_metric_point("", String(measure.TVOC));
|
add_metric_point("", String(tvoc));
|
||||||
}
|
}
|
||||||
if (utils::isValidVOC(measure.TVOCRaw)) {
|
if (utils::isValidVOC(tvoc_raw)) {
|
||||||
add_metric("tvoc_raw",
|
add_metric("tvoc_raw",
|
||||||
"The raw input value to the Total Volatile Organic Compounds "
|
"The raw input value to the Total Volatile Organic Compounds "
|
||||||
"(TVOC) index as measured by the AirGradient SGP sensor",
|
"(TVOC) index as measured by the AirGradient SGP sensor",
|
||||||
"gauge");
|
"gauge");
|
||||||
add_metric_point("", String(measure.TVOCRaw));
|
add_metric_point("", String(tvoc_raw));
|
||||||
}
|
}
|
||||||
if (utils::isValidNOx(measure.NOx)) {
|
if (utils::isValidNOx(nox)) {
|
||||||
add_metric("nox_index",
|
add_metric("nox_index",
|
||||||
"The processed Nitrous Oxide (NOx) index as measured by the "
|
"The processed Nitrous Oxide (NOx) index as measured by the "
|
||||||
"AirGradient SGP sensor",
|
"AirGradient SGP sensor",
|
||||||
"gauge");
|
"gauge");
|
||||||
add_metric_point("", String(measure.NOx));
|
add_metric_point("", String(nox));
|
||||||
}
|
}
|
||||||
if (utils::isValidNOx(measure.NOxRaw)) {
|
if (utils::isValidNOx(nox_raw)) {
|
||||||
add_metric("nox_raw",
|
add_metric("nox_raw",
|
||||||
"The raw input value to the Nitrous Oxide (NOx) index as "
|
"The raw input value to the Nitrous Oxide (NOx) index as "
|
||||||
"measured by the AirGradient SGP sensor",
|
"measured by the AirGradient SGP sensor",
|
||||||
"gauge");
|
"gauge");
|
||||||
add_metric_point("", String(measure.NOxRaw));
|
add_metric_point("", String(nox_raw));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,9 +49,8 @@ CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License
|
|||||||
#define SENSOR_TVOC_UPDATE_INTERVAL 1000 /** ms */
|
#define SENSOR_TVOC_UPDATE_INTERVAL 1000 /** ms */
|
||||||
#define SENSOR_CO2_UPDATE_INTERVAL 4000 /** ms */
|
#define SENSOR_CO2_UPDATE_INTERVAL 4000 /** ms */
|
||||||
#define SENSOR_PM_UPDATE_INTERVAL 2000 /** ms */
|
#define SENSOR_PM_UPDATE_INTERVAL 2000 /** ms */
|
||||||
#define SENSOR_TEMP_HUM_UPDATE_INTERVAL 2000 /** ms */
|
#define SENSOR_TEMP_HUM_UPDATE_INTERVAL 6000 /** ms */
|
||||||
#define DISPLAY_DELAY_SHOW_CONTENT_MS 2000 /** ms */
|
#define DISPLAY_DELAY_SHOW_CONTENT_MS 2000 /** ms */
|
||||||
#define FIRMWARE_CHECK_FOR_UPDATE_MS (60 * 60 * 1000) /** ms */
|
|
||||||
|
|
||||||
static AirGradient ag(DIY_PRO_INDOOR_V4_2);
|
static AirGradient ag(DIY_PRO_INDOOR_V4_2);
|
||||||
static Configuration configuration(Serial);
|
static Configuration configuration(Serial);
|
||||||
@ -69,7 +68,6 @@ static LocalServer localServer(Serial, openMetrics, measurements, configuration,
|
|||||||
static MqttClient mqttClient(Serial);
|
static MqttClient mqttClient(Serial);
|
||||||
|
|
||||||
static uint32_t factoryBtnPressTime = 0;
|
static uint32_t factoryBtnPressTime = 0;
|
||||||
static int getCO2FailCount = 0;
|
|
||||||
static AgFirmwareMode fwMode = FW_MODE_I_42PS;
|
static AgFirmwareMode fwMode = FW_MODE_I_42PS;
|
||||||
|
|
||||||
static String fwNewVersion;
|
static String fwNewVersion;
|
||||||
@ -91,6 +89,8 @@ static void wdgFeedUpdate(void);
|
|||||||
static bool sgp41Init(void);
|
static bool sgp41Init(void);
|
||||||
static void wifiFactoryConfigure(void);
|
static void wifiFactoryConfigure(void);
|
||||||
static void mqttHandle(void);
|
static void mqttHandle(void);
|
||||||
|
static int calculateMaxPeriod(int updateInterval);
|
||||||
|
static void setMeasurementMaxPeriod();
|
||||||
|
|
||||||
AgSchedule dispLedSchedule(DISP_UPDATE_INTERVAL, oledDisplaySchedule);
|
AgSchedule dispLedSchedule(DISP_UPDATE_INTERVAL, oledDisplaySchedule);
|
||||||
AgSchedule configSchedule(SERVER_CONFIG_SYNC_INTERVAL,
|
AgSchedule configSchedule(SERVER_CONFIG_SYNC_INTERVAL,
|
||||||
@ -131,6 +131,10 @@ void setup() {
|
|||||||
|
|
||||||
/** Init sensor */
|
/** Init sensor */
|
||||||
boardInit();
|
boardInit();
|
||||||
|
setMeasurementMaxPeriod();
|
||||||
|
|
||||||
|
// Uncomment below line to print every measurements reading update
|
||||||
|
// measurements.setDebug(true);
|
||||||
|
|
||||||
/** Connecting wifi */
|
/** Connecting wifi */
|
||||||
bool connectToWifi = false;
|
bool connectToWifi = false;
|
||||||
@ -255,17 +259,16 @@ void loop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void co2Update(void) {
|
static void co2Update(void) {
|
||||||
|
if (!configuration.hasSensorS8) {
|
||||||
|
// Device don't have S8 sensor
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int value = ag.s8.getCo2();
|
int value = ag.s8.getCo2();
|
||||||
if (utils::isValidCO2(value)) {
|
if (utils::isValidCO2(value)) {
|
||||||
measurements.CO2 = value;
|
measurements.update(Measurements::CO2, value);
|
||||||
getCO2FailCount = 0;
|
|
||||||
Serial.printf("CO2 (ppm): %d\r\n", measurements.CO2);
|
|
||||||
} else {
|
} else {
|
||||||
getCO2FailCount++;
|
measurements.update(Measurements::CO2, utils::getInvalidCO2());
|
||||||
Serial.printf("Get CO2 failed: %d\r\n", getCO2FailCount);
|
|
||||||
if (getCO2FailCount >= 3) {
|
|
||||||
measurements.CO2 = utils::getInvalidCO2();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,8 +396,7 @@ static void mqttHandle(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mqttClient.isConnected()) {
|
if (mqttClient.isConnected()) {
|
||||||
String payload = measurements.toString(true, fwMode, wifiConnector.RSSI(),
|
String payload = measurements.toString(true, fwMode, wifiConnector.RSSI(), ag, configuration);
|
||||||
&ag, &configuration);
|
|
||||||
String topic = "airgradient/readings/" + ag.deviceId();
|
String topic = "airgradient/readings/" + ag.deviceId();
|
||||||
if (mqttClient.publish(topic.c_str(), payload.c_str(), payload.length())) {
|
if (mqttClient.publish(topic.c_str(), payload.c_str(), payload.length())) {
|
||||||
Serial.println("MQTT sync success");
|
Serial.println("MQTT sync success");
|
||||||
@ -583,46 +585,27 @@ static void oledDisplaySchedule(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void updateTvoc(void) {
|
static void updateTvoc(void) {
|
||||||
measurements.TVOC = ag.sgp41.getTvocIndex();
|
if (!configuration.hasSensorSGP) {
|
||||||
measurements.TVOCRaw = ag.sgp41.getTvocRaw();
|
return;
|
||||||
measurements.NOx = ag.sgp41.getNoxIndex();
|
}
|
||||||
measurements.NOxRaw = ag.sgp41.getNoxRaw();
|
|
||||||
|
|
||||||
Serial.println();
|
measurements.update(Measurements::TVOC, ag.sgp41.getTvocIndex());
|
||||||
Serial.printf("TVOC index: %d\r\n", measurements.TVOC);
|
measurements.update(Measurements::TVOCRaw, ag.sgp41.getTvocRaw());
|
||||||
Serial.printf("TVOC raw: %d\r\n", measurements.TVOCRaw);
|
measurements.update(Measurements::NOx, ag.sgp41.getNoxIndex());
|
||||||
Serial.printf("NOx index: %d\r\n", measurements.NOx);
|
measurements.update(Measurements::NOxRaw, ag.sgp41.getNoxRaw());
|
||||||
Serial.printf("NOx raw: %d\r\n", measurements.NOxRaw);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updatePm(void) {
|
static void updatePm(void) {
|
||||||
if (ag.pms5003.connected()) {
|
if (ag.pms5003.connected()) {
|
||||||
measurements.pm01_1 = ag.pms5003.getPm01Ae();
|
measurements.update(Measurements::PM01, ag.pms5003.getPm01Ae());
|
||||||
measurements.pm25_1 = ag.pms5003.getPm25Ae();
|
measurements.update(Measurements::PM25, ag.pms5003.getPm25Ae());
|
||||||
measurements.pm10_1 = ag.pms5003.getPm10Ae();
|
measurements.update(Measurements::PM10, ag.pms5003.getPm10Ae());
|
||||||
measurements.pm03PCount_1 = ag.pms5003.getPm03ParticleCount();
|
measurements.update(Measurements::PM03_PC, ag.pms5003.getPm03ParticleCount());
|
||||||
|
|
||||||
Serial.println();
|
|
||||||
Serial.printf("PM1 ug/m3: %d\r\n", measurements.pm01_1);
|
|
||||||
Serial.printf("PM2.5 ug/m3: %d\r\n", measurements.pm25_1);
|
|
||||||
Serial.printf("PM10 ug/m3: %d\r\n", measurements.pm10_1);
|
|
||||||
Serial.printf("PM0.3 Count: %d\r\n", measurements.pm03PCount_1);
|
|
||||||
Serial.printf("PM firmware version: %d\r\n", ag.pms5003.getFirmwareVersion());
|
|
||||||
ag.pms5003.resetFailCount();
|
|
||||||
} else {
|
} else {
|
||||||
ag.pms5003.updateFailCount();
|
measurements.update(Measurements::PM01, utils::getInvalidPmValue());
|
||||||
Serial.printf("PMS read failed %d times\r\n", ag.pms5003.getFailCount());
|
measurements.update(Measurements::PM25, utils::getInvalidPmValue());
|
||||||
if (ag.pms5003.getFailCount() >= PMS_FAIL_COUNT_SET_INVALID) {
|
measurements.update(Measurements::PM10, utils::getInvalidPmValue());
|
||||||
measurements.pm01_1 = utils::getInvalidPmValue();
|
measurements.update(Measurements::PM03_PC, utils::getInvalidPmValue());
|
||||||
measurements.pm25_1 = utils::getInvalidPmValue();
|
|
||||||
measurements.pm10_1 = utils::getInvalidPmValue();
|
|
||||||
measurements.pm03PCount_1 = utils::getInvalidPmValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ag.pms5003.getFailCount() >= ag.pms5003.getFailCountMax()) {
|
|
||||||
Serial.printf("PMS failure count reach to max set %d, restarting...", ag.pms5003.getFailCountMax());
|
|
||||||
ESP.restart();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -633,8 +616,7 @@ static void sendDataToServer(void) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String syncData = measurements.toString(false, fwMode, wifiConnector.RSSI(),
|
String syncData = measurements.toString(false, fwMode, wifiConnector.RSSI(), ag, configuration);
|
||||||
&ag, &configuration);
|
|
||||||
if (apiClient.postToServer(syncData)) {
|
if (apiClient.postToServer(syncData)) {
|
||||||
Serial.println();
|
Serial.println();
|
||||||
Serial.println(
|
Serial.println(
|
||||||
@ -645,26 +627,54 @@ static void sendDataToServer(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void tempHumUpdate(void) {
|
static void tempHumUpdate(void) {
|
||||||
delay(100);
|
|
||||||
if (ag.sht.measure()) {
|
if (ag.sht.measure()) {
|
||||||
measurements.Temperature = ag.sht.getTemperature();
|
float temp = ag.sht.getTemperature();
|
||||||
measurements.Humidity = ag.sht.getRelativeHumidity();
|
float rhum = ag.sht.getRelativeHumidity();
|
||||||
|
|
||||||
Serial.printf("Temperature in C: %0.2f\r\n", measurements.Temperature);
|
measurements.update(Measurements::Temperature, temp);
|
||||||
Serial.printf("Relative Humidity: %d\r\n", measurements.Humidity);
|
measurements.update(Measurements::Humidity, rhum);
|
||||||
Serial.printf("Temperature compensated in C: %0.2f\r\n",
|
|
||||||
measurements.Temperature);
|
|
||||||
Serial.printf("Relative Humidity compensated: %d\r\n",
|
|
||||||
measurements.Humidity);
|
|
||||||
|
|
||||||
// Update compensation temperature and humidity for SGP41
|
// Update compensation temperature and humidity for SGP41
|
||||||
if (configuration.hasSensorSGP) {
|
if (configuration.hasSensorSGP) {
|
||||||
ag.sgp41.setCompensationTemperatureHumidity(measurements.Temperature,
|
ag.sgp41.setCompensationTemperatureHumidity(temp, rhum);
|
||||||
measurements.Humidity);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
measurements.update(Measurements::Temperature, utils::getInvalidTemperature());
|
||||||
|
measurements.update(Measurements::Humidity, utils::getInvalidHumidity());
|
||||||
Serial.println("SHT read failed");
|
Serial.println("SHT read failed");
|
||||||
measurements.Temperature = utils::getInvalidTemperature();
|
|
||||||
measurements.Humidity = utils::getInvalidHumidity();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set max period for each measurement type based on sensor update interval*/
|
||||||
|
void setMeasurementMaxPeriod() {
|
||||||
|
/// Max period for S8 sensors measurements
|
||||||
|
measurements.maxPeriod(Measurements::CO2, calculateMaxPeriod(SENSOR_CO2_UPDATE_INTERVAL));
|
||||||
|
/// Max period for SGP sensors measurements
|
||||||
|
measurements.maxPeriod(Measurements::TVOC, calculateMaxPeriod(SENSOR_TVOC_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::TVOCRaw, calculateMaxPeriod(SENSOR_TVOC_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::NOx, calculateMaxPeriod(SENSOR_TVOC_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::NOxRaw, calculateMaxPeriod(SENSOR_TVOC_UPDATE_INTERVAL));
|
||||||
|
/// Max period for PMS sensors measurements
|
||||||
|
measurements.maxPeriod(Measurements::PM25, calculateMaxPeriod(SENSOR_PM_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::PM01, calculateMaxPeriod(SENSOR_PM_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::PM10, calculateMaxPeriod(SENSOR_PM_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::PM03_PC, calculateMaxPeriod(SENSOR_PM_UPDATE_INTERVAL));
|
||||||
|
// Temperature and Humidity
|
||||||
|
if (configuration.hasSensorSHT) {
|
||||||
|
/// Max period for SHT sensors measurements
|
||||||
|
measurements.maxPeriod(Measurements::Temperature,
|
||||||
|
calculateMaxPeriod(SENSOR_TEMP_HUM_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::Humidity,
|
||||||
|
calculateMaxPeriod(SENSOR_TEMP_HUM_UPDATE_INTERVAL));
|
||||||
|
} else {
|
||||||
|
/// Temp and hum data retrieved from PMS5003T sensor
|
||||||
|
measurements.maxPeriod(Measurements::Temperature,
|
||||||
|
calculateMaxPeriod(SENSOR_PM_UPDATE_INTERVAL));
|
||||||
|
measurements.maxPeriod(Measurements::Humidity, calculateMaxPeriod(SENSOR_PM_UPDATE_INTERVAL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int calculateMaxPeriod(int updateInterval) {
|
||||||
|
// 0.5 is 50% reduced interval for max period
|
||||||
|
return (SERVER_SYNC_INTERVAL - (SERVER_SYNC_INTERVAL * 0.5)) / updateInterval;
|
||||||
|
}
|
@ -53,9 +53,8 @@ void LocalServer::_GET_metrics(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LocalServer::_GET_measure(void) {
|
void LocalServer::_GET_measure(void) {
|
||||||
server.send(
|
String toSend = measure.toString(true, fwMode, wifiConnector.RSSI(), *ag, config);
|
||||||
200, "application/json",
|
server.send(200, "application/json", toSend);
|
||||||
measure.toString(true, fwMode, wifiConnector.RSSI(), ag, &config));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalServer::setFwMode(AgFirmwareMode fwMode) { this->fwMode = fwMode; }
|
void LocalServer::setFwMode(AgFirmwareMode fwMode) { this->fwMode = fwMode; }
|
||||||
|
@ -73,19 +73,30 @@ String OpenMetrics::getPayload(void) {
|
|||||||
int pm03PCount = utils::getInvalidPmValue();
|
int pm03PCount = utils::getInvalidPmValue();
|
||||||
int atmpCompensated = utils::getInvalidTemperature();
|
int atmpCompensated = utils::getInvalidTemperature();
|
||||||
int ahumCompensated = utils::getInvalidHumidity();
|
int ahumCompensated = utils::getInvalidHumidity();
|
||||||
|
int tvoc = utils::getInvalidVOC();
|
||||||
|
int tvoc_raw = utils::getInvalidVOC();
|
||||||
|
int nox = utils::getInvalidNOx();
|
||||||
|
int nox_raw = utils::getInvalidNOx();
|
||||||
|
|
||||||
if (config.hasSensorSHT) {
|
if (config.hasSensorSHT) {
|
||||||
_temp = measure.Temperature;
|
_temp = measure.getFloat(Measurements::Temperature);
|
||||||
_hum = measure.Humidity;
|
_hum = measure.getFloat(Measurements::Humidity);
|
||||||
atmpCompensated = _temp;
|
atmpCompensated = _temp;
|
||||||
ahumCompensated = _hum;
|
ahumCompensated = _hum;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.hasSensorPMS1) {
|
if (config.hasSensorPMS1) {
|
||||||
pm01 = measure.pm01_1;
|
pm01 = measure.get(Measurements::PM01);
|
||||||
pm25 = measure.pm25_1;
|
pm25 = measure.get(Measurements::PM25);
|
||||||
pm10 = measure.pm10_1;
|
pm10 = measure.get(Measurements::PM10);
|
||||||
pm03PCount = measure.pm03PCount_1;
|
pm03PCount = measure.get(Measurements::PM03_PC);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.hasSensorSGP) {
|
||||||
|
tvoc = measure.get(Measurements::TVOC);
|
||||||
|
tvoc_raw = measure.get(Measurements::TVOCRaw);
|
||||||
|
nox = measure.get(Measurements::NOx);
|
||||||
|
nox_raw = measure.get(Measurements::NOxRaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.hasSensorPMS1) {
|
if (config.hasSensorPMS1) {
|
||||||
@ -120,33 +131,33 @@ String OpenMetrics::getPayload(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (config.hasSensorSGP) {
|
if (config.hasSensorSGP) {
|
||||||
if (utils::isValidVOC(measure.TVOC)) {
|
if (utils::isValidVOC(tvoc)) {
|
||||||
add_metric("tvoc_index",
|
add_metric("tvoc_index",
|
||||||
"The processed Total Volatile Organic Compounds (TVOC) index "
|
"The processed Total Volatile Organic Compounds (TVOC) index "
|
||||||
"as measured by the AirGradient SGP sensor",
|
"as measured by the AirGradient SGP sensor",
|
||||||
"gauge");
|
"gauge");
|
||||||
add_metric_point("", String(measure.TVOC));
|
add_metric_point("", String(tvoc));
|
||||||
}
|
}
|
||||||
if (utils::isValidVOC(measure.TVOCRaw)) {
|
if (utils::isValidVOC(tvoc_raw)) {
|
||||||
add_metric("tvoc_raw",
|
add_metric("tvoc_raw",
|
||||||
"The raw input value to the Total Volatile Organic Compounds "
|
"The raw input value to the Total Volatile Organic Compounds "
|
||||||
"(TVOC) index as measured by the AirGradient SGP sensor",
|
"(TVOC) index as measured by the AirGradient SGP sensor",
|
||||||
"gauge");
|
"gauge");
|
||||||
add_metric_point("", String(measure.TVOCRaw));
|
add_metric_point("", String(tvoc_raw));
|
||||||
}
|
}
|
||||||
if (utils::isValidNOx(measure.NOx)) {
|
if (utils::isValidNOx(nox)) {
|
||||||
add_metric("nox_index",
|
add_metric("nox_index",
|
||||||
"The processed Nitrous Oxide (NOx) index as measured by the "
|
"The processed Nitrous Oxide (NOx) index as measured by the "
|
||||||
"AirGradient SGP sensor",
|
"AirGradient SGP sensor",
|
||||||
"gauge");
|
"gauge");
|
||||||
add_metric_point("", String(measure.NOx));
|
add_metric_point("", String(nox));
|
||||||
}
|
}
|
||||||
if (utils::isValidNOx(measure.NOxRaw)) {
|
if (utils::isValidNOx(nox_raw)) {
|
||||||
add_metric("nox_raw",
|
add_metric("nox_raw",
|
||||||
"The raw input value to the Nitrous Oxide (NOx) index as "
|
"The raw input value to the Nitrous Oxide (NOx) index as "
|
||||||
"measured by the AirGradient SGP sensor",
|
"measured by the AirGradient SGP sensor",
|
||||||
"gauge");
|
"gauge");
|
||||||
add_metric_point("", String(measure.NOxRaw));
|
add_metric_point("", String(nox_raw));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,6 @@ static LocalServer localServer(Serial, openMetrics, measurements, configuration,
|
|||||||
wifiConnector);
|
wifiConnector);
|
||||||
|
|
||||||
static uint32_t factoryBtnPressTime = 0;
|
static uint32_t factoryBtnPressTime = 0;
|
||||||
static int getCO2FailCount = 0;
|
|
||||||
static AgFirmwareMode fwMode = FW_MODE_I_9PSL;
|
static AgFirmwareMode fwMode = FW_MODE_I_9PSL;
|
||||||
|
|
||||||
static bool ledBarButtonTest = false;
|
static bool ledBarButtonTest = false;
|
||||||
@ -324,14 +323,13 @@ void loop() {
|
|||||||
|
|
||||||
static void co2Update(void) {
|
static void co2Update(void) {
|
||||||
if (!configuration.hasSensorS8) {
|
if (!configuration.hasSensorS8) {
|
||||||
// Device don't have SHT sensor
|
// Device don't have S8 sensor
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int value = ag->s8.getCo2();
|
int value = ag->s8.getCo2();
|
||||||
if (utils::isValidCO2(value)) {
|
if (utils::isValidCO2(value)) {
|
||||||
measurements.update(Measurements::CO2, value);
|
measurements.update(Measurements::CO2, value);
|
||||||
// Serial.printf("CO2 (ppm): %d\r\n", measurements.CO2);
|
|
||||||
} else {
|
} else {
|
||||||
measurements.update(Measurements::CO2, utils::getInvalidCO2());
|
measurements.update(Measurements::CO2, utils::getInvalidCO2());
|
||||||
}
|
}
|
||||||
@ -996,12 +994,6 @@ static void updateTvoc(void) {
|
|||||||
measurements.update(Measurements::TVOCRaw, ag->sgp41.getTvocRaw());
|
measurements.update(Measurements::TVOCRaw, ag->sgp41.getTvocRaw());
|
||||||
measurements.update(Measurements::NOx, ag->sgp41.getNoxIndex());
|
measurements.update(Measurements::NOx, ag->sgp41.getNoxIndex());
|
||||||
measurements.update(Measurements::NOxRaw, ag->sgp41.getNoxRaw());
|
measurements.update(Measurements::NOxRaw, ag->sgp41.getNoxRaw());
|
||||||
|
|
||||||
// Serial.println();
|
|
||||||
// Serial.printf("TVOC index: %d\r\n", measurements.TVOC);
|
|
||||||
// Serial.printf("TVOC raw: %d\r\n", measurements.TVOCRaw);
|
|
||||||
// Serial.printf("NOx index: %d\r\n", measurements.NOx);
|
|
||||||
// Serial.printf("NOx raw: %d\r\n", measurements.NOxRaw);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updatePMS5003() {
|
static void updatePMS5003() {
|
||||||
@ -1010,13 +1002,6 @@ static void updatePMS5003() {
|
|||||||
measurements.update(Measurements::PM25, ag->pms5003.getPm25Ae());
|
measurements.update(Measurements::PM25, ag->pms5003.getPm25Ae());
|
||||||
measurements.update(Measurements::PM10, ag->pms5003.getPm10Ae());
|
measurements.update(Measurements::PM10, ag->pms5003.getPm10Ae());
|
||||||
measurements.update(Measurements::PM03_PC, ag->pms5003.getPm03ParticleCount());
|
measurements.update(Measurements::PM03_PC, ag->pms5003.getPm03ParticleCount());
|
||||||
|
|
||||||
// Serial.println();
|
|
||||||
// Serial.printf("PM1 ug/m3: %d\r\n", measurements.pm01_1);
|
|
||||||
// Serial.printf("PM2.5 ug/m3: %d\r\n", measurements.pm25_1);
|
|
||||||
// Serial.printf("PM10 ug/m3: %d\r\n", measurements.pm10_1);
|
|
||||||
// Serial.printf("PM0.3 Count: %d\r\n", measurements.pm03PCount_1);
|
|
||||||
// Serial.printf("PM firmware version: %d\r\n", ag->pms5003.getFirmwareVersion());
|
|
||||||
} else {
|
} else {
|
||||||
measurements.update(Measurements::PM01, utils::getInvalidPmValue());
|
measurements.update(Measurements::PM01, utils::getInvalidPmValue());
|
||||||
measurements.update(Measurements::PM25, utils::getInvalidPmValue());
|
measurements.update(Measurements::PM25, utils::getInvalidPmValue());
|
||||||
@ -1133,11 +1118,6 @@ static void tempHumUpdate(void) {
|
|||||||
measurements.update(Measurements::Temperature, temp);
|
measurements.update(Measurements::Temperature, temp);
|
||||||
measurements.update(Measurements::Humidity, rhum);
|
measurements.update(Measurements::Humidity, rhum);
|
||||||
|
|
||||||
// Serial.printf("Temperature in C: %0.2f\n", temp);
|
|
||||||
// Serial.printf("Relative Humidity: %d\n", rhum);
|
|
||||||
// Serial.printf("Temperature compensated in C: %0.2f\n", temp);
|
|
||||||
// Serial.printf("Relative Humidity compensated: %0.2f\n", rhum);
|
|
||||||
|
|
||||||
// Update compensation temperature and humidity for SGP41
|
// Update compensation temperature and humidity for SGP41
|
||||||
if (configuration.hasSensorSGP) {
|
if (configuration.hasSensorSGP) {
|
||||||
ag->sgp41.setCompensationTemperatureHumidity(temp, rhum);
|
ag->sgp41.setCompensationTemperatureHumidity(temp, rhum);
|
||||||
|
@ -42,14 +42,14 @@ public:
|
|||||||
Temperature,
|
Temperature,
|
||||||
Humidity,
|
Humidity,
|
||||||
CO2,
|
CO2,
|
||||||
TVOC,
|
TVOC, // index value
|
||||||
TVOCRaw,
|
TVOCRaw,
|
||||||
NOx,
|
NOx, // index value
|
||||||
NOxRaw,
|
NOxRaw,
|
||||||
PM25,
|
PM25,
|
||||||
PM01,
|
PM01,
|
||||||
PM10,
|
PM10,
|
||||||
PM03_PC,
|
PM03_PC, // Particle count
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -125,9 +125,9 @@ private:
|
|||||||
FloatValue _temperature[2];
|
FloatValue _temperature[2];
|
||||||
FloatValue _humidity[2];
|
FloatValue _humidity[2];
|
||||||
IntegerValue _co2;
|
IntegerValue _co2;
|
||||||
IntegerValue _tvoc;
|
IntegerValue _tvoc; // Index value
|
||||||
IntegerValue _tvoc_raw;
|
IntegerValue _tvoc_raw;
|
||||||
IntegerValue _nox;
|
IntegerValue _nox; // Index value
|
||||||
IntegerValue _nox_raw;
|
IntegerValue _nox_raw;
|
||||||
IntegerValue _pm_25[2];
|
IntegerValue _pm_25[2];
|
||||||
IntegerValue _pm_01[2];
|
IntegerValue _pm_01[2];
|
||||||
|
Reference in New Issue
Block a user