mirror of
https://github.com/airgradienthq/arduino.git
synced 2025-07-14 08:26:31 +02:00
Update BASIC.ino
example
This commit is contained in:
@ -31,190 +31,376 @@ CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License
|
|||||||
#include "AgConfigure.h"
|
#include "AgConfigure.h"
|
||||||
#include "AgSchedule.h"
|
#include "AgSchedule.h"
|
||||||
#include "AgWiFiConnector.h"
|
#include "AgWiFiConnector.h"
|
||||||
|
#include "LocalServer.h"
|
||||||
|
#include "OpenMetrics.h"
|
||||||
|
#include "MqttClient.h"
|
||||||
#include <AirGradient.h>
|
#include <AirGradient.h>
|
||||||
#include <ESP8266HTTPClient.h>
|
#include <ESP8266HTTPClient.h>
|
||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESP8266mDNS.h>
|
||||||
#include <WiFiClient.h>
|
#include <WiFiClient.h>
|
||||||
|
|
||||||
#define WIFI_CONNECT_COUNTDOWN_MAX 180 /** sec */
|
#define LED_BAR_ANIMATION_PERIOD 100 /** ms */
|
||||||
#define WIFI_CONNECT_RETRY_MS 10000 /** ms */
|
#define DISP_UPDATE_INTERVAL 2500 /** ms */
|
||||||
#define LED_BAR_COUNT_INIT_VALUE (-1) /** */
|
#define SERVER_CONFIG_SYNC_INTERVAL 60000 /** ms */
|
||||||
#define LED_BAR_ANIMATION_PERIOD 100 /** ms */
|
#define SERVER_SYNC_INTERVAL 60000 /** ms */
|
||||||
#define DISP_UPDATE_INTERVAL 5000 /** ms */
|
#define MQTT_SYNC_INTERVAL 60000 /** ms */
|
||||||
#define SERVER_CONFIG_SYNC_INTERVAL 60000 /** ms */
|
#define SENSOR_CO2_CALIB_COUNTDOWN_MAX 5 /** sec */
|
||||||
#define SERVER_SYNC_INTERVAL 60000 /** ms */
|
#define SENSOR_TVOC_UPDATE_INTERVAL 1000 /** ms */
|
||||||
#define SENSOR_CO2_CALIB_COUNTDOWN_MAX 5 /** sec */
|
#define SENSOR_CO2_UPDATE_INTERVAL 4000 /** ms */
|
||||||
#define SENSOR_TVOC_UPDATE_INTERVAL 1000 /** ms */
|
#define SENSOR_PM_UPDATE_INTERVAL 2000 /** ms */
|
||||||
#define SENSOR_CO2_UPDATE_INTERVAL 5000 /** ms */
|
#define SENSOR_TEMP_HUM_UPDATE_INTERVAL 2000 /** ms */
|
||||||
#define SENSOR_PM_UPDATE_INTERVAL 5000 /** ms */
|
#define DISPLAY_DELAY_SHOW_CONTENT_MS 2000 /** ms */
|
||||||
#define SENSOR_TEMP_HUM_UPDATE_INTERVAL 2000 /** ms */
|
#define FIRMWARE_CHECK_FOR_UPDATE_MS (60 * 60 * 1000) /** ms */
|
||||||
#define DISPLAY_DELAY_SHOW_CONTENT_MS 2000 /** ms */
|
|
||||||
#define WIFI_HOTSPOT_PASSWORD_DEFAULT \
|
|
||||||
"cleanair" /** default WiFi AP password \
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Create airgradient instance for 'DIY_BASIC' board */
|
static AirGradient ag(DIY_BASIC);
|
||||||
static AirGradient ag = AirGradient(DIY_BASIC);
|
|
||||||
static Configuration configuration(Serial);
|
static Configuration configuration(Serial);
|
||||||
static AgApiClient apiClient(Serial, configuration);
|
static AgApiClient apiClient(Serial, configuration);
|
||||||
|
|
||||||
static Measurements measurements;
|
static Measurements measurements;
|
||||||
static OledDisplay oledDisp(configuration, measurements, Serial);
|
static OledDisplay oledDisplay(configuration, measurements, Serial);
|
||||||
static StateMachine sm(oledDisp, Serial, measurements, configuration);
|
static StateMachine stateMachine(oledDisplay, Serial, measurements,
|
||||||
static WifiConnector wifiConnector(oledDisp, Serial, sm, configuration);
|
configuration);
|
||||||
|
static WifiConnector wifiConnector(oledDisplay, Serial, stateMachine,
|
||||||
|
configuration);
|
||||||
|
static OpenMetrics openMetrics(measurements, configuration, wifiConnector,
|
||||||
|
apiClient);
|
||||||
|
static LocalServer localServer(Serial, openMetrics, measurements, configuration,
|
||||||
|
wifiConnector);
|
||||||
|
static MqttClient mqttClient(Serial);
|
||||||
|
|
||||||
static int co2Ppm = -1;
|
static int pmFailCount = 0;
|
||||||
static int pm25 = -1;
|
static int getCO2FailCount = 0;
|
||||||
static float temp = -1001;
|
static AgFirmwareMode fwMode = FW_MODE_I_BASIC_40PS;
|
||||||
static int hum = -1;
|
|
||||||
|
static String fwNewVersion;
|
||||||
|
|
||||||
static void boardInit(void);
|
static void boardInit(void);
|
||||||
static void failedHandler(String msg);
|
static void failedHandler(String msg);
|
||||||
static void executeCo2Calibration(void);
|
static void configurationUpdateSchedule(void);
|
||||||
static void updateServerConfiguration(void);
|
static void appDispHandler(void);
|
||||||
static void co2Update(void);
|
static void oledDisplaySchedule(void);
|
||||||
static void pmUpdate(void);
|
static void updateTvoc(void);
|
||||||
static void tempHumUpdate(void);
|
static void updatePm(void);
|
||||||
static void sendDataToServer(void);
|
static void sendDataToServer(void);
|
||||||
static void dispHandler(void);
|
static void tempHumUpdate(void);
|
||||||
static String getDevId(void);
|
static void co2Update(void);
|
||||||
static void showNr(void);
|
static void mdnsInit(void);
|
||||||
|
static void initMqtt(void);
|
||||||
|
static void factoryConfigReset(void);
|
||||||
|
static void wdgFeedUpdate(void);
|
||||||
|
static bool sgp41Init(void);
|
||||||
|
static void wifiFactoryConfigure(void);
|
||||||
|
static void mqttHandle(void);
|
||||||
|
|
||||||
bool hasSensorS8 = true;
|
AgSchedule dispLedSchedule(DISP_UPDATE_INTERVAL, oledDisplaySchedule);
|
||||||
bool hasSensorPMS = true;
|
|
||||||
bool hasSensorSHT = true;
|
|
||||||
int pmFailCount = 0;
|
|
||||||
int getCO2FailCount = 0;
|
|
||||||
AgSchedule configSchedule(SERVER_CONFIG_SYNC_INTERVAL,
|
AgSchedule configSchedule(SERVER_CONFIG_SYNC_INTERVAL,
|
||||||
updateServerConfiguration);
|
configurationUpdateSchedule);
|
||||||
AgSchedule serverSchedule(SERVER_SYNC_INTERVAL, sendDataToServer);
|
AgSchedule agApiPostSchedule(SERVER_SYNC_INTERVAL, sendDataToServer);
|
||||||
AgSchedule dispSchedule(DISP_UPDATE_INTERVAL, dispHandler);
|
|
||||||
AgSchedule co2Schedule(SENSOR_CO2_UPDATE_INTERVAL, co2Update);
|
AgSchedule co2Schedule(SENSOR_CO2_UPDATE_INTERVAL, co2Update);
|
||||||
AgSchedule pmsSchedule(SENSOR_PM_UPDATE_INTERVAL, pmUpdate);
|
AgSchedule pmsSchedule(SENSOR_PM_UPDATE_INTERVAL, updatePm);
|
||||||
AgSchedule tempHumSchedule(SENSOR_TEMP_HUM_UPDATE_INTERVAL, tempHumUpdate);
|
AgSchedule tempHumSchedule(SENSOR_TEMP_HUM_UPDATE_INTERVAL, tempHumUpdate);
|
||||||
|
AgSchedule tvocSchedule(SENSOR_TVOC_UPDATE_INTERVAL, updateTvoc);
|
||||||
|
AgSchedule watchdogFeedSchedule(60000, wdgFeedUpdate);
|
||||||
|
AgSchedule mqttSchedule(MQTT_SYNC_INTERVAL, mqttHandle);
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
|
/** Serial for print debug message */
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
showNr();
|
delay(100); /** For bester show log */
|
||||||
|
|
||||||
|
/** Print device ID into log */
|
||||||
|
Serial.println("Serial nr: " + ag.deviceId());
|
||||||
|
|
||||||
|
/** Initialize local configure */
|
||||||
|
configuration.begin();
|
||||||
|
|
||||||
/** Init I2C */
|
/** Init I2C */
|
||||||
Wire.begin(ag.getI2cSdaPin(), ag.getI2cSclPin());
|
Wire.begin(ag.getI2cSdaPin(), ag.getI2cSclPin());
|
||||||
|
Wire.endTransmission(1);
|
||||||
delay(1000);
|
delay(1000);
|
||||||
|
|
||||||
/** Board init */
|
configuration.setAirGradient(&ag);
|
||||||
|
oledDisplay.setAirGradient(&ag);
|
||||||
|
stateMachine.setAirGradient(&ag);
|
||||||
|
wifiConnector.setAirGradient(&ag);
|
||||||
|
apiClient.setAirGradient(&ag);
|
||||||
|
openMetrics.setAirGradient(&ag);
|
||||||
|
localServer.setAirGraident(&ag);
|
||||||
|
|
||||||
|
/** Init sensor */
|
||||||
boardInit();
|
boardInit();
|
||||||
|
|
||||||
/** Init AirGradient server */
|
/** Connecting wifi */
|
||||||
apiClient.begin();
|
bool connectToWifi = false;
|
||||||
apiClient.setAirGradient(&ag);
|
|
||||||
configuration.setAirGradient(&ag);
|
|
||||||
wifiConnector.setAirGradient(&ag);
|
|
||||||
|
|
||||||
/** Show boot display */
|
connectToWifi = !configuration.isOfflineMode();
|
||||||
displayShowText("DIY basic", "Lib:" + ag.getVersion(), "");
|
if (connectToWifi) {
|
||||||
delay(2000);
|
apiClient.begin();
|
||||||
|
|
||||||
/** WiFi connect */
|
if (wifiConnector.connect()) {
|
||||||
// connectToWifi();
|
if (wifiConnector.isConnected()) {
|
||||||
if (wifiConnector.connect()) {
|
mdnsInit();
|
||||||
if (WiFi.status() == WL_CONNECTED) {
|
localServer.begin();
|
||||||
sendDataToAg();
|
initMqtt();
|
||||||
|
sendDataToAg();
|
||||||
|
|
||||||
apiClient.fetchServerConfiguration();
|
apiClient.fetchServerConfiguration();
|
||||||
if (configuration.isCo2CalibrationRequested()) {
|
configSchedule.update();
|
||||||
executeCo2Calibration();
|
if (apiClient.isFetchConfigureFailed()) {
|
||||||
|
if (apiClient.isNotAvailableOnDashboard()) {
|
||||||
|
stateMachine.displaySetAddToDashBoard();
|
||||||
|
stateMachine.displayHandle(
|
||||||
|
AgStateMachineWiFiOkServerOkSensorConfigFailed);
|
||||||
|
} else {
|
||||||
|
stateMachine.displayClearAddToDashBoard();
|
||||||
|
}
|
||||||
|
delay(DISPLAY_DELAY_SHOW_CONTENT_MS);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (wifiConnector.isConfigurePorttalTimeout()) {
|
||||||
|
oledDisplay.showRebooting();
|
||||||
|
delay(2500);
|
||||||
|
oledDisplay.setText("", "", "");
|
||||||
|
ESP.restart();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** Show serial number display */
|
/** Set offline mode without saving, cause wifi is not configured */
|
||||||
ag.display.clear();
|
if (wifiConnector.hasConfigurated() == false) {
|
||||||
ag.display.setCursor(1, 1);
|
Serial.println("Set offline mode cause wifi is not configurated");
|
||||||
ag.display.setText("Warm Up");
|
configuration.setOfflineModeWithoutSave(true);
|
||||||
ag.display.setCursor(1, 15);
|
}
|
||||||
ag.display.setText("Serial#");
|
|
||||||
ag.display.setCursor(1, 29);
|
|
||||||
String id = getNormalizedMac();
|
|
||||||
Serial.println("Device id: " + id);
|
|
||||||
String id1 = id.substring(0, 9);
|
|
||||||
String id2 = id.substring(9, 12);
|
|
||||||
ag.display.setText("\'" + id1);
|
|
||||||
ag.display.setCursor(1, 40);
|
|
||||||
ag.display.setText(id2 + "\'");
|
|
||||||
ag.display.show();
|
|
||||||
|
|
||||||
delay(5000);
|
/** Show display Warning up */
|
||||||
|
String sn = "SN:" + ag.deviceId();
|
||||||
|
oledDisplay.setText("Warming Up", sn.c_str(), "");
|
||||||
|
|
||||||
|
delay(DISPLAY_DELAY_SHOW_CONTENT_MS);
|
||||||
|
|
||||||
|
Serial.println("Display brightness: " +
|
||||||
|
String(configuration.getDisplayBrightness()));
|
||||||
|
oledDisplay.setBrightness(configuration.getDisplayBrightness());
|
||||||
|
|
||||||
|
appDispHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
/** Handle schedule */
|
||||||
|
dispLedSchedule.run();
|
||||||
configSchedule.run();
|
configSchedule.run();
|
||||||
serverSchedule.run();
|
agApiPostSchedule.run();
|
||||||
dispSchedule.run();
|
|
||||||
if (hasSensorS8) {
|
if (configuration.hasSensorS8) {
|
||||||
co2Schedule.run();
|
co2Schedule.run();
|
||||||
}
|
}
|
||||||
if (hasSensorPMS) {
|
if (configuration.hasSensorPMS1) {
|
||||||
pmsSchedule.run();
|
pmsSchedule.run();
|
||||||
|
ag.pms5003.handle();
|
||||||
}
|
}
|
||||||
if (hasSensorSHT) {
|
if (configuration.hasSensorSHT) {
|
||||||
tempHumSchedule.run();
|
tempHumSchedule.run();
|
||||||
}
|
}
|
||||||
|
if (configuration.hasSensorSGP) {
|
||||||
|
tvocSchedule.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Auto reset watchdog timer if offline mode or postDataToAirGradient */
|
||||||
|
if (configuration.isOfflineMode() ||
|
||||||
|
(configuration.isPostDataToAirGradient() == false)) {
|
||||||
|
watchdogFeedSchedule.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check for handle WiFi reconnect */
|
||||||
wifiConnector.handle();
|
wifiConnector.handle();
|
||||||
|
|
||||||
/** Read PMS on loop */
|
/** factory reset handle */
|
||||||
ag.pms5003.handle();
|
// factoryConfigReset();
|
||||||
|
|
||||||
|
/** check that local configura changed then do some action */
|
||||||
|
configUpdateHandle();
|
||||||
|
|
||||||
|
localServer._handle();
|
||||||
|
|
||||||
|
if (configuration.hasSensorSGP) {
|
||||||
|
ag.sgp41.handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
MDNS.update();
|
||||||
|
|
||||||
|
mqttSchedule.run();
|
||||||
|
mqttClient.handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void co2Update(void) {
|
||||||
|
int value = ag.s8.getCo2();
|
||||||
|
if (value >= 0) {
|
||||||
|
measurements.CO2 = value;
|
||||||
|
getCO2FailCount = 0;
|
||||||
|
Serial.printf("CO2 (ppm): %d\r\n", measurements.CO2);
|
||||||
|
} else {
|
||||||
|
getCO2FailCount++;
|
||||||
|
Serial.printf("Get CO2 failed: %d\r\n", getCO2FailCount);
|
||||||
|
if (getCO2FailCount >= 3) {
|
||||||
|
measurements.CO2 = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mdnsInit(void) {
|
||||||
|
Serial.println("mDNS init");
|
||||||
|
if (!MDNS.begin(localServer.getHostname().c_str())) {
|
||||||
|
Serial.println("Init mDNS failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MDNS.addService("_airgradient", "_tcp", 80);
|
||||||
|
MDNS.addServiceTxt("_airgradient", "_tcp", "model",
|
||||||
|
AgFirmwareModeName(fwMode));
|
||||||
|
MDNS.addServiceTxt("_airgradient", "_tcp", "serialno", ag.deviceId());
|
||||||
|
MDNS.addServiceTxt("_airgradient", "_tcp", "fw_ver", ag.getVersion());
|
||||||
|
MDNS.addServiceTxt("_airgradient", "_tcp", "vendor", "AirGradient");
|
||||||
|
|
||||||
|
MDNS.announce();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void initMqtt(void) {
|
||||||
|
if (mqttClient.begin(configuration.getMqttBrokerUri())) {
|
||||||
|
Serial.println("Setup connect to MQTT broker successful");
|
||||||
|
} else {
|
||||||
|
Serial.println("setup Connect to MQTT broker failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wdgFeedUpdate(void) {
|
||||||
|
ag.watchdog.reset();
|
||||||
|
Serial.println();
|
||||||
|
Serial.println("Offline mode or isPostToAirGradient = false: watchdog reset");
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool sgp41Init(void) {
|
||||||
|
ag.sgp41.setNoxLearningOffset(configuration.getNoxLearningOffset());
|
||||||
|
ag.sgp41.setTvocLearningOffset(configuration.getTvocLearningOffset());
|
||||||
|
if (ag.sgp41.begin(Wire)) {
|
||||||
|
Serial.println("Init SGP41 success");
|
||||||
|
configuration.hasSensorSGP = true;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
Serial.println("Init SGP41 failuire");
|
||||||
|
configuration.hasSensorSGP = false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wifiFactoryConfigure(void) {
|
||||||
|
WiFi.persistent(true);
|
||||||
|
WiFi.begin("airgradient", "cleanair");
|
||||||
|
WiFi.persistent(false);
|
||||||
|
oledDisplay.setText("Configure WiFi", "connect to", "\'airgradient\'");
|
||||||
|
delay(2500);
|
||||||
|
oledDisplay.setText("Rebooting...", "", "");
|
||||||
|
delay(2500);
|
||||||
|
oledDisplay.setText("", "", "");
|
||||||
|
ESP.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mqttHandle(void) {
|
||||||
|
if(mqttClient.isConnected() == false) {
|
||||||
|
mqttClient.connect(String("airgradient-") + ag.deviceId());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mqttClient.isConnected()) {
|
||||||
|
String payload = measurements.toString(true, fwMode, wifiConnector.RSSI(),
|
||||||
|
&ag, &configuration);
|
||||||
|
String topic = "airgradient/readings/" + ag.deviceId();
|
||||||
|
if (mqttClient.publish(topic.c_str(), payload.c_str(), payload.length())) {
|
||||||
|
Serial.println("MQTT sync success");
|
||||||
|
} else {
|
||||||
|
Serial.println("MQTT sync failure");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sendDataToAg() {
|
static void sendDataToAg() {
|
||||||
// delay(1500);
|
/** Change oledDisplay and led state */
|
||||||
if (apiClient.sendPing(wifiConnector.RSSI(), 0)) {
|
stateMachine.displayHandle(AgStateMachineWiFiOkServerConnecting);
|
||||||
// Ping Server succses
|
|
||||||
|
delay(1500);
|
||||||
|
if (apiClient.sendPing(wifiConnector.RSSI(), measurements.bootCount)) {
|
||||||
|
stateMachine.displayHandle(AgStateMachineWiFiOkServerConnected);
|
||||||
} else {
|
} else {
|
||||||
// Ping server failed
|
stateMachine.displayHandle(AgStateMachineWiFiOkServerConnectFailed);
|
||||||
}
|
}
|
||||||
// delay(DISPLAY_DELAY_SHOW_CONTENT_MS);
|
delay(DISPLAY_DELAY_SHOW_CONTENT_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void displayShowText(String ln1, String ln2, String ln3) {
|
void dispSensorNotFound(String ss) {
|
||||||
char buf[9];
|
oledDisplay.setText("Sensor", ss.c_str(), "not found");
|
||||||
ag.display.clear();
|
delay(2000);
|
||||||
|
|
||||||
ag.display.setCursor(1, 1);
|
|
||||||
ag.display.setText(ln1);
|
|
||||||
ag.display.setCursor(1, 19);
|
|
||||||
ag.display.setText(ln2);
|
|
||||||
ag.display.setCursor(1, 37);
|
|
||||||
ag.display.setText(ln3);
|
|
||||||
|
|
||||||
ag.display.show();
|
|
||||||
delay(100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void boardInit(void) {
|
static void boardInit(void) {
|
||||||
/** Init SHT sensor */
|
/** Display init */
|
||||||
|
oledDisplay.begin();
|
||||||
|
|
||||||
|
/** Show boot display */
|
||||||
|
Serial.println("Firmware Version: " + ag.getVersion());
|
||||||
|
|
||||||
|
if (ag.isBasic()) {
|
||||||
|
oledDisplay.setText("DIY Basic", ag.getVersion().c_str(), "");
|
||||||
|
} else {
|
||||||
|
oledDisplay.setText("AirGradient ONE",
|
||||||
|
"FW Version: ", ag.getVersion().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(DISPLAY_DELAY_SHOW_CONTENT_MS);
|
||||||
|
|
||||||
|
ag.watchdog.begin();
|
||||||
|
|
||||||
|
/** Show message init sensor */
|
||||||
|
oledDisplay.setText("Sensor", "init...", "");
|
||||||
|
|
||||||
|
/** Init sensor SGP41 */
|
||||||
|
configuration.hasSensorSGP = false;
|
||||||
|
// if (sgp41Init() == false) {
|
||||||
|
// dispSensorNotFound("SGP41");
|
||||||
|
// }
|
||||||
|
|
||||||
|
/** Init SHT */
|
||||||
if (ag.sht.begin(Wire) == false) {
|
if (ag.sht.begin(Wire) == false) {
|
||||||
hasSensorSHT = false;
|
Serial.println("SHTx sensor not found");
|
||||||
Serial.println("SHT sensor not found");
|
configuration.hasSensorSHT = false;
|
||||||
|
dispSensorNotFound("SHT");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** CO2 init */
|
/** Init S8 CO2 sensor */
|
||||||
if (ag.s8.begin(&Serial) == false) {
|
if (ag.s8.begin(&Serial) == false) {
|
||||||
Serial.println("CO2 S8 snsor not found");
|
Serial.println("CO2 S8 sensor not found");
|
||||||
hasSensorS8 = false;
|
configuration.hasSensorS8 = false;
|
||||||
|
dispSensorNotFound("S8");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** PMS init */
|
/** Init PMS5003 */
|
||||||
|
configuration.hasSensorPMS1 = true;
|
||||||
|
configuration.hasSensorPMS2 = false;
|
||||||
if (ag.pms5003.begin(&Serial) == false) {
|
if (ag.pms5003.begin(&Serial) == false) {
|
||||||
Serial.println("PMS sensor not found");
|
Serial.println("PMS sensor not found");
|
||||||
hasSensorPMS = false;
|
configuration.hasSensorPMS1 = false;
|
||||||
|
|
||||||
|
dispSensorNotFound("PMS");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Display init */
|
/** Set S8 CO2 abc days period */
|
||||||
ag.display.begin(Wire);
|
if (configuration.hasSensorS8) {
|
||||||
ag.display.setTextColor(1);
|
if (ag.s8.setAbcPeriod(configuration.getCO2CalibrationAbcDays() * 24)) {
|
||||||
ag.display.clear();
|
Serial.println("Set S8 AbcDays successful");
|
||||||
ag.display.show();
|
} else {
|
||||||
delay(100);
|
Serial.println("Set S8 AbcDays failure");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
localServer.setFwMode(fwMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void failedHandler(String msg) {
|
static void failedHandler(String msg) {
|
||||||
@ -224,181 +410,160 @@ static void failedHandler(String msg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void executeCo2Calibration(void) {
|
static void configurationUpdateSchedule(void) {
|
||||||
/** Count down for co2CalibCountdown secs */
|
|
||||||
for (int i = 0; i < SENSOR_CO2_CALIB_COUNTDOWN_MAX; i++) {
|
|
||||||
displayShowText("CO2 calib.", "after",
|
|
||||||
String(SENSOR_CO2_CALIB_COUNTDOWN_MAX - i) + " sec");
|
|
||||||
delay(1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ag.s8.setBaselineCalibration()) {
|
|
||||||
displayShowText("Calib", "success", "");
|
|
||||||
delay(1000);
|
|
||||||
displayShowText("Wait to", "complete", "...");
|
|
||||||
int count = 0;
|
|
||||||
while (ag.s8.isBaseLineCalibrationDone() == false) {
|
|
||||||
delay(1000);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
displayShowText("Finished", "after", String(count) + " sec");
|
|
||||||
delay(DISPLAY_DELAY_SHOW_CONTENT_MS);
|
|
||||||
} else {
|
|
||||||
displayShowText("Calibration", "failure", "");
|
|
||||||
delay(DISPLAY_DELAY_SHOW_CONTENT_MS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void updateServerConfiguration(void) {
|
|
||||||
if (apiClient.fetchServerConfiguration()) {
|
if (apiClient.fetchServerConfiguration()) {
|
||||||
if (configuration.isCo2CalibrationRequested()) {
|
configUpdateHandle();
|
||||||
if (hasSensorS8) {
|
|
||||||
executeCo2Calibration();
|
|
||||||
} else {
|
|
||||||
Serial.println("CO2 S8 not available, calib ignored");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (configuration.getCO2CalibrationAbcDays() > 0) {
|
|
||||||
if (hasSensorS8) {
|
|
||||||
int newHour = configuration.getCO2CalibrationAbcDays() * 24;
|
|
||||||
Serial.printf("abcDays config: %d days(%d hours)\r\n",
|
|
||||||
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(configuration.getCO2CalibrationAbcDays() *
|
|
||||||
24) == false) {
|
|
||||||
Serial.println("Set S8 abcDays period calib failed");
|
|
||||||
} else {
|
|
||||||
Serial.println("Set S8 abcDays period calib success");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Serial.println("CO2 S8 not available, set 'abcDays' ignored");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void co2Update() {
|
static void configUpdateHandle() {
|
||||||
int value = ag.s8.getCo2();
|
if (configuration.isUpdated() == false) {
|
||||||
if (value >= 0) {
|
return;
|
||||||
co2Ppm = value;
|
}
|
||||||
getCO2FailCount = 0;
|
|
||||||
Serial.printf("CO2 index: %d\r\n", co2Ppm);
|
stateMachine.executeCo2Calibration();
|
||||||
} else {
|
|
||||||
getCO2FailCount++;
|
String mqttUri = configuration.getMqttBrokerUri();
|
||||||
Serial.printf("Get CO2 failed: %d\r\n", getCO2FailCount);
|
if (mqttClient.isCurrentUri(mqttUri) == false) {
|
||||||
if (getCO2FailCount >= 3) {
|
mqttClient.end();
|
||||||
co2Ppm = -1;
|
initMqtt();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configuration.hasSensorSGP) {
|
||||||
|
if (configuration.noxLearnOffsetChanged() ||
|
||||||
|
configuration.tvocLearnOffsetChanged()) {
|
||||||
|
ag.sgp41.end();
|
||||||
|
|
||||||
|
int oldTvocOffset = ag.sgp41.getTvocLearningOffset();
|
||||||
|
int oldNoxOffset = ag.sgp41.getNoxLearningOffset();
|
||||||
|
bool result = sgp41Init();
|
||||||
|
const char *resultStr = "successful";
|
||||||
|
if (!result) {
|
||||||
|
resultStr = "failure";
|
||||||
|
}
|
||||||
|
if (oldTvocOffset != configuration.getTvocLearningOffset()) {
|
||||||
|
Serial.printf("Setting tvocLearningOffset from %d to %d hours %s\r\n",
|
||||||
|
oldTvocOffset, configuration.getTvocLearningOffset(),
|
||||||
|
resultStr);
|
||||||
|
}
|
||||||
|
if (oldNoxOffset != configuration.getNoxLearningOffset()) {
|
||||||
|
Serial.printf("Setting noxLearningOffset from %d to %d hours %s\r\n",
|
||||||
|
oldNoxOffset, configuration.getNoxLearningOffset(),
|
||||||
|
resultStr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (configuration.isDisplayBrightnessChanged()) {
|
||||||
|
oledDisplay.setBrightness(configuration.getDisplayBrightness());
|
||||||
|
}
|
||||||
|
|
||||||
|
appDispHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pmUpdate() {
|
static void appDispHandler(void) {
|
||||||
|
AgStateMachineState state = AgStateMachineNormal;
|
||||||
|
|
||||||
|
/** Only show display status on online mode. */
|
||||||
|
if (configuration.isOfflineMode() == false) {
|
||||||
|
if (wifiConnector.isConnected() == false) {
|
||||||
|
state = AgStateMachineWiFiLost;
|
||||||
|
} else if (apiClient.isFetchConfigureFailed()) {
|
||||||
|
state = AgStateMachineSensorConfigFailed;
|
||||||
|
if (apiClient.isNotAvailableOnDashboard()) {
|
||||||
|
stateMachine.displaySetAddToDashBoard();
|
||||||
|
} else {
|
||||||
|
stateMachine.displayClearAddToDashBoard();
|
||||||
|
}
|
||||||
|
} else if (apiClient.isPostToServerFailed()) {
|
||||||
|
state = AgStateMachineServerLost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stateMachine.displayHandle(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void oledDisplaySchedule(void) {
|
||||||
|
|
||||||
|
appDispHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void updateTvoc(void) {
|
||||||
|
measurements.TVOC = ag.sgp41.getTvocIndex();
|
||||||
|
measurements.TVOCRaw = ag.sgp41.getTvocRaw();
|
||||||
|
measurements.NOx = ag.sgp41.getNoxIndex();
|
||||||
|
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 updatePm(void) {
|
||||||
if (ag.pms5003.isFailed() == false) {
|
if (ag.pms5003.isFailed() == false) {
|
||||||
pm25 = ag.pms5003.getPm25Ae();
|
measurements.pm01_1 = ag.pms5003.getPm01Ae();
|
||||||
Serial.printf("PMS2.5: %d\r\n", pm25);
|
measurements.pm25_1 = ag.pms5003.getPm25Ae();
|
||||||
|
measurements.pm10_1 = ag.pms5003.getPm10Ae();
|
||||||
|
measurements.pm03PCount_1 = 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);
|
||||||
pmFailCount = 0;
|
pmFailCount = 0;
|
||||||
} else {
|
} else {
|
||||||
Serial.printf("PM read failed, %d", pmFailCount);
|
|
||||||
pmFailCount++;
|
pmFailCount++;
|
||||||
|
Serial.printf("PMS read failed: %d\r\n", pmFailCount);
|
||||||
if (pmFailCount >= 3) {
|
if (pmFailCount >= 3) {
|
||||||
pm25 = -1;
|
measurements.pm01_1 = -1;
|
||||||
|
measurements.pm25_1 = -1;
|
||||||
|
measurements.pm10_1 = -1;
|
||||||
|
measurements.pm03PCount_1 = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tempHumUpdate() {
|
static void sendDataToServer(void) {
|
||||||
|
/** Ignore send data to server if postToAirGradient disabled */
|
||||||
|
if (configuration.isPostDataToAirGradient() == false ||
|
||||||
|
configuration.isOfflineMode()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String syncData = measurements.toString(false, fwMode, wifiConnector.RSSI(),
|
||||||
|
&ag, &configuration);
|
||||||
|
if (apiClient.postToServer(syncData)) {
|
||||||
|
ag.watchdog.reset();
|
||||||
|
Serial.println();
|
||||||
|
Serial.println(
|
||||||
|
"Online mode and isPostToAirGradient = true: watchdog reset");
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
measurements.bootCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tempHumUpdate(void) {
|
||||||
|
delay(100);
|
||||||
if (ag.sht.measure()) {
|
if (ag.sht.measure()) {
|
||||||
temp = ag.sht.getTemperature();
|
measurements.Temperature = ag.sht.getTemperature();
|
||||||
hum = ag.sht.getRelativeHumidity();
|
measurements.Humidity = ag.sht.getRelativeHumidity();
|
||||||
Serial.printf("Temperature: %0.2f\r\n", temp);
|
|
||||||
Serial.printf(" Humidity: %d\r\n", hum);
|
|
||||||
} else {
|
|
||||||
Serial.println("Meaure SHT failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sendDataToServer() {
|
Serial.printf("Temperature in C: %0.2f\r\n", measurements.Temperature);
|
||||||
String wifi = "\"wifi\":" + String(WiFi.RSSI());
|
Serial.printf("Relative Humidity: %d\r\n", measurements.Humidity);
|
||||||
String rco2 = "";
|
Serial.printf("Temperature compensated in C: %0.2f\r\n",
|
||||||
if(co2Ppm >= 0){
|
measurements.Temperature);
|
||||||
rco2 = ",\"rco2\":" + String(co2Ppm);
|
Serial.printf("Relative Humidity compensated: %d\r\n",
|
||||||
}
|
measurements.Humidity);
|
||||||
String pm02 = "";
|
|
||||||
if(pm25) {
|
|
||||||
pm02 = ",\"pm02\":" + String(pm25);
|
|
||||||
}
|
|
||||||
String rhum = "";
|
|
||||||
if(hum >= 0){
|
|
||||||
rhum = ",\"rhum\":" + String(rhum);
|
|
||||||
}
|
|
||||||
String payload = "{" + wifi + rco2 + pm02 + rhum + "}";
|
|
||||||
|
|
||||||
if (apiClient.postToServer(payload) == false) {
|
// Update compensation temperature and humidity for SGP41
|
||||||
Serial.println("Post to server failed");
|
if (configuration.hasSensorSGP) {
|
||||||
}
|
ag.sgp41.setCompensationTemperatureHumidity(measurements.Temperature,
|
||||||
}
|
measurements.Humidity);
|
||||||
|
|
||||||
static void dispHandler() {
|
|
||||||
String ln1 = "";
|
|
||||||
String ln2 = "";
|
|
||||||
String ln3 = "";
|
|
||||||
|
|
||||||
if (configuration.isPmStandardInUSAQI()) {
|
|
||||||
if (pm25 < 0) {
|
|
||||||
ln1 = "AQI: -";
|
|
||||||
} else {
|
|
||||||
ln1 = "AQI:" + String(ag.pms5003.convertPm25ToUsAqi(pm25));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (pm25 < 0) {
|
Serial.println("SHT read failed");
|
||||||
ln1 = "PM :- ug";
|
|
||||||
|
|
||||||
} else {
|
|
||||||
ln1 = "PM :" + String(pm25) + " ug";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (co2Ppm > -1001) {
|
|
||||||
ln2 = "CO2:" + String(co2Ppm);
|
|
||||||
} else {
|
|
||||||
ln2 = "CO2: -";
|
|
||||||
}
|
|
||||||
|
|
||||||
String _hum = "-";
|
|
||||||
if (hum > 0) {
|
|
||||||
_hum = String(hum);
|
|
||||||
}
|
|
||||||
|
|
||||||
String _temp = "-";
|
|
||||||
|
|
||||||
if (configuration.isTemperatureUnitInF()) {
|
|
||||||
if (temp > -1001) {
|
|
||||||
_temp = String((temp * 9 / 5) + 32).substring(0, 4);
|
|
||||||
}
|
|
||||||
ln3 = _temp + " " + _hum + "%";
|
|
||||||
} else {
|
|
||||||
if (temp > -1001) {
|
|
||||||
_temp = String(temp).substring(0, 4);
|
|
||||||
}
|
|
||||||
ln3 = _temp + " " + _hum + "%";
|
|
||||||
}
|
|
||||||
displayShowText(ln1, ln2, ln3);
|
|
||||||
}
|
|
||||||
|
|
||||||
static String getDevId(void) { return getNormalizedMac(); }
|
|
||||||
|
|
||||||
static void showNr(void) {
|
|
||||||
Serial.println();
|
|
||||||
Serial.println("Serial nr: " + getDevId());
|
|
||||||
}
|
|
||||||
|
|
||||||
String getNormalizedMac() {
|
|
||||||
String mac = WiFi.macAddress();
|
|
||||||
mac.replace(":", "");
|
|
||||||
mac.toLowerCase();
|
|
||||||
return mac;
|
|
||||||
}
|
}
|
||||||
|
61
examples/BASIC/LocalServer.cpp
Normal file
61
examples/BASIC/LocalServer.cpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#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), server(80) {}
|
||||||
|
|
||||||
|
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();
|
||||||
|
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) {
|
||||||
|
if(ag->isOne()) {
|
||||||
|
server.send(200, "application/json", config.toString());
|
||||||
|
} else {
|
||||||
|
server.send(200, "application/json", config.toString(fwMode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = config.getFailedMesage();
|
||||||
|
}
|
||||||
|
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; }
|
38
examples/BASIC/LocalServer.h
Normal file
38
examples/BASIC/LocalServer.h
Normal 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 <ESP8266WebServer.h>
|
||||||
|
|
||||||
|
class LocalServer : public PrintLog {
|
||||||
|
private:
|
||||||
|
AirGradient *ag;
|
||||||
|
OpenMetrics &openMetrics;
|
||||||
|
Measurements &measure;
|
||||||
|
Configuration &config;
|
||||||
|
WifiConnector &wifiConnector;
|
||||||
|
ESP8266WebServer 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_ */
|
186
examples/BASIC/OpenMetrics.cpp
Normal file
186
examples/BASIC/OpenMetrics.cpp
Normal 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;
|
||||||
|
int atmpCompensated = -1;
|
||||||
|
int ahumCompensated = -1;
|
||||||
|
|
||||||
|
if (config.hasSensorSHT) {
|
||||||
|
_temp = measure.Temperature;
|
||||||
|
_hum = measure.Humidity;
|
||||||
|
atmpCompensated = _temp;
|
||||||
|
ahumCompensated = _hum;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.hasSensorPMS1) {
|
||||||
|
pm01 = measure.pm01_1;
|
||||||
|
pm25 = measure.pm25_1;
|
||||||
|
pm10 = measure.pm10_1;
|
||||||
|
pm03PCount = measure.pm03PCount_1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.hasSensorPMS1) {
|
||||||
|
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 / PMS "
|
||||||
|
"sensor, in degrees Celsius",
|
||||||
|
"gauge", "celsius");
|
||||||
|
add_metric_point("", String(_temp));
|
||||||
|
}
|
||||||
|
if (atmpCompensated > -1001) {
|
||||||
|
add_metric("temperature_compensated",
|
||||||
|
"The compensated ambient temperature as measured by the "
|
||||||
|
"AirGradient SHT / PMS "
|
||||||
|
"sensor, in degrees Celsius",
|
||||||
|
"gauge", "celsius");
|
||||||
|
add_metric_point("", String(atmpCompensated));
|
||||||
|
}
|
||||||
|
if (_hum >= 0) {
|
||||||
|
add_metric(
|
||||||
|
"humidity",
|
||||||
|
"The relative humidity as measured by the AirGradient SHT sensor",
|
||||||
|
"gauge", "percent");
|
||||||
|
add_metric_point("", String(_hum));
|
||||||
|
}
|
||||||
|
if (ahumCompensated >= 0) {
|
||||||
|
add_metric("humidity_compensated",
|
||||||
|
"The compensated relative humidity as measured by the "
|
||||||
|
"AirGradient SHT / PMS sensor",
|
||||||
|
"gauge", "percent");
|
||||||
|
add_metric_point("", String(ahumCompensated));
|
||||||
|
}
|
||||||
|
|
||||||
|
response += "# EOF\n";
|
||||||
|
return response;
|
||||||
|
}
|
28
examples/BASIC/OpenMetrics.h
Normal file
28
examples/BASIC/OpenMetrics.h
Normal 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_ */
|
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Show dashboard temperature and humdity
|
* @brief Show dashboard temperature and humdity
|
||||||
*
|
*
|
||||||
* @param hasStatus
|
* @param hasStatus
|
||||||
*/
|
*/
|
||||||
void OledDisplay::showTempHum(bool hasStatus) {
|
void OledDisplay::showTempHum(bool hasStatus) {
|
||||||
char buf[10];
|
char buf[10];
|
||||||
@ -58,20 +58,20 @@ void OledDisplay::setCentralText(int y, const char *text) {
|
|||||||
DISP()->drawStr(x, y, text);
|
DISP()->drawStr(x, y, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Construct a new Ag Oled Display:: Ag Oled Display object
|
* @brief Construct a new Ag Oled Display:: Ag Oled Display object
|
||||||
*
|
*
|
||||||
* @param config AgConfiguration
|
* @param config AgConfiguration
|
||||||
* @param value Measurements
|
* @param value Measurements
|
||||||
* @param log Serial Stream
|
* @param log Serial Stream
|
||||||
*/
|
*/
|
||||||
OledDisplay::OledDisplay(Configuration &config, Measurements &value, Stream &log)
|
OledDisplay::OledDisplay(Configuration &config, Measurements &value,
|
||||||
|
Stream &log)
|
||||||
: PrintLog(log, "OledDisplay"), config(config), value(value) {}
|
: PrintLog(log, "OledDisplay"), config(config), value(value) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set AirGradient instance
|
* @brief Set AirGradient instance
|
||||||
*
|
*
|
||||||
* @param ag Point to AirGradient instance
|
* @param ag Point to AirGradient instance
|
||||||
*/
|
*/
|
||||||
void OledDisplay::setAirGradient(AirGradient *ag) { this->ag = ag; }
|
void OledDisplay::setAirGradient(AirGradient *ag) { this->ag = ag; }
|
||||||
@ -90,23 +90,31 @@ bool OledDisplay::begin(void) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create u8g2 instance */
|
if (ag->isOne() || ag->isPro3_7() || ag->isPro4_2()) {
|
||||||
u8g2 = new U8G2_SH1106_128X64_NONAME_F_HW_I2C(U8G2_R0, U8X8_PIN_NONE);
|
/** Create u8g2 instance */
|
||||||
if (u8g2 == NULL) {
|
u8g2 = new U8G2_SH1106_128X64_NONAME_F_HW_I2C(U8G2_R0, U8X8_PIN_NONE);
|
||||||
logError("Create 'U8G2' failed");
|
if (u8g2 == NULL) {
|
||||||
return false;
|
logError("Create 'U8G2' failed");
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/** Init u8g2 */
|
/** Init u8g2 */
|
||||||
if (DISP()->begin() == false) {
|
if (DISP()->begin() == false) {
|
||||||
logError("U8G2 'begin' failed");
|
logError("U8G2 'begin' failed");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
} else if (ag->isBasic()) {
|
||||||
|
logInfo("DIY_BASIC init");
|
||||||
|
ag->display.begin(Wire);
|
||||||
|
ag->display.setTextColor(1);
|
||||||
|
ag->display.clear();
|
||||||
|
ag->display.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Show low brightness on startup. then it's completely turn off on main
|
/** Show low brightness on startup. then it's completely turn off on main
|
||||||
* application */
|
* application */
|
||||||
int brightness = config.getDisplayBrightness();
|
int brightness = config.getDisplayBrightness();
|
||||||
if(brightness == 0) {
|
if (brightness == 0) {
|
||||||
setBrightness(1);
|
setBrightness(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,9 +133,13 @@ void OledDisplay::end(void) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Free u8g2 */
|
if (ag->isOne() || ag->isPro3_7() || ag->isPro4_2()) {
|
||||||
delete DISP();
|
/** Free u8g2 */
|
||||||
u8g2 = NULL;
|
delete DISP();
|
||||||
|
u8g2 = NULL;
|
||||||
|
} else if (ag->isBasic()) {
|
||||||
|
ag->display.end();
|
||||||
|
}
|
||||||
|
|
||||||
isBegin = false;
|
isBegin = false;
|
||||||
logInfo("end");
|
logInfo("end");
|
||||||
@ -135,10 +147,10 @@ void OledDisplay::end(void) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Show text on 3 line of display
|
* @brief Show text on 3 line of display
|
||||||
*
|
*
|
||||||
* @param line1
|
* @param line1
|
||||||
* @param line2
|
* @param line2
|
||||||
* @param line3
|
* @param line3
|
||||||
*/
|
*/
|
||||||
void OledDisplay::setText(String &line1, String &line2, String &line3) {
|
void OledDisplay::setText(String &line1, String &line2, String &line3) {
|
||||||
setText(line1.c_str(), line2.c_str(), line3.c_str());
|
setText(line1.c_str(), line2.c_str(), line3.c_str());
|
||||||
@ -146,190 +158,256 @@ void OledDisplay::setText(String &line1, String &line2, String &line3) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Show text on 3 line of display
|
* @brief Show text on 3 line of display
|
||||||
*
|
*
|
||||||
* @param line1
|
* @param line1
|
||||||
* @param line2
|
* @param line2
|
||||||
* @param line3
|
* @param line3
|
||||||
*/
|
*/
|
||||||
void OledDisplay::setText(const char *line1, const char *line2,
|
void OledDisplay::setText(const char *line1, const char *line2,
|
||||||
const char *line3) {
|
const char *line3) {
|
||||||
if (isDisplayOff) {
|
if (isDisplayOff) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DISP()->firstPage();
|
if (ag->isOne() || ag->isPro3_7() || ag->isPro4_2()) {
|
||||||
do {
|
DISP()->firstPage();
|
||||||
DISP()->setFont(u8g2_font_t0_16_tf);
|
do {
|
||||||
DISP()->drawStr(1, 10, line1);
|
DISP()->setFont(u8g2_font_t0_16_tf);
|
||||||
DISP()->drawStr(1, 30, line2);
|
DISP()->drawStr(1, 10, line1);
|
||||||
DISP()->drawStr(1, 50, line3);
|
DISP()->drawStr(1, 30, line2);
|
||||||
} while (DISP()->nextPage());
|
DISP()->drawStr(1, 50, line3);
|
||||||
|
} while (DISP()->nextPage());
|
||||||
|
} else if (ag->isBasic()) {
|
||||||
|
ag->display.clear();
|
||||||
|
|
||||||
|
ag->display.setCursor(1, 1);
|
||||||
|
ag->display.setText(line1);
|
||||||
|
ag->display.setCursor(1, 17);
|
||||||
|
ag->display.setText(line2);
|
||||||
|
ag->display.setCursor(1, 33);
|
||||||
|
ag->display.setText(line3);
|
||||||
|
|
||||||
|
ag->display.show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set Text on 4 line
|
* @brief Set Text on 4 line
|
||||||
*
|
*
|
||||||
* @param line1
|
* @param line1
|
||||||
* @param line2
|
* @param line2
|
||||||
* @param line3
|
* @param line3
|
||||||
* @param line4
|
* @param line4
|
||||||
*/
|
*/
|
||||||
void OledDisplay::setText(String &line1, String &line2, String &line3,
|
void OledDisplay::setText(String &line1, String &line2, String &line3,
|
||||||
String &line4) {
|
String &line4) {
|
||||||
setText(line1.c_str(), line2.c_str(), line3.c_str(), line4.c_str());
|
setText(line1.c_str(), line2.c_str(), line3.c_str(), line4.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set Text on 4 line
|
* @brief Set Text on 4 line
|
||||||
*
|
*
|
||||||
* @param line1
|
* @param line1
|
||||||
* @param line2
|
* @param line2
|
||||||
* @param line3
|
* @param line3
|
||||||
* @param line4
|
* @param line4
|
||||||
*/
|
*/
|
||||||
void OledDisplay::setText(const char *line1, const char *line2,
|
void OledDisplay::setText(const char *line1, const char *line2,
|
||||||
const char *line3, const char *line4) {
|
const char *line3, const char *line4) {
|
||||||
if (isDisplayOff) {
|
if (isDisplayOff) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DISP()->firstPage();
|
if (ag->isOne() || ag->isPro3_7() || ag->isPro4_2()) {
|
||||||
do {
|
DISP()->firstPage();
|
||||||
DISP()->setFont(u8g2_font_t0_16_tf);
|
do {
|
||||||
DISP()->drawStr(1, 10, line1);
|
DISP()->setFont(u8g2_font_t0_16_tf);
|
||||||
DISP()->drawStr(1, 25, line2);
|
DISP()->drawStr(1, 10, line1);
|
||||||
DISP()->drawStr(1, 40, line3);
|
DISP()->drawStr(1, 25, line2);
|
||||||
DISP()->drawStr(1, 55, line4);
|
DISP()->drawStr(1, 40, line3);
|
||||||
} while (DISP()->nextPage());
|
DISP()->drawStr(1, 55, line4);
|
||||||
|
} while (DISP()->nextPage());
|
||||||
|
} else if (ag->isBasic()) {
|
||||||
|
ag->display.clear();
|
||||||
|
ag->display.setCursor(0, 0);
|
||||||
|
ag->display.setText(line1);
|
||||||
|
ag->display.setCursor(0, 10);
|
||||||
|
ag->display.setText(line2);
|
||||||
|
ag->display.setCursor(0, 20);
|
||||||
|
ag->display.setText(line3);
|
||||||
|
ag->display.show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Update dashboard content
|
* @brief Update dashboard content
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void OledDisplay::showDashboard(void) { showDashboard(NULL); }
|
void OledDisplay::showDashboard(void) { showDashboard(NULL); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Update dashboard content and error status
|
* @brief Update dashboard content and error status
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void OledDisplay::showDashboard(const char *status) {
|
void OledDisplay::showDashboard(const char *status) {
|
||||||
if (isDisplayOff) {
|
if (isDisplayOff) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char strBuf[10];
|
char strBuf[16];
|
||||||
|
if (ag->isOne() || ag->isPro3_7() || ag->isPro4_2()) {
|
||||||
DISP()->firstPage();
|
|
||||||
do {
|
|
||||||
DISP()->setFont(u8g2_font_t0_16_tf);
|
|
||||||
if ((status == NULL) || (strlen(status) == 0)) {
|
|
||||||
showTempHum(false);
|
|
||||||
} else {
|
|
||||||
String strStatus = "Show status: " + String(status);
|
|
||||||
logInfo(strStatus);
|
|
||||||
|
|
||||||
int strWidth = DISP()->getStrWidth(status);
|
|
||||||
DISP()->drawStr((DISP()->getWidth() - strWidth) / 2, 10, status);
|
|
||||||
|
|
||||||
/** Show WiFi NA*/
|
|
||||||
if (strcmp(status, "WiFi N/A") == 0) {
|
|
||||||
DISP()->setFont(u8g2_font_t0_12_tf);
|
|
||||||
showTempHum(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Draw horizonal line */
|
|
||||||
DISP()->drawLine(1, 13, 128, 13);
|
|
||||||
|
|
||||||
/** Show CO2 label */
|
|
||||||
DISP()->setFont(u8g2_font_t0_12_tf);
|
|
||||||
DISP()->drawUTF8(1, 27, "CO2");
|
|
||||||
|
|
||||||
DISP()->setFont(u8g2_font_t0_22b_tf);
|
|
||||||
if (value.CO2 > 0) {
|
|
||||||
int val = 9999;
|
|
||||||
if (value.CO2 < 10000) {
|
|
||||||
val = value.CO2;
|
|
||||||
}
|
|
||||||
sprintf(strBuf, "%d", val);
|
|
||||||
} else {
|
|
||||||
sprintf(strBuf, "%s", "-");
|
|
||||||
}
|
|
||||||
DISP()->drawStr(1, 48, strBuf);
|
|
||||||
|
|
||||||
/** Show CO2 value index */
|
|
||||||
DISP()->setFont(u8g2_font_t0_12_tf);
|
|
||||||
DISP()->drawStr(1, 61, "ppm");
|
|
||||||
|
|
||||||
/** Draw vertical line */
|
|
||||||
DISP()->drawLine(45, 14, 45, 64);
|
|
||||||
DISP()->drawLine(82, 14, 82, 64);
|
|
||||||
|
|
||||||
/** Draw PM2.5 label */
|
|
||||||
DISP()->setFont(u8g2_font_t0_12_tf);
|
|
||||||
DISP()->drawStr(48, 27, "PM2.5");
|
|
||||||
|
|
||||||
/** Draw PM2.5 value */
|
|
||||||
DISP()->setFont(u8g2_font_t0_22b_tf);
|
|
||||||
if (config.isPmStandardInUSAQI()) {
|
|
||||||
if (value.pm25_1 >= 0) {
|
|
||||||
sprintf(strBuf, "%d", ag->pms5003.convertPm25ToUsAqi(value.pm25_1));
|
|
||||||
} else {
|
|
||||||
sprintf(strBuf, "%s", "-");
|
|
||||||
}
|
|
||||||
DISP()->drawStr(48, 48, strBuf);
|
|
||||||
DISP()->setFont(u8g2_font_t0_12_tf);
|
|
||||||
DISP()->drawUTF8(48, 61, "AQI");
|
|
||||||
} else {
|
|
||||||
if (value.pm25_1 >= 0) {
|
|
||||||
sprintf(strBuf, "%d", value.pm25_1);
|
|
||||||
} else {
|
|
||||||
sprintf(strBuf, "%s", "-");
|
|
||||||
}
|
|
||||||
DISP()->drawStr(48, 48, strBuf);
|
|
||||||
DISP()->setFont(u8g2_font_t0_12_tf);
|
|
||||||
DISP()->drawUTF8(48, 61, "ug/m³");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Draw tvocIndexlabel */
|
|
||||||
DISP()->setFont(u8g2_font_t0_12_tf);
|
|
||||||
DISP()->drawStr(85, 27, "tvoc:");
|
|
||||||
|
|
||||||
/** Draw tvocIndexvalue */
|
|
||||||
if (value.TVOC >= 0) {
|
|
||||||
sprintf(strBuf, "%d", value.TVOC);
|
|
||||||
} else {
|
|
||||||
sprintf(strBuf, "%s", "-");
|
|
||||||
}
|
|
||||||
DISP()->drawStr(85, 39, strBuf);
|
|
||||||
|
|
||||||
/** Draw NOx label */
|
|
||||||
DISP()->drawStr(85, 53, "NOx:");
|
|
||||||
if (value.NOx >= 0) {
|
|
||||||
sprintf(strBuf, "%d", value.NOx);
|
|
||||||
} else {
|
|
||||||
sprintf(strBuf, "%s", "-");
|
|
||||||
}
|
|
||||||
DISP()->drawStr(85, 63, strBuf);
|
|
||||||
} while (DISP()->nextPage());
|
|
||||||
}
|
|
||||||
|
|
||||||
void OledDisplay::setBrightness(int percent) {
|
|
||||||
if (percent == 0) {
|
|
||||||
isDisplayOff = true;
|
|
||||||
|
|
||||||
// Clear display.
|
|
||||||
DISP()->firstPage();
|
DISP()->firstPage();
|
||||||
do {
|
do {
|
||||||
} while (DISP()->nextPage());
|
DISP()->setFont(u8g2_font_t0_16_tf);
|
||||||
|
if ((status == NULL) || (strlen(status) == 0)) {
|
||||||
|
showTempHum(false);
|
||||||
|
} else {
|
||||||
|
String strStatus = "Show status: " + String(status);
|
||||||
|
logInfo(strStatus);
|
||||||
|
|
||||||
} else {
|
int strWidth = DISP()->getStrWidth(status);
|
||||||
isDisplayOff = false;
|
DISP()->drawStr((DISP()->getWidth() - strWidth) / 2, 10, status);
|
||||||
DISP()->setContrast((127 * percent) / 100);
|
|
||||||
|
/** Show WiFi NA*/
|
||||||
|
if (strcmp(status, "WiFi N/A") == 0) {
|
||||||
|
DISP()->setFont(u8g2_font_t0_12_tf);
|
||||||
|
showTempHum(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Draw horizonal line */
|
||||||
|
DISP()->drawLine(1, 13, 128, 13);
|
||||||
|
|
||||||
|
/** Show CO2 label */
|
||||||
|
DISP()->setFont(u8g2_font_t0_12_tf);
|
||||||
|
DISP()->drawUTF8(1, 27, "CO2");
|
||||||
|
|
||||||
|
DISP()->setFont(u8g2_font_t0_22b_tf);
|
||||||
|
if (value.CO2 > 0) {
|
||||||
|
int val = 9999;
|
||||||
|
if (value.CO2 < 10000) {
|
||||||
|
val = value.CO2;
|
||||||
|
}
|
||||||
|
sprintf(strBuf, "%d", val);
|
||||||
|
} else {
|
||||||
|
sprintf(strBuf, "%s", "-");
|
||||||
|
}
|
||||||
|
DISP()->drawStr(1, 48, strBuf);
|
||||||
|
|
||||||
|
/** Show CO2 value index */
|
||||||
|
DISP()->setFont(u8g2_font_t0_12_tf);
|
||||||
|
DISP()->drawStr(1, 61, "ppm");
|
||||||
|
|
||||||
|
/** Draw vertical line */
|
||||||
|
DISP()->drawLine(45, 14, 45, 64);
|
||||||
|
DISP()->drawLine(82, 14, 82, 64);
|
||||||
|
|
||||||
|
/** Draw PM2.5 label */
|
||||||
|
DISP()->setFont(u8g2_font_t0_12_tf);
|
||||||
|
DISP()->drawStr(48, 27, "PM2.5");
|
||||||
|
|
||||||
|
/** Draw PM2.5 value */
|
||||||
|
DISP()->setFont(u8g2_font_t0_22b_tf);
|
||||||
|
if (config.isPmStandardInUSAQI()) {
|
||||||
|
if (value.pm25_1 >= 0) {
|
||||||
|
sprintf(strBuf, "%d", ag->pms5003.convertPm25ToUsAqi(value.pm25_1));
|
||||||
|
} else {
|
||||||
|
sprintf(strBuf, "%s", "-");
|
||||||
|
}
|
||||||
|
DISP()->drawStr(48, 48, strBuf);
|
||||||
|
DISP()->setFont(u8g2_font_t0_12_tf);
|
||||||
|
DISP()->drawUTF8(48, 61, "AQI");
|
||||||
|
} else {
|
||||||
|
if (value.pm25_1 >= 0) {
|
||||||
|
sprintf(strBuf, "%d", value.pm25_1);
|
||||||
|
} else {
|
||||||
|
sprintf(strBuf, "%s", "-");
|
||||||
|
}
|
||||||
|
DISP()->drawStr(48, 48, strBuf);
|
||||||
|
DISP()->setFont(u8g2_font_t0_12_tf);
|
||||||
|
DISP()->drawUTF8(48, 61, "ug/m³");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Draw tvocIndexlabel */
|
||||||
|
DISP()->setFont(u8g2_font_t0_12_tf);
|
||||||
|
DISP()->drawStr(85, 27, "tvoc:");
|
||||||
|
|
||||||
|
/** Draw tvocIndexvalue */
|
||||||
|
if (value.TVOC >= 0) {
|
||||||
|
sprintf(strBuf, "%d", value.TVOC);
|
||||||
|
} else {
|
||||||
|
sprintf(strBuf, "%s", "-");
|
||||||
|
}
|
||||||
|
DISP()->drawStr(85, 39, strBuf);
|
||||||
|
|
||||||
|
/** Draw NOx label */
|
||||||
|
DISP()->drawStr(85, 53, "NOx:");
|
||||||
|
if (value.NOx >= 0) {
|
||||||
|
sprintf(strBuf, "%d", value.NOx);
|
||||||
|
} else {
|
||||||
|
sprintf(strBuf, "%s", "-");
|
||||||
|
}
|
||||||
|
DISP()->drawStr(85, 63, strBuf);
|
||||||
|
} while (DISP()->nextPage());
|
||||||
|
} else if (ag->isBasic()) {
|
||||||
|
ag->display.clear();
|
||||||
|
|
||||||
|
/** Set CO2 */
|
||||||
|
snprintf(strBuf, sizeof(strBuf), "CO2:%d", value.CO2);
|
||||||
|
ag->display.setCursor(0, 0);
|
||||||
|
ag->display.setText(strBuf);
|
||||||
|
|
||||||
|
/** Set PM */
|
||||||
|
ag->display.setCursor(0, 12);
|
||||||
|
snprintf(strBuf, sizeof(strBuf), "PM2.5:%d", value.pm25_1);
|
||||||
|
ag->display.setText(strBuf);
|
||||||
|
|
||||||
|
/** Set temperature and humidity */
|
||||||
|
if (value.Temperature <= -1001.0f) {
|
||||||
|
if (config.isTemperatureUnitInF()) {
|
||||||
|
snprintf(strBuf, sizeof(strBuf), "T:-F");
|
||||||
|
} else {
|
||||||
|
snprintf(strBuf, sizeof(strBuf), "T:-C");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (config.isTemperatureUnitInF()) {
|
||||||
|
float tempF = (value.Temperature * 9) / 5 + 32;
|
||||||
|
snprintf(strBuf, sizeof(strBuf), "T:%d F", (int)tempF);
|
||||||
|
} else {
|
||||||
|
snprintf(strBuf, sizeof(strBuf), "T:%d C", (int)value.Temperature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ag->display.setCursor(0, 24);
|
||||||
|
ag->display.setText(strBuf);
|
||||||
|
|
||||||
|
snprintf(strBuf, sizeof(strBuf), "H:%d %%", (int)value.Humidity);
|
||||||
|
ag->display.setCursor(0, 36);
|
||||||
|
ag->display.setText(strBuf);
|
||||||
|
|
||||||
|
ag->display.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OledDisplay::setBrightness(int percent) {
|
||||||
|
if (ag->isOne() || ag->isPro3_7() || ag->isPro4_2()) {
|
||||||
|
if (percent == 0) {
|
||||||
|
isDisplayOff = true;
|
||||||
|
|
||||||
|
// Clear display.
|
||||||
|
DISP()->firstPage();
|
||||||
|
do {
|
||||||
|
} while (DISP()->nextPage());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
isDisplayOff = false;
|
||||||
|
DISP()->setContrast((127 * percent) / 100);
|
||||||
|
}
|
||||||
|
} else if (ag->isBasic()) {
|
||||||
|
ag->display.setContrast((255 * percent) / 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
void OledDisplay::showFirmwareUpdateVersion(String version) {
|
void OledDisplay::showFirmwareUpdateVersion(String version) {
|
||||||
if (isDisplayOff) {
|
if (isDisplayOff) {
|
||||||
return;
|
return;
|
||||||
@ -410,13 +488,25 @@ void OledDisplay::showFirmwareUpdateUpToDate(void) {
|
|||||||
setCentralText(40, "up to date");
|
setCentralText(40, "up to date");
|
||||||
} while (DISP()->nextPage());
|
} while (DISP()->nextPage());
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void OledDisplay::showRebooting(void) {
|
void OledDisplay::showRebooting(void) {
|
||||||
DISP()->firstPage();
|
if (ag->isOne() || ag->isPro3_7() || ag->isPro4_2()) {
|
||||||
do {
|
DISP()->firstPage();
|
||||||
DISP()->setFont(u8g2_font_t0_16_tf);
|
do {
|
||||||
// setCentralText(20, "Firmware Update");
|
DISP()->setFont(u8g2_font_t0_16_tf);
|
||||||
setCentralText(40, "Rebooting...");
|
// setCentralText(20, "Firmware Update");
|
||||||
// setCentralText(60, String("Retry after 24h"));
|
setCentralText(40, "Reboot...");
|
||||||
} while (DISP()->nextPage());
|
// setCentralText(60, String("Retry after 24h"));
|
||||||
|
} while (DISP()->nextPage());
|
||||||
|
} else if (ag->isBasic()) {
|
||||||
|
ag->display.clear();
|
||||||
|
|
||||||
|
ag->display.setCursor(0, 20);
|
||||||
|
ag->display.setText("Rebooting...");
|
||||||
|
|
||||||
|
ag->display.show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,12 +36,16 @@ public:
|
|||||||
void showDashboard(void);
|
void showDashboard(void);
|
||||||
void showDashboard(const char *status);
|
void showDashboard(const char *status);
|
||||||
void setBrightness(int percent);
|
void setBrightness(int percent);
|
||||||
|
#ifdef ESP32
|
||||||
void showFirmwareUpdateVersion(String version);
|
void showFirmwareUpdateVersion(String version);
|
||||||
void showFirmwareUpdateProgress(int percent);
|
void showFirmwareUpdateProgress(int percent);
|
||||||
void showFirmwareUpdateSuccess(int count);
|
void showFirmwareUpdateSuccess(int count);
|
||||||
void showFirmwareUpdateFailed(void);
|
void showFirmwareUpdateFailed(void);
|
||||||
void showFirmwareUpdateSkipped(void);
|
void showFirmwareUpdateSkipped(void);
|
||||||
void showFirmwareUpdateUpToDate(void);
|
void showFirmwareUpdateUpToDate(void);
|
||||||
|
#else
|
||||||
|
|
||||||
|
#endif
|
||||||
void showRebooting(void);
|
void showRebooting(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,11 +7,11 @@
|
|||||||
|
|
||||||
#define SENSOR_CO2_CALIB_COUNTDOWN_MAX 5 /** sec */
|
#define SENSOR_CO2_CALIB_COUNTDOWN_MAX 5 /** sec */
|
||||||
|
|
||||||
#define RGB_COLOR_R 255, 0, 0 /** Red */
|
#define RGB_COLOR_R 255, 0, 0 /** Red */
|
||||||
#define RGB_COLOR_G 0, 255, 0 /** Green */
|
#define RGB_COLOR_G 0, 255, 0 /** Green */
|
||||||
#define RGB_COLOR_Y 255, 255, 0 /** Yellow */
|
#define RGB_COLOR_Y 255, 255, 0 /** Yellow */
|
||||||
#define RGB_COLOR_O 255, 165, 0 /** Organge */
|
#define RGB_COLOR_O 255, 165, 0 /** Organge */
|
||||||
#define RGB_COLOR_P 160, 32, 240 /** Purple */
|
#define RGB_COLOR_P 160, 32, 240 /** Purple */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Animation LED bar with color
|
* @brief Animation LED bar with color
|
||||||
@ -228,6 +228,9 @@ void StateMachine::co2Calibration(void) {
|
|||||||
String str =
|
String str =
|
||||||
"after " + String(SENSOR_CO2_CALIB_COUNTDOWN_MAX - i) + " sec";
|
"after " + String(SENSOR_CO2_CALIB_COUNTDOWN_MAX - i) + " sec";
|
||||||
disp.setText("Start CO2 calib", str.c_str(), "");
|
disp.setText("Start CO2 calib", str.c_str(), "");
|
||||||
|
} else if (ag->isBasic()) {
|
||||||
|
String str = String(SENSOR_CO2_CALIB_COUNTDOWN_MAX - i) + " sec";
|
||||||
|
disp.setText("CO2 Calib", "after", str.c_str());
|
||||||
} else {
|
} else {
|
||||||
logInfo("Start CO2 calib after " +
|
logInfo("Start CO2 calib after " +
|
||||||
String(SENSOR_CO2_CALIB_COUNTDOWN_MAX - i) + " sec");
|
String(SENSOR_CO2_CALIB_COUNTDOWN_MAX - i) + " sec");
|
||||||
@ -238,6 +241,8 @@ void StateMachine::co2Calibration(void) {
|
|||||||
if (ag->s8.setBaselineCalibration()) {
|
if (ag->s8.setBaselineCalibration()) {
|
||||||
if (ag->isOne() || (ag->isPro4_2()) || ag->isPro3_7()) {
|
if (ag->isOne() || (ag->isPro4_2()) || ag->isPro3_7()) {
|
||||||
disp.setText("Calibration", "success", "");
|
disp.setText("Calibration", "success", "");
|
||||||
|
} else if (ag->isBasic()) {
|
||||||
|
disp.setText("CO2 Calib", "success", "");
|
||||||
} else {
|
} else {
|
||||||
logInfo("CO2 Calibration: success");
|
logInfo("CO2 Calibration: success");
|
||||||
}
|
}
|
||||||
@ -264,7 +269,10 @@ void StateMachine::co2Calibration(void) {
|
|||||||
} else {
|
} else {
|
||||||
if (ag->isOne() || (ag->isPro4_2()) || ag->isPro3_7()) {
|
if (ag->isOne() || (ag->isPro4_2()) || ag->isPro3_7()) {
|
||||||
disp.setText("Calibration", "failure!!!", "");
|
disp.setText("Calibration", "failure!!!", "");
|
||||||
} else {
|
} else if(ag->isBasic()) {
|
||||||
|
disp.setText("CO2 calib", "failure!!!", "");
|
||||||
|
}
|
||||||
|
else {
|
||||||
logInfo("CO2 Calibration: failure!!!");
|
logInfo("CO2 Calibration: failure!!!");
|
||||||
}
|
}
|
||||||
delay(2000);
|
delay(2000);
|
||||||
@ -279,15 +287,16 @@ void StateMachine::co2Calibration(void) {
|
|||||||
if (ag->s8.setAbcPeriod(config.getCO2CalibrationAbcDays() * 24)) {
|
if (ag->s8.setAbcPeriod(config.getCO2CalibrationAbcDays() * 24)) {
|
||||||
resultStr = "successful";
|
resultStr = "successful";
|
||||||
}
|
}
|
||||||
String fromStr = String(curHour/24) + " days";
|
String fromStr = String(curHour / 24) + " days";
|
||||||
if(curHour == 0){
|
if (curHour == 0) {
|
||||||
fromStr = "off";
|
fromStr = "off";
|
||||||
}
|
}
|
||||||
String toStr = String(config.getCO2CalibrationAbcDays()) + " days";
|
String toStr = String(config.getCO2CalibrationAbcDays()) + " days";
|
||||||
if(config.getCO2CalibrationAbcDays() == 0) {
|
if (config.getCO2CalibrationAbcDays() == 0) {
|
||||||
toStr = "off";
|
toStr = "off";
|
||||||
}
|
}
|
||||||
String msg = "Setting S8 from " + fromStr + " to " + toStr + " " + resultStr;
|
String msg =
|
||||||
|
"Setting S8 from " + fromStr + " to " + toStr + " " + resultStr;
|
||||||
logInfo(msg);
|
logInfo(msg);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -314,9 +323,7 @@ void StateMachine::ledBarTest(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StateMachine::ledBarPowerUpTest(void) {
|
void StateMachine::ledBarPowerUpTest(void) { ledBarRunTest(); }
|
||||||
ledBarRunTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
void StateMachine::ledBarRunTest(void) {
|
void StateMachine::ledBarRunTest(void) {
|
||||||
disp.setText("LED Test", "running", ".....");
|
disp.setText("LED Test", "running", ".....");
|
||||||
@ -398,8 +405,8 @@ StateMachine::~StateMachine() {}
|
|||||||
* @param state
|
* @param state
|
||||||
*/
|
*/
|
||||||
void StateMachine::displayHandle(AgStateMachineState state) {
|
void StateMachine::displayHandle(AgStateMachineState state) {
|
||||||
// Ignore handle if not ONE_INDOOR board
|
// Ignore handle if not support display
|
||||||
if (!(ag->isOne() || (ag->isPro4_2()) || ag->isPro3_7())) {
|
if (!(ag->isOne() || (ag->isPro4_2()) || ag->isPro3_7() || ag->isBasic())) {
|
||||||
if (state == AgStateMachineCo2Calibration) {
|
if (state == AgStateMachineCo2Calibration) {
|
||||||
co2Calibration();
|
co2Calibration();
|
||||||
}
|
}
|
||||||
@ -417,11 +424,17 @@ void StateMachine::displayHandle(AgStateMachineState state) {
|
|||||||
case AgStateMachineWiFiManagerMode:
|
case AgStateMachineWiFiManagerMode:
|
||||||
case AgStateMachineWiFiManagerPortalActive: {
|
case AgStateMachineWiFiManagerPortalActive: {
|
||||||
if (wifiConnectCountDown >= 0) {
|
if (wifiConnectCountDown >= 0) {
|
||||||
String line1 = String(wifiConnectCountDown) + "s to connect";
|
if (ag->isBasic()) {
|
||||||
String line2 = "to WiFi hotspot:";
|
String ssid = "\"airgradient-" + ag->deviceId() + "\" " +
|
||||||
String line3 = "\"airgradient-";
|
String(wifiConnectCountDown) + String("s");
|
||||||
String line4 = ag->deviceId() + "\"";
|
disp.setText("Connect tohotspot:", ssid.c_str(), "");
|
||||||
disp.setText(line1, line2, line3, line4);
|
} else {
|
||||||
|
String line1 = String(wifiConnectCountDown) + "s to connect";
|
||||||
|
String line2 = "to WiFi hotspot:";
|
||||||
|
String line3 = "\"airgradient-";
|
||||||
|
String line4 = ag->deviceId() + "\"";
|
||||||
|
disp.setText(line1, line2, line3, line4);
|
||||||
|
}
|
||||||
wifiConnectCountDown--;
|
wifiConnectCountDown--;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -435,7 +448,12 @@ void StateMachine::displayHandle(AgStateMachineState state) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AgStateMachineWiFiOkServerConnecting: {
|
case AgStateMachineWiFiOkServerConnecting: {
|
||||||
disp.setText("Connecting to", "Server", "...");
|
if (ag->isBasic()) {
|
||||||
|
disp.setText("Connecting", "to", "Server...");
|
||||||
|
} else {
|
||||||
|
disp.setText("Connecting to", "Server", "...");
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AgStateMachineWiFiOkServerConnected: {
|
case AgStateMachineWiFiOkServerConnected: {
|
||||||
@ -451,7 +469,11 @@ void StateMachine::displayHandle(AgStateMachineState state) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AgStateMachineWiFiOkServerOkSensorConfigFailed: {
|
case AgStateMachineWiFiOkServerOkSensorConfigFailed: {
|
||||||
disp.setText("Monitor not", "setup on", "dashboard");
|
if (ag->isBasic()) {
|
||||||
|
disp.setText("Monitor", "not on", "dashboard");
|
||||||
|
} else {
|
||||||
|
disp.setText("Monitor not", "setup on", "dashboard");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AgStateMachineWiFiLost: {
|
case AgStateMachineWiFiLost: {
|
||||||
@ -502,7 +524,7 @@ void StateMachine::displayHandle(void) { displayHandle(dispState); }
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void StateMachine::displaySetAddToDashBoard(void) {
|
void StateMachine::displaySetAddToDashBoard(void) {
|
||||||
if(addToDashBoard == false) {
|
if (addToDashBoard == false) {
|
||||||
addToDashboardTime = 0;
|
addToDashboardTime = 0;
|
||||||
addToDashBoardToggle = true;
|
addToDashBoardToggle = true;
|
||||||
}
|
}
|
||||||
@ -527,7 +549,8 @@ void StateMachine::displayWiFiConnectCountDown(int count) {
|
|||||||
void StateMachine::ledAnimationInit(void) { ledBarAnimationCount = -1; }
|
void StateMachine::ledAnimationInit(void) { ledBarAnimationCount = -1; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handle LED from state, only handle LED if board type is: One Indoor or Open Air
|
* @brief Handle LED from state, only handle LED if board type is: One Indoor or
|
||||||
|
* Open Air
|
||||||
*
|
*
|
||||||
* @param state
|
* @param state
|
||||||
*/
|
*/
|
||||||
|
@ -19,7 +19,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ag->isOne() || (ag->isPro4_2()) || ag->isPro3_7()) {
|
if (ag->isOne() || (ag->isPro4_2()) || ag->isPro3_7() || ag->isBasic()) {
|
||||||
if (config->hasSensorPMS1) {
|
if (config->hasSensorPMS1) {
|
||||||
if (this->pm01_1 >= 0) {
|
if (this->pm01_1 >= 0) {
|
||||||
root["pm01"] = this->pm01_1;
|
root["pm01"] = this->pm01_1;
|
||||||
@ -177,7 +177,9 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
|
|||||||
root["bootCount"] = bootCount;
|
root["bootCount"] = bootCount;
|
||||||
|
|
||||||
if (localServer) {
|
if (localServer) {
|
||||||
root["ledMode"] = config->getLedBarModeName();
|
if (ag->isOne()) {
|
||||||
|
root["ledMode"] = config->getLedBarModeName();
|
||||||
|
}
|
||||||
root["firmware"] = ag->getVersion();
|
root["firmware"] = ag->getVersion();
|
||||||
root["model"] = AgFirmwareModeName(fwMode);
|
root["model"] = AgFirmwareModeName(fwMode);
|
||||||
}
|
}
|
||||||
|
@ -49,8 +49,8 @@ bool WifiConnector::connect(void) {
|
|||||||
WIFI()->setSaveConfigCallback([this]() { _wifiSaveConfig(); });
|
WIFI()->setSaveConfigCallback([this]() { _wifiSaveConfig(); });
|
||||||
WIFI()->setSaveParamsCallback([this]() { _wifiSaveParamCallback(); });
|
WIFI()->setSaveParamsCallback([this]() { _wifiSaveParamCallback(); });
|
||||||
WIFI()->setConfigPortalTimeoutCallback([this]() {_wifiTimeoutCallback();});
|
WIFI()->setConfigPortalTimeoutCallback([this]() {_wifiTimeoutCallback();});
|
||||||
if (ag->isOne() || (ag->isPro4_2()) || ag->isPro3_7()) {
|
if (ag->isOne() || (ag->isPro4_2()) || ag->isPro3_7() || ag->isBasic()) {
|
||||||
disp.setText("Connecting to", "WiFi", "...");
|
disp.setText("Connect to", "WiFi", "...");
|
||||||
} else {
|
} else {
|
||||||
logInfo("Connecting to WiFi...");
|
logInfo("Connecting to WiFi...");
|
||||||
}
|
}
|
||||||
@ -81,6 +81,7 @@ bool WifiConnector::connect(void) {
|
|||||||
WifiConnector *connector = (WifiConnector *)obj;
|
WifiConnector *connector = (WifiConnector *)obj;
|
||||||
while (connector->_wifiConfigPortalActive()) {
|
while (connector->_wifiConfigPortalActive()) {
|
||||||
connector->_wifiProcess();
|
connector->_wifiProcess();
|
||||||
|
vTaskDelay(1);
|
||||||
}
|
}
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
},
|
},
|
||||||
@ -142,7 +143,7 @@ bool WifiConnector::connect(void) {
|
|||||||
/** Show display wifi connect result failed */
|
/** Show display wifi connect result failed */
|
||||||
if (WiFi.isConnected() == false) {
|
if (WiFi.isConnected() == false) {
|
||||||
sm.handleLeds(AgStateMachineWiFiManagerConnectFailed);
|
sm.handleLeds(AgStateMachineWiFiManagerConnectFailed);
|
||||||
if (ag->isOne() || ag->isPro4_2() || ag->isPro3_7()) {
|
if (ag->isOne() || ag->isPro4_2() || ag->isPro3_7() || ag->isBasic()) {
|
||||||
sm.displayHandle(AgStateMachineWiFiManagerConnectFailed);
|
sm.displayHandle(AgStateMachineWiFiManagerConnectFailed);
|
||||||
}
|
}
|
||||||
delay(6000);
|
delay(6000);
|
||||||
@ -247,7 +248,7 @@ void WifiConnector::_wifiProcess() {
|
|||||||
if (WiFi.isConnected() == false) {
|
if (WiFi.isConnected() == false) {
|
||||||
/** Display countdown */
|
/** Display countdown */
|
||||||
uint32_t ms;
|
uint32_t ms;
|
||||||
if (ag->isOne() || (ag->isPro4_2()) || ag->isPro3_7()) {
|
if (ag->isOne() || (ag->isPro4_2()) || ag->isPro3_7() || ag->isBasic()) {
|
||||||
ms = (uint32_t)(millis() - dispPeriod);
|
ms = (uint32_t)(millis() - dispPeriod);
|
||||||
if (ms >= 1000) {
|
if (ms >= 1000) {
|
||||||
dispPeriod = millis();
|
dispPeriod = millis();
|
||||||
|
@ -66,6 +66,8 @@ bool AirGradient::isPro3_7(void) {
|
|||||||
return boardType == BoardType::DIY_PRO_INDOOR_V3_7;
|
return boardType == BoardType::DIY_PRO_INDOOR_V3_7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AirGradient::isBasic(void) { return boardType == BoardType::DIY_BASIC; }
|
||||||
|
|
||||||
String AirGradient::deviceId(void) {
|
String AirGradient::deviceId(void) {
|
||||||
String mac = WiFi.macAddress();
|
String mac = WiFi.macAddress();
|
||||||
mac.replace(":", "");
|
mac.replace(":", "");
|
||||||
|
@ -149,6 +149,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool isPro3_7(void);
|
bool isPro3_7(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check that Airgradient object is DIY_BASIC
|
||||||
|
*
|
||||||
|
* @return true Yes
|
||||||
|
* @return false No
|
||||||
|
*/
|
||||||
|
bool isBasic(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get device Id
|
* @brief Get device Id
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user