mirror of
https://github.com/airgradienthq/arduino.git
synced 2025-06-29 17:50:58 +02:00
Compare commits
33 Commits
Author | SHA1 | Date | |
---|---|---|---|
8a83e408d3 | |||
7a1a0337d1 | |||
6bdd4cb02f | |||
38bd758b69 | |||
6aa19ea3e6 | |||
da323b1a46 | |||
2ae90444bb | |||
21e802da33 | |||
e0869fbaf0 | |||
70662091ec | |||
960d2bad64 | |||
7abf7f5e6a | |||
6bad4fd04b | |||
a17f18b3db | |||
3da4900462 | |||
d2d81f6b4b | |||
0b12f56513 | |||
f7e811e34b | |||
037bb37184 | |||
fde510ba96 | |||
14b152a2a7 | |||
ef6b041529 | |||
11ecea1493 | |||
3e2e8b15eb | |||
4249a86fd5 | |||
4a58b0b1c7 | |||
5f93329e96 | |||
59d189e1d3 | |||
65e759fb90 | |||
6ea0ab9272 | |||
6e54409512 | |||
c04ab90fd2 | |||
ed02f66ca2 |
@ -17,62 +17,66 @@ With the path "/measures/current" you can get the current air quality data.
|
|||||||
|
|
||||||
http://airgradient_ecda3b1eaaaf.local/measures/current
|
http://airgradient_ecda3b1eaaaf.local/measures/current
|
||||||
|
|
||||||
“ecda3b1eaaaf” being the serial number of your monitor
|
“ecda3b1eaaaf” being the serial number of your monitor.
|
||||||
|
|
||||||
You get the following response:
|
You get the following response:
|
||||||
~~~
|
```json
|
||||||
{"wifi":-46,
|
{
|
||||||
"serialno":"ecda3b1eaaaf",
|
"wifi": -46,
|
||||||
"rco2":447,
|
"serialno": "ecda3b1eaaaf",
|
||||||
"pm01":3,
|
"rco2": 447,
|
||||||
"pm02":7,
|
"pm01": 3,
|
||||||
"pm10":8,
|
"pm02": 7,
|
||||||
"pm003Count":442,
|
"pm10": 8,
|
||||||
"atmp":25.87,
|
"pm003Count": 442,
|
||||||
"rhum":43,
|
"atmp": 25.87,
|
||||||
"tvocIndex":100,
|
"rhum": 43,
|
||||||
"tvoc_raw":33051,
|
"tvocIndex": 100,
|
||||||
"noxIndex":1,
|
"tvoc_raw": 33051,
|
||||||
"nox_raw":16307,
|
"noxIndex": 1,
|
||||||
"boot":6,
|
"nox_raw": 16307,
|
||||||
"ledMode":"pm",
|
"boot": 6,
|
||||||
"firmwareVersion":"3.0.10beta",
|
"ledMode": "pm",
|
||||||
"fwMode":"I-9PSL"}
|
"firmwareVersion": "3.0.10beta",
|
||||||
~~~
|
"fwMode": "I-9PSL"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|Properties|Type|Explanation|
|
| Properties | Type | Explanation |
|
||||||
|-|-|-|
|
|------------------|--------|--------------------------------------------------------------------|
|
||||||
|serialno|String| Serial Number of the monitor|
|
| serialno | String | Serial Number of the monitor |
|
||||||
|wifi|Number| WiFi signal strength|
|
| wifi | Number | WiFi signal strength |
|
||||||
|pm01, pm02, pm10|Number| PM1, PM2.5 and PM10 in ug/m3|
|
| pm01, pm02, pm10 | Number | PM1, PM2.5 and PM10 in ug/m3 |
|
||||||
|rco2|Number| CO2 in ppm|
|
| rco2 | Number | CO2 in ppm |
|
||||||
|pm003Count|Number| Particle count per dL|
|
| pm003Count | Number | Particle count per dL |
|
||||||
|atmp|Number| Temperature in Degrees Celcius|
|
| atmp | Number | Temperature in Degrees Celcius |
|
||||||
|rhum|Number| Relative Humidity|
|
| rhum | Number | Relative Humidity |
|
||||||
|tvocIndex|Number| Senisiron VOC Index|
|
| tvocIndex | Number | Senisiron VOC Index |
|
||||||
|tvoc_raw|Number| VOC raw value|
|
| tvoc_raw | Number | VOC raw value |
|
||||||
|noxIndex|Number| Senisirion NOx Index|
|
| noxIndex | Number | Senisirion NOx Index |
|
||||||
|nox_raw|Number| NOx raw value|
|
| nox_raw | Number | NOx raw value |
|
||||||
|boot|Number| Counts every measurement cycle. Low boot counts indicate restarts.|
|
| boot | Number | Counts every measurement cycle. Low boot counts indicate restarts. |
|
||||||
|ledMode|String| Current configuration of the LED mode|
|
| ledMode | String | Current configuration of the LED mode |
|
||||||
|firmwareVersion|String| Current firmware version|
|
| firmwareVersion | String | Current firmware version |
|
||||||
|fwMode|String| Current model name|
|
| fwMode | String | Current model name |
|
||||||
|
|
||||||
#### Get Configuration Parameters (GET)
|
#### Get Configuration Parameters (GET)
|
||||||
With the path "/config" you can get the current configuration.
|
With the path "/config" you can get the current configuration.
|
||||||
~~~
|
```json
|
||||||
{"country":"US",
|
{
|
||||||
"pmStandard":"ugm3",
|
"country": "US",
|
||||||
"ledBarMode":"pm",
|
"pmStandard": "ugm3",
|
||||||
"displayMode":"on",
|
"ledBarMode": "pm",
|
||||||
"abcDays":30,
|
"displayMode": "on",
|
||||||
"tvocLearningOffset":12,
|
"abcDays": 30,
|
||||||
"noxLearningOffset":12,
|
"tvocLearningOffset": 12,
|
||||||
"mqttBrokerUrl":"",
|
"noxLearningOffset": 12,
|
||||||
"temperatureUnit":"f",
|
"mqttBrokerUrl": "",
|
||||||
"configurationControl":"both",
|
"temperatureUnit": "f",
|
||||||
"postDataToAirGradient":true}
|
"configurationControl": "both",
|
||||||
~~~
|
"postDataToAirGradient": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
#### Set Configuration Parameters (PUT)
|
#### Set Configuration Parameters (PUT)
|
||||||
|
|
||||||
@ -82,24 +86,24 @@ Example to force CO2 calibration
|
|||||||
|
|
||||||
```curl -X PUT -H "Content-Type: application/json" -d '{"co2CalibrationRequested":true}' http://airgradient_84fce612eff4.local/config ```
|
```curl -X PUT -H "Content-Type: application/json" -d '{"co2CalibrationRequested":true}' http://airgradient_84fce612eff4.local/config ```
|
||||||
|
|
||||||
Example to set monitor to Celcius
|
Example to set monitor to Celsius
|
||||||
|
|
||||||
```curl -X PUT -H "Content-Type: application/json" -d '{"temperatureUnit":"c"}' http://airgradient_84fce612eff4.local/config ```
|
```curl -X PUT -H "Content-Type: application/json" -d '{"temperatureUnit":"c"}' http://airgradient_84fce612eff4.local/config ```
|
||||||
|
|
||||||
#### Avoiding Conflicts with Configuration on AirGradient Server
|
#### Avoiding Conflicts with Configuration on AirGradient Server
|
||||||
If the monitor is setup on the AirGradient dashboard, it will also receive configurations from there. In case you do not want this, please set "configurationControl" to local. In case you set it to cloud and want to change it to local, you need to make a factory reset.
|
If the monitor is set up on the AirGradient dashboard, it will also receive configurations from there. In case you do not want this, please set `configurationControl` to `local`. In case you set it to `cloud` and want to change it to `local`, you need to make a factory reset.
|
||||||
|
|
||||||
#### Configuration Parameters (GET/PUT)
|
#### Configuration Parameters (GET/PUT)
|
||||||
|
|
||||||
|Properties|Type|Accepted Values|Example|
|
| Properties | Description | Type | Accepted Values | Example |
|
||||||
|-|-|-|-|
|
|-------------------------|:-------------------------------------------------------|---------|-----------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|
|
||||||
|country|String| Country code as [ALPHA-2 notation](https://www.iban.com/country-codes) | {"country": "TH"}|
|
| country | Country where the device is. | String | Country code as [ALPHA-2 notation](https://www.iban.com/country-codes) | {"country": "TH"} |
|
||||||
|pmStandard|String|ugm3 : ug/m3 <br> usaqi: USAQI | {"pmStandard": "ugm3"}|
|
| pmStandard | Particle matter standard used on the display. | String | `ugm3`: ug/m3 <br> `us-aqi`: USAQI | {"pmStandard": "ugm3"} |
|
||||||
|ledBarMode|String|co2: LED bar displays CO2 <br> pm: LED bar displays PM <br> off: Turn off LED bar | {"ledBarMode": "off"}|
|
| ledBarMode | Mode in which the led bar can be set. | String | `co2`: LED bar displays CO2 <br>`pm`: LED bar displays PM <br>`off`: Turn off LED bar | {"ledBarMode": "off"} |
|
||||||
|abcDays|Number|Number of days for CO2 automatic baseline balibration. Maximum 200 days. Default 8 days. | {"abcDays": 8}|
|
| abcDays | Number of days for CO2 automatic baseline calibration. | Number | Maximum 200 days. Default 8 days. | {"abcDays": 8} |
|
||||||
|mqttBrokerUrl|String|MQTT broker URL. | {"mqttBrokerUrl":"mqtt://192.168.0.18:1883"} |
|
| mqttBrokerUrl | MQTT broker URL. | String | | {"mqttBrokerUrl": "mqtt://192.168.0.18:1883"} |
|
||||||
|temperatureUnit|String|c or C: Degree Celsius °C <br>f or F: Degree Fahrenheit °F | {"temperatureUnit": "c"}|
|
| temperatureUnit | Temperature unit shown on the display. | String | `c` or `C`: Degree Celsius °C <br>`f` or `F`: Degree Fahrenheit °F | {"temperatureUnit": "c"} |
|
||||||
|configurationControl|String|both : Accept local and cloud configuration <br>local : Accept only local configuration <br>cloud : Accept only cloud configuration | {"configurationControl": "both"}|
|
| configurationControl | The configuration source of the device. | String | `both`: Accept local and cloud configuration <br>`local`: Accept only local configuration <br>`cloud`: Accept only cloud configuration | {"configurationControl": "both"} |
|
||||||
|postDataToAirGradient|Boolean|Send data to AirGradient cloud: <br>true : Enabled <br>false: Disabled | {"postDataToAirGradient": true}|
|
| postDataToAirGradient | Send data to AirGradient cloud. | Boolean | `true`: Enabled <br>`false`: Disabled | {"postDataToAirGradient": true} |
|
||||||
|co2CalibrationRequested|Boolean|Trigger CO2 calibration (400ppm) on monitor:<br>true : Calibration will be triggered | {"co2CalibrationRequested": true}|
|
| co2CalibrationRequested | Can be set to trigger a calibration. | Boolean | `true`: CO2 calibration (400ppm) will be triggered | {"co2CalibrationRequested": true} |
|
||||||
|ledBarTestRequested|Boolean|Test LED bar:<br> true : LEDs will run test sequence | {"ledBarTestRequested": true}|
|
| ledBarTestRequested | Can be set to trigger a test. | Boolean | `true` : LEDs will run test sequence | {"ledBarTestRequested": true} |
|
||||||
|
@ -41,7 +41,7 @@ CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License
|
|||||||
#define LED_BAR_COUNT_INIT_VALUE (-1) /** */
|
#define LED_BAR_COUNT_INIT_VALUE (-1) /** */
|
||||||
#define LED_BAR_ANIMATION_PERIOD 100 /** ms */
|
#define LED_BAR_ANIMATION_PERIOD 100 /** ms */
|
||||||
#define DISP_UPDATE_INTERVAL 5000 /** ms */
|
#define DISP_UPDATE_INTERVAL 5000 /** ms */
|
||||||
#define SERVER_CONFIG_UPDATE_INTERVAL 30000 /** ms */
|
#define SERVER_CONFIG_SYNC_INTERVAL 60000 /** ms */
|
||||||
#define SERVER_SYNC_INTERVAL 60000 /** ms */
|
#define SERVER_SYNC_INTERVAL 60000 /** ms */
|
||||||
#define SENSOR_CO2_CALIB_COUNTDOWN_MAX 5 /** sec */
|
#define SENSOR_CO2_CALIB_COUNTDOWN_MAX 5 /** sec */
|
||||||
#define SENSOR_TVOC_UPDATE_INTERVAL 1000 /** ms */
|
#define SENSOR_TVOC_UPDATE_INTERVAL 1000 /** ms */
|
||||||
@ -82,7 +82,7 @@ bool hasSensorPMS = true;
|
|||||||
bool hasSensorSHT = true;
|
bool hasSensorSHT = true;
|
||||||
int pmFailCount = 0;
|
int pmFailCount = 0;
|
||||||
int getCO2FailCount = 0;
|
int getCO2FailCount = 0;
|
||||||
AgSchedule configSchedule(SERVER_CONFIG_UPDATE_INTERVAL,
|
AgSchedule configSchedule(SERVER_CONFIG_SYNC_INTERVAL,
|
||||||
updateServerConfiguration);
|
updateServerConfiguration);
|
||||||
AgSchedule serverSchedule(SERVER_SYNC_INTERVAL, sendDataToServer);
|
AgSchedule serverSchedule(SERVER_SYNC_INTERVAL, sendDataToServer);
|
||||||
AgSchedule dispSchedule(DISP_UPDATE_INTERVAL, dispHandler);
|
AgSchedule dispSchedule(DISP_UPDATE_INTERVAL, dispHandler);
|
||||||
|
@ -55,7 +55,7 @@ CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License
|
|||||||
|
|
||||||
#define LED_BAR_ANIMATION_PERIOD 100 /** ms */
|
#define LED_BAR_ANIMATION_PERIOD 100 /** ms */
|
||||||
#define DISP_UPDATE_INTERVAL 2500 /** ms */
|
#define DISP_UPDATE_INTERVAL 2500 /** ms */
|
||||||
#define SERVER_CONFIG_UPDATE_INTERVAL 15000 /** ms */
|
#define SERVER_CONFIG_SYNC_INTERVAL 60000 /** ms */
|
||||||
#define SERVER_SYNC_INTERVAL 60000 /** ms */
|
#define SERVER_SYNC_INTERVAL 60000 /** ms */
|
||||||
#define MQTT_SYNC_INTERVAL 60000 /** ms */
|
#define MQTT_SYNC_INTERVAL 60000 /** ms */
|
||||||
#define SENSOR_CO2_CALIB_COUNTDOWN_MAX 5 /** sec */
|
#define SENSOR_CO2_CALIB_COUNTDOWN_MAX 5 /** sec */
|
||||||
@ -64,6 +64,7 @@ CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License
|
|||||||
#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 FIRMWARE_CHECK_FOR_UPDATE_MS (60*60*1000) /** ms */
|
||||||
|
|
||||||
/** I2C define */
|
/** I2C define */
|
||||||
#define I2C_SDA_PIN 7
|
#define I2C_SDA_PIN 7
|
||||||
@ -113,12 +114,13 @@ static void factoryConfigReset(void);
|
|||||||
static void wdgFeedUpdate(void);
|
static void wdgFeedUpdate(void);
|
||||||
static void ledBarEnabledUpdate(void);
|
static void ledBarEnabledUpdate(void);
|
||||||
static bool sgp41Init(void);
|
static bool sgp41Init(void);
|
||||||
|
static void firmwareCheckForUpdate(void);
|
||||||
static void otaHandlerCallback(OtaState state, String mesasge);
|
static void otaHandlerCallback(OtaState state, String mesasge);
|
||||||
static void displayExecuteOta(OtaState state, String msg,
|
static void displayExecuteOta(OtaState state, String msg,
|
||||||
int processing);
|
int processing);
|
||||||
|
|
||||||
AgSchedule dispLedSchedule(DISP_UPDATE_INTERVAL, oledDisplayLedBarSchedule);
|
AgSchedule dispLedSchedule(DISP_UPDATE_INTERVAL, oledDisplayLedBarSchedule);
|
||||||
AgSchedule configSchedule(SERVER_CONFIG_UPDATE_INTERVAL,
|
AgSchedule configSchedule(SERVER_CONFIG_SYNC_INTERVAL,
|
||||||
configurationUpdateSchedule);
|
configurationUpdateSchedule);
|
||||||
AgSchedule agApiPostSchedule(SERVER_SYNC_INTERVAL, sendDataToServer);
|
AgSchedule agApiPostSchedule(SERVER_SYNC_INTERVAL, sendDataToServer);
|
||||||
AgSchedule co2Schedule(SENSOR_CO2_UPDATE_INTERVAL, co2Update);
|
AgSchedule co2Schedule(SENSOR_CO2_UPDATE_INTERVAL, co2Update);
|
||||||
@ -126,6 +128,7 @@ AgSchedule pmsSchedule(SENSOR_PM_UPDATE_INTERVAL, updatePm);
|
|||||||
AgSchedule tempHumSchedule(SENSOR_TEMP_HUM_UPDATE_INTERVAL, tempHumUpdate);
|
AgSchedule tempHumSchedule(SENSOR_TEMP_HUM_UPDATE_INTERVAL, tempHumUpdate);
|
||||||
AgSchedule tvocSchedule(SENSOR_TVOC_UPDATE_INTERVAL, updateTvoc);
|
AgSchedule tvocSchedule(SENSOR_TVOC_UPDATE_INTERVAL, updateTvoc);
|
||||||
AgSchedule watchdogFeedSchedule(60000, wdgFeedUpdate);
|
AgSchedule watchdogFeedSchedule(60000, wdgFeedUpdate);
|
||||||
|
AgSchedule checkForUpdateSchedule(FIRMWARE_CHECK_FOR_UPDATE_MS, firmwareCheckForUpdate);
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
/** Serial for print debug message */
|
/** Serial for print debug message */
|
||||||
@ -166,16 +169,6 @@ void setup() {
|
|||||||
/** Connecting wifi */
|
/** Connecting wifi */
|
||||||
bool connectToWifi = false;
|
bool connectToWifi = false;
|
||||||
if (ag->isOne()) {
|
if (ag->isOne()) {
|
||||||
if (ledBarButtonTest) {
|
|
||||||
if (ag->button.getState() == PushButton::BUTTON_PRESSED) {
|
|
||||||
WiFi.begin("airgradient", "cleanair");
|
|
||||||
Serial.println("WiFi Credential reset to factory defaults");
|
|
||||||
ESP.restart();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ledBarEnabledUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Show message confirm offline mode, should me perform if LED bar button
|
/** Show message confirm offline mode, should me perform if LED bar button
|
||||||
* test pressed */
|
* test pressed */
|
||||||
if (ledBarButtonTest == false) {
|
if (ledBarButtonTest == false) {
|
||||||
@ -219,10 +212,8 @@ void setup() {
|
|||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
// ota not supported
|
// ota not supported
|
||||||
#else
|
#else
|
||||||
otaHandler.updateFirmwareIfOutdated(ag->deviceId());
|
firmwareCheckForUpdate();
|
||||||
|
checkForUpdateSchedule.update();
|
||||||
/** Update first OTA */
|
|
||||||
measurements.otaBootCount = 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
apiClient.fetchServerConfiguration();
|
apiClient.fetchServerConfiguration();
|
||||||
@ -241,8 +232,12 @@ void setup() {
|
|||||||
ledBarEnabledUpdate();
|
ledBarEnabledUpdate();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
oledDisplay.showRebooting();
|
if (wifiConnector.isConfigurePorttalTimeout()) {
|
||||||
delay(2500);
|
oledDisplay.showRebooting();
|
||||||
|
delay(2500);
|
||||||
|
oledDisplay.setText("", "", "");
|
||||||
|
ESP.restart();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,6 +307,9 @@ void loop() {
|
|||||||
|
|
||||||
/** check that local configura changed then do some action */
|
/** check that local configura changed then do some action */
|
||||||
configUpdateHandle();
|
configUpdateHandle();
|
||||||
|
|
||||||
|
/** Firmware check for update handle */
|
||||||
|
checkForUpdateSchedule.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void co2Update(void) {
|
static void co2Update(void) {
|
||||||
@ -420,6 +418,7 @@ static void factoryConfigReset(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Reset WIFI */
|
/** Reset WIFI */
|
||||||
|
WiFi.enableSTA(true); // Incase offline mode
|
||||||
WiFi.disconnect(true, true);
|
WiFi.disconnect(true, true);
|
||||||
|
|
||||||
/** Reset local config */
|
/** Reset local config */
|
||||||
@ -431,6 +430,7 @@ static void factoryConfigReset(void) {
|
|||||||
Serial.println("Factory reset successful");
|
Serial.println("Factory reset successful");
|
||||||
}
|
}
|
||||||
delay(3000);
|
delay(3000);
|
||||||
|
oledDisplay.setText("","","");
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -488,7 +488,22 @@ static bool sgp41Init(void) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void firmwareCheckForUpdate(void) {
|
||||||
|
Serial.println();
|
||||||
|
Serial.println("firmwareCheckForUpdate:");
|
||||||
|
|
||||||
|
if (wifiConnector.isConnected()) {
|
||||||
|
Serial.println("firmwareCheckForUpdate: Perform");
|
||||||
|
otaHandler.setHandlerCallback(otaHandlerCallback);
|
||||||
|
otaHandler.updateFirmwareIfOutdated(ag->deviceId());
|
||||||
|
} else {
|
||||||
|
Serial.println("firmwareCheckForUpdate: Ignored");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
static void otaHandlerCallback(OtaState state, String mesasge) {
|
static void otaHandlerCallback(OtaState state, String mesasge) {
|
||||||
|
Serial.println("OTA message: " + mesasge);
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case OtaState::OTA_STATE_BEGIN:
|
case OtaState::OTA_STATE_BEGIN:
|
||||||
displayExecuteOta(state, fwNewVersion, 0);
|
displayExecuteOta(state, fwNewVersion, 0);
|
||||||
@ -511,7 +526,7 @@ static void displayExecuteOta(OtaState state, String msg, int processing) {
|
|||||||
switch (state) {
|
switch (state) {
|
||||||
case OtaState::OTA_STATE_BEGIN: {
|
case OtaState::OTA_STATE_BEGIN: {
|
||||||
if (ag->isOne()) {
|
if (ag->isOne()) {
|
||||||
oledDisplay.showNewFirmwareVersion(msg);
|
oledDisplay.showFirmwareUpdateVersion(msg);
|
||||||
} else {
|
} else {
|
||||||
Serial.println("New firmware: " + msg);
|
Serial.println("New firmware: " + msg);
|
||||||
}
|
}
|
||||||
@ -520,7 +535,7 @@ static void displayExecuteOta(OtaState state, String msg, int processing) {
|
|||||||
}
|
}
|
||||||
case OtaState::OTA_STATE_FAIL: {
|
case OtaState::OTA_STATE_FAIL: {
|
||||||
if (ag->isOne()) {
|
if (ag->isOne()) {
|
||||||
oledDisplay.showNewFirmwareFailed();
|
oledDisplay.showFirmwareUpdateFailed();
|
||||||
} else {
|
} else {
|
||||||
Serial.println("Error: Firmware update: failed");
|
Serial.println("Error: Firmware update: failed");
|
||||||
}
|
}
|
||||||
@ -528,9 +543,29 @@ static void displayExecuteOta(OtaState state, String msg, int processing) {
|
|||||||
delay(2500);
|
delay(2500);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case OtaState::OTA_STATE_SKIP: {
|
||||||
|
if (ag->isOne()) {
|
||||||
|
oledDisplay.showFirmwareUpdateSkipped();
|
||||||
|
} else {
|
||||||
|
Serial.println("Firmware update: Skipped");
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(2500);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OtaState::OTA_STATE_UP_TO_DATE: {
|
||||||
|
if (ag->isOne()) {
|
||||||
|
oledDisplay.showFirmwareUpdateUpToDate();
|
||||||
|
} else {
|
||||||
|
Serial.println("Firmware update: up to date");
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(2500);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case OtaState::OTA_STATE_PROCESSING: {
|
case OtaState::OTA_STATE_PROCESSING: {
|
||||||
if (ag->isOne()) {
|
if (ag->isOne()) {
|
||||||
oledDisplay.showNewFirmwareUpdating(String(processing));
|
oledDisplay.showFirmwareUpdateProgress(processing);
|
||||||
} else {
|
} else {
|
||||||
Serial.println("Firmware update: " + String(processing) + String("%"));
|
Serial.println("Firmware update: " + String(processing) + String("%"));
|
||||||
}
|
}
|
||||||
@ -546,13 +581,14 @@ static void displayExecuteOta(OtaState state, String msg, int processing) {
|
|||||||
while (i != 0) {
|
while (i != 0) {
|
||||||
i = i - 1;
|
i = i - 1;
|
||||||
if (ag->isOne()) {
|
if (ag->isOne()) {
|
||||||
oledDisplay.showNewFirmwareSuccess(String(i));
|
oledDisplay.showFirmwareUpdateSuccess(i);
|
||||||
} else {
|
} else {
|
||||||
Serial.println("Rebooting... " + String(i));
|
Serial.println("Rebooting... " + String(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
delay(1000);
|
delay(1000);
|
||||||
}
|
}
|
||||||
|
oledDisplay.setBrightness(0);
|
||||||
esp_restart();
|
esp_restart();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -641,6 +677,24 @@ static void oneIndoorInit(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Check for button to reset WiFi connecto to "airgraident" after test LED
|
||||||
|
* bar */
|
||||||
|
if (ledBarButtonTest) {
|
||||||
|
if (ag->button.getState() == ag->button.BUTTON_PRESSED) {
|
||||||
|
WiFi.begin("airgradient", "cleanair");
|
||||||
|
oledDisplay.setText("Configure WiFi", "connect to", "\'airgradient\'");
|
||||||
|
delay(2500);
|
||||||
|
oledDisplay.setText("Rebooting...", "","");
|
||||||
|
delay(2500);
|
||||||
|
oledDisplay.setText("","","");
|
||||||
|
ESP.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ledBarEnabledUpdate();
|
||||||
|
|
||||||
|
/** Show message init sensor */
|
||||||
|
oledDisplay.setText("Sensor", "initializing...", "");
|
||||||
|
|
||||||
/** Init sensor SGP41 */
|
/** Init sensor SGP41 */
|
||||||
if (sgp41Init() == false) {
|
if (sgp41Init() == false) {
|
||||||
dispSensorNotFound("SGP41");
|
dispSensorNotFound("SGP41");
|
||||||
@ -881,32 +935,6 @@ static void configUpdateHandle() {
|
|||||||
stateMachine.executeLedBarTest();
|
stateMachine.executeLedBarTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
fwNewVersion = configuration.newFirmwareVersion();
|
|
||||||
if (fwNewVersion.length()) {
|
|
||||||
bool doOta = false;
|
|
||||||
if (measurements.otaBootCount == 0) {
|
|
||||||
doOta = true;
|
|
||||||
Serial.println("First OTA");
|
|
||||||
} else {
|
|
||||||
/** Only check for update each 1h*/
|
|
||||||
const float otaBootCount = 60.0f / (SERVER_SYNC_INTERVAL / 60000.0f);
|
|
||||||
if ((measurements.bootCount - measurements.otaBootCount) >= (int)otaBootCount) {
|
|
||||||
doOta = true;
|
|
||||||
} else {
|
|
||||||
Serial.println(
|
|
||||||
"OTA ignore, try again next " +
|
|
||||||
String(30 - (measurements.bootCount - measurements.otaBootCount)) +
|
|
||||||
String(" boots"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (doOta) {
|
|
||||||
measurements.otaBootCount = measurements.bootCount;
|
|
||||||
otaHandler.setHandlerCallback(otaHandlerCallback);
|
|
||||||
otaHandler.updateFirmwareIfOutdated(ag->deviceId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
appDispHandler();
|
appDispHandler();
|
||||||
appLedHandler();
|
appLedHandler();
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,8 @@ enum OtaUpdateOutcome {
|
|||||||
enum OtaState {
|
enum OtaState {
|
||||||
OTA_STATE_BEGIN,
|
OTA_STATE_BEGIN,
|
||||||
OTA_STATE_FAIL,
|
OTA_STATE_FAIL,
|
||||||
|
OTA_STATE_SKIP,
|
||||||
|
OTA_STATE_UP_TO_DATE,
|
||||||
OTA_STATE_PROCESSING,
|
OTA_STATE_PROCESSING,
|
||||||
OTA_STATE_SUCCESS
|
OTA_STATE_SUCCESS
|
||||||
};
|
};
|
||||||
@ -40,13 +42,22 @@ public:
|
|||||||
config.url = urlAsChar;
|
config.url = urlAsChar;
|
||||||
OtaUpdateOutcome ret = attemptToPerformOta(&config);
|
OtaUpdateOutcome ret = attemptToPerformOta(&config);
|
||||||
Serial.println(ret);
|
Serial.println(ret);
|
||||||
if (ret == OtaUpdateOutcome::UPDATE_PERFORMED) {
|
if (this->callback) {
|
||||||
if (this->callback) {
|
switch (ret) {
|
||||||
|
case OtaUpdateOutcome::UPDATE_PERFORMED:
|
||||||
this->callback(OtaState::OTA_STATE_SUCCESS, "");
|
this->callback(OtaState::OTA_STATE_SUCCESS, "");
|
||||||
}
|
break;
|
||||||
} else {
|
case OtaUpdateOutcome::UDPATE_SKIPPED:
|
||||||
if(this->callback) {
|
this->callback(OtaState::OTA_STATE_SKIP, "");
|
||||||
|
break;
|
||||||
|
case OtaUpdateOutcome::ALREADY_UP_TO_DATE:
|
||||||
|
this->callback(OtaState::OTA_STATE_UP_TO_DATE, "");
|
||||||
|
break;
|
||||||
|
case OtaUpdateOutcome::UPDATE_FAILED:
|
||||||
this->callback(OtaState::OTA_STATE_FAIL, "");
|
this->callback(OtaState::OTA_STATE_FAIL, "");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,6 +138,9 @@ private:
|
|||||||
int data_read =
|
int data_read =
|
||||||
esp_http_client_read(client, upgrade_data_buf, OTA_BUF_SIZE);
|
esp_http_client_read(client, upgrade_data_buf, OTA_BUF_SIZE);
|
||||||
if (data_read == 0) {
|
if (data_read == 0) {
|
||||||
|
if (this->callback) {
|
||||||
|
this->callback(OtaState::OTA_STATE_PROCESSING, String(100));
|
||||||
|
}
|
||||||
Serial.println("Connection closed, all data received");
|
Serial.println("Connection closed, all data received");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
name=AirGradient Air Quality Sensor
|
name=AirGradient Air Quality Sensor
|
||||||
version=3.1.0-beta.1
|
version=3.1.3
|
||||||
author=AirGradient <support@airgradient.com>
|
author=AirGradient <support@airgradient.com>
|
||||||
maintainer=AirGradient <support@airgradient.com>
|
maintainer=AirGradient <support@airgradient.com>
|
||||||
sentence=ESP32-C3 / ESP8266 library for air quality monitor measuring PM, CO2, Temperature, TVOC and Humidity with OLED display.
|
sentence=ESP32-C3 / ESP8266 library for air quality monitor measuring PM, CO2, Temperature, TVOC and Humidity with OLED display.
|
||||||
|
@ -330,7 +330,7 @@ void OledDisplay::setBrightness(int percent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OledDisplay::showNewFirmwareVersion(String version) {
|
void OledDisplay::showFirmwareUpdateVersion(String version) {
|
||||||
if (isDisplayOff) {
|
if (isDisplayOff) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -344,7 +344,7 @@ void OledDisplay::showNewFirmwareVersion(String version) {
|
|||||||
} while (DISP()->nextPage());
|
} while (DISP()->nextPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OledDisplay::showNewFirmwareUpdating(String percent) {
|
void OledDisplay::showFirmwareUpdateProgress(int percent) {
|
||||||
if (isDisplayOff) {
|
if (isDisplayOff) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -353,11 +353,11 @@ void OledDisplay::showNewFirmwareUpdating(String percent) {
|
|||||||
do {
|
do {
|
||||||
DISP()->setFont(u8g2_font_t0_16_tf);
|
DISP()->setFont(u8g2_font_t0_16_tf);
|
||||||
setCentralText(20, "Firmware Update");
|
setCentralText(20, "Firmware Update");
|
||||||
setCentralText(50, String("Updating... ") + percent + String("%"));
|
setCentralText(50, String("Updating... ") + String(percent) + String("%"));
|
||||||
} while (DISP()->nextPage());
|
} while (DISP()->nextPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OledDisplay::showNewFirmwareSuccess(String count) {
|
void OledDisplay::showFirmwareUpdateSuccess(int count) {
|
||||||
if (isDisplayOff) {
|
if (isDisplayOff) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -367,11 +367,11 @@ void OledDisplay::showNewFirmwareSuccess(String count) {
|
|||||||
DISP()->setFont(u8g2_font_t0_16_tf);
|
DISP()->setFont(u8g2_font_t0_16_tf);
|
||||||
setCentralText(20, "Firmware Update");
|
setCentralText(20, "Firmware Update");
|
||||||
setCentralText(40, "Success");
|
setCentralText(40, "Success");
|
||||||
setCentralText(60, String("Rebooting... ") + count);
|
setCentralText(60, String("Rebooting... ") + String(count));
|
||||||
} while (DISP()->nextPage());
|
} while (DISP()->nextPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OledDisplay::showNewFirmwareFailed(void) {
|
void OledDisplay::showFirmwareUpdateFailed(void) {
|
||||||
if (isDisplayOff) {
|
if (isDisplayOff) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -380,8 +380,34 @@ void OledDisplay::showNewFirmwareFailed(void) {
|
|||||||
do {
|
do {
|
||||||
DISP()->setFont(u8g2_font_t0_16_tf);
|
DISP()->setFont(u8g2_font_t0_16_tf);
|
||||||
setCentralText(20, "Firmware Update");
|
setCentralText(20, "Firmware Update");
|
||||||
setCentralText(40, "Failed");
|
setCentralText(40, "fail, will retry");
|
||||||
setCentralText(60, String("Retry after 24h"));
|
// setCentralText(60, "will retry");
|
||||||
|
} while (DISP()->nextPage());
|
||||||
|
}
|
||||||
|
|
||||||
|
void OledDisplay::showFirmwareUpdateSkipped(void) {
|
||||||
|
if (isDisplayOff) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DISP()->firstPage();
|
||||||
|
do {
|
||||||
|
DISP()->setFont(u8g2_font_t0_16_tf);
|
||||||
|
setCentralText(20, "Firmware Update");
|
||||||
|
setCentralText(40, "skipped");
|
||||||
|
} while (DISP()->nextPage());
|
||||||
|
}
|
||||||
|
|
||||||
|
void OledDisplay::showFirmwareUpdateUpToDate(void) {
|
||||||
|
if (isDisplayOff) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DISP()->firstPage();
|
||||||
|
do {
|
||||||
|
DISP()->setFont(u8g2_font_t0_16_tf);
|
||||||
|
setCentralText(20, "Firmware Update");
|
||||||
|
setCentralText(40, "up to date");
|
||||||
} while (DISP()->nextPage());
|
} while (DISP()->nextPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,10 +36,12 @@ public:
|
|||||||
void showDashboard(void);
|
void showDashboard(void);
|
||||||
void showDashboard(const char *status);
|
void showDashboard(const char *status);
|
||||||
void setBrightness(int percent);
|
void setBrightness(int percent);
|
||||||
void showNewFirmwareVersion(String version);
|
void showFirmwareUpdateVersion(String version);
|
||||||
void showNewFirmwareUpdating(String percent);
|
void showFirmwareUpdateProgress(int percent);
|
||||||
void showNewFirmwareSuccess(String count);
|
void showFirmwareUpdateSuccess(int count);
|
||||||
void showNewFirmwareFailed(void);
|
void showFirmwareUpdateFailed(void);
|
||||||
|
void showFirmwareUpdateSkipped(void);
|
||||||
|
void showFirmwareUpdateUpToDate(void);
|
||||||
void showRebooting(void);
|
void showRebooting(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -174,6 +174,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
root["boot"] = bootCount;
|
root["boot"] = bootCount;
|
||||||
|
root["bootCount"] = bootCount;
|
||||||
|
|
||||||
if (localServer) {
|
if (localServer) {
|
||||||
root["ledMode"] = config->getLedBarModeName();
|
root["ledMode"] = config->getLedBarModeName();
|
||||||
|
@ -69,7 +69,6 @@ public:
|
|||||||
int countPosition;
|
int countPosition;
|
||||||
const int targetCount = 20;
|
const int targetCount = 20;
|
||||||
int bootCount;
|
int bootCount;
|
||||||
int otaBootCount;
|
|
||||||
|
|
||||||
String toString(bool isLocal, AgFirmwareMode fwMode, int rssi, void* _ag, void* _config);
|
String toString(bool isLocal, AgFirmwareMode fwMode, int rssi, void* _ag, void* _config);
|
||||||
};
|
};
|
||||||
|
@ -53,6 +53,7 @@ bool WifiConnector::connect(void) {
|
|||||||
WIFI()->setAPCallback([this](WiFiManager *obj) { _wifiApCallback(); });
|
WIFI()->setAPCallback([this](WiFiManager *obj) { _wifiApCallback(); });
|
||||||
WIFI()->setSaveConfigCallback([this]() { _wifiSaveConfig(); });
|
WIFI()->setSaveConfigCallback([this]() { _wifiSaveConfig(); });
|
||||||
WIFI()->setSaveParamsCallback([this]() { _wifiSaveParamCallback(); });
|
WIFI()->setSaveParamsCallback([this]() { _wifiSaveParamCallback(); });
|
||||||
|
WIFI()->setConfigPortalTimeoutCallback([this](){});
|
||||||
if (ag->isOne()) {
|
if (ag->isOne()) {
|
||||||
disp.setText("Connecting to", "WiFi", "...");
|
disp.setText("Connecting to", "WiFi", "...");
|
||||||
} else {
|
} else {
|
||||||
@ -245,6 +246,7 @@ void WifiConnector::_wifiSaveParamCallback(void) {
|
|||||||
bool WifiConnector::_wifiConfigPortalActive(void) {
|
bool WifiConnector::_wifiConfigPortalActive(void) {
|
||||||
return WIFI()->getConfigPortalActive();
|
return WIFI()->getConfigPortalActive();
|
||||||
}
|
}
|
||||||
|
void WifiConnector::_wifiTimeoutCallback(void) { connectorTimeout = true; }
|
||||||
#endif
|
#endif
|
||||||
/**
|
/**
|
||||||
* @brief Process WiFiManager connection
|
* @brief Process WiFiManager connection
|
||||||
@ -352,3 +354,11 @@ bool WifiConnector::hasConfigurated(void) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get WiFi connection porttal timeout.
|
||||||
|
*
|
||||||
|
* @return true
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
|
bool WifiConnector::isConfigurePorttalTimeout(void) { return connectorTimeout; }
|
||||||
|
@ -24,6 +24,7 @@ private:
|
|||||||
bool hasConfig;
|
bool hasConfig;
|
||||||
uint32_t lastRetry;
|
uint32_t lastRetry;
|
||||||
bool hasPortalConfig = false;
|
bool hasPortalConfig = false;
|
||||||
|
bool connectorTimeout = false;
|
||||||
|
|
||||||
bool wifiClientConnected(void);
|
bool wifiClientConnected(void);
|
||||||
|
|
||||||
@ -44,6 +45,7 @@ public:
|
|||||||
void _wifiSaveConfig(void);
|
void _wifiSaveConfig(void);
|
||||||
void _wifiSaveParamCallback(void);
|
void _wifiSaveParamCallback(void);
|
||||||
bool _wifiConfigPortalActive(void);
|
bool _wifiConfigPortalActive(void);
|
||||||
|
void _wifiTimeoutCallback(void);
|
||||||
#endif
|
#endif
|
||||||
void _wifiProcess();
|
void _wifiProcess();
|
||||||
bool isConnected(void);
|
bool isConnected(void);
|
||||||
@ -51,6 +53,7 @@ public:
|
|||||||
int RSSI(void);
|
int RSSI(void);
|
||||||
String localIpStr(void);
|
String localIpStr(void);
|
||||||
bool hasConfigurated(void);
|
bool hasConfigurated(void);
|
||||||
|
bool isConfigurePorttalTimeout(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /** _AG_WIFI_CONNECTOR_H_ */
|
#endif /** _AG_WIFI_CONNECTOR_H_ */
|
||||||
|
Reference in New Issue
Block a user