Compare commits

..

24 Commits
3.1.6 ... 3.1.8

Author SHA1 Message Date
fd2cef153e Merge pull request #239 from airgradienthq/hotfix/led-bar-show-pm-status
Fix: Correct LED bar show PM status
2024-09-17 10:25:42 +07:00
507b958fdf Correct LED bar show PM value use compensate 2024-09-17 10:15:47 +07:00
335c29ebb1 Merge remote-tracking branch 'origin/develop' into hotfix/led-bar-show-pm-status 2024-09-17 10:01:58 +07:00
2907d6f14e Merge pull request #238 from airgradienthq/hotfix/PM-compensation-receiving-temperature-instead-of-RH
Fix pm compensation: receiving temperature instead of humidity
2024-09-17 09:44:50 +07:00
c8d5b546ed correct PM compensate the input argument value humidity instead of temperature, fix #234 2024-09-16 14:52:04 +07:00
b7cfdc4c4d Update AirGradient.h to v 3.1.8 2024-09-16 12:47:50 +07:00
994d281e02 Update Version to 3.1.8 2024-09-16 12:47:08 +07:00
39470384e4 Merge pull request #233 from airgradienthq/cubic-PM2009X
Changed PM initialization to also support the Cubic PM2009X
2024-09-16 12:08:18 +07:00
c25ba764bf Merge pull request #236 from airgradienthq/add-log-pms-version-code
Add log: PMS5003x sensor print log firmware version
2024-09-16 11:02:32 +07:00
826ff00f42 add log message PM sensor firmware version 2024-09-16 10:36:45 +07:00
520550037d Explicitly set active mode for PM sensor upon initialization 2024-09-15 08:26:38 +07:00
90f336dee7 Revert "Explicitly set active mode for PM sensor upon initialization"
This reverts commit 0d39643e76.
2024-09-15 08:23:32 +07:00
0d39643e76 Explicitly set active mode for PM sensor upon initialization 2024-09-15 08:22:50 +07:00
b7339de31f Merge pull request #232 from samuelbles07/feat/ag-client-timeout
Feat/ag-client-timeout
2024-09-12 15:06:23 +07:00
013fb94307 Only for tcp timeout
Ignoring connect to server timeout
2024-09-11 16:37:50 +07:00
e16373a64d Add new public member to set http client timeout by caller 2024-09-11 16:02:13 +07:00
f929623443 Fix uri formatting postToServer to use apiRoot 2024-09-11 16:01:16 +07:00
59587ce2b7 Add http request timeout number for ApiClient 2024-09-11 15:48:44 +07:00
9ec74450a5 Merge branch 'master' into develop 2024-09-02 19:56:46 +07:00
28096e9faf Update version to 3.1.7 2024-09-02 19:55:16 +07:00
682378a47c Merge pull request #231 from airgradienthq/develop
Add WiFi feature
2024-09-02 19:53:33 +07:00
a1861be7b7 Merge pull request #230 from airgradienthq/feature/wifi-connect-to-default
Add default WiFi connect
2024-09-02 19:50:47 +07:00
99ddd24432 Merge branch 'develop' into feature/wifi-connect-to-default 2024-09-02 19:44:53 +07:00
03e2afbf54 WiFi Connect to default airgradient if WiFi connected is empty 2024-08-26 15:47:49 +07:00
16 changed files with 103 additions and 41 deletions

View File

@ -513,6 +513,7 @@ static void updatePm(void) {
Serial.printf("PM2.5 ug/m3: %d\r\n", measurements.pm25_1);
Serial.printf("PM10 ug/m3: %d\r\n", measurements.pm10_1);
Serial.printf("PM0.3 Count: %d\r\n", measurements.pm03PCount_1);
Serial.printf("PM firmware version: %d\r\n", ag.pms5003.getFirmwareVersion());
ag.pms5003.resetFailCount();
} else {
ag.pms5003.updateFailCount();

View File

@ -565,6 +565,7 @@ static void updatePm(void) {
Serial.printf("PM2.5 ug/m3: %d\r\n", measurements.pm25_1);
Serial.printf("PM10 ug/m3: %d\r\n", measurements.pm10_1);
Serial.printf("PM0.3 Count: %d\r\n", measurements.pm03PCount_1);
Serial.printf("PM firmware version: %d\r\n", ag.pms5003.getFirmwareVersion());
ag.pms5003.resetFailCount();
} else {
ag.pms5003.updateFailCount();

View File

@ -327,9 +327,7 @@ static void factoryConfigReset(void) {
// }
/** Reset WIFI */
// WiFi.enableSTA(true); // Incase offline mode
// WiFi.disconnect(true, true);
wifiConnector.reset();
WiFi.disconnect(true, true);
/** Reset local config */
configuration.reset();
@ -608,6 +606,7 @@ static void updatePm(void) {
Serial.printf("PM2.5 ug/m3: %d\r\n", measurements.pm25_1);
Serial.printf("PM10 ug/m3: %d\r\n", measurements.pm10_1);
Serial.printf("PM0.3 Count: %d\r\n", measurements.pm03PCount_1);
Serial.printf("PM firmware version: %d\r\n", ag.pms5003.getFirmwareVersion());
ag.pms5003.resetFailCount();
} else {
ag.pms5003.updateFailCount();

View File

@ -423,8 +423,7 @@ static void factoryConfigReset(void) {
}
/** Reset WIFI */
Serial.println("Set wifi connect to 'airgradient' as default");
WiFi.begin("airgradient", "cleanair");
WiFi.disconnect(true, true);
/** Reset local config */
configuration.reset();
@ -698,7 +697,7 @@ static void oneIndoorInit(void) {
ledBarEnabledUpdate();
/** Show message init sensor */
oledDisplay.setText("Sensor", "initializing...", "");
oledDisplay.setText("Monitor", "initializing...", "");
/** Init sensor SGP41 */
if (sgp41Init() == false) {
@ -779,27 +778,27 @@ static void openAirInit(void) {
}
}
/** Try to find the PMS on other difference port with S8 */
/** Attempt to detect PM sensors */
if (fwMode == FW_MODE_O_1PST) {
bool pmInitSuccess = false;
if (serial0Available) {
if (ag->pms5003t_1.begin(Serial0) == false) {
configuration.hasSensorPMS1 = false;
Serial.println("PMS1 sensor not found");
Serial.println("No PM sensor detected on Serial0");
} else {
serial0Available = false;
pmInitSuccess = true;
Serial.println("Found PMS 1 on Serial0");
Serial.println("Detected PM 1 on Serial0");
}
}
if (pmInitSuccess == false) {
if (serial1Available) {
if (ag->pms5003t_1.begin(Serial1) == false) {
configuration.hasSensorPMS1 = false;
Serial.println("PMS1 sensor not found");
Serial.println("No PM sensor detected on Serial1");
} else {
serial1Available = false;
Serial.println("Found PMS 1 on Serial1");
Serial.println("Detected PM 1 on Serial1");
}
}
}
@ -807,15 +806,15 @@ static void openAirInit(void) {
} else {
if (ag->pms5003t_1.begin(Serial0) == false) {
configuration.hasSensorPMS1 = false;
Serial.println("PMS1 sensor not found");
Serial.println("No PM sensor detected on Serial0");
} else {
Serial.println("Found PMS 1 on Serial0");
Serial.println("Detected PM 1 on Serial0");
}
if (ag->pms5003t_2.begin(Serial1) == false) {
configuration.hasSensorPMS2 = false;
Serial.println("PMS2 sensor not found");
Serial.println("No PM sensor detected on Serial1");
} else {
Serial.println("Found PMS 2 on Serial1");
Serial.println("Detected PM 2 on Serial1");
}
if (fwMode == FW_MODE_O_1PP) {
@ -1021,10 +1020,11 @@ static void updatePm(void) {
Serial.printf("PM2.5 ug/m3: %d\r\n", measurements.pm25_1);
Serial.printf("PM10 ug/m3: %d\r\n", measurements.pm10_1);
Serial.printf("PM0.3 Count: %d\r\n", measurements.pm03PCount_1);
Serial.printf("PM firmware version: %d\r\n", ag->pms5003.getFirmwareVersion());
ag->pms5003.resetFailCount();
} else {
ag->pms5003.updateFailCount();
Serial.printf("PMS read faile %d times\r\n", ag->pms5003.getFailCount());
Serial.printf("PMS read failed %d times\r\n", ag->pms5003.getFailCount());
if (ag->pms5003.getFailCount() >= PMS_FAIL_COUNT_SET_INVALID) {
measurements.pm01_1 = utils::getInvalidPmValue();
measurements.pm25_1 = utils::getInvalidPmValue();
@ -1060,6 +1060,7 @@ static void updatePm(void) {
ag->pms5003t_1.compensateTemp(measurements.temp_1));
Serial.printf("[1] Relative Humidity compensated: %0.2f\r\n",
ag->pms5003t_1.compensateHum(measurements.hum_1));
Serial.printf("[1] PM firmware version: %d\r\n", ag->pms5003t_1.getFirmwareVersion());
ag->pms5003t_1.resetFailCount();
} else {
@ -1103,6 +1104,7 @@ static void updatePm(void) {
ag->pms5003t_1.compensateTemp(measurements.temp_2));
Serial.printf("[2] Relative Humidity compensated: %0.2f\r\n",
ag->pms5003t_1.compensateHum(measurements.hum_2));
Serial.printf("[2] PM firmware version: %d\r\n", ag->pms5003t_2.getFirmwareVersion());
ag->pms5003t_2.resetFailCount();
} else {

View File

@ -1,5 +1,5 @@
name=AirGradient Air Quality Sensor
version=3.1.6
version=3.1.8
author=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.

View File

@ -58,6 +58,7 @@ bool AgApiClient::fetchServerConfiguration(void) {
}
#else
HTTPClient client;
client.setTimeout(timeoutMs);
if (client.begin(uri) == false) {
getConfigFailed = true;
return false;
@ -113,14 +114,13 @@ bool AgApiClient::postToServer(String data) {
return false;
}
String uri =
"http://hw.airgradient.com/sensors/airgradient:" + ag->deviceId() +
"/measures";
String uri = apiRoot + "/sensors/airgradient:" + ag->deviceId() + "/measures";
// logInfo("Post uri: " + uri);
// logInfo("Post data: " + data);
WiFiClient wifiClient;
HTTPClient client;
client.setTimeout(timeoutMs);
if (client.begin(wifiClient, uri.c_str()) == false) {
logError("Init client failed");
return false;
@ -190,3 +190,12 @@ bool AgApiClient::sendPing(int rssi, int bootCount) {
String AgApiClient::getApiRoot() const { return apiRoot; }
void AgApiClient::setApiRoot(const String &apiRoot) { this->apiRoot = apiRoot; }
/**
* @brief Set http request timeout. (Default: 10s)
*
* @param timeoutMs
*/
void AgApiClient::setTimeout(uint16_t timeoutMs) {
this->timeoutMs = timeoutMs;
}

View File

@ -25,6 +25,7 @@ private:
bool getConfigFailed;
bool postToServerFailed;
bool notAvailableOnDashboard = false; // Device not setup on Airgradient cloud dashboard.
uint16_t timeoutMs = 10000; // Default set to 10s
public:
AgApiClient(Stream &stream, Configuration &config);
@ -40,6 +41,7 @@ public:
bool sendPing(int rssi, int bootCount);
String getApiRoot() const;
void setApiRoot(const String &apiRoot);
void setTimeout(uint16_t timeoutMs);
};
#endif /** _AG_API_CLIENT_H_ */

View File

@ -519,7 +519,7 @@ void OledDisplay::showRebooting(void) {
do {
DISP()->setFont(u8g2_font_t0_16_tf);
// setCentralText(20, "Firmware Update");
setCentralText(40, "Reboot...");
setCentralText(40, "Rebooting...");
// setCentralText(60, String("Retry after 24h"));
} while (DISP()->nextPage());
} else if (ag->isBasic()) {

View File

@ -141,7 +141,7 @@ void StateMachine::co2handleLeds(void) {
*
*/
void StateMachine::pm25handleLeds(void) {
int pm25Value = value.pm25_1;
int pm25Value = ag->pms5003.compensate(value.pm25_1, value.Humidity);
if (pm25Value < 5) {
/** G; 1 */
ag->ledBar.setColor(RGB_COLOR_G, ag->ledBar.getNumberOfLeds() - 1);

View File

@ -130,8 +130,8 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
}
}
int pm25 = (ag->pms5003t_1.compensate(this->pm25_1, this->temp_1) +
ag->pms5003t_2.compensate(this->pm25_2, this->temp_2)) /
int pm25 = (ag->pms5003t_1.compensate(this->pm25_1, this->hum_1) +
ag->pms5003t_2.compensate(this->pm25_2, this->hum_2)) /
2;
root["pm02Compensated"] = pm25;
}
@ -171,7 +171,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
}
}
}
root["pm02Compensated"] = ag->pms5003t_1.compensate(this->pm25_1, this->temp_1);
root["pm02Compensated"] = ag->pms5003t_1.compensate(this->pm25_1, this->hum_1);
if (!localServer) {
root[json_prop_pmFirmware] =
pms5003TFirmwareVersion(ag->pms5003t_1.getFirmwareVersion());
@ -212,7 +212,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
}
}
}
root["pm02Compensated"] = ag->pms5003t_2.compensate(this->pm25_2, this->temp_2);
root["pm02Compensated"] = ag->pms5003t_2.compensate(this->pm25_2, this->hum_2);
if(!localServer) {
root[json_prop_pmFirmware] =
pms5003TFirmwareVersion(ag->pms5003t_1.getFirmwareVersion());
@ -253,7 +253,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
}
}
}
root["pm02Compensated"] = ag->pms5003t_1.compensate(this->pm25_1, this->temp_1);
root["pm02Compensated"] = ag->pms5003t_1.compensate(this->pm25_1, this->hum_1);
if(!localServer) {
root[json_prop_pmFirmware] =
pms5003TFirmwareVersion(ag->pms5003t_1.getFirmwareVersion());
@ -291,7 +291,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
}
}
}
root["pm02Compensated"] = ag->pms5003t_1.compensate(this->pm25_1, this->temp_1);
root["pm02Compensated"] = ag->pms5003t_1.compensate(this->pm25_1, this->hum_1);
if(!localServer) {
root[json_prop_pmFirmware] =
pms5003TFirmwareVersion(ag->pms5003t_2.getFirmwareVersion());
@ -332,7 +332,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
}
}
}
root["channels"]["1"]["pm02Compensated"] = ag->pms5003t_1.compensate(this->pm25_1, this->temp_1);
root["channels"]["1"]["pm02Compensated"] = ag->pms5003t_1.compensate(this->pm25_1, this->hum_1);
// PMS5003T version
if(!localServer) {
@ -374,7 +374,7 @@ String Measurements::toString(bool localServer, AgFirmwareMode fwMode, int rssi,
}
}
}
root["channels"]["2"]["pm02Compensated"] = ag->pms5003t_2.compensate(this->pm25_2, this->temp_2);
root["channels"]["2"]["pm02Compensated"] = ag->pms5003t_2.compensate(this->pm25_2, this->hum_2);
// PMS5003T version
if(!localServer) {
root["channels"]["2"][json_prop_pmFirmware] =

View File

@ -41,6 +41,28 @@ bool WifiConnector::connect(void) {
}
}
WiFi.begin();
String wifiSSID = WIFI()->getWiFiSSID(true);
if (wifiSSID.isEmpty()) {
logInfo("Connected WiFi is empty, connect to default wifi \"" +
String(this->defaultSsid) + String("\""));
/** Set wifi connect */
WiFi.begin(this->defaultSsid, this->defaultPassword);
/** Wait for wifi connect to AP */
int count = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
count++;
if (count >= 15) {
logError("Try connect to default wifi \"" + String(this->defaultSsid) +
String("\" failed"));
break;
}
}
}
WIFI()->setConfigPortalBlocking(false);
WIFI()->setConnectTimeout(15);
WIFI()->setTimeout(WIFI_CONNECT_COUNTDOWN_MAX);
@ -50,7 +72,7 @@ bool WifiConnector::connect(void) {
WIFI()->setSaveParamsCallback([this]() { _wifiSaveParamCallback(); });
WIFI()->setConfigPortalTimeoutCallback([this]() {_wifiTimeoutCallback();});
if (ag->isOne() || (ag->isPro4_2()) || ag->isPro3_3() || ag->isBasic()) {
disp.setText("Connect to", "WiFi", "...");
disp.setText("Connecting to", "WiFi", "...");
} else {
logInfo("Connecting to WiFi...");
}
@ -383,3 +405,11 @@ bool WifiConnector::hasConfigurated(void) {
* @return false
*/
bool WifiConnector::isConfigurePorttalTimeout(void) { return connectorTimeout; }
/**
* @brief Set wifi connect to default WiFi
*
*/
void WifiConnector::setDefault(void) {
WiFi.begin("airgradient", "cleanair");
}

View File

@ -46,6 +46,10 @@ public:
String localIpStr(void);
bool hasConfigurated(void);
bool isConfigurePorttalTimeout(void);
const char* defaultSsid = "airgradient";
const char* defaultPassword = "cleanair";
void setDefault(void);
};
#endif /** _AG_WIFI_CONNECTOR_H_ */

View File

@ -15,7 +15,7 @@
#include "Main/utils.h"
#ifndef GIT_VERSION
#define GIT_VERSION "3.1.6-snap"
#define GIT_VERSION "3.1.8-snap"
#endif
/**

View File

@ -2,34 +2,48 @@
#include "../Main/BoardDef.h"
/**
* @brief Init and check that sensor has connected
* @brief Initializes the sensor and attempts to read data.
*
* @param stream UART stream
* @return true Sucecss
* @return false Failure
*/
bool PMSBase::begin(Stream *stream) {
Serial.printf("initializing PM sensor\n");
this->stream = stream;
failed = true;
failCount = 0;
lastRead = 0; // To read buffer on handle without wait after 1.5sec
this->stream->flush();
// empty first
int bytesCleared = 0;
while (this->stream->read() != -1) {
bytesCleared++;
}
Serial.printf("cleared %d byte(s)\n", bytesCleared);
// explicitly put the sensor into active mode, this seems to be be needed for the Cubic PM2009X
Serial.printf("setting active mode\n");
uint8_t activeModeCommand[] = { 0x42, 0x4D, 0xE1, 0x00, 0x01, 0x01, 0x71 };
size_t bytesWritten = this->stream->write(activeModeCommand, sizeof(activeModeCommand));
Serial.printf("%d byte(s) written\n", bytesWritten);
// Run and check sensor data for 4sec
while (1) {
handle();
if (failed == false) {
return true;
Serial.printf("PM sensor initialized\n");
return true;
}
delay(1);
delay(10);
uint32_t ms = (uint32_t)(millis() - lastRead);
if (ms >= 4000) {
break;
}
}
Serial.printf("PM sensor initialization failed\n");
return false;
}

View File

@ -5,6 +5,9 @@
#define PMS_FAIL_COUNT_SET_INVALID 3
/**
* Known to work with these sensors: Plantower PMS5003, Plantower PMS5003, Cubic PM2009X
*/
class PMSBase {
public:
bool begin(Stream *stream);

View File

@ -38,14 +38,11 @@ bool PMS5003::begin(HardwareSerial &serial) {
PMS5003::PMS5003(BoardType def) : _boardDef(def) {}
/**
* @brief Init sensor
*
* @return true Success
* @return false Failure
* Initializes the sensor.
*/
bool PMS5003::begin(void) {
if (this->_isBegin) {
AgLog("Initialized, call end() then try again");
AgLog("Already initialized, call end() then try again");
return true;
}