mirror of
https://github.com/airgradienthq/arduino.git
synced 2025-07-05 20:26:31 +02:00
Add DiyProIndoorV4_2.ino
example
This commit is contained in:
785
examples/DiyProIndoorV4_2/DiyProIndoorV4_2.ino
Normal file
785
examples/DiyProIndoorV4_2/DiyProIndoorV4_2.ino
Normal file
@ -0,0 +1,785 @@
|
|||||||
|
#include "AgApiClient.h"
|
||||||
|
#include "AgConfigure.h"
|
||||||
|
#include "AgSchedule.h"
|
||||||
|
#include "AgWiFiConnector.h"
|
||||||
|
#include "LocalServer.h"
|
||||||
|
#include "OpenMetrics.h"
|
||||||
|
#include <AirGradient.h>
|
||||||
|
#include <ESP8266HTTPClient.h>
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESP8266mDNS.h>
|
||||||
|
#include <WiFiClient.h>
|
||||||
|
|
||||||
|
#define LED_BAR_ANIMATION_PERIOD 100 /** ms */
|
||||||
|
#define DISP_UPDATE_INTERVAL 2500 /** ms */
|
||||||
|
#define SERVER_CONFIG_SYNC_INTERVAL 60000 /** ms */
|
||||||
|
#define SERVER_SYNC_INTERVAL 60000 /** ms */
|
||||||
|
#define MQTT_SYNC_INTERVAL 60000 /** ms */
|
||||||
|
#define SENSOR_CO2_CALIB_COUNTDOWN_MAX 5 /** sec */
|
||||||
|
#define SENSOR_TVOC_UPDATE_INTERVAL 1000 /** ms */
|
||||||
|
#define SENSOR_CO2_UPDATE_INTERVAL 4000 /** ms */
|
||||||
|
#define SENSOR_PM_UPDATE_INTERVAL 2000 /** ms */
|
||||||
|
#define SENSOR_TEMP_HUM_UPDATE_INTERVAL 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 Configuration configuration(Serial);
|
||||||
|
static AgApiClient apiClient(Serial, configuration);
|
||||||
|
static Measurements measurements;
|
||||||
|
static OledDisplay oledDisplay(configuration, measurements, Serial);
|
||||||
|
static StateMachine stateMachine(oledDisplay, Serial, measurements,
|
||||||
|
configuration);
|
||||||
|
static WifiConnector wifiConnector(oledDisplay, Serial, stateMachine,
|
||||||
|
configuration);
|
||||||
|
static OpenMetrics openMetrics(measurements, configuration, wifiConnector,
|
||||||
|
apiClient);
|
||||||
|
static LocalServer localServer(Serial, openMetrics, measurements, configuration,
|
||||||
|
wifiConnector);
|
||||||
|
|
||||||
|
static int pmFailCount = 0;
|
||||||
|
static uint32_t factoryBtnPressTime = 0;
|
||||||
|
static int getCO2FailCount = 0;
|
||||||
|
static AgFirmwareMode fwMode = FW_MODE_I_8PSL;
|
||||||
|
|
||||||
|
static bool ledBarButtonTest = false;
|
||||||
|
static String fwNewVersion;
|
||||||
|
|
||||||
|
static void boardInit(void);
|
||||||
|
static void failedHandler(String msg);
|
||||||
|
static void configurationUpdateSchedule(void);
|
||||||
|
static void appLedHandler(void);
|
||||||
|
static void appDispHandler(void);
|
||||||
|
static void oledDisplayLedBarSchedule(void);
|
||||||
|
static void updateTvoc(void);
|
||||||
|
static void updatePm(void);
|
||||||
|
static void sendDataToServer(void);
|
||||||
|
static void tempHumUpdate(void);
|
||||||
|
static void co2Update(void);
|
||||||
|
static void mdnsInit(void);
|
||||||
|
static void createMqttTask(void);
|
||||||
|
static void initMqtt(void);
|
||||||
|
static void factoryConfigReset(void);
|
||||||
|
static void wdgFeedUpdate(void);
|
||||||
|
static void ledBarEnabledUpdate(void);
|
||||||
|
static bool sgp41Init(void);
|
||||||
|
static void wifiFactoryConfigure(void);
|
||||||
|
|
||||||
|
AgSchedule dispLedSchedule(DISP_UPDATE_INTERVAL, oledDisplayLedBarSchedule);
|
||||||
|
AgSchedule configSchedule(SERVER_CONFIG_SYNC_INTERVAL,
|
||||||
|
configurationUpdateSchedule);
|
||||||
|
AgSchedule agApiPostSchedule(SERVER_SYNC_INTERVAL, sendDataToServer);
|
||||||
|
AgSchedule co2Schedule(SENSOR_CO2_UPDATE_INTERVAL, co2Update);
|
||||||
|
AgSchedule pmsSchedule(SENSOR_PM_UPDATE_INTERVAL, updatePm);
|
||||||
|
AgSchedule tempHumSchedule(SENSOR_TEMP_HUM_UPDATE_INTERVAL, tempHumUpdate);
|
||||||
|
AgSchedule tvocSchedule(SENSOR_TVOC_UPDATE_INTERVAL, updateTvoc);
|
||||||
|
AgSchedule watchdogFeedSchedule(60000, wdgFeedUpdate);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
/** Serial for print debug message */
|
||||||
|
Serial.begin(115200);
|
||||||
|
delay(100); /** For bester show log */
|
||||||
|
|
||||||
|
/** Print device ID into log */
|
||||||
|
Serial.println("Serial nr: " + ag.deviceId());
|
||||||
|
|
||||||
|
/** Initialize local configure */
|
||||||
|
configuration.begin();
|
||||||
|
|
||||||
|
/** Init I2C */
|
||||||
|
Wire.begin(ag.getI2cSdaPin(), ag.getI2cSclPin());
|
||||||
|
delay(1000);
|
||||||
|
|
||||||
|
configuration.setAirGradient(&ag);
|
||||||
|
oledDisplay.setAirGradient(&ag);
|
||||||
|
stateMachine.setAirGradient(&ag);
|
||||||
|
wifiConnector.setAirGradient(&ag);
|
||||||
|
apiClient.setAirGradient(&ag);
|
||||||
|
openMetrics.setAirGradient(&ag);
|
||||||
|
localServer.setAirGraident(&ag);
|
||||||
|
|
||||||
|
/** Init sensor */
|
||||||
|
boardInit();
|
||||||
|
|
||||||
|
/** Connecting wifi */
|
||||||
|
bool connectToWifi = false;
|
||||||
|
if (ag.isOne() || ag.getBoardType() == DIY_PRO_INDOOR_V4_2) {
|
||||||
|
/** Show message confirm offline mode, should me perform if LED bar button
|
||||||
|
* test pressed */
|
||||||
|
if (ledBarButtonTest == false) {
|
||||||
|
oledDisplay.setText(
|
||||||
|
"Press now for",
|
||||||
|
configuration.isOfflineMode() ? "online mode" : "offline mode", "");
|
||||||
|
uint32_t startTime = millis();
|
||||||
|
while (true) {
|
||||||
|
if (ag.button.getState() == ag.button.BUTTON_PRESSED) {
|
||||||
|
configuration.setOfflineMode(!configuration.isOfflineMode());
|
||||||
|
|
||||||
|
oledDisplay.setText(
|
||||||
|
"Offline Mode",
|
||||||
|
configuration.isOfflineMode() ? " = True" : " = False", "");
|
||||||
|
delay(1000);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
uint32_t periodMs = (uint32_t)(millis() - startTime);
|
||||||
|
if (periodMs >= 3000) {
|
||||||
|
Serial.println("Set for offline mode timeout");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(1);
|
||||||
|
}
|
||||||
|
connectToWifi = !configuration.isOfflineMode();
|
||||||
|
} else {
|
||||||
|
configuration.setOfflineModeWithoutSave(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
connectToWifi = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connectToWifi) {
|
||||||
|
apiClient.begin();
|
||||||
|
|
||||||
|
if (wifiConnector.connect()) {
|
||||||
|
if (wifiConnector.isConnected()) {
|
||||||
|
mdnsInit();
|
||||||
|
localServer.begin();
|
||||||
|
initMqtt();
|
||||||
|
sendDataToAg();
|
||||||
|
|
||||||
|
apiClient.fetchServerConfiguration();
|
||||||
|
configSchedule.update();
|
||||||
|
if (apiClient.isFetchConfigureFailed()) {
|
||||||
|
if (ag.isOne() || (ag.getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
|
if (apiClient.isNotAvailableOnDashboard()) {
|
||||||
|
stateMachine.displaySetAddToDashBoard();
|
||||||
|
stateMachine.displayHandle(
|
||||||
|
AgStateMachineWiFiOkServerOkSensorConfigFailed);
|
||||||
|
} else {
|
||||||
|
stateMachine.displayClearAddToDashBoard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stateMachine.handleLeds(
|
||||||
|
AgStateMachineWiFiOkServerOkSensorConfigFailed);
|
||||||
|
delay(DISPLAY_DELAY_SHOW_CONTENT_MS);
|
||||||
|
} else {
|
||||||
|
ledBarEnabledUpdate();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (wifiConnector.isConfigurePorttalTimeout()) {
|
||||||
|
oledDisplay.showRebooting();
|
||||||
|
delay(2500);
|
||||||
|
oledDisplay.setText("", "", "");
|
||||||
|
ESP.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** Set offline mode without saving, cause wifi is not configured */
|
||||||
|
if (wifiConnector.hasConfigurated() == false) {
|
||||||
|
Serial.println("Set offline mode cause wifi is not configurated");
|
||||||
|
configuration.setOfflineModeWithoutSave(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Show display Warning up */
|
||||||
|
if (ag.isOne() || (ag.getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
|
oledDisplay.setText("Warming Up", "Serial Number:", ag.deviceId().c_str());
|
||||||
|
delay(DISPLAY_DELAY_SHOW_CONTENT_MS);
|
||||||
|
|
||||||
|
Serial.println("Display brightness: " +
|
||||||
|
String(configuration.getDisplayBrightness()));
|
||||||
|
oledDisplay.setBrightness(configuration.getDisplayBrightness());
|
||||||
|
}
|
||||||
|
|
||||||
|
appLedHandler();
|
||||||
|
appDispHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
/** Handle schedule */
|
||||||
|
dispLedSchedule.run();
|
||||||
|
configSchedule.run();
|
||||||
|
agApiPostSchedule.run();
|
||||||
|
|
||||||
|
if (configuration.hasSensorS8) {
|
||||||
|
co2Schedule.run();
|
||||||
|
}
|
||||||
|
if (configuration.hasSensorPMS) {
|
||||||
|
pmsSchedule.run();
|
||||||
|
ag.pms5003.handle();
|
||||||
|
}
|
||||||
|
if (ag.isOne() || (ag.getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
|
if (configuration.hasSensorSHT) {
|
||||||
|
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();
|
||||||
|
|
||||||
|
/** factory reset handle */
|
||||||
|
factoryConfigReset();
|
||||||
|
|
||||||
|
/** check that local configura changed then do some action */
|
||||||
|
configUpdateHandle();
|
||||||
|
|
||||||
|
localServer._handle();
|
||||||
|
|
||||||
|
if (ag.getBoardType() == DIY_PRO_INDOOR_V4_2) {
|
||||||
|
ag.sgp41.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");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void createMqttTask(void) {
|
||||||
|
// if (mqttTask) {
|
||||||
|
// vTaskDelete(mqttTask);
|
||||||
|
// mqttTask = NULL;
|
||||||
|
// Serial.println("Delete old MQTT task");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Serial.println("Create new MQTT task");
|
||||||
|
// xTaskCreate(
|
||||||
|
// [](void *param) {
|
||||||
|
// for (;;) {
|
||||||
|
// delay(MQTT_SYNC_INTERVAL);
|
||||||
|
|
||||||
|
// /** Send data */
|
||||||
|
// 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");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// "mqtt-task", 1024 * 4, NULL, 6, &mqttTask);
|
||||||
|
|
||||||
|
// if (mqttTask == NULL) {
|
||||||
|
// Serial.println("Creat mqttTask failed");
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
static void initMqtt(void) {
|
||||||
|
// if (mqttClient.begin(configuration.getMqttBrokerUri())) {
|
||||||
|
// Serial.println("Connect to MQTT broker successful");
|
||||||
|
// createMqttTask();
|
||||||
|
// } else {
|
||||||
|
// Serial.println("Connect to MQTT broker failed");
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
static void factoryConfigReset(void) {
|
||||||
|
if (ag.button.getState() == ag.button.BUTTON_PRESSED) {
|
||||||
|
if (factoryBtnPressTime == 0) {
|
||||||
|
factoryBtnPressTime = millis();
|
||||||
|
} else {
|
||||||
|
uint32_t ms = (uint32_t)(millis() - factoryBtnPressTime);
|
||||||
|
if (ms >= 2000) {
|
||||||
|
// Show display message: For factory keep for x seconds
|
||||||
|
if (ag.isOne() || (ag.getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
|
oledDisplay.setText("Factory reset", "keep pressed", "for 8 sec");
|
||||||
|
} else {
|
||||||
|
Serial.println("Factory reset, keep pressed for 8 sec");
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = 7;
|
||||||
|
while (ag.button.getState() == ag.button.BUTTON_PRESSED) {
|
||||||
|
delay(1000);
|
||||||
|
if (ag.isOne() || (ag.getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
|
|
||||||
|
String str = "for " + String(count) + " sec";
|
||||||
|
oledDisplay.setText("Factory reset", "keep pressed", str.c_str());
|
||||||
|
} else {
|
||||||
|
Serial.printf("Factory reset, keep pressed for %d sec\r\n", count);
|
||||||
|
}
|
||||||
|
count--;
|
||||||
|
if (count == 0) {
|
||||||
|
/** Stop MQTT task first */
|
||||||
|
// if (mqttTask) {
|
||||||
|
// vTaskDelete(mqttTask);
|
||||||
|
// mqttTask = NULL;
|
||||||
|
// }
|
||||||
|
|
||||||
|
/** Reset WIFI */
|
||||||
|
WiFi.enableSTA(true); // Incase offline mode
|
||||||
|
WiFi.disconnect(true, true);
|
||||||
|
|
||||||
|
/** Reset local config */
|
||||||
|
configuration.reset();
|
||||||
|
|
||||||
|
if (ag.isOne() || (ag.getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
|
oledDisplay.setText("Factory reset", "successful", "");
|
||||||
|
} else {
|
||||||
|
Serial.println("Factory reset successful");
|
||||||
|
}
|
||||||
|
delay(3000);
|
||||||
|
oledDisplay.setText("", "", "");
|
||||||
|
ESP.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Show current content cause reset ignore */
|
||||||
|
factoryBtnPressTime = 0;
|
||||||
|
if (ag.isOne() || (ag.getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
|
appDispHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (factoryBtnPressTime != 0) {
|
||||||
|
if (ag.isOne() || (ag.getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
|
/** Restore last display content */
|
||||||
|
appDispHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
factoryBtnPressTime = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wdgFeedUpdate(void) {
|
||||||
|
ag.watchdog.reset();
|
||||||
|
Serial.println();
|
||||||
|
Serial.println("Offline mode or isPostToAirGradient = false: watchdog reset");
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ledBarEnabledUpdate(void) {
|
||||||
|
if (ag.isOne() || (ag.getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
|
int brightness = configuration.getLedBarBrightness();
|
||||||
|
Serial.println("LED bar brightness: " + String(brightness));
|
||||||
|
if ((brightness == 0) || (configuration.getLedBarMode() == LedBarModeOff)) {
|
||||||
|
ag.ledBar.setEnable(false);
|
||||||
|
} else {
|
||||||
|
ag.ledBar.setBrightness(brightness);
|
||||||
|
ag.ledBar.setEnable(configuration.getLedBarMode() != LedBarModeOff);
|
||||||
|
}
|
||||||
|
ag.ledBar.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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.begin("airgradient", "cleanair");
|
||||||
|
oledDisplay.setText("Configure WiFi", "connect to", "\'airgradient\'");
|
||||||
|
delay(2500);
|
||||||
|
oledDisplay.setText("Rebooting...", "", "");
|
||||||
|
delay(2500);
|
||||||
|
oledDisplay.setText("", "", "");
|
||||||
|
ESP.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sendDataToAg() {
|
||||||
|
/** Change oledDisplay and led state */
|
||||||
|
if (ag.isOne() || (ag.getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
|
stateMachine.displayHandle(AgStateMachineWiFiOkServerConnecting);
|
||||||
|
}
|
||||||
|
stateMachine.handleLeds(AgStateMachineWiFiOkServerConnecting);
|
||||||
|
|
||||||
|
/** Task handle led connecting animation */
|
||||||
|
// xTaskCreate(
|
||||||
|
// [](void *obj) {
|
||||||
|
// for (;;) {
|
||||||
|
// // ledSmHandler();
|
||||||
|
// stateMachine.handleLeds();
|
||||||
|
// if (stateMachine.getLedState() !=
|
||||||
|
// AgStateMachineWiFiOkServerConnecting) {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// delay(LED_BAR_ANIMATION_PERIOD);
|
||||||
|
// }
|
||||||
|
// vTaskDelete(NULL);
|
||||||
|
// },
|
||||||
|
// "task_led", 2048, NULL, 5, NULL);
|
||||||
|
|
||||||
|
delay(1500);
|
||||||
|
if (apiClient.sendPing(wifiConnector.RSSI(), measurements.bootCount)) {
|
||||||
|
if (ag.isOne() || (ag.getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
|
stateMachine.displayHandle(AgStateMachineWiFiOkServerConnected);
|
||||||
|
}
|
||||||
|
stateMachine.handleLeds(AgStateMachineWiFiOkServerConnected);
|
||||||
|
} else {
|
||||||
|
if (ag.isOne() || (ag.getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
|
stateMachine.displayHandle(AgStateMachineWiFiOkServerConnectFailed);
|
||||||
|
}
|
||||||
|
stateMachine.handleLeds(AgStateMachineWiFiOkServerConnectFailed);
|
||||||
|
}
|
||||||
|
delay(DISPLAY_DELAY_SHOW_CONTENT_MS);
|
||||||
|
stateMachine.handleLeds(AgStateMachineNormal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispSensorNotFound(String ss) {
|
||||||
|
ss = ss + " not found";
|
||||||
|
oledDisplay.setText("Sensor init", "Error:", ss.c_str());
|
||||||
|
delay(2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void boardInit(void) {
|
||||||
|
/** Display init */
|
||||||
|
oledDisplay.begin();
|
||||||
|
|
||||||
|
/** Show boot display */
|
||||||
|
Serial.println("Firmware Version: " + ag.getVersion());
|
||||||
|
|
||||||
|
oledDisplay.setText("AirGradient ONE",
|
||||||
|
"FW Version: ", ag.getVersion().c_str());
|
||||||
|
delay(DISPLAY_DELAY_SHOW_CONTENT_MS);
|
||||||
|
|
||||||
|
ag.ledBar.begin();
|
||||||
|
ag.button.begin();
|
||||||
|
ag.watchdog.begin();
|
||||||
|
|
||||||
|
/** Run LED test on start up if button pressed */
|
||||||
|
if (ag.isOne()) {
|
||||||
|
oledDisplay.setText("Press now for", "LED test", "");
|
||||||
|
} else if (ag.getBoardType() == DIY_PRO_INDOOR_V4_2) {
|
||||||
|
oledDisplay.setText("Press now for", "factory WiFi", "configure");
|
||||||
|
}
|
||||||
|
|
||||||
|
ledBarButtonTest = false;
|
||||||
|
uint32_t stime = millis();
|
||||||
|
while (true) {
|
||||||
|
if (ag.button.getState() == ag.button.BUTTON_PRESSED) {
|
||||||
|
if (ag.isOne()) {
|
||||||
|
ledBarButtonTest = true;
|
||||||
|
stateMachine.executeLedBarPowerUpTest();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ag.getBoardType() == DIY_PRO_INDOOR_V4_2) {
|
||||||
|
wifiFactoryConfigure();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delay(1);
|
||||||
|
uint32_t ms = (uint32_t)(millis() - stime);
|
||||||
|
if (ms >= 3000) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
delay(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Check for button to reset WiFi connecto to "airgraident" after test LED
|
||||||
|
* bar */
|
||||||
|
if (ledBarButtonTest && ag.isOne()) {
|
||||||
|
if (ag.button.getState() == ag.button.BUTTON_PRESSED) {
|
||||||
|
wifiFactoryConfigure();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ledBarEnabledUpdate();
|
||||||
|
|
||||||
|
/** Show message init sensor */
|
||||||
|
oledDisplay.setText("Sensor", "initializing...", "");
|
||||||
|
|
||||||
|
/** Init sensor SGP41 */
|
||||||
|
if (sgp41Init() == false) {
|
||||||
|
dispSensorNotFound("SGP41");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Init SHT */
|
||||||
|
if (ag.sht.begin(Wire) == false) {
|
||||||
|
Serial.println("SHTx sensor not found");
|
||||||
|
configuration.hasSensorSHT = false;
|
||||||
|
dispSensorNotFound("SHT");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Init S8 CO2 sensor */
|
||||||
|
if (ag.s8.begin(&Serial) == false) {
|
||||||
|
Serial.println("CO2 S8 sensor not found");
|
||||||
|
configuration.hasSensorS8 = false;
|
||||||
|
dispSensorNotFound("S8");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Init PMS5003 */
|
||||||
|
configuration.hasSensorPMS1 = false;
|
||||||
|
configuration.hasSensorPMS2 = false;
|
||||||
|
if (ag.pms5003.begin(&Serial) == false) {
|
||||||
|
Serial.println("PMS sensor not found");
|
||||||
|
configuration.hasSensorPMS = false;
|
||||||
|
|
||||||
|
dispSensorNotFound("PMS");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set S8 CO2 abc days period */
|
||||||
|
if (configuration.hasSensorS8) {
|
||||||
|
if (ag.s8.setAbcPeriod(configuration.getCO2CalibrationAbcDays() * 24)) {
|
||||||
|
Serial.println("Set S8 AbcDays successful");
|
||||||
|
} else {
|
||||||
|
Serial.println("Set S8 AbcDays failure");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
localServer.setFwMode(FW_MODE_I_8PSL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void failedHandler(String msg) {
|
||||||
|
while (true) {
|
||||||
|
Serial.println(msg);
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void configurationUpdateSchedule(void) {
|
||||||
|
if (apiClient.fetchServerConfiguration()) {
|
||||||
|
configUpdateHandle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void configUpdateHandle() {
|
||||||
|
if (configuration.isUpdated() == false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
stateMachine.executeCo2Calibration();
|
||||||
|
|
||||||
|
// String mqttUri = configuration.getMqttBrokerUri();
|
||||||
|
// if (mqttClient.isCurrentUri(mqttUri) == false) {
|
||||||
|
// mqttClient.end();
|
||||||
|
// 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 (ag.isOne() || (ag.getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
|
if (configuration.isLedBarBrightnessChanged()) {
|
||||||
|
if (configuration.getLedBarBrightness() == 0) {
|
||||||
|
ag.ledBar.setEnable(false);
|
||||||
|
} else {
|
||||||
|
if (configuration.getLedBarMode() != LedBarMode::LedBarModeOff) {
|
||||||
|
ag.ledBar.setEnable(true);
|
||||||
|
}
|
||||||
|
ag.ledBar.setBrightness(configuration.getLedBarBrightness());
|
||||||
|
}
|
||||||
|
ag.ledBar.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (configuration.isLedBarModeChanged()) {
|
||||||
|
// if (configuration.getLedBarBrightness() == 0) {
|
||||||
|
// ag.ledBar.setEnable(false);
|
||||||
|
// } else {
|
||||||
|
// if (configuration.getLedBarMode() == LedBarMode::LedBarModeOff) {
|
||||||
|
// ag.ledBar.setEnable(false);
|
||||||
|
// } else {
|
||||||
|
// ag.ledBar.setEnable(true);
|
||||||
|
// ag.ledBar.setBrightness(configuration.getLedBarBrightness());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// ag.ledBar.show();
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (configuration.isDisplayBrightnessChanged()) {
|
||||||
|
oledDisplay.setBrightness(configuration.getDisplayBrightness());
|
||||||
|
}
|
||||||
|
|
||||||
|
// stateMachine.executeLedBarTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
appDispHandler();
|
||||||
|
appLedHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void appLedHandler(void) {
|
||||||
|
AgStateMachineState state = AgStateMachineNormal;
|
||||||
|
if (configuration.isOfflineMode() == false) {
|
||||||
|
if (wifiConnector.isConnected() == false) {
|
||||||
|
state = AgStateMachineWiFiLost;
|
||||||
|
} else if (apiClient.isFetchConfigureFailed()) {
|
||||||
|
state = AgStateMachineSensorConfigFailed;
|
||||||
|
} else if (apiClient.isPostToServerFailed()) {
|
||||||
|
state = AgStateMachineServerLost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stateMachine.handleLeds(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void appDispHandler(void) {
|
||||||
|
if (ag.isOne() || (ag.getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
|
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 oledDisplayLedBarSchedule(void) {
|
||||||
|
if (ag.isOne() || (ag.getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
|
if (factoryBtnPressTime == 0) {
|
||||||
|
appDispHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
appLedHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
measurements.pm01_1 = ag.pms5003.getPm01Ae();
|
||||||
|
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;
|
||||||
|
} else {
|
||||||
|
pmFailCount++;
|
||||||
|
Serial.printf("PMS read failed: %d\r\n", pmFailCount);
|
||||||
|
if (pmFailCount >= 3) {
|
||||||
|
measurements.pm01_1 = -1;
|
||||||
|
measurements.pm25_1 = -1;
|
||||||
|
measurements.pm10_1 = -1;
|
||||||
|
measurements.pm03PCount_1 = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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()) {
|
||||||
|
measurements.Temperature = ag.sht.getTemperature();
|
||||||
|
measurements.Humidity = ag.sht.getRelativeHumidity();
|
||||||
|
|
||||||
|
Serial.printf("Temperature in C: %0.2f\r\n", measurements.Temperature);
|
||||||
|
Serial.printf("Relative Humidity: %d\r\n", measurements.Humidity);
|
||||||
|
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
|
||||||
|
if (configuration.hasSensorSGP) {
|
||||||
|
ag.sgp41.setCompensationTemperatureHumidity(measurements.Temperature,
|
||||||
|
measurements.Humidity);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Serial.println("SHT read failed");
|
||||||
|
}
|
||||||
|
}
|
61
examples/DiyProIndoorV4_2/LocalServer.cpp
Normal file
61
examples/DiyProIndoorV4_2/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/DiyProIndoorV4_2/LocalServer.h
Normal file
38
examples/DiyProIndoorV4_2/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/DiyProIndoorV4_2/OpenMetrics.cpp
Normal file
186
examples/DiyProIndoorV4_2/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.hasSensorPMS) {
|
||||||
|
pm01 = measure.pm01_1;
|
||||||
|
pm25 = measure.pm25_1;
|
||||||
|
pm10 = measure.pm10_1;
|
||||||
|
pm03PCount = measure.pm03PCount_1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.hasSensorPMS) {
|
||||||
|
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/DiyProIndoorV4_2/OpenMetrics.h
Normal file
28
examples/DiyProIndoorV4_2/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_ */
|
@ -43,7 +43,7 @@ JSON_PROP_DEF(ledBarTestRequested);
|
|||||||
JSON_PROP_DEF(offlineMode);
|
JSON_PROP_DEF(offlineMode);
|
||||||
|
|
||||||
#define jprop_model_default ""
|
#define jprop_model_default ""
|
||||||
#define jprop_country_default ""
|
#define jprop_country_default "TH"
|
||||||
#define jprop_pmStandard_default getPMStandardString(false)
|
#define jprop_pmStandard_default getPMStandardString(false)
|
||||||
#define jprop_ledBarMode_default getLedBarModeName(LedBarMode::LedBarModeCO2)
|
#define jprop_ledBarMode_default getLedBarModeName(LedBarMode::LedBarModeCO2)
|
||||||
#define jprop_abcDays_default 8
|
#define jprop_abcDays_default 8
|
||||||
@ -614,15 +614,18 @@ bool Configuration::parse(String data, bool isLocal) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JSON.typeof_(root["targetFirmware"]) == "string") {
|
if (ag->getBoardType() == ONE_INDOOR ||
|
||||||
String newVer = root["targetFirmware"];
|
ag->getBoardType() == OPEN_AIR_OUTDOOR) {
|
||||||
String curVer = String(GIT_VERSION);
|
if (JSON.typeof_(root["targetFirmware"]) == "string") {
|
||||||
if (curVer != newVer) {
|
String newVer = root["targetFirmware"];
|
||||||
logInfo("Detected new firmware version: " + newVer);
|
String curVer = String(GIT_VERSION);
|
||||||
otaNewFirmwareVersion = newVer;
|
if (curVer != newVer) {
|
||||||
udpated = true;
|
logInfo("Detected new firmware version: " + newVer);
|
||||||
} else {
|
otaNewFirmwareVersion = newVer;
|
||||||
otaNewFirmwareVersion = String("");
|
udpated = true;
|
||||||
|
} else {
|
||||||
|
otaNewFirmwareVersion = String("");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ public:
|
|||||||
bool hasSensorS8 = true;
|
bool hasSensorS8 = true;
|
||||||
bool hasSensorPMS1 = true;
|
bool hasSensorPMS1 = true;
|
||||||
bool hasSensorPMS2 = true;
|
bool hasSensorPMS2 = true;
|
||||||
|
bool hasSensorPMS = true;
|
||||||
bool hasSensorSGP = true;
|
bool hasSensorSGP = true;
|
||||||
bool hasSensorSHT = true;
|
bool hasSensorSHT = true;
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ void StateMachine::co2Calibration(void) {
|
|||||||
|
|
||||||
/** Count down to 0 then start */
|
/** Count down to 0 then start */
|
||||||
for (int i = 0; i < SENSOR_CO2_CALIB_COUNTDOWN_MAX; i++) {
|
for (int i = 0; i < SENSOR_CO2_CALIB_COUNTDOWN_MAX; i++) {
|
||||||
if (ag->isOne()) {
|
if (ag->isOne() || (ag->getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
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(), "");
|
||||||
@ -236,13 +236,13 @@ void StateMachine::co2Calibration(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ag->s8.setBaselineCalibration()) {
|
if (ag->s8.setBaselineCalibration()) {
|
||||||
if (ag->isOne()) {
|
if (ag->isOne() || (ag->getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
disp.setText("Calibration", "success", "");
|
disp.setText("Calibration", "success", "");
|
||||||
} else {
|
} else {
|
||||||
logInfo("CO2 Calibration: success");
|
logInfo("CO2 Calibration: success");
|
||||||
}
|
}
|
||||||
delay(1000);
|
delay(1000);
|
||||||
if (ag->isOne()) {
|
if (ag->isOne() || (ag->getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
disp.setText("Wait for", "calib finish", "...");
|
disp.setText("Wait for", "calib finish", "...");
|
||||||
} else {
|
} else {
|
||||||
logInfo("CO2 Calibration: Wait for calibration finish...");
|
logInfo("CO2 Calibration: Wait for calibration finish...");
|
||||||
@ -254,7 +254,7 @@ void StateMachine::co2Calibration(void) {
|
|||||||
delay(1000);
|
delay(1000);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
if (ag->isOne()) {
|
if (ag->isOne() || (ag->getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
String str = "after " + String(count);
|
String str = "after " + String(count);
|
||||||
disp.setText("Calib finish", str.c_str(), "sec");
|
disp.setText("Calib finish", str.c_str(), "sec");
|
||||||
} else {
|
} else {
|
||||||
@ -262,7 +262,7 @@ void StateMachine::co2Calibration(void) {
|
|||||||
}
|
}
|
||||||
delay(2000);
|
delay(2000);
|
||||||
} else {
|
} else {
|
||||||
if (ag->isOne()) {
|
if (ag->isOne() || (ag->getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
disp.setText("Calibration", "failure!!!", "");
|
disp.setText("Calibration", "failure!!!", "");
|
||||||
} else {
|
} else {
|
||||||
logInfo("CO2 Calibration: failure!!!");
|
logInfo("CO2 Calibration: failure!!!");
|
||||||
@ -399,7 +399,7 @@ StateMachine::~StateMachine() {}
|
|||||||
*/
|
*/
|
||||||
void StateMachine::displayHandle(AgStateMachineState state) {
|
void StateMachine::displayHandle(AgStateMachineState state) {
|
||||||
// Ignore handle if not ONE_INDOOR board
|
// Ignore handle if not ONE_INDOOR board
|
||||||
if (!ag->isOne()) {
|
if (!(ag->isOne() || (ag->getBoardType() == DIY_PRO_INDOOR_V4_2))) {
|
||||||
if (state == AgStateMachineCo2Calibration) {
|
if (state == AgStateMachineCo2Calibration) {
|
||||||
co2Calibration();
|
co2Calibration();
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,8 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ag->isOne()) {
|
if (ag->isOne() || (ag->getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
if (config->hasSensorPMS1) {
|
if (config->hasSensorPMS1 || config->hasSensorPMS) {
|
||||||
if (this->pm01_1 >= 0) {
|
if (this->pm01_1 >= 0) {
|
||||||
root["pm01"] = this->pm01_1;
|
root["pm01"] = this->pm01_1;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
*/
|
*/
|
||||||
void WifiConnector::setAirGradient(AirGradient *ag) { this->ag = ag; }
|
void WifiConnector::setAirGradient(AirGradient *ag) { this->ag = ag; }
|
||||||
|
|
||||||
#ifdef ESP32
|
|
||||||
/**
|
/**
|
||||||
* @brief Construct a new Ag Wi Fi Connector:: Ag Wi Fi Connector object
|
* @brief Construct a new Ag Wi Fi Connector:: Ag Wi Fi Connector object
|
||||||
*
|
*
|
||||||
@ -24,9 +23,10 @@ void WifiConnector::setAirGradient(AirGradient *ag) { this->ag = ag; }
|
|||||||
WifiConnector::WifiConnector(OledDisplay &disp, Stream &log, StateMachine &sm,
|
WifiConnector::WifiConnector(OledDisplay &disp, Stream &log, StateMachine &sm,
|
||||||
Configuration &config)
|
Configuration &config)
|
||||||
: PrintLog(log, "WifiConnector"), disp(disp), sm(sm), config(config) {}
|
: PrintLog(log, "WifiConnector"), disp(disp), sm(sm), config(config) {}
|
||||||
#else
|
|
||||||
WifiConnector::WifiConnector(Stream &log) : PrintLog(log, "WiFiConnector") {}
|
// #ifdef ESP8266
|
||||||
#endif
|
// WifiConnector::WifiConnector(Stream &log) : PrintLog(log, "WiFiConnector") {}
|
||||||
|
// #endif
|
||||||
|
|
||||||
WifiConnector::~WifiConnector() {}
|
WifiConnector::~WifiConnector() {}
|
||||||
|
|
||||||
@ -49,20 +49,18 @@ bool WifiConnector::connect(void) {
|
|||||||
WIFI()->setConnectTimeout(15);
|
WIFI()->setConnectTimeout(15);
|
||||||
WIFI()->setTimeout(WIFI_CONNECT_COUNTDOWN_MAX);
|
WIFI()->setTimeout(WIFI_CONNECT_COUNTDOWN_MAX);
|
||||||
|
|
||||||
#ifdef ESP32
|
|
||||||
WIFI()->setAPCallback([this](WiFiManager *obj) { _wifiApCallback(); });
|
WIFI()->setAPCallback([this](WiFiManager *obj) { _wifiApCallback(); });
|
||||||
WIFI()->setSaveConfigCallback([this]() { _wifiSaveConfig(); });
|
WIFI()->setSaveConfigCallback([this]() { _wifiSaveConfig(); });
|
||||||
WIFI()->setSaveParamsCallback([this]() { _wifiSaveParamCallback(); });
|
WIFI()->setSaveParamsCallback([this]() { _wifiSaveParamCallback(); });
|
||||||
WIFI()->setConfigPortalTimeoutCallback([this](){});
|
WIFI()->setConfigPortalTimeoutCallback([this]() {});
|
||||||
if (ag->isOne()) {
|
if (ag->isOne() || (ag->getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
disp.setText("Connecting to", "WiFi", "...");
|
disp.setText("Connecting to", "WiFi", "...");
|
||||||
} else {
|
} else {
|
||||||
logInfo("Connecting to WiFi...");
|
logInfo("Connecting to WiFi...");
|
||||||
}
|
}
|
||||||
ssid = "airgradient-" + ag->deviceId();
|
ssid = "airgradient-" + ag->deviceId();
|
||||||
#else
|
|
||||||
ssid = "AG-" + String(ESP.getChipId(), HEX);
|
// ssid = "AG-" + String(ESP.getChipId(), HEX);
|
||||||
#endif
|
|
||||||
WIFI()->setConfigPortalTimeout(WIFI_CONNECT_COUNTDOWN_MAX);
|
WIFI()->setConfigPortalTimeout(WIFI_CONNECT_COUNTDOWN_MAX);
|
||||||
|
|
||||||
WiFiManagerParameter postToAg("chbPostToAg",
|
WiFiManagerParameter postToAg("chbPostToAg",
|
||||||
@ -78,6 +76,8 @@ bool WifiConnector::connect(void) {
|
|||||||
|
|
||||||
WIFI()->autoConnect(ssid.c_str(), WIFI_HOTSPOT_PASSWORD_DEFAULT);
|
WIFI()->autoConnect(ssid.c_str(), WIFI_HOTSPOT_PASSWORD_DEFAULT);
|
||||||
|
|
||||||
|
logInfo("Wait for configure portal");
|
||||||
|
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
// Task handle WiFi connection.
|
// Task handle WiFi connection.
|
||||||
xTaskCreate(
|
xTaskCreate(
|
||||||
@ -139,10 +139,14 @@ bool WifiConnector::connect(void) {
|
|||||||
|
|
||||||
delay(1); // avoid watchdog timer reset.
|
delay(1); // avoid watchdog timer reset.
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
_wifiProcess();
|
||||||
|
#endif
|
||||||
|
|
||||||
/** 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()) {
|
if (ag->isOne() || ag->getBoardType() == DIY_PRO_INDOOR_V4_2) {
|
||||||
sm.displayHandle(AgStateMachineWiFiManagerConnectFailed);
|
sm.displayHandle(AgStateMachineWiFiManagerConnectFailed);
|
||||||
}
|
}
|
||||||
delay(6000);
|
delay(6000);
|
||||||
@ -160,9 +164,7 @@ bool WifiConnector::connect(void) {
|
|||||||
}
|
}
|
||||||
hasPortalConfig = false;
|
hasPortalConfig = false;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
_wifiProcess();
|
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,20 +181,20 @@ void WifiConnector::disconnect(void) {
|
|||||||
|
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
#else
|
#else
|
||||||
void WifiConnector::displayShowText(String ln1, String ln2, String ln3) {
|
// void WifiConnector::displayShowText(String ln1, String ln2, String ln3) {
|
||||||
char buf[9];
|
// char buf[9];
|
||||||
ag->display.clear();
|
// ag->display.clear();
|
||||||
|
|
||||||
ag->display.setCursor(1, 1);
|
// ag->display.setCursor(1, 1);
|
||||||
ag->display.setText(ln1);
|
// ag->display.setText(ln1);
|
||||||
ag->display.setCursor(1, 19);
|
// ag->display.setCursor(1, 19);
|
||||||
ag->display.setText(ln2);
|
// ag->display.setText(ln2);
|
||||||
ag->display.setCursor(1, 37);
|
// ag->display.setCursor(1, 37);
|
||||||
ag->display.setText(ln3);
|
// ag->display.setText(ln3);
|
||||||
|
|
||||||
ag->display.show();
|
// ag->display.show();
|
||||||
delay(100);
|
// delay(100);
|
||||||
}
|
// }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -205,7 +207,6 @@ bool WifiConnector::wifiClientConnected(void) {
|
|||||||
return WiFi.softAPgetStationNum() ? true : false;
|
return WiFi.softAPgetStationNum() ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ESP32
|
|
||||||
/**
|
/**
|
||||||
* @brief Handle WiFiManage softAP setup completed callback
|
* @brief Handle WiFiManage softAP setup completed callback
|
||||||
*
|
*
|
||||||
@ -247,7 +248,7 @@ bool WifiConnector::_wifiConfigPortalActive(void) {
|
|||||||
return WIFI()->getConfigPortalActive();
|
return WIFI()->getConfigPortalActive();
|
||||||
}
|
}
|
||||||
void WifiConnector::_wifiTimeoutCallback(void) { connectorTimeout = true; }
|
void WifiConnector::_wifiTimeoutCallback(void) { connectorTimeout = true; }
|
||||||
#endif
|
|
||||||
/**
|
/**
|
||||||
* @brief Process WiFiManager connection
|
* @brief Process WiFiManager connection
|
||||||
*
|
*
|
||||||
@ -256,34 +257,66 @@ void WifiConnector::_wifiProcess() {
|
|||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
WIFI()->process();
|
WIFI()->process();
|
||||||
#else
|
#else
|
||||||
int count = WIFI_CONNECT_COUNTDOWN_MAX;
|
/** Wait for WiFi connect and show LED, display status */
|
||||||
displayShowText(String(WIFI_CONNECT_COUNTDOWN_MAX) + " sec", "SSID:", ssid);
|
uint32_t dispPeriod = millis();
|
||||||
|
uint32_t ledPeriod = millis();
|
||||||
|
bool clientConnectChanged = false;
|
||||||
|
AgStateMachineState stateOld = sm.getDisplayState();
|
||||||
|
|
||||||
while (WIFI()->getConfigPortalActive()) {
|
while (WIFI()->getConfigPortalActive()) {
|
||||||
WIFI()->process();
|
WIFI()->process();
|
||||||
|
|
||||||
uint32_t lastTime = millis();
|
if (WiFi.isConnected() == false) {
|
||||||
uint32_t ms = (uint32_t)(millis() - lastTime);
|
/** Display countdown */
|
||||||
if (ms >= 1000) {
|
uint32_t ms;
|
||||||
lastTime = millis();
|
if (ag->isOne() || (ag->getBoardType() == DIY_PRO_INDOOR_V4_2)) {
|
||||||
|
ms = (uint32_t)(millis() - dispPeriod);
|
||||||
|
if (ms >= 1000) {
|
||||||
|
dispPeriod = millis();
|
||||||
|
sm.displayHandle();
|
||||||
|
logInfo("displayHandle state: " + String(sm.getDisplayState()));
|
||||||
|
} else {
|
||||||
|
if (stateOld != sm.getDisplayState()) {
|
||||||
|
stateOld = sm.getDisplayState();
|
||||||
|
sm.displayHandle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
displayShowText(String(count) + " sec", "SSID:", ssid);
|
/** LED animations */
|
||||||
|
ms = (uint32_t)(millis() - ledPeriod);
|
||||||
|
if (ms >= 100) {
|
||||||
|
ledPeriod = millis();
|
||||||
|
sm.handleLeds();
|
||||||
|
}
|
||||||
|
|
||||||
count--;
|
/** Check for client connect to change led color */
|
||||||
|
bool clientConnected = wifiClientConnected();
|
||||||
// Timeout
|
if (clientConnected != clientConnectChanged) {
|
||||||
if (count == 0) {
|
clientConnectChanged = clientConnected;
|
||||||
break;
|
if (clientConnectChanged) {
|
||||||
|
sm.handleLeds(AgStateMachineWiFiManagerPortalActive);
|
||||||
|
} else {
|
||||||
|
sm.ledAnimationInit();
|
||||||
|
sm.handleLeds(AgStateMachineWiFiManagerMode);
|
||||||
|
if (ag->isOne()) {
|
||||||
|
sm.displayHandle(AgStateMachineWiFiManagerMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!WiFi.isConnected()) {
|
// TODO This is for basic
|
||||||
displayShowText("Booting", "offline", "mode");
|
// if (!WiFi.isConnected()) {
|
||||||
Serial.println("failed to connect and hit timeout");
|
// disp.setText("Booting", "offline", "mode");
|
||||||
delay(2500);
|
// Serial.println("failed to connect and hit timeout");
|
||||||
} else {
|
// delay(2500);
|
||||||
hasConfig = true;
|
// } else {
|
||||||
}
|
// hasConfig = true;
|
||||||
|
// }
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,7 +377,7 @@ String WifiConnector::localIpStr(void) { return WiFi.localIP().toString(); }
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get status that wifi has configurated
|
* @brief Get status that wifi has configurated
|
||||||
*
|
*
|
||||||
* @return true Configurated
|
* @return true Configurated
|
||||||
* @return false Not Configurated
|
* @return false Not Configurated
|
||||||
*/
|
*/
|
||||||
@ -357,8 +390,8 @@ bool WifiConnector::hasConfigurated(void) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get WiFi connection porttal timeout.
|
* @brief Get WiFi connection porttal timeout.
|
||||||
*
|
*
|
||||||
* @return true
|
* @return true
|
||||||
* @return false
|
* @return false
|
||||||
*/
|
*/
|
||||||
bool WifiConnector::isConfigurePorttalTimeout(void) { return connectorTimeout; }
|
bool WifiConnector::isConfigurePorttalTimeout(void) { return connectorTimeout; }
|
||||||
|
@ -12,13 +12,10 @@
|
|||||||
class WifiConnector : public PrintLog {
|
class WifiConnector : public PrintLog {
|
||||||
private:
|
private:
|
||||||
AirGradient *ag;
|
AirGradient *ag;
|
||||||
#ifdef ESP32
|
|
||||||
OledDisplay &disp;
|
OledDisplay &disp;
|
||||||
StateMachine &sm;
|
StateMachine &sm;
|
||||||
Configuration &config;
|
Configuration &config;
|
||||||
#else
|
|
||||||
void displayShowText(String ln1, String ln2, String ln3);
|
|
||||||
#endif
|
|
||||||
String ssid;
|
String ssid;
|
||||||
void *wifi = NULL;
|
void *wifi = NULL;
|
||||||
bool hasConfig;
|
bool hasConfig;
|
||||||
@ -30,23 +27,21 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
void setAirGradient(AirGradient *ag);
|
void setAirGradient(AirGradient *ag);
|
||||||
#ifdef ESP32
|
|
||||||
WifiConnector(OledDisplay &disp, Stream &log, StateMachine &sm, Configuration& config);
|
WifiConnector(OledDisplay &disp, Stream &log, StateMachine &sm, Configuration& config);
|
||||||
#else
|
#ifdef ESP8266
|
||||||
WifiConnector(Stream &log);
|
// WifiConnector(Stream &log);
|
||||||
#endif
|
#endif
|
||||||
~WifiConnector();
|
~WifiConnector();
|
||||||
|
|
||||||
bool connect(void);
|
bool connect(void);
|
||||||
void disconnect(void);
|
void disconnect(void);
|
||||||
void handle(void);
|
void handle(void);
|
||||||
#ifdef ESP32
|
|
||||||
void _wifiApCallback(void);
|
void _wifiApCallback(void);
|
||||||
void _wifiSaveConfig(void);
|
void _wifiSaveConfig(void);
|
||||||
void _wifiSaveParamCallback(void);
|
void _wifiSaveParamCallback(void);
|
||||||
bool _wifiConfigPortalActive(void);
|
bool _wifiConfigPortalActive(void);
|
||||||
void _wifiTimeoutCallback(void);
|
void _wifiTimeoutCallback(void);
|
||||||
#endif
|
|
||||||
void _wifiProcess();
|
void _wifiProcess();
|
||||||
bool isConnected(void);
|
bool isConnected(void);
|
||||||
void reset(void);
|
void reset(void);
|
||||||
|
@ -14,6 +14,8 @@ const char *AgFirmwareModeName(AgFirmwareMode mode) {
|
|||||||
return "0-1PS";
|
return "0-1PS";
|
||||||
case FW_MODE_O_1P:
|
case FW_MODE_O_1P:
|
||||||
return "O-1P";
|
return "O-1P";
|
||||||
|
case FW_MODE_I_8PSL:
|
||||||
|
return "I-8PSL";
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -101,6 +101,7 @@ enum AgFirmwareMode {
|
|||||||
FW_MODE_O_1PP, /** PMS5003T_1, PMS5003T_2 */
|
FW_MODE_O_1PP, /** PMS5003T_1, PMS5003T_2 */
|
||||||
FW_MODE_O_1PS, /** PMS5003T, S8 */
|
FW_MODE_O_1PS, /** PMS5003T, S8 */
|
||||||
FW_MODE_O_1P, /** PMS5003T */
|
FW_MODE_O_1P, /** PMS5003T */
|
||||||
|
FW_MODE_I_8PSL, /** DIY_PRO 4.2 */
|
||||||
};
|
};
|
||||||
const char *AgFirmwareModeName(AgFirmwareMode mode);
|
const char *AgFirmwareModeName(AgFirmwareMode mode);
|
||||||
|
|
||||||
|
@ -116,6 +116,9 @@ void LedBar::setColor(uint8_t red, uint8_t green, uint8_t blue) {
|
|||||||
*/
|
*/
|
||||||
void LedBar::show(void) {
|
void LedBar::show(void) {
|
||||||
// Ignore update the LED if LED bar disabled
|
// Ignore update the LED if LED bar disabled
|
||||||
|
if(this->isBegin() == false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (enabled == false) {
|
if (enabled == false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user