mirror of
https://github.com/airgradienthq/arduino.git
synced 2025-07-30 00:47:17 +02:00
[temporary commit]
This commit is contained in:
@ -170,13 +170,13 @@ public:
|
|||||||
if (JSON.typeof_(root["ledBarMode"]) == "string") {
|
if (JSON.typeof_(root["ledBarMode"]) == "string") {
|
||||||
String mode = root["ledBarMode"];
|
String mode = root["ledBarMode"];
|
||||||
if (mode == "co2") {
|
if (mode == "co2") {
|
||||||
ledBarMode = UseLedBarCO2;
|
ledBarMode = LedBarModeCO2;
|
||||||
} else if (mode == "pm") {
|
} else if (mode == "pm") {
|
||||||
ledBarMode = UseLedBarPM;
|
ledBarMode = LedBarModePm;
|
||||||
} else if (mode == "off") {
|
} else if (mode == "off") {
|
||||||
ledBarMode = UseLedBarOff;
|
ledBarMode = LedBarModeOff;
|
||||||
} else {
|
} else {
|
||||||
ledBarMode = UseLedBarOff;
|
ledBarMode = LedBarModeOff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,9 +330,9 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Get server config led bar mode
|
* @brief Get server config led bar mode
|
||||||
*
|
*
|
||||||
* @return UseLedBar
|
* @return LedBarMode
|
||||||
*/
|
*/
|
||||||
UseLedBar getLedBarMode(void) { return ledBarMode; }
|
LedBarMode getLedBarMode(void) { return ledBarMode; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool inF; /** Temperature unit, true: F, false: C */
|
bool inF; /** Temperature unit, true: F, false: C */
|
||||||
@ -341,7 +341,7 @@ private:
|
|||||||
bool serverFailed; /** Flag indicate post data to server failed */
|
bool serverFailed; /** Flag indicate post data to server failed */
|
||||||
bool co2Calib; /** Is co2Ppmcalibration requset */
|
bool co2Calib; /** Is co2Ppmcalibration requset */
|
||||||
int co2AbcCalib = -1; /** update auto calibration number of day */
|
int co2AbcCalib = -1; /** update auto calibration number of day */
|
||||||
UseLedBar ledBarMode = UseLedBarCO2; /** */
|
LedBarMode ledBarMode = LedBarModeCO2; /** */
|
||||||
char models[20]; /** */
|
char models[20]; /** */
|
||||||
char mqttBroker[256]; /** */
|
char mqttBroker[256]; /** */
|
||||||
};
|
};
|
||||||
|
@ -1,444 +0,0 @@
|
|||||||
#include "LocalConfig.h"
|
|
||||||
#include "EEPROM.h"
|
|
||||||
|
|
||||||
const char *CONFIGURATION_CONTROL_NAME[] = {
|
|
||||||
[Local] = "local", [Cloud] = "cloud", [Both] = "both"};
|
|
||||||
|
|
||||||
void LocalConfig::printLog(String log) {
|
|
||||||
debugLog.printf("[LocalConfig] %s\r\n", log.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
String LocalConfig::getLedBarModeName(UseLedBar mode) {
|
|
||||||
UseLedBar ledBarMode = mode;
|
|
||||||
if (ledBarMode == UseLedBarOff) {
|
|
||||||
return String("off");
|
|
||||||
} else if (ledBarMode == UseLedBarPM) {
|
|
||||||
return String("pm");
|
|
||||||
} else if (ledBarMode == UseLedBarCO2) {
|
|
||||||
return String("co2");
|
|
||||||
} else {
|
|
||||||
return String("off");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalConfig::saveConfig(void) {
|
|
||||||
config._check = 0;
|
|
||||||
int len = sizeof(config) - sizeof(config._check);
|
|
||||||
uint8_t *data = (uint8_t *)&config;
|
|
||||||
for (int i = 0; i < len; i++) {
|
|
||||||
config._check += data[i];
|
|
||||||
}
|
|
||||||
EEPROM.writeBytes(0, &config, sizeof(config));
|
|
||||||
EEPROM.commit();
|
|
||||||
printLog("Save Config");
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalConfig::loadConfig(void) {
|
|
||||||
if (EEPROM.readBytes(0, &config, sizeof(config)) != sizeof(config)) {
|
|
||||||
printLog("Load configure failed");
|
|
||||||
defaultConfig();
|
|
||||||
} else {
|
|
||||||
uint32_t sum = 0;
|
|
||||||
uint8_t *data = (uint8_t *)&config;
|
|
||||||
int len = sizeof(config) - sizeof(config._check);
|
|
||||||
for (int i = 0; i < len; i++) {
|
|
||||||
sum += data[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sum != config._check) {
|
|
||||||
printLog("Configure validate invalid");
|
|
||||||
defaultConfig();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void LocalConfig::defaultConfig(void) {
|
|
||||||
// Default country is null
|
|
||||||
memset(config.country, 0, sizeof(config.country));
|
|
||||||
// Default MQTT broker is null.
|
|
||||||
memset(config.mqttBroker, 0, sizeof(config.mqttBroker));
|
|
||||||
|
|
||||||
config.configurationControl = ConfigurationControl::Both;
|
|
||||||
config.inUSAQI = false; // pmStandard = ugm3
|
|
||||||
config.inF = false;
|
|
||||||
config.postDataToAirGradient = true;
|
|
||||||
config.displayMode = true;
|
|
||||||
config.useRGBLedBar = UseLedBar::UseLedBarCO2;
|
|
||||||
config.abcDays = 7;
|
|
||||||
config.tvocLearningOffset = 12;
|
|
||||||
config.noxLearningOffset = 12;
|
|
||||||
config.temperatureUnit = 'c';
|
|
||||||
|
|
||||||
saveConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LocalConfig::printConfig(void) { printLog(toString()); }
|
|
||||||
|
|
||||||
LocalConfig::LocalConfig(Stream &debugLog) : debugLog(debugLog) {}
|
|
||||||
|
|
||||||
LocalConfig::~LocalConfig() {}
|
|
||||||
|
|
||||||
bool LocalConfig::begin(void) {
|
|
||||||
EEPROM.begin(512);
|
|
||||||
loadConfig();
|
|
||||||
printConfig();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Parse JSON configura string to local configure
|
|
||||||
*
|
|
||||||
* @param data JSON string data
|
|
||||||
* @param isLocal true of data got from local, otherwise get from Aigradient
|
|
||||||
* server
|
|
||||||
* @return true Success
|
|
||||||
* @return false Failure
|
|
||||||
*/
|
|
||||||
bool LocalConfig::parse(String data, bool isLocal) {
|
|
||||||
JSONVar root = JSON.parse(data);
|
|
||||||
if (JSON.typeof_(root) == "undefined") {
|
|
||||||
printLog("Configuration JSON invalid");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
printLog("Parse configure success");
|
|
||||||
|
|
||||||
/** Is configuration changed */
|
|
||||||
bool changed = false;
|
|
||||||
|
|
||||||
/** Get ConfigurationControl */
|
|
||||||
if (JSON.typeof_(root["configurationControl"]) == "string") {
|
|
||||||
String configurationControl = root["configurationControl"];
|
|
||||||
if (configurationControl ==
|
|
||||||
String(CONFIGURATION_CONTROL_NAME[ConfigurationControl::Local])) {
|
|
||||||
config.configurationControl = (uint8_t)ConfigurationControl::Local;
|
|
||||||
changed = true;
|
|
||||||
} else if (configurationControl ==
|
|
||||||
String(
|
|
||||||
CONFIGURATION_CONTROL_NAME[ConfigurationControl::Cloud])) {
|
|
||||||
config.configurationControl = (uint8_t)ConfigurationControl::Cloud;
|
|
||||||
changed = true;
|
|
||||||
} else if (configurationControl ==
|
|
||||||
String(CONFIGURATION_CONTROL_NAME[ConfigurationControl::Both])) {
|
|
||||||
config.configurationControl = (uint8_t)ConfigurationControl::Both;
|
|
||||||
changed = true;
|
|
||||||
} else {
|
|
||||||
printLog("'configurationControl' value '" + configurationControl +
|
|
||||||
"' invalid");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((config.configurationControl == (byte)ConfigurationControl::Cloud)) {
|
|
||||||
printLog("Ignore, cause ConfigurationControl is " +
|
|
||||||
String(CONFIGURATION_CONTROL_NAME[config.configurationControl]));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSON.typeof_(root["country"]) == "string") {
|
|
||||||
String country = root["country"];
|
|
||||||
if (country.length() == 2) {
|
|
||||||
if (country != String(config.country)) {
|
|
||||||
changed = true;
|
|
||||||
snprintf(config.country, sizeof(config.country), country.c_str());
|
|
||||||
printLog("Set country: " + country);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update temperature unit if get configuration from server
|
|
||||||
if (isLocal == false) {
|
|
||||||
if (country == "US") {
|
|
||||||
if (config.temperatureUnit == 'c') {
|
|
||||||
changed = true;
|
|
||||||
config.temperatureUnit = 'f';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (config.temperatureUnit == 'f') {
|
|
||||||
changed = true;
|
|
||||||
config.temperatureUnit = 'c';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printLog("Country name " + country +
|
|
||||||
" invalid. Find details here (ALPHA-2): "
|
|
||||||
"https://www.iban.com/country-codes");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSON.typeof_(root["pmStandard"]) == "string") {
|
|
||||||
String pmStandard = root["pmStandard"];
|
|
||||||
bool inUSAQI = true;
|
|
||||||
if (pmStandard == "ugm3") {
|
|
||||||
inUSAQI = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inUSAQI != config.inUSAQI) {
|
|
||||||
config.inUSAQI = inUSAQI;
|
|
||||||
changed = true;
|
|
||||||
printLog("Set PM standard: " + pmStandard);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSON.typeof_(root["co2CalibrationRequested"]) == "boolean") {
|
|
||||||
co2CalibrationRequested = root["co2CalibrationRequested"];
|
|
||||||
printLog("Set co2CalibrationRequested: " + String(co2CalibrationRequested));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSON.typeof_(root["ledBarTestRequested"]) == "boolean") {
|
|
||||||
ledBarTestRequested = root["ledBarTestRequested"];
|
|
||||||
printLog("Set ledBarTestRequested: " + String(ledBarTestRequested));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSON.typeof_(root["ledBarMode"]) == "string") {
|
|
||||||
String mode = root["ledBarMode"];
|
|
||||||
uint8_t ledBarMode = config.useRGBLedBar;
|
|
||||||
if (mode == "co2") {
|
|
||||||
ledBarMode = UseLedBarCO2;
|
|
||||||
} else if (mode == "pm") {
|
|
||||||
ledBarMode = UseLedBarPM;
|
|
||||||
} else if (mode == "off") {
|
|
||||||
ledBarMode = UseLedBarOff;
|
|
||||||
} else {
|
|
||||||
ledBarMode = config.useRGBLedBar;
|
|
||||||
printLog("ledBarMode value '" + mode + "' invalid");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ledBarMode != config.useRGBLedBar) {
|
|
||||||
config.useRGBLedBar = ledBarMode;
|
|
||||||
changed = true;
|
|
||||||
printLog("Set ledBarMode: " + mode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSON.typeof_(root["displayMode"]) == "string") {
|
|
||||||
String mode = root["displayMode"];
|
|
||||||
bool displayMode = false;
|
|
||||||
if (mode == "on") {
|
|
||||||
displayMode = true;
|
|
||||||
} else if (mode == "off") {
|
|
||||||
displayMode = false;
|
|
||||||
} else {
|
|
||||||
displayMode = config.displayMode;
|
|
||||||
printLog("displayMode '" + mode + "' invalid");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (displayMode != config.displayMode) {
|
|
||||||
changed = true;
|
|
||||||
config.displayMode = displayMode;
|
|
||||||
printLog("Set displayMode: " + mode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSON.typeof_(root["abcDays"]) == "number") {
|
|
||||||
int abcDays = root["abcDays"];
|
|
||||||
if (abcDays != config.abcDays) {
|
|
||||||
config.abcDays = abcDays;
|
|
||||||
changed = true;
|
|
||||||
printLog("Set abcDays: " + String(abcDays));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSON.typeof_(root["tvocLearningOffset"]) == "number") {
|
|
||||||
int tvocLearningOffset = root["tvocLearningOffset"];
|
|
||||||
if (tvocLearningOffset != config.tvocLearningOffset) {
|
|
||||||
changed = true;
|
|
||||||
config.tvocLearningOffset = tvocLearningOffset;
|
|
||||||
printLog("Set tvocLearningOffset: " + String(tvocLearningOffset));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSON.typeof_(root["noxLearningOffset"]) == "number") {
|
|
||||||
int noxLearningOffset = root["noxLearningOffset"];
|
|
||||||
if (noxLearningOffset != config.noxLearningOffset) {
|
|
||||||
changed = true;
|
|
||||||
config.noxLearningOffset = noxLearningOffset;
|
|
||||||
printLog("Set noxLearningOffset: " + String(noxLearningOffset));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSON.typeof_(root["mqttBrokerUrl"]) == "string") {
|
|
||||||
String broker = root["mqttBrokerUrl"];
|
|
||||||
if (broker.length() < sizeof(config.mqttBroker)) {
|
|
||||||
if (broker != String(config.mqttBroker)) {
|
|
||||||
changed = true;
|
|
||||||
snprintf(config.mqttBroker, sizeof(config.mqttBroker), broker.c_str());
|
|
||||||
printLog("Set mqttBrokerUrl: " + broker);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printLog("Error: mqttBroker length invalid: " + String(broker.length()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char temperatureUnit = 0;
|
|
||||||
if (JSON.typeof_(root["temperatureUnit"]) == "string") {
|
|
||||||
String unit = root["temperatureUnit"];
|
|
||||||
if (unit == "c" || unit == "C") {
|
|
||||||
temperatureUnit = 'c';
|
|
||||||
} else if (unit == "f" || unit == "F") {
|
|
||||||
temperatureUnit = 'f';
|
|
||||||
} else {
|
|
||||||
temperatureUnit = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (temperatureUnit != config.temperatureUnit) {
|
|
||||||
changed = true;
|
|
||||||
config.temperatureUnit = temperatureUnit;
|
|
||||||
if (temperatureUnit == 0) {
|
|
||||||
printLog("set temperatureUnit: null");
|
|
||||||
} else {
|
|
||||||
printLog("set temperatureUnit: " + String(temperatureUnit));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSON.typeof_(root["postDataToAirGradient"]) == "boolean") {
|
|
||||||
bool post = root["postDataToAirGradient"];
|
|
||||||
if (post != config.postDataToAirGradient) {
|
|
||||||
changed = true;
|
|
||||||
config.postDataToAirGradient = post;
|
|
||||||
printLog("Set postDataToAirGradient: " + String(post));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Parse data only got from AirGradient server */
|
|
||||||
if (isLocal == false) {
|
|
||||||
if (JSON.typeof_(root["model"]) == "string") {
|
|
||||||
String model = root["model"];
|
|
||||||
if (model.length() < sizeof(config.model)) {
|
|
||||||
if (model != String(config.model)) {
|
|
||||||
changed = true;
|
|
||||||
snprintf(config.model, sizeof(config.model), model.c_str());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printLog("Error: modal name length invalid: " + String(model.length()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changed) {
|
|
||||||
saveConfig();
|
|
||||||
}
|
|
||||||
printConfig();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
String LocalConfig::toString(void) {
|
|
||||||
JSONVar root;
|
|
||||||
|
|
||||||
/** "country" */
|
|
||||||
root["Country"] = String(config.country);
|
|
||||||
|
|
||||||
/** "pmStandard" */
|
|
||||||
if (config.inUSAQI) {
|
|
||||||
root["pmStandard"] = "USAQI";
|
|
||||||
} else {
|
|
||||||
root["pmStandard"] = "ugm3";
|
|
||||||
}
|
|
||||||
|
|
||||||
/** co2CalibrationRequested */
|
|
||||||
/** ledBarTestRequested */
|
|
||||||
|
|
||||||
/** "ledBarMode" */
|
|
||||||
root["ledBarMode"] = getLedBarModeName();
|
|
||||||
|
|
||||||
/** "displayMode" */
|
|
||||||
root["displayMode"] = config.displayMode;
|
|
||||||
|
|
||||||
/** "abcDays" */
|
|
||||||
root["abcDays"] = config.abcDays;
|
|
||||||
|
|
||||||
/** "tvocLearningOffset" */
|
|
||||||
root["tvocLearningOffset"] = config.tvocLearningOffset;
|
|
||||||
|
|
||||||
/** "noxLearningOffset" */
|
|
||||||
root["noxLearningOffset"] = config.noxLearningOffset;
|
|
||||||
|
|
||||||
/** "mqttBrokerUrl" */
|
|
||||||
root["mqttBrokerUrl"] = String(config.mqttBroker);
|
|
||||||
|
|
||||||
/** "temperatureUnit" */
|
|
||||||
root["temperatureUnit"] = String(config.temperatureUnit);
|
|
||||||
|
|
||||||
/** configurationControl */
|
|
||||||
root["configurationControl"] =
|
|
||||||
String(CONFIGURATION_CONTROL_NAME[config.configurationControl]);
|
|
||||||
|
|
||||||
/** "postDataToAirGradient" */
|
|
||||||
root["postDataToAirGradient"] = config.postDataToAirGradient;
|
|
||||||
|
|
||||||
return JSON.stringify(root);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LocalConfig::isTemperatureUnitInF(void) {
|
|
||||||
return (config.temperatureUnit == 'f');
|
|
||||||
}
|
|
||||||
|
|
||||||
String LocalConfig::getCountry(void) { return String(config.country); }
|
|
||||||
|
|
||||||
bool LocalConfig::isPmStandardInUSAQI(void) { return config.inUSAQI; }
|
|
||||||
|
|
||||||
int LocalConfig::getCO2CalirationAbcDays(void) { return config.abcDays; }
|
|
||||||
|
|
||||||
UseLedBar LocalConfig::getLedBarMode(void) {
|
|
||||||
return (UseLedBar)config.useRGBLedBar;
|
|
||||||
}
|
|
||||||
|
|
||||||
String LocalConfig::getLedBarModeName(void) {
|
|
||||||
return getLedBarModeName((UseLedBar)config.useRGBLedBar);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LocalConfig::getDisplayMode(void) { return config.displayMode; }
|
|
||||||
|
|
||||||
String LocalConfig::getMqttBrokerUri(void) { return String(config.mqttBroker); }
|
|
||||||
|
|
||||||
bool LocalConfig::isPostDataToAirGradient(void) {
|
|
||||||
return config.postDataToAirGradient;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigurationControl LocalConfig::getConfigurationControl(void) {
|
|
||||||
return (ConfigurationControl)config.configurationControl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief CO2 manual calib request, the request flag will clear after get. Must
|
|
||||||
* call this after parse success
|
|
||||||
*
|
|
||||||
* @return true Requested
|
|
||||||
* @return false Not requested
|
|
||||||
*/
|
|
||||||
bool LocalConfig::isCo2CalibrationRequested(void) {
|
|
||||||
bool requested = co2CalibrationRequested;
|
|
||||||
co2CalibrationRequested = false; // clear requested
|
|
||||||
return requested;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief LED bar test request, the request flag will clear after get. Must call
|
|
||||||
* this function after parse success
|
|
||||||
*
|
|
||||||
* @return true Requested
|
|
||||||
* @return false Not requested
|
|
||||||
*/
|
|
||||||
bool LocalConfig::isLedBarTestRequested(void) {
|
|
||||||
bool requested = ledBarTestRequested;
|
|
||||||
ledBarTestRequested = false;
|
|
||||||
return requested;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Reset default configure
|
|
||||||
*/
|
|
||||||
void LocalConfig::reset(void) {
|
|
||||||
defaultConfig();
|
|
||||||
printLog("Reset to default configure");
|
|
||||||
printConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get model name, it's usage for offline mode
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
String LocalConfig::getModel(void) { return String(config.model); }
|
|
@ -1,66 +0,0 @@
|
|||||||
#ifndef _LOCAL_CONFIG_H_
|
|
||||||
#define _LOCAL_CONFIG_H_
|
|
||||||
|
|
||||||
#include <AirGradient.h>
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <Arduino_JSON.h>
|
|
||||||
|
|
||||||
class LocalConfig {
|
|
||||||
private:
|
|
||||||
struct Config {
|
|
||||||
char model[20];
|
|
||||||
char country[3]; /** Country name has only 2 character, ex: TH = Thailand */
|
|
||||||
char mqttBroker[256]; /** MQTT broker URI */
|
|
||||||
bool inUSAQI; /** If PM standard "ugm3" inUSAQI = false, otherwise is true
|
|
||||||
*/
|
|
||||||
bool inF; /** Temperature unit F */
|
|
||||||
bool postDataToAirGradient; /** If true, monitor will not POST data to
|
|
||||||
airgradient server. Make sure no error
|
|
||||||
message shown on monitor */
|
|
||||||
uint8_t configurationControl; /** If true, configuration from airgradient server
|
|
||||||
will be ignored */
|
|
||||||
bool displayMode; /** true if enable display */
|
|
||||||
uint8_t useRGBLedBar;
|
|
||||||
uint8_t abcDays;
|
|
||||||
int tvocLearningOffset;
|
|
||||||
int noxLearningOffset;
|
|
||||||
char temperatureUnit; // 'f' or 'c'
|
|
||||||
|
|
||||||
uint32_t _check;
|
|
||||||
};
|
|
||||||
struct Config config;
|
|
||||||
bool co2CalibrationRequested;
|
|
||||||
bool ledBarTestRequested;
|
|
||||||
Stream &debugLog;
|
|
||||||
|
|
||||||
void printLog(String log);
|
|
||||||
String getLedBarModeName(UseLedBar mode);
|
|
||||||
void saveConfig(void);
|
|
||||||
void loadConfig(void);
|
|
||||||
void defaultConfig(void);
|
|
||||||
void printConfig(void);
|
|
||||||
|
|
||||||
public:
|
|
||||||
LocalConfig(Stream &debugLog);
|
|
||||||
~LocalConfig();
|
|
||||||
|
|
||||||
bool begin(void);
|
|
||||||
bool parse(String data, bool isLocal);
|
|
||||||
String toString(void);
|
|
||||||
bool isTemperatureUnitInF(void);
|
|
||||||
String getCountry(void);
|
|
||||||
bool isPmStandardInUSAQI(void);
|
|
||||||
int getCO2CalirationAbcDays(void);
|
|
||||||
UseLedBar getLedBarMode(void);
|
|
||||||
String getLedBarModeName(void);
|
|
||||||
bool getDisplayMode(void);
|
|
||||||
String getMqttBrokerUri(void);
|
|
||||||
bool isPostDataToAirGradient(void);
|
|
||||||
ConfigurationControl getConfigurationControl(void);
|
|
||||||
bool isCo2CalibrationRequested(void);
|
|
||||||
bool isLedBarTestRequested(void);
|
|
||||||
void reset(void);
|
|
||||||
String getModel(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /** _LOCAL_CONFIG_H_ */
|
|
@ -46,50 +46,18 @@ CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License
|
|||||||
#include <HardwareSerial.h>
|
#include <HardwareSerial.h>
|
||||||
#include <WiFiManager.h>
|
#include <WiFiManager.h>
|
||||||
|
|
||||||
|
#include "AgApiClient.h"
|
||||||
|
#include "AgConfigure.h"
|
||||||
|
#include "AgSchedule.h"
|
||||||
|
#include "AgStateMachine.h"
|
||||||
#include "EEPROM.h"
|
#include "EEPROM.h"
|
||||||
#include "LocalConfig.h"
|
#include "MqttClient.h"
|
||||||
#include <AirGradient.h>
|
#include <AirGradient.h>
|
||||||
#include <Arduino_JSON.h>
|
#include <Arduino_JSON.h>
|
||||||
#include <ESPmDNS.h>
|
#include <ESPmDNS.h>
|
||||||
#include <U8g2lib.h>
|
#include <U8g2lib.h>
|
||||||
#include <WebServer.h>
|
#include <WebServer.h>
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Application state machine state
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
enum {
|
|
||||||
APP_SM_WIFI_MANAGER_MODE, /** In WiFi Manger Mode */
|
|
||||||
APP_SM_WIFI_MANAGER_PORTAL_ACTIVE, /** WiFi Manager has connected to mobile
|
|
||||||
phone */
|
|
||||||
APP_SM_WIFI_MANAGER_STA_CONNECTING, /** After SSID and PW entered and OK
|
|
||||||
clicked, connection to WiFI network is
|
|
||||||
attempted*/
|
|
||||||
APP_SM_WIFI_MANAGER_STA_CONNECTED, /** Connecting to WiFi worked */
|
|
||||||
APP_SM_WIFI_OK_SERVER_CONNECTING, /** Once connected to WiFi an attempt to
|
|
||||||
reach the server is performed */
|
|
||||||
APP_SM_WIFI_OK_SERVER_CONNECTED, /** Server is reachable, all fine */
|
|
||||||
/** Exceptions during WIFi Setup */
|
|
||||||
APP_SM_WIFI_MANAGER_CONNECT_FAILED, /** Cannot connect to WiFi (e.g. wrong
|
|
||||||
password, WPA Enterprise etc.) */
|
|
||||||
APP_SM_WIFI_OK_SERVER_CONNECT_FAILED, /** Connected to WiFi but server not
|
|
||||||
reachable, e.g. firewall block/
|
|
||||||
whitelisting needed etc. */
|
|
||||||
APP_SM_WIFI_OK_SERVER_OK_SENSOR_CONFIG_FAILED, /** Server reachable but sensor
|
|
||||||
not configured correctly*/
|
|
||||||
|
|
||||||
/** During Normal Operation */
|
|
||||||
APP_SM_WIFI_LOST, /** Connection to WiFi network failed credentials incorrect
|
|
||||||
encryption not supported etc. */
|
|
||||||
APP_SM_SERVER_LOST, /** Connected to WiFi network but the server cannot be
|
|
||||||
reached through the internet, e.g. blocked by firewall
|
|
||||||
*/
|
|
||||||
APP_SM_SENSOR_CONFIG_FAILED, /** Server is reachable but there is some
|
|
||||||
configuration issue to be fixed on the server
|
|
||||||
side */
|
|
||||||
APP_SM_NORMAL,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define LED_FAST_BLINK_DELAY 250 /** ms */
|
#define LED_FAST_BLINK_DELAY 250 /** ms */
|
||||||
#define LED_SLOW_BLINK_DELAY 1000 /** ms */
|
#define LED_SLOW_BLINK_DELAY 1000 /** ms */
|
||||||
#define LED_SHORT_BLINK_DELAY 500 /** ms */
|
#define LED_SHORT_BLINK_DELAY 500 /** ms */
|
||||||
@ -108,321 +76,19 @@ enum {
|
|||||||
#define SENSOR_PM_UPDATE_INTERVAL 2000 /** ms */
|
#define SENSOR_PM_UPDATE_INTERVAL 2000 /** ms */
|
||||||
#define SENSOR_TEMP_HUM_UPDATE_INTERVAL 2000 /** ms */
|
#define SENSOR_TEMP_HUM_UPDATE_INTERVAL 2000 /** ms */
|
||||||
#define DISPLAY_DELAY_SHOW_CONTENT_MS 2000 /** ms */
|
#define DISPLAY_DELAY_SHOW_CONTENT_MS 2000 /** ms */
|
||||||
#define WIFI_HOTSPOT_PASSWORD_DEFAULT \
|
|
||||||
"cleanair" /** default WiFi AP password \
|
/** Default WiFi AP password */
|
||||||
*/
|
#define WIFI_HOTSPOT_PASSWORD_DEFAULT "cleanair"
|
||||||
|
|
||||||
/** I2C define */
|
/** I2C define */
|
||||||
#define I2C_SDA_PIN 7
|
#define I2C_SDA_PIN 7
|
||||||
#define I2C_SCL_PIN 6
|
#define I2C_SCL_PIN 6
|
||||||
#define OLED_I2C_ADDR 0x3C
|
#define OLED_I2C_ADDR 0x3C
|
||||||
|
|
||||||
enum {
|
static MqttClient mqttClient(Serial);
|
||||||
FW_MODE_I_9PSL, /** ONE_INDOOR */
|
|
||||||
FW_MODE_O_1PST, /** PMS5003T, S8 and SGP41 */
|
|
||||||
FW_MODE_O_1PPT, /** PMS5003T_1, PMS5003T_2, SGP41 */
|
|
||||||
FW_MODE_O_1PP, /** PMS5003T_1, PMS5003T_2 */
|
|
||||||
FW_MDOE_O_1PS /** PMS5003T, S8 */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Schedule handle with timing period
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class AgSchedule {
|
|
||||||
public:
|
|
||||||
AgSchedule(int period, void (*handler)(void))
|
|
||||||
: period(period), handler(handler) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Handle schedule
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void run(void) {
|
|
||||||
uint32_t ms = (uint32_t)(millis() - count);
|
|
||||||
if (ms >= period) {
|
|
||||||
handler();
|
|
||||||
count = millis();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @brief Set schedule handle period
|
|
||||||
*
|
|
||||||
* @param period
|
|
||||||
*/
|
|
||||||
void setPeriod(int period) { this->period = period; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
void (*handler)(void); /** Callback handle */
|
|
||||||
int period; /** Schedule handle period */
|
|
||||||
int count; /** Schedule time count check */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief AirGradient server configuration and sync data
|
|
||||||
*/
|
|
||||||
class AgServer {
|
|
||||||
public:
|
|
||||||
AgServer(LocalConfig &localConfig) : config(localConfig) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize airgradient server, it's load the server configuration if
|
|
||||||
* failed load it to default.
|
|
||||||
*/
|
|
||||||
void begin(void) {
|
|
||||||
configFailed = false;
|
|
||||||
serverFailed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Fetch server configuration, if get sucessed and configuratrion
|
|
||||||
* parameter has changed store into local storage
|
|
||||||
*
|
|
||||||
* @param id Device ID
|
|
||||||
* @return true Success
|
|
||||||
* @return false Failure
|
|
||||||
*/
|
|
||||||
bool fetchServerConfiguration(String id) {
|
|
||||||
if (config.getConfigurationControl() == ConfigurationControl::Local) {
|
|
||||||
Serial.println("Ignore fetch server configuration");
|
|
||||||
|
|
||||||
// Clear server configuration failed flag, cause it's ignore but not
|
|
||||||
// really failed
|
|
||||||
configFailed = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
String uri =
|
|
||||||
"http://hw.airgradient.com/sensors/airgradient:" + id + "/one/config";
|
|
||||||
|
|
||||||
/** Init http client */
|
|
||||||
HTTPClient client;
|
|
||||||
if (client.begin(uri) == false) {
|
|
||||||
configFailed = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Get */
|
|
||||||
int retCode = client.GET();
|
|
||||||
if (retCode != 200) {
|
|
||||||
client.end();
|
|
||||||
configFailed = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** clear failed */
|
|
||||||
configFailed = false;
|
|
||||||
|
|
||||||
/** Get response string */
|
|
||||||
String respContent = client.getString();
|
|
||||||
client.end();
|
|
||||||
Serial.println("Get server config: " + respContent);
|
|
||||||
|
|
||||||
return config.parse(respContent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Post data to Airgradient server
|
|
||||||
*
|
|
||||||
* @param id Device Id
|
|
||||||
* @param payload Data payload
|
|
||||||
* @return true Success
|
|
||||||
* @return false Failure
|
|
||||||
*/
|
|
||||||
bool postToServer(String id, String payload) {
|
|
||||||
if (config.isPostDataToAirGradient() == false) {
|
|
||||||
Serial.println("Ignore post to Airgrdient server");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (WiFi.isConnected() == false) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Serial.printf("Post payload: %s\r\n", payload.c_str());
|
|
||||||
|
|
||||||
String uri =
|
|
||||||
"http://hw.airgradient.com/sensors/airgradient:" + id + "/measures";
|
|
||||||
|
|
||||||
WiFiClient wifiClient;
|
|
||||||
HTTPClient client;
|
|
||||||
if (client.begin(wifiClient, uri.c_str()) == false) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
client.addHeader("content-type", "application/json");
|
|
||||||
int retCode = client.POST(payload);
|
|
||||||
client.end();
|
|
||||||
|
|
||||||
if ((retCode == 200) || (retCode == 429)) {
|
|
||||||
serverFailed = false;
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
Serial.printf("Post response failed code: %d\r\n", retCode);
|
|
||||||
}
|
|
||||||
serverFailed = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get status of get server configuration is failed
|
|
||||||
*
|
|
||||||
* @return true Failed
|
|
||||||
* @return false Success
|
|
||||||
*/
|
|
||||||
bool isConfigFailed(void) { return configFailed; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get status of post server configuration is failed
|
|
||||||
*
|
|
||||||
* @return true Failed
|
|
||||||
* @return false Success
|
|
||||||
*/
|
|
||||||
bool isServerFailed(void) { return serverFailed; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool configFailed; /** Flag indicate get server configuration failed */
|
|
||||||
bool serverFailed; /** Flag indicate post data to server failed */
|
|
||||||
LocalConfig &config;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void mqtt_event_handler(void *handler_args, esp_event_base_t base,
|
|
||||||
int32_t event_id, void *event_data);
|
|
||||||
|
|
||||||
class AgMqtt {
|
|
||||||
private:
|
|
||||||
bool _isBegin = false;
|
|
||||||
String uri;
|
|
||||||
String hostname;
|
|
||||||
String user;
|
|
||||||
String pass;
|
|
||||||
int port;
|
|
||||||
esp_mqtt_client_handle_t client;
|
|
||||||
bool clientConnected = false;
|
|
||||||
int connectFailedCount = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
AgMqtt() {}
|
|
||||||
~AgMqtt() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize mqtt
|
|
||||||
*
|
|
||||||
* @param uri Complete mqtt uri, ex:
|
|
||||||
* mqtts://username:password@my.broker.com:4711
|
|
||||||
* @return true Success
|
|
||||||
* @return false Failure
|
|
||||||
*/
|
|
||||||
bool begin(String uri) {
|
|
||||||
if (_isBegin) {
|
|
||||||
Serial.println("Mqtt already begin, call 'end' and try again");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uri.isEmpty()) {
|
|
||||||
Serial.println("Mqtt uri is empty");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->uri = uri;
|
|
||||||
Serial.printf("mqtt init '%s'\r\n", uri.c_str());
|
|
||||||
|
|
||||||
/** config esp_mqtt client */
|
|
||||||
esp_mqtt_client_config_t config = {
|
|
||||||
.uri = this->uri.c_str(),
|
|
||||||
};
|
|
||||||
|
|
||||||
/** init client */
|
|
||||||
client = esp_mqtt_client_init(&config);
|
|
||||||
if (client == NULL) {
|
|
||||||
Serial.println("MQTT client init failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Register event */
|
|
||||||
if (esp_mqtt_client_register_event(client, MQTT_EVENT_ANY,
|
|
||||||
mqtt_event_handler, this) != ESP_OK) {
|
|
||||||
Serial.println("MQTT client register event failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (esp_mqtt_client_start(client) != ESP_OK) {
|
|
||||||
Serial.println("MQTT client start failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_isBegin = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Deinitialize mqtt
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void end(void) {
|
|
||||||
if (_isBegin == false) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_mqtt_client_disconnect(client);
|
|
||||||
esp_mqtt_client_stop(client);
|
|
||||||
esp_mqtt_client_destroy(client);
|
|
||||||
_isBegin = false;
|
|
||||||
|
|
||||||
Serial.println("mqtt de-init");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool publish(const char *topic, const char *payload, int len) {
|
|
||||||
if ((_isBegin == false) || (clientConnected == false)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (esp_mqtt_client_publish(client, topic, payload, len, 0, 0) == ESP_OK) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get current complete mqtt uri
|
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
String getUri(void) { return uri; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Update mqtt connection changed
|
|
||||||
*
|
|
||||||
* @param connected
|
|
||||||
*/
|
|
||||||
void _connectionHandler(bool connected) {
|
|
||||||
clientConnected = connected;
|
|
||||||
if (clientConnected == false) {
|
|
||||||
connectFailedCount++;
|
|
||||||
} else {
|
|
||||||
connectFailedCount = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Mqtt client connect status
|
|
||||||
*
|
|
||||||
* @return true Connected
|
|
||||||
* @return false Disconnected or Not initialize
|
|
||||||
*/
|
|
||||||
bool isConnected(void) { return (_isBegin && clientConnected); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get number of times connection failed
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
int connectionFailedCount(void) { return connectFailedCount; }
|
|
||||||
};
|
|
||||||
|
|
||||||
static AgMqtt agMqtt;
|
|
||||||
static TaskHandle_t mqttTask = NULL;
|
static TaskHandle_t mqttTask = NULL;
|
||||||
static LocalConfig localConfig(Serial);
|
static AgConfigure localConfig(Serial);
|
||||||
static AgServer agServer(localConfig);
|
static AgApiClient agServer(Serial, localConfig);
|
||||||
|
|
||||||
static AirGradient *ag;
|
static AirGradient *ag;
|
||||||
static U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0,
|
static U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0,
|
||||||
@ -430,11 +96,11 @@ static U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0,
|
|||||||
static WiFiManager wifiManager;
|
static WiFiManager wifiManager;
|
||||||
static WebServer webServer;
|
static WebServer webServer;
|
||||||
|
|
||||||
static bool wifiHasConfig = false; /** */
|
static bool wifiHasConfig = false; /** */
|
||||||
static int connectCountDown; /** wifi configuration countdown */
|
static int connectCountDown; /** wifi configuration countdown */
|
||||||
static int ledCount; /** For LED animation */
|
static int ledCount; /** For LED animation */
|
||||||
static int ledSmState = APP_SM_NORMAL; /** Save display SM */
|
static int ledSmState = AgStateMachineNormal; /** Save display SM */
|
||||||
static int dispSmState = APP_SM_NORMAL; /** Save LED SM */
|
static int dispSmState = AgStateMachineNormal; /** Save LED SM */
|
||||||
|
|
||||||
/** Init schedule */
|
/** Init schedule */
|
||||||
static bool hasSensorS8 = true;
|
static bool hasSensorS8 = true;
|
||||||
@ -448,7 +114,7 @@ static int getCO2FailCount = 0;
|
|||||||
static uint32_t addToDashboardTime;
|
static uint32_t addToDashboardTime;
|
||||||
static bool isAddToDashboard = true;
|
static bool isAddToDashboard = true;
|
||||||
static bool offlineMode = false;
|
static bool offlineMode = false;
|
||||||
static int fwMode = FW_MODE_I_9PSL;
|
static AgFirmwareMode fwMode = FW_MODE_I_9PSL;
|
||||||
|
|
||||||
static int tvocIndex = -1;
|
static int tvocIndex = -1;
|
||||||
static int tvocRawIndex = -1;
|
static int tvocRawIndex = -1;
|
||||||
@ -562,7 +228,7 @@ void setup() {
|
|||||||
ledTest();
|
ledTest();
|
||||||
} else {
|
} else {
|
||||||
/** Check LED mode to disabled LED */
|
/** Check LED mode to disabled LED */
|
||||||
if (localConfig.getLedBarMode() == UseLedBarOff) {
|
if (localConfig.getLedBarMode() == LedBarModeOff) {
|
||||||
ag->ledBar.setEnable(false);
|
ag->ledBar.setEnable(false);
|
||||||
}
|
}
|
||||||
connectToWifi();
|
connectToWifi();
|
||||||
@ -579,7 +245,7 @@ void setup() {
|
|||||||
|
|
||||||
/** MQTT init */
|
/** MQTT init */
|
||||||
if (localConfig.getMqttBrokerUri().isEmpty() == false) {
|
if (localConfig.getMqttBrokerUri().isEmpty() == false) {
|
||||||
if (agMqtt.begin(localConfig.getMqttBrokerUri())) {
|
if (mqttClient.begin(localConfig.getMqttBrokerUri())) {
|
||||||
createMqttTask();
|
createMqttTask();
|
||||||
Serial.println("MQTT client init success");
|
Serial.println("MQTT client init success");
|
||||||
} else {
|
} else {
|
||||||
@ -594,14 +260,14 @@ void setup() {
|
|||||||
|
|
||||||
/** Get first connected to wifi */
|
/** Get first connected to wifi */
|
||||||
agServer.fetchServerConfiguration(getDevId());
|
agServer.fetchServerConfiguration(getDevId());
|
||||||
if (agServer.isConfigFailed()) {
|
if (agServer.isFetchConfigureFailed()) {
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
dispSmHandler(APP_SM_WIFI_OK_SERVER_OK_SENSOR_CONFIG_FAILED);
|
dispSmHandler(AgStateMachineWiFiOkServerOkSensorConfigFailed);
|
||||||
}
|
}
|
||||||
ledSmHandler(APP_SM_WIFI_OK_SERVER_OK_SENSOR_CONFIG_FAILED);
|
ledSmHandler(AgStateMachineWiFiOkServerOkSensorConfigFailed);
|
||||||
delay(DISPLAY_DELAY_SHOW_CONTENT_MS);
|
delay(DISPLAY_DELAY_SHOW_CONTENT_MS);
|
||||||
} else {
|
} else {
|
||||||
ag->ledBar.setEnable(localConfig.getLedBarMode() != UseLedBarOff);
|
ag->ledBar.setEnable(localConfig.getLedBarMode() != LedBarModeOff);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
offlineMode = true;
|
offlineMode = true;
|
||||||
@ -805,13 +471,13 @@ void webServerMetricsGet(void) {
|
|||||||
"1 if the AirGradient device was able to successfully fetch its "
|
"1 if the AirGradient device was able to successfully fetch its "
|
||||||
"configuration from the server",
|
"configuration from the server",
|
||||||
"gauge");
|
"gauge");
|
||||||
add_metric_point("", agServer.isConfigFailed() ? "0" : "1");
|
add_metric_point("", agServer.isFetchConfigureFailed() ? "0" : "1");
|
||||||
|
|
||||||
add_metric(
|
add_metric(
|
||||||
"post_ok",
|
"post_ok",
|
||||||
"1 if the AirGradient device was able to successfully send to the server",
|
"1 if the AirGradient device was able to successfully send to the server",
|
||||||
"gauge");
|
"gauge");
|
||||||
add_metric_point("", agServer.isServerFailed() ? "0" : "1");
|
add_metric_point("", agServer.isPostToServerFailed() ? "0" : "1");
|
||||||
|
|
||||||
add_metric(
|
add_metric(
|
||||||
"wifi_rssi",
|
"wifi_rssi",
|
||||||
@ -971,7 +637,8 @@ static void webServerInit(void) {
|
|||||||
webServer.on("/config", HTTP_PUT, localConfigPut);
|
webServer.on("/config", HTTP_PUT, localConfigPut);
|
||||||
webServer.begin();
|
webServer.begin();
|
||||||
MDNS.addService("_airgradient", "_tcp", 80);
|
MDNS.addService("_airgradient", "_tcp", 80);
|
||||||
MDNS.addServiceTxt("_airgradient", "_tcp", "model", getFirmwareModeName());
|
MDNS.addServiceTxt("_airgradient", "_tcp", "model",
|
||||||
|
AgFirmwareModeName(fwMode));
|
||||||
MDNS.addServiceTxt("_airgradient", "_tcp", "serialno", getDevId());
|
MDNS.addServiceTxt("_airgradient", "_tcp", "serialno", getDevId());
|
||||||
MDNS.addServiceTxt("_airgradient", "_tcp", "fw_ver", ag->getVersion());
|
MDNS.addServiceTxt("_airgradient", "_tcp", "fw_ver", ag->getVersion());
|
||||||
MDNS.addServiceTxt("_airgradient", "_tcp", "vendor", "AirGradient");
|
MDNS.addServiceTxt("_airgradient", "_tcp", "vendor", "AirGradient");
|
||||||
@ -1135,7 +802,7 @@ static String getServerSyncData(bool localServer) {
|
|||||||
if (localServer) {
|
if (localServer) {
|
||||||
root["ledMode"] = localConfig.getLedBarModeName();
|
root["ledMode"] = localConfig.getLedBarModeName();
|
||||||
root["firmwareVersion"] = ag->getVersion();
|
root["firmwareVersion"] = ag->getVersion();
|
||||||
root["fwMode"] = getFirmwareModeName();
|
root["fwMode"] = AgFirmwareModeName(fwMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return JSON.stringify(root);
|
return JSON.stringify(root);
|
||||||
@ -1153,11 +820,10 @@ static void createMqttTask(void) {
|
|||||||
delay(MQTT_SYNC_INTERVAL);
|
delay(MQTT_SYNC_INTERVAL);
|
||||||
|
|
||||||
/** Send data */
|
/** Send data */
|
||||||
if (agMqtt.isConnected()) {
|
if (mqttClient.isConnected()) {
|
||||||
String syncData = getServerSyncData(false);
|
String payload = getServerSyncData(false);
|
||||||
String topic = "airgradient/readings/" + getDevId();
|
String topic = "airgradient/readings/" + getDevId();
|
||||||
if (agMqtt.publish(topic.c_str(), syncData.c_str(),
|
if (mqttClient.publish(topic, payload)) {
|
||||||
syncData.length())) {
|
|
||||||
Serial.println("MQTT sync success");
|
Serial.println("MQTT sync success");
|
||||||
} else {
|
} else {
|
||||||
Serial.println("MQTT sync failure");
|
Serial.println("MQTT sync failure");
|
||||||
@ -1255,16 +921,16 @@ static void sendPing() {
|
|||||||
|
|
||||||
/** Change disp and led state */
|
/** Change disp and led state */
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
dispSmHandler(APP_SM_WIFI_OK_SERVER_CONNECTING);
|
dispSmHandler(AgStateMachineWiFiOkServerConnecting);
|
||||||
}
|
}
|
||||||
ledSmHandler(APP_SM_WIFI_OK_SERVER_CONNECTING);
|
ledSmHandler(AgStateMachineWiFiOkServerConnecting);
|
||||||
|
|
||||||
/** Task handle led connecting animation */
|
/** Task handle led connecting animation */
|
||||||
xTaskCreate(
|
xTaskCreate(
|
||||||
[](void *obj) {
|
[](void *obj) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ledSmHandler();
|
ledSmHandler();
|
||||||
if (ledSmState != APP_SM_WIFI_OK_SERVER_CONNECTING) {
|
if (ledSmState != AgStateMachineWiFiOkServerConnecting) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
delay(LED_BAR_ANIMATION_PERIOD);
|
delay(LED_BAR_ANIMATION_PERIOD);
|
||||||
@ -1276,18 +942,18 @@ static void sendPing() {
|
|||||||
delay(1500);
|
delay(1500);
|
||||||
if (agServer.postToServer(getDevId(), JSON.stringify(root))) {
|
if (agServer.postToServer(getDevId(), JSON.stringify(root))) {
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
dispSmHandler(APP_SM_WIFI_OK_SERVER_CONNECTED);
|
dispSmHandler(AgStateMachineWiFiOkServerConnected);
|
||||||
}
|
}
|
||||||
ledSmHandler(APP_SM_WIFI_OK_SERVER_CONNECTED);
|
ledSmHandler(AgStateMachineWiFiOkServerConnected);
|
||||||
} else {
|
} else {
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
dispSmHandler(APP_SM_WIFI_OK_SERVER_CONNECT_FAILED);
|
dispSmHandler(AgStateMachineWiFiOkServerConnectFailed);
|
||||||
}
|
}
|
||||||
ledSmHandler(APP_SM_WIFI_OK_SERVER_CONNECT_FAILED);
|
ledSmHandler(AgStateMachineWiFiOkServerConnectFailed);
|
||||||
}
|
}
|
||||||
delay(DISPLAY_DELAY_SHOW_CONTENT_MS);
|
delay(DISPLAY_DELAY_SHOW_CONTENT_MS);
|
||||||
|
|
||||||
ledSmHandler(APP_SM_NORMAL);
|
ledSmHandler(AgStateMachineNormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void displayShowWifiText(String ln1, String ln2, String ln3,
|
static void displayShowWifiText(String ln1, String ln2, String ln3,
|
||||||
@ -1489,22 +1155,22 @@ static void connectToWifi() {
|
|||||||
connectCountDown = WIFI_CONNECT_COUNTDOWN_MAX;
|
connectCountDown = WIFI_CONNECT_COUNTDOWN_MAX;
|
||||||
ledCount = LED_BAR_COUNT_INIT_VALUE;
|
ledCount = LED_BAR_COUNT_INIT_VALUE;
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
dispSmState = APP_SM_WIFI_MANAGER_MODE;
|
dispSmState = AgStateMachineWiFiManagerMode;
|
||||||
}
|
}
|
||||||
ledSmState = APP_SM_WIFI_MANAGER_MODE;
|
ledSmState = AgStateMachineWiFiManagerMode;
|
||||||
});
|
});
|
||||||
wifiManager.setSaveConfigCallback([]() {
|
wifiManager.setSaveConfigCallback([]() {
|
||||||
/** Wifi connected save the configuration */
|
/** Wifi connected save the configuration */
|
||||||
dispSmState = APP_SM_WIFI_MANAGER_STA_CONNECTED;
|
dispSmState = AgStateMachineWiFiManagerStaConnected;
|
||||||
ledSmHandler(APP_SM_WIFI_MANAGER_STA_CONNECTED);
|
ledSmHandler(AgStateMachineWiFiManagerStaConnected);
|
||||||
});
|
});
|
||||||
wifiManager.setSaveParamsCallback([]() {
|
wifiManager.setSaveParamsCallback([]() {
|
||||||
/** Wifi set connect: ssid, password */
|
/** Wifi set connect: ssid, password */
|
||||||
ledCount = LED_BAR_COUNT_INIT_VALUE;
|
ledCount = LED_BAR_COUNT_INIT_VALUE;
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
dispSmState = APP_SM_WIFI_MANAGER_STA_CONNECTING;
|
dispSmState = AgStateMachineWiFiManagerStaConnecting;
|
||||||
}
|
}
|
||||||
ledSmState = APP_SM_WIFI_MANAGER_STA_CONNECTING;
|
ledSmState = AgStateMachineWiFiManagerStaConnecting;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
@ -1557,12 +1223,12 @@ static void connectToWifi() {
|
|||||||
if (clientConnected != clientConnectChanged) {
|
if (clientConnected != clientConnectChanged) {
|
||||||
clientConnectChanged = clientConnected;
|
clientConnectChanged = clientConnected;
|
||||||
if (clientConnectChanged) {
|
if (clientConnectChanged) {
|
||||||
ledSmHandler(APP_SM_WIFI_MANAGER_PORTAL_ACTIVE);
|
ledSmHandler(AgStateMachineWiFiManagerPortalActive);
|
||||||
} else {
|
} else {
|
||||||
ledCount = LED_BAR_COUNT_INIT_VALUE;
|
ledCount = LED_BAR_COUNT_INIT_VALUE;
|
||||||
ledSmHandler(APP_SM_WIFI_MANAGER_MODE);
|
ledSmHandler(AgStateMachineWiFiManagerMode);
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
dispSmHandler(APP_SM_WIFI_MANAGER_MODE);
|
dispSmHandler(AgStateMachineWiFiManagerMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1571,9 +1237,9 @@ static void connectToWifi() {
|
|||||||
|
|
||||||
/** Show display wifi connect result failed */
|
/** Show display wifi connect result failed */
|
||||||
if (WiFi.isConnected() == false) {
|
if (WiFi.isConnected() == false) {
|
||||||
ledSmHandler(APP_SM_WIFI_MANAGER_CONNECT_FAILED);
|
ledSmHandler(AgStateMachineWiFiManagerConnectFailed);
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
dispSmHandler(APP_SM_WIFI_MANAGER_CONNECT_FAILED);
|
dispSmHandler(AgStateMachineWiFiManagerConnectFailed);
|
||||||
}
|
}
|
||||||
delay(6000);
|
delay(6000);
|
||||||
} else {
|
} else {
|
||||||
@ -1884,25 +1550,7 @@ static void openAirInit(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial.printf("Firmware Mode: %s\r\n", getFirmwareModeName());
|
Serial.printf("Firmware Mode: %s\r\n", AgFirmwareModeName(fwMode));
|
||||||
}
|
|
||||||
|
|
||||||
static String getFirmwareModeName() {
|
|
||||||
switch (fwMode) {
|
|
||||||
case FW_MODE_I_9PSL:
|
|
||||||
return "I-9PSL";
|
|
||||||
case FW_MODE_O_1PP:
|
|
||||||
return "O-1PP";
|
|
||||||
case FW_MODE_O_1PPT:
|
|
||||||
return "O-1PPT";
|
|
||||||
case FW_MODE_O_1PST:
|
|
||||||
return "O-1PST";
|
|
||||||
case FW_MDOE_O_1PS:
|
|
||||||
return "0-1PS";
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return "UNKNOWN";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isOneIndoor(void) {
|
static bool isOneIndoor(void) {
|
||||||
@ -1952,7 +1600,7 @@ static void configUpdateHandle() {
|
|||||||
|
|
||||||
// Update LED bar
|
// Update LED bar
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
ag->ledBar.setEnable(localConfig.getLedBarMode() != UseLedBarOff);
|
ag->ledBar.setEnable(localConfig.getLedBarMode() != LedBarModeOff);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (localConfig.getCO2CalirationAbcDays() > 0) {
|
if (localConfig.getCO2CalirationAbcDays() > 0) {
|
||||||
@ -1986,15 +1634,15 @@ static void configUpdateHandle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String mqttUri = localConfig.getMqttBrokerUri();
|
String mqttUri = localConfig.getMqttBrokerUri();
|
||||||
if (mqttUri != agMqtt.getUri()) {
|
if (mqttClient.isCurrentUri(mqttUri)) {
|
||||||
agMqtt.end();
|
mqttClient.end();
|
||||||
|
|
||||||
if (mqttTask != NULL) {
|
if (mqttTask != NULL) {
|
||||||
vTaskDelete(mqttTask);
|
vTaskDelete(mqttTask);
|
||||||
mqttTask = NULL;
|
mqttTask = NULL;
|
||||||
}
|
}
|
||||||
if (mqttUri.length() > 0) {
|
if (mqttUri.length() > 0) {
|
||||||
if (agMqtt.begin(mqttUri)) {
|
if (mqttClient.begin(mqttUri)) {
|
||||||
Serial.println("Connect to MQTT broker successful");
|
Serial.println("Connect to MQTT broker successful");
|
||||||
createMqttTask();
|
createMqttTask();
|
||||||
} else {
|
} else {
|
||||||
@ -2163,7 +1811,7 @@ static void singleLedAnimation(uint8_t r, uint8_t g, uint8_t b) {
|
|||||||
* @param sm APP state machine
|
* @param sm APP state machine
|
||||||
*/
|
*/
|
||||||
static void ledSmHandler(int sm) {
|
static void ledSmHandler(int sm) {
|
||||||
if (sm > APP_SM_NORMAL) {
|
if (sm > AgStateMachineNormal) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2172,7 +1820,7 @@ static void ledSmHandler(int sm) {
|
|||||||
ag->ledBar.clear(); // Set all LED OFF
|
ag->ledBar.clear(); // Set all LED OFF
|
||||||
}
|
}
|
||||||
switch (sm) {
|
switch (sm) {
|
||||||
case APP_SM_WIFI_MANAGER_MODE: {
|
case AgStateMachineWiFiManagerMode: {
|
||||||
/** In WiFi Manager Mode */
|
/** In WiFi Manager Mode */
|
||||||
/** Turn LED OFF */
|
/** Turn LED OFF */
|
||||||
/** Turn midle LED Color */
|
/** Turn midle LED Color */
|
||||||
@ -2183,7 +1831,7 @@ static void ledSmHandler(int sm) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_WIFI_MANAGER_PORTAL_ACTIVE: {
|
case AgStateMachineWiFiManagerPortalActive: {
|
||||||
/** WiFi Manager has connected to mobile phone */
|
/** WiFi Manager has connected to mobile phone */
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
ag->ledBar.setColor(0, 0, 255);
|
ag->ledBar.setColor(0, 0, 255);
|
||||||
@ -2192,7 +1840,7 @@ static void ledSmHandler(int sm) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_WIFI_MANAGER_STA_CONNECTING: {
|
case AgStateMachineWiFiManagerStaConnecting: {
|
||||||
/** after SSID and PW entered and OK clicked, connection to WiFI network is
|
/** after SSID and PW entered and OK clicked, connection to WiFI network is
|
||||||
* attempted */
|
* attempted */
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
@ -2202,7 +1850,7 @@ static void ledSmHandler(int sm) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_WIFI_MANAGER_STA_CONNECTED: {
|
case AgStateMachineWiFiManagerStaConnected: {
|
||||||
/** Connecting to WiFi worked */
|
/** Connecting to WiFi worked */
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
ag->ledBar.setColor(255, 255, 255);
|
ag->ledBar.setColor(255, 255, 255);
|
||||||
@ -2211,7 +1859,7 @@ static void ledSmHandler(int sm) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_WIFI_OK_SERVER_CONNECTING: {
|
case AgStateMachineWiFiOkServerConnecting: {
|
||||||
/** once connected to WiFi an attempt to reach the server is performed */
|
/** once connected to WiFi an attempt to reach the server is performed */
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
singleLedAnimation(0, 255, 0);
|
singleLedAnimation(0, 255, 0);
|
||||||
@ -2220,7 +1868,7 @@ static void ledSmHandler(int sm) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_WIFI_OK_SERVER_CONNECTED: {
|
case AgStateMachineWiFiOkServerConnected: {
|
||||||
/** Server is reachable, all fine */
|
/** Server is reachable, all fine */
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
ag->ledBar.setColor(0, 255, 0);
|
ag->ledBar.setColor(0, 255, 0);
|
||||||
@ -2236,7 +1884,7 @@ static void ledSmHandler(int sm) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_WIFI_MANAGER_CONNECT_FAILED: {
|
case AgStateMachineWiFiManagerConnectFailed: {
|
||||||
/** Cannot connect to WiFi (e.g. wrong password, WPA Enterprise etc.) */
|
/** Cannot connect to WiFi (e.g. wrong password, WPA Enterprise etc.) */
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
ag->ledBar.setColor(255, 0, 0);
|
ag->ledBar.setColor(255, 0, 0);
|
||||||
@ -2253,7 +1901,7 @@ static void ledSmHandler(int sm) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_WIFI_OK_SERVER_CONNECT_FAILED: {
|
case AgStateMachineWiFiOkServerConnectFailed: {
|
||||||
/** Connected to WiFi but server not reachable, e.g. firewall block/
|
/** Connected to WiFi but server not reachable, e.g. firewall block/
|
||||||
* whitelisting needed etc. */
|
* whitelisting needed etc. */
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
@ -2270,7 +1918,7 @@ static void ledSmHandler(int sm) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_WIFI_OK_SERVER_OK_SENSOR_CONFIG_FAILED: {
|
case AgStateMachineWiFiOkServerOkSensorConfigFailed: {
|
||||||
/** Server reachable but sensor not configured correctly */
|
/** Server reachable but sensor not configured correctly */
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
ag->ledBar.setColor(139, 24, 248); /** violet */
|
ag->ledBar.setColor(139, 24, 248); /** violet */
|
||||||
@ -2286,7 +1934,7 @@ static void ledSmHandler(int sm) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_WIFI_LOST: {
|
case AgStateMachineWiFiLost: {
|
||||||
/** Connection to WiFi network failed credentials incorrect encryption not
|
/** Connection to WiFi network failed credentials incorrect encryption not
|
||||||
* supported etc. */
|
* supported etc. */
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
@ -2299,7 +1947,7 @@ static void ledSmHandler(int sm) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_SERVER_LOST: {
|
case AgStateMachineServerLost: {
|
||||||
/** Connected to WiFi network but the server cannot be reached through the
|
/** Connected to WiFi network but the server cannot be reached through the
|
||||||
* internet, e.g. blocked by firewall */
|
* internet, e.g. blocked by firewall */
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
@ -2312,7 +1960,7 @@ static void ledSmHandler(int sm) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_SENSOR_CONFIG_FAILED: {
|
case AgStateMachineSensorConfigFailed: {
|
||||||
/** Server is reachable but there is some configuration issue to be fixed on
|
/** Server is reachable but there is some configuration issue to be fixed on
|
||||||
* the server side */
|
* the server side */
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
@ -2325,7 +1973,7 @@ static void ledSmHandler(int sm) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_NORMAL: {
|
case AgStateMachineNormal: {
|
||||||
if (isOneIndoor()) {
|
if (isOneIndoor()) {
|
||||||
sensorLedColorHandler();
|
sensorLedColorHandler();
|
||||||
} else {
|
} else {
|
||||||
@ -2360,15 +2008,15 @@ static void ledSmHandler(void) { ledSmHandler(ledSmState); }
|
|||||||
* @param sm APP state machine
|
* @param sm APP state machine
|
||||||
*/
|
*/
|
||||||
static void dispSmHandler(int sm) {
|
static void dispSmHandler(int sm) {
|
||||||
if (sm > APP_SM_NORMAL) {
|
if (sm > AgStateMachineNormal) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dispSmState = sm;
|
dispSmState = sm;
|
||||||
|
|
||||||
switch (sm) {
|
switch (sm) {
|
||||||
case APP_SM_WIFI_MANAGER_MODE:
|
case AgStateMachineWiFiManagerMode:
|
||||||
case APP_SM_WIFI_MANAGER_PORTAL_ACTIVE: {
|
case AgStateMachineWiFiManagerPortalActive: {
|
||||||
if (connectCountDown >= 0) {
|
if (connectCountDown >= 0) {
|
||||||
displayShowWifiText(String(connectCountDown) + "s to connect",
|
displayShowWifiText(String(connectCountDown) + "s to connect",
|
||||||
"to WiFi hotspot:", "\"airgradient-",
|
"to WiFi hotspot:", "\"airgradient-",
|
||||||
@ -2377,43 +2025,43 @@ static void dispSmHandler(int sm) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_WIFI_MANAGER_STA_CONNECTING: {
|
case AgStateMachineWiFiManagerStaConnecting: {
|
||||||
displayShowText("Trying to", "connect to WiFi", "...");
|
displayShowText("Trying to", "connect to WiFi", "...");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_WIFI_MANAGER_STA_CONNECTED: {
|
case AgStateMachineWiFiManagerStaConnected: {
|
||||||
displayShowText("WiFi connection", "successful", "");
|
displayShowText("WiFi connection", "successful", "");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_WIFI_OK_SERVER_CONNECTING: {
|
case AgStateMachineWiFiOkServerConnecting: {
|
||||||
displayShowText("Connecting to", "Server", "...");
|
displayShowText("Connecting to", "Server", "...");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_WIFI_OK_SERVER_CONNECTED: {
|
case AgStateMachineWiFiOkServerConnected: {
|
||||||
displayShowText("Server", "connection", "successful");
|
displayShowText("Server", "connection", "successful");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_WIFI_MANAGER_CONNECT_FAILED: {
|
case AgStateMachineWiFiManagerConnectFailed: {
|
||||||
displayShowText("WiFi not", "connected", "");
|
displayShowText("WiFi not", "connected", "");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_WIFI_OK_SERVER_CONNECT_FAILED: {
|
case AgStateMachineWiFiOkServerConnectFailed: {
|
||||||
// displayShowText("Server not", "reachable", "");
|
// displayShowText("Server not", "reachable", "");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_WIFI_OK_SERVER_OK_SENSOR_CONFIG_FAILED: {
|
case AgStateMachineWiFiOkServerOkSensorConfigFailed: {
|
||||||
displayShowText("Monitor not", "setup on", "dashboard");
|
displayShowText("Monitor not", "setup on", "dashboard");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_WIFI_LOST: {
|
case AgStateMachineWiFiLost: {
|
||||||
displayShowDashboard("WiFi N/A");
|
displayShowDashboard("WiFi N/A");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_SERVER_LOST: {
|
case AgStateMachineServerLost: {
|
||||||
displayShowDashboard("Server N/A");
|
displayShowDashboard("Server N/A");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_SENSOR_CONFIG_FAILED: {
|
case AgStateMachineSensorConfigFailed: {
|
||||||
uint32_t ms = (uint32_t)(millis() - addToDashboardTime);
|
uint32_t ms = (uint32_t)(millis() - addToDashboardTime);
|
||||||
if (ms >= 5000) {
|
if (ms >= 5000) {
|
||||||
addToDashboardTime = millis();
|
addToDashboardTime = millis();
|
||||||
@ -2426,7 +2074,7 @@ static void dispSmHandler(int sm) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case APP_SM_NORMAL: {
|
case AgStateMachineNormal: {
|
||||||
displayShowDashboard("");
|
displayShowDashboard("");
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -2439,13 +2087,13 @@ static void dispSmHandler(int sm) {
|
|||||||
*/
|
*/
|
||||||
static void sensorLedColorHandler(void) {
|
static void sensorLedColorHandler(void) {
|
||||||
switch (localConfig.getLedBarMode()) {
|
switch (localConfig.getLedBarMode()) {
|
||||||
case UseLedBarCO2:
|
case LedBarModeCO2:
|
||||||
setRGBledCO2color(co2Ppm);
|
setRGBledCO2color(co2Ppm);
|
||||||
break;
|
break;
|
||||||
case UseLedBarPM:
|
case LedBarModePm:
|
||||||
setRGBledPMcolor(pm25_1);
|
setRGBledPMcolor(pm25_1);
|
||||||
break;
|
break;
|
||||||
case UseLedBarOff:
|
case LedBarModeOff:
|
||||||
ag->ledBar.clear();
|
ag->ledBar.clear();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -2458,13 +2106,13 @@ static void sensorLedColorHandler(void) {
|
|||||||
* @brief APP LED color handler
|
* @brief APP LED color handler
|
||||||
*/
|
*/
|
||||||
static void appLedHandler(void) {
|
static void appLedHandler(void) {
|
||||||
uint8_t state = APP_SM_NORMAL;
|
uint8_t state = AgStateMachineNormal;
|
||||||
if (WiFi.isConnected() == false) {
|
if (WiFi.isConnected() == false) {
|
||||||
state = APP_SM_WIFI_LOST;
|
state = AgStateMachineWiFiLost;
|
||||||
} else if (agServer.isConfigFailed()) {
|
} else if (agServer.isFetchConfigureFailed()) {
|
||||||
state = APP_SM_SENSOR_CONFIG_FAILED;
|
state = AgStateMachineSensorConfigFailed;
|
||||||
} else if (agServer.isServerFailed()) {
|
} else if (agServer.isPostToServerFailed()) {
|
||||||
state = APP_SM_SERVER_LOST;
|
state = AgStateMachineServerLost;
|
||||||
}
|
}
|
||||||
ledSmHandler(state);
|
ledSmHandler(state);
|
||||||
}
|
}
|
||||||
@ -2473,13 +2121,13 @@ static void appLedHandler(void) {
|
|||||||
* @brief APP display content handler
|
* @brief APP display content handler
|
||||||
*/
|
*/
|
||||||
static void appDispHandler(void) {
|
static void appDispHandler(void) {
|
||||||
uint8_t state = APP_SM_NORMAL;
|
uint8_t state = AgStateMachineNormal;
|
||||||
if (WiFi.isConnected() == false) {
|
if (WiFi.isConnected() == false) {
|
||||||
state = APP_SM_WIFI_LOST;
|
state = AgStateMachineWiFiLost;
|
||||||
} else if (agServer.isConfigFailed()) {
|
} else if (agServer.isFetchConfigureFailed()) {
|
||||||
state = APP_SM_SENSOR_CONFIG_FAILED;
|
state = AgStateMachineSensorConfigFailed;
|
||||||
} else if (agServer.isServerFailed()) {
|
} else if (agServer.isPostToServerFailed()) {
|
||||||
state = APP_SM_SERVER_LOST;
|
state = AgStateMachineServerLost;
|
||||||
}
|
}
|
||||||
dispSmHandler(state);
|
dispSmHandler(state);
|
||||||
}
|
}
|
||||||
@ -2724,52 +2372,3 @@ static void tempHumUpdate(void) {
|
|||||||
Serial.println("SHT read failed");
|
Serial.println("SHT read failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mqtt_event_handler(void *handler_args, esp_event_base_t base,
|
|
||||||
int32_t event_id, void *event_data) {
|
|
||||||
AgMqtt *mqtt = (AgMqtt *)handler_args;
|
|
||||||
|
|
||||||
esp_mqtt_event_handle_t event = (esp_mqtt_event_handle_t)event_data;
|
|
||||||
esp_mqtt_client_handle_t client = event->client;
|
|
||||||
int msg_id;
|
|
||||||
switch ((esp_mqtt_event_id_t)event_id) {
|
|
||||||
case MQTT_EVENT_CONNECTED:
|
|
||||||
Serial.println("MQTT_EVENT_CONNECTED");
|
|
||||||
// msg_id = esp_mqtt_client_subscribe(client, "helloworld", 0);
|
|
||||||
// Serial.printf("sent subscribe successful, msg_id=%d\r\n", msg_id);
|
|
||||||
mqtt->_connectionHandler(true);
|
|
||||||
break;
|
|
||||||
case MQTT_EVENT_DISCONNECTED:
|
|
||||||
Serial.println("MQTT_EVENT_DISCONNECTED");
|
|
||||||
mqtt->_connectionHandler(false);
|
|
||||||
break;
|
|
||||||
case MQTT_EVENT_SUBSCRIBED:
|
|
||||||
break;
|
|
||||||
case MQTT_EVENT_UNSUBSCRIBED:
|
|
||||||
Serial.printf("MQTT_EVENT_UNSUBSCRIBED, msg_id=%d\r\n", event->msg_id);
|
|
||||||
break;
|
|
||||||
case MQTT_EVENT_PUBLISHED:
|
|
||||||
Serial.printf("MQTT_EVENT_PUBLISHED, msg_id=%d\r\n", event->msg_id);
|
|
||||||
break;
|
|
||||||
case MQTT_EVENT_DATA:
|
|
||||||
Serial.println("MQTT_EVENT_DATA");
|
|
||||||
// add null terminal to data
|
|
||||||
// event->data[event->data_len] = 0;
|
|
||||||
// rpc_attritbutes_handler(event->data, event->data_len);
|
|
||||||
break;
|
|
||||||
case MQTT_EVENT_ERROR:
|
|
||||||
Serial.println("MQTT_EVENT_ERROR");
|
|
||||||
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
|
|
||||||
Serial.printf("reported from esp-tls: %d",
|
|
||||||
event->error_handle->esp_tls_last_esp_err);
|
|
||||||
Serial.printf("reported from tls stack: %d",
|
|
||||||
event->error_handle->esp_tls_stack_err);
|
|
||||||
Serial.printf("captured as transport's socket errno: %d",
|
|
||||||
event->error_handle->esp_transport_sock_errno);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Serial.printf("Other event id:%d\r\n", event->event_id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user