[temporary commit]

This commit is contained in:
Phat Nguyen
2024-04-03 07:04:28 +07:00
parent 954a7751cc
commit f52eab87d2
4 changed files with 105 additions and 1016 deletions

View File

@ -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]; /** */
}; };

View File

@ -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); }

View File

@ -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_ */

View File

@ -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;
}
}