clarifying method/variable/class names

This commit is contained in:
Phat Nguyen
2024-04-07 16:39:01 +07:00
parent 9a03fb2bd7
commit 4577082731
21 changed files with 1372 additions and 1279 deletions

View File

@ -15,7 +15,6 @@ https://www.airgradient.com/documentation/diy-v4/
Following libraries need to be installed:
“WifiManager by tzapu, tablatronix” tested with version 2.0.16-rc.2
"Arduino_JSON" by Arduino version 0.2.0
"U8g2" by oliver version 2.34.22
Please make sure you have esp8266 board manager installed. Tested with
version 3.1.2.
@ -32,15 +31,15 @@ CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License
*/
#include <AirGradient.h>
#include "AgSchedule.h"
#include "AgConfigure.h"
#include "AgApiClient.h"
#include "AgConfigure.h"
#include "AgSchedule.h"
#include "AgWiFiConnector.h"
#include <AirGradient.h>
#include <Arduino_JSON.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <WiFiManager.h>
#define WIFI_CONNECT_COUNTDOWN_MAX 180 /** sec */
#define WIFI_CONNECT_RETRY_MS 10000 /** ms */
@ -61,20 +60,19 @@ CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License
/** Create airgradient instance for 'DIY_BASIC' board */
static AirGradient ag = AirGradient(DIY_BASIC);
static AgConfigure localConfig(Serial);
static AgApiClient apiClient(Serial, localConfig);
static Configuration configuration(Serial);
static AgApiClient apiClient(Serial, configuration);
static WifiConnector wifiConnector(Serial);
static int co2Ppm = -1;
static int pm25 = -1;
static float temp = -1001;
static int hum = -1;
static long val;
static String wifiSSID = "";
static bool wifiHasConfig = false; /** */
static void boardInit(void);
static void failedHandler(String msg);
static void co2Calibration(void);
static void executeCo2Calibration(void);
static void updateServerConfiguration(void);
static void co2Update(void);
static void pmUpdate(void);
@ -82,7 +80,6 @@ static void tempHumUpdate(void);
static void sendDataToServer(void);
static void dispHandler(void);
static String getDevId(void);
static void updateWiFiConnect(void);
static void showNr(void);
bool hasSensorS8 = true;
@ -112,23 +109,24 @@ void setup() {
/** Init AirGradient server */
apiClient.begin();
apiClient.setAirGradient(&ag);
wifiConnector.setAirGradient(&ag);
/** Show boot display */
displayShowText("DIY basic", "Lib:" + ag.getVersion(), "");
delay(2000);
/** WiFi connect */
connectToWifi();
if (WiFi.status() == WL_CONNECTED) {
wifiHasConfig = true;
sendPing();
// connectToWifi();
if (wifiConnector.connect()) {
if (WiFi.status() == WL_CONNECTED) {
sendDataToAg();
apiClient.fetchServerConfiguration();
if (localConfig.isCo2CalibrationRequested()) {
co2Calibration();
apiClient.fetchServerConfiguration();
if (configuration.isCo2CalibrationRequested()) {
executeCo2Calibration();
}
}
}
/** Show serial number display */
ag.display.clear();
ag.display.setCursor(1, 1);
@ -162,13 +160,13 @@ void loop() {
tempHumSchedule.run();
}
updateWiFiConnect();
wifiConnector.handle();
/** Read PMS on loop */
ag.pms5003.handle();
}
static void sendPing() {
static void sendDataToAg() {
JSONVar root;
root["wifi"] = WiFi.RSSI();
root["boot"] = 0;
@ -197,39 +195,6 @@ void displayShowText(String ln1, String ln2, String ln3) {
delay(100);
}
// Wifi Manager
void connectToWifi() {
WiFiManager wifiManager;
wifiSSID = "AG-" + String(ESP.getChipId(), HEX);
wifiManager.setConfigPortalBlocking(false);
wifiManager.setConfigPortalTimeout(WIFI_CONNECT_COUNTDOWN_MAX);
wifiManager.autoConnect(wifiSSID.c_str(), WIFI_HOTSPOT_PASSWORD_DEFAULT);
uint32_t lastTime = millis();
int count = WIFI_CONNECT_COUNTDOWN_MAX;
displayShowText(String(WIFI_CONNECT_COUNTDOWN_MAX) + " sec",
"SSID:", wifiSSID);
while (wifiManager.getConfigPortalActive()) {
wifiManager.process();
uint32_t ms = (uint32_t)(millis() - lastTime);
if (ms >= 1000) {
lastTime = millis();
displayShowText(String(count) + " sec", "SSID:", wifiSSID);
count--;
// Timeout
if (count == 0) {
break;
}
}
}
if (!WiFi.isConnected()) {
displayShowText("Booting", "offline", "mode");
Serial.println("failed to connect and hit timeout");
delay(DISPLAY_DELAY_SHOW_CONTENT_MS);
}
}
static void boardInit(void) {
/** Init SHT sensor */
if (ag.sht.begin(Wire) == false) {
@ -264,7 +229,7 @@ static void failedHandler(String msg) {
}
}
static void co2Calibration(void) {
static void executeCo2Calibration(void) {
/** Count down for co2CalibCountdown secs */
for (int i = 0; i < SENSOR_CO2_CALIB_COUNTDOWN_MAX; i++) {
displayShowText("CO2 calib", "after",
@ -291,25 +256,25 @@ static void co2Calibration(void) {
static void updateServerConfiguration(void) {
if (apiClient.fetchServerConfiguration()) {
if (localConfig.isCo2CalibrationRequested()) {
if (configuration.isCo2CalibrationRequested()) {
if (hasSensorS8) {
co2Calibration();
executeCo2Calibration();
} else {
Serial.println("CO2 S8 not available, calib ignored");
}
}
if (localConfig.getCO2CalirationAbcDays() > 0) {
if (configuration.getCO2CalibrationAbcDays() > 0) {
if (hasSensorS8) {
int newHour = localConfig.getCO2CalirationAbcDays() * 24;
int newHour = configuration.getCO2CalibrationAbcDays() * 24;
Serial.printf("abcDays config: %d days(%d hours)\r\n",
localConfig.getCO2CalirationAbcDays(), newHour);
configuration.getCO2CalibrationAbcDays(), newHour);
int curHour = ag.s8.getAbcPeriod();
Serial.printf("Current config: %d (hours)\r\n", curHour);
if (curHour == newHour) {
Serial.println("set 'abcDays' ignored");
} else {
if (ag.s8.setAbcPeriod(localConfig.getCO2CalirationAbcDays() * 24) ==
false) {
if (ag.s8.setAbcPeriod(configuration.getCO2CalibrationAbcDays() *
24) == false) {
Serial.println("Set S8 abcDays period calib failed");
} else {
Serial.println("Set S8 abcDays period calib success");
@ -388,7 +353,7 @@ static void dispHandler() {
String ln2 = "";
String ln3 = "";
if (localConfig.isPmStandardInUSAQI()) {
if (configuration.isPmStandardInUSAQI()) {
if (pm25 < 0) {
ln1 = "AQI: -";
} else {
@ -415,7 +380,7 @@ static void dispHandler() {
String _temp = "-";
if (localConfig.isTemperatureUnitInF()) {
if (configuration.isTemperatureUnitInF()) {
if (temp > -1001) {
_temp = String((temp * 9 / 5) + 32).substring(0, 4);
}
@ -431,27 +396,6 @@ static void dispHandler() {
static String getDevId(void) { return getNormalizedMac(); }
/**
* @brief WiFi reconnect handler
*/
static void updateWiFiConnect(void) {
static uint32_t lastRetry;
if (wifiHasConfig == false) {
return;
}
if (WiFi.isConnected()) {
lastRetry = millis();
return;
}
uint32_t ms = (uint32_t)(millis() - lastRetry);
if (ms >= WIFI_CONNECT_RETRY_MS) {
lastRetry = millis();
WiFi.reconnect();
Serial.printf("Re-Connect WiFi\r\n");
}
}
static void showNr(void) {
Serial.println();
Serial.println("Serial nr: " + getDevId());

View File

@ -0,0 +1,68 @@
#include "LocalServer.h"
LocalServer::LocalServer(Stream &log, OpenMetrics &openMetrics,
Measurements &measure, Configuration &config,
WifiConnector &wifiConnector)
: PrintLog(log, "LocalServer"), openMetrics(openMetrics), measure(measure),
config(config), wifiConnector(wifiConnector) {}
LocalServer::~LocalServer() {}
bool LocalServer::begin(void) {
server.on("/measures/current", HTTP_GET, [this]() { _GET_measure(); });
server.on(openMetrics.getApi(), HTTP_GET, [this]() { _GET_metrics(); });
server.on("/config", HTTP_GET, [this]() { _GET_config(); });
server.on("/config", HTTP_PUT, [this]() { _PUT_config(); });
server.begin();
if (xTaskCreate(
[](void *param) {
LocalServer *localServer = (LocalServer *)param;
for (;;) {
localServer->_handle();
}
},
"webserver", 1024 * 4, this, 5, NULL) != pdTRUE) {
Serial.println("Create task handle webserver failed");
}
logInfo("Init: " + getHostname() + ".local");
return true;
}
void LocalServer::setAirGraident(AirGradient *ag) { this->ag = ag; }
String LocalServer::getHostname(void) {
return "airgradient_" + ag->deviceId();
}
void LocalServer::_handle(void) { server.handleClient(); }
void LocalServer::_GET_config(void) {
server.send(200, "application/json", config.toString());
}
void LocalServer::_PUT_config(void) {
String data = server.arg(0);
String response = "";
int statusCode = 400; // Status code for data invalid
if (config.parse(data, true)) {
statusCode = 200;
response = "Success";
} else {
response = "Set for cloud configuration. Local configuration ignored";
}
server.send(statusCode, "text/plain", response);
}
void LocalServer::_GET_metrics(void) {
server.send(200, openMetrics.getApiContentType(), openMetrics.getPayload());
}
void LocalServer::_GET_measure(void) {
server.send(
200, "application/json",
measure.toString(true, fwMode, wifiConnector.RSSI(), ag, &config));
}
void LocalServer::setFwMode(AgFirmwareMode fwMode) { this->fwMode = fwMode; }

View File

@ -0,0 +1,38 @@
#ifndef _LOCAL_SERVER_H_
#define _LOCAL_SERVER_H_
#include "AgConfigure.h"
#include "AgValue.h"
#include "AirGradient.h"
#include "OpenMetrics.h"
#include "AgWiFiConnector.h"
#include <Arduino.h>
#include <WebServer.h>
class LocalServer : public PrintLog {
private:
AirGradient *ag;
OpenMetrics &openMetrics;
Measurements &measure;
Configuration &config;
WifiConnector &wifiConnector;
WebServer server;
AgFirmwareMode fwMode;
public:
LocalServer(Stream &log, OpenMetrics &openMetrics, Measurements &measure,
Configuration &config, WifiConnector& wifiConnector);
~LocalServer();
bool begin(void);
void setAirGraident(AirGradient *ag);
String getHostname(void);
void setFwMode(AgFirmwareMode fwMode);
void _handle(void);
void _GET_config(void);
void _PUT_config(void);
void _GET_metrics(void);
void _GET_measure(void);
};
#endif /** _LOCAL_SERVER_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,186 @@
#include "OpenMetrics.h"
OpenMetrics::OpenMetrics(Measurements &measure, Configuration &config,
WifiConnector &wifiConnector, AgApiClient &apiClient)
: measure(measure), config(config), wifiConnector(wifiConnector),
apiClient(apiClient) {}
OpenMetrics::~OpenMetrics() {}
void OpenMetrics::setAirGradient(AirGradient *ag) { this->ag = ag; }
const char *OpenMetrics::getApiContentType(void) {
return "application/openmetrics-text; version=1.0.0; charset=utf-8";
}
const char *OpenMetrics::getApi(void) { return "/metrics"; }
String OpenMetrics::getPayload(void) {
String response;
String current_metric_name;
const auto add_metric = [&](const String &name, const String &help,
const String &type, const String &unit = "") {
current_metric_name = "airgradient_" + name;
if (!unit.isEmpty())
current_metric_name += "_" + unit;
response += "# HELP " + current_metric_name + " " + help + "\n";
response += "# TYPE " + current_metric_name + " " + type + "\n";
if (!unit.isEmpty())
response += "# UNIT " + current_metric_name + " " + unit + "\n";
};
const auto add_metric_point = [&](const String &labels, const String &value) {
response += current_metric_name + "{" + labels + "} " + value + "\n";
};
add_metric("info", "AirGradient device information", "info");
add_metric_point("airgradient_serial_number=\"" + ag->deviceId() +
"\",airgradient_device_type=\"" + ag->getBoardName() +
"\",airgradient_library_version=\"" + ag->getVersion() +
"\"",
"1");
add_metric("config_ok",
"1 if the AirGradient device was able to successfully fetch its "
"configuration from the server",
"gauge");
add_metric_point("", apiClient.isFetchConfigureFailed() ? "0" : "1");
add_metric(
"post_ok",
"1 if the AirGradient device was able to successfully send to the server",
"gauge");
add_metric_point("", apiClient.isPostToServerFailed() ? "0" : "1");
add_metric(
"wifi_rssi",
"WiFi signal strength from the AirGradient device perspective, in dBm",
"gauge", "dbm");
add_metric_point("", String(wifiConnector.RSSI()));
if (config.hasSensorS8 && measure.CO2 >= 0) {
add_metric("co2",
"Carbon dioxide concentration as measured by the AirGradient S8 "
"sensor, in parts per million",
"gauge", "ppm");
add_metric_point("", String(measure.CO2));
}
float _temp = -1001;
float _hum = -1;
int pm01 = -1;
int pm25 = -1;
int pm10 = -1;
int pm03PCount = -1;
if (config.hasSensorPMS1 && config.hasSensorPMS2) {
_temp = (measure.temp_1 + measure.temp_2) / 2.0f;
_hum = (measure.hum_1 + measure.hum_2) / 2.0f;
pm01 = (measure.pm01_1 + measure.pm01_2) / 2;
pm25 = (measure.pm25_1 + measure.pm25_2) / 2;
pm10 = (measure.pm10_1 + measure.pm10_2) / 2;
pm03PCount = (measure.pm03PCount_1 + measure.pm03PCount_2) / 2;
} else {
if (ag->isOne()) {
if (config.hasSensorSHT) {
_temp = measure.Temperature;
_hum = measure.Humidity;
}
} else {
if (config.hasSensorPMS1) {
_temp = measure.temp_1;
_hum = measure.hum_1;
pm01 = measure.pm01_1;
pm25 = measure.pm25_1;
pm10 = measure.pm10_1;
pm03PCount = measure.pm03PCount_1;
}
if (config.hasSensorPMS2) {
_temp = measure.temp_2;
_hum = measure.hum_2;
pm01 = measure.pm01_2;
pm25 = measure.pm25_2;
pm10 = measure.pm10_2;
pm03PCount = measure.pm03PCount_2;
}
}
}
if (config.hasSensorPMS1 || config.hasSensorPMS2) {
if (pm01 >= 0) {
add_metric("pm1",
"PM1.0 concentration as measured by the AirGradient PMS "
"sensor, in micrograms per cubic meter",
"gauge", "ugm3");
add_metric_point("", String(pm01));
}
if (pm25 >= 0) {
add_metric("pm2d5",
"PM2.5 concentration as measured by the AirGradient PMS "
"sensor, in micrograms per cubic meter",
"gauge", "ugm3");
add_metric_point("", String(pm25));
}
if (pm10 >= 0) {
add_metric("pm10",
"PM10 concentration as measured by the AirGradient PMS "
"sensor, in micrograms per cubic meter",
"gauge", "ugm3");
add_metric_point("", String(pm10));
}
if (pm03PCount >= 0) {
add_metric("pm0d3",
"PM0.3 concentration as measured by the AirGradient PMS "
"sensor, in number of particules per 100 milliliters",
"gauge", "p100ml");
add_metric_point("", String(pm03PCount));
}
}
if (config.hasSensorSGP) {
if (measure.TVOC >= 0) {
add_metric("tvoc_index",
"The processed Total Volatile Organic Compounds (TVOC) index "
"as measured by the AirGradient SGP sensor",
"gauge");
add_metric_point("", String(measure.TVOC));
}
if (measure.TVOCRaw >= 0) {
add_metric("tvoc_raw",
"The raw input value to the Total Volatile Organic Compounds "
"(TVOC) index as measured by the AirGradient SGP sensor",
"gauge");
add_metric_point("", String(measure.TVOCRaw));
}
if (measure.NOx >= 0) {
add_metric("nox_index",
"The processed Nitrous Oxide (NOx) index as measured by the "
"AirGradient SGP sensor",
"gauge");
add_metric_point("", String(measure.NOx));
}
if (measure.NOxRaw >= 0) {
add_metric("nox_raw",
"The raw input value to the Nitrous Oxide (NOx) index as "
"measured by the AirGradient SGP sensor",
"gauge");
add_metric_point("", String(measure.NOxRaw));
}
}
if (_temp > -1001) {
add_metric("temperature",
"The ambient temperature as measured by the AirGradient SHT "
"sensor, in degrees Celsius",
"gauge", "celsius");
add_metric_point("", String(_temp));
}
if (_hum >= 0) {
add_metric(
"humidity",
"The relative humidity as measured by the AirGradient SHT sensor",
"gauge", "percent");
add_metric_point("", String(_hum));
}
response += "# EOF\n";
return response;
}

View File

@ -0,0 +1,28 @@
#ifndef _OPEN_METRICS_H_
#define _OPEN_METRICS_H_
#include "AgConfigure.h"
#include "AgValue.h"
#include "AgWiFiConnector.h"
#include "AirGradient.h"
#include "AgApiClient.h"
class OpenMetrics{
private:
AirGradient *ag;
Measurements &measure;
Configuration &config;
WifiConnector &wifiConnector;
AgApiClient &apiClient;
public:
OpenMetrics(Measurements &measure, Configuration &conig,
WifiConnector &wifiConnector, AgApiClient& apiClient);
~OpenMetrics();
void setAirGradient(AirGradient *ag);
const char *getApiContentType(void);
const char* getApi(void);
String getPayload(void);
};
#endif /** _OPEN_METRICS_H_ */