Compare commits

..

44 Commits
3.3.7 ... 3.4.1

Author SHA1 Message Date
Samuel Siburian
23f8c383fd Merge pull request #345 from airgradienthq/feat/print-s8-info
Print S8 sensor information
2025-10-02 19:22:22 +07:00
samuelbles07
c0ad1dbfad Print S8 sensor information 2025-10-02 19:18:59 +07:00
Samuel Siburian
75be7d9fc5 Merge pull request #342 from mtlynch/no-trailing-spaces
Eliminate trailing whitespace
2025-09-25 13:45:11 +07:00
Samuel Siburian
309d322100 Merge pull request #343 from sysboy/typo-fix-failuire
Simple typo fix
2025-09-25 11:37:54 +07:00
Steve
89ebe6c39f Simple typo fix 2025-09-23 15:40:36 +01:00
Michael Lynch
29db5469f5 Eliminate trailing whitespace 2025-09-17 20:06:50 -04:00
Samuel Siburian
5802cf17f6 Merge pull request #328 from MallocArray/patch-3
Correct Yellow and Orange LED colors
2025-09-15 19:58:19 +07:00
Samuel Siburian
4a4ce89f00 Merge pull request #340 from airgradienthq/release-information
Add release information section on README
2025-09-15 13:15:42 +07:00
samuelbles07
8985e08a00 fix link typo 2025-09-15 13:05:19 +07:00
samuelbles07
e984aced18 Add release process 2025-09-15 13:03:28 +07:00
samuelbles07
73edf56c97 Fix points to how to compile documents 2025-09-15 13:03:16 +07:00
samuelbles07
e54c62a2ef Merge remote-tracking branch 'origin/develop' into develop 2025-09-12 14:34:50 +07:00
samuelbles07
5c95f011e4 Fix typo in openmetrics 2025-09-12 14:33:36 +07:00
Samuel Siburian
bed448e7d6 Merge pull request #289 from hestiahacker/contributing_improvements
docs: added some details about how to compile and contribute changes upstream
2025-09-03 15:53:17 +07:00
Samuel Siburian
eb8378adfa Merge pull request #338 from Adrien-P/fix/mqtt-with-auth-connected-flag
fix: ensure connected flag set for both authenticated connections.
2025-08-19 10:03:47 +07:00
Adrien-P
f94ed5c5f5 fix: ensure connected flag set for both authenticated connections. 2025-08-18 19:33:30 +02:00
Samuel Siburian
9471f3e323 Merge pull request #337 from mtlynch/fix-js-example
Fix JSON example in /config docs
2025-08-14 01:45:50 +07:00
Samuel Siburian
e6d90372c2 Merge pull request #336 from mtlynch/link-docs
Link to inner docs pages from main README
2025-08-14 01:45:05 +07:00
Michael Lynch
fabf0550fc Fix JSON example in /config docs
The JSON example has an extra closing brace, causing the JSON to be invalid. The fix is to remove the stray closing brace.
2025-08-12 20:45:41 -04:00
Michael Lynch
ce0af5bf60 Link to inner docs pages from main README
Fixes #335

There's useful documentation in the docs/ directory, but it's hard for users to discover it, as there are no links to it.

This change updates the README to add links to the inner docs pages for users interested in customizing and re-flashing firmware onto their devices as well as understanding the OTA update system.
2025-08-12 20:08:29 -04:00
Samuel Siburian
93bdbd85d5 Merge pull request #333 from airgradienthq/feat/support-2g
Support 2G fallback for CE network options
2025-08-01 12:03:45 +07:00
samuelbles07
29f583f20d Fix compile error for esp8266 env 2025-08-01 11:59:41 +07:00
samuelbles07
0f6a2fe908 Bump airgradient-client 2025-08-01 11:54:11 +07:00
Samuel Siburian
e3ce2c41be Merge pull request #332 from airgradienthq/fix/post-time-resolution
Fix post measures time resolutions closer to 1 second
2025-07-28 11:47:53 +07:00
samuelbles07
92b3c69b98 Decrease network task iteration delay
Position post measure first before get configuration
2025-07-26 18:23:04 +07:00
samuelbles07
f4d518aa87 Fix agschedule anon function call order 2025-07-26 18:22:30 +07:00
Samuel Siburian
831c844c24 Merge pull request #330 from airgradienthq/feat/post-ccid
Provide SIM card ICCID when performing ota update
2025-06-20 17:38:22 +07:00
samuelbles07
060a7f6815 Provide iccid when checking if firmware update available 2025-06-20 01:08:46 +07:00
samuelbles07
d8eb6b3c1a Prepare release 3.3.9 2025-06-18 14:25:14 +07:00
MallocArray
77859bea22 Correct Yellow and Orange LED colors 2025-06-16 20:38:19 -05:00
Samuel Siburian
969858b5cb Merge pull request #324 from airgradienthq/fix/comms-ag-server
Post measures and fetch configuration on boot only if respective configuration is set
2025-06-10 01:29:58 +07:00
samuelbles07
09b5805686 Apply brightness 2025-06-10 01:26:29 +07:00
samuelbles07
b09b753339 Only send first measures on boot if postDataToAirgradient is enabled 2025-06-10 01:10:14 +07:00
samuelbles07
ddb3dba131 Skip fetch configuration on boot when configuration control is local 2025-06-10 01:09:53 +07:00
Samuel Siburian
e780b0ace6 Merge pull request #323 from airgradienthq/fix/local-config-update
Update configuration changes by callback
2025-06-09 02:21:07 +07:00
samuelbles07
e82da5401e Add new flag for command request
Such as led bar test and co2 calibration test
2025-06-09 02:13:32 +07:00
samuelbles07
50a98acde4 Update configuration changes to main by callback 2025-06-06 04:10:53 +07:00
samuelbles07
7049d21a41 Prepare release 3.3.8 2025-05-14 13:09:12 +07:00
samuelbles07
d5cdeaa9f3 Fix print average function schedule
if pms value invalid show the channel
2025-05-14 13:01:23 +07:00
Samuel Siburian
09207c6923 Merge pull request #319 from airgradienthq/fix/resizing-queue
Fix resizing measurement queue after post by cellular post
2025-05-14 12:53:07 +07:00
samuelbles07
0a64424196 add show content delay for display brightness 2025-05-14 12:39:42 +07:00
hestiahacker
21b9ddb2ed Improved contribution instructions
Improved wording suggested by @Iroxxar
2025-05-11 01:10:25 -05:00
hestia
1ee05da5d1 docs: added some details about how to compile and contribute changes upstream 2025-05-11 01:10:22 -05:00
samuelbles07
626a2240fa Fix resizing queue after success post
This fix should be make it more consistent
2025-05-09 15:45:53 +07:00
36 changed files with 266 additions and 177 deletions

View File

@@ -1,5 +1,36 @@
on: [push, pull_request] on: [push, pull_request]
jobs: jobs:
trailing-whitespace:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4.2.2
with:
fetch-depth: 0
- name: Check for trailing whitespace
run: |
set -u
# Don't enforce checks on vendored libraries.
readonly EXCLUDED_DIR='src/Libraries'
has_trailing_whitespace=false
while read -r line; do
if grep \
"\s$" \
--line-number \
--with-filename \
--binary-files=without-match \
"${line}"; then
has_trailing_whitespace=true
fi
done < <(git ls-files | grep --invert-match "^${EXCLUDED_DIR}/")
if [ "$has_trailing_whitespace" = true ]; then
echo "ERROR: Found trailing whitespace"
exit 1
fi
compile: compile:
strategy: strategy:
fail-fast: false fail-fast: false

View File

@@ -20,13 +20,32 @@ Make sure you have exactly the versions of libraries and boards installed as des
If you have an older version of the AirGradient PCB not mentioned in the example files, please downgrade this library to version 2.4.15 to support these legacy boards. If you have an older version of the AirGradient PCB not mentioned in the example files, please downgrade this library to version 2.4.15 to support these legacy boards.
### Release Process
Releases published on GitHub are **not immediately deployed to all devices in the market**. Each release first goes through internal testing, including limited deployments in select locations to verify stability and functionality.
If the tests pass, the firmware is then made available for:
- **FOTA (Firmware Over-The-Air) updates** from AirGradient dashboard
- **Manual flashing** via [Airgradient](https://www.airgradient.com/documentation/firmwares/) website
Each GitHub release note will also include the planned rollout date for wider availability.
## Help & Support ## Help & Support
If you have any questions or problems, check out [our forum](https://forum.airgradient.com/). If you have any questions or problems, check out [our forum](https://forum.airgradient.com/).
## Documentation ## Development
Local server API documentation is available in [/docs/local-server.md](/docs/local-server.md) and AirGradient server API on [https://api.airgradient.com/public/docs/api/v1/](https://api.airgradient.com/public/docs/api/v1/). * See [compilation instructions](/docs/howto-compile.md) for details about how to customize AirGradient's firmware and flash it to your device.
## Over the air (OTA) updates
* See the [OTA Updates documentation](/docs/ota-updates.md) for details about how AirGradient monitors receive over the air updates.
## API documentation
* [Local server API documentation](/docs/local-server.md)
* [AirGradient Cloud server API documentation](https://api.airgradient.com/public/docs/api/v1/).
## The following libraries have been integrated into this library for ease of use ## The following libraries have been integrated into this library for ease of use

View File

@@ -90,7 +90,7 @@ Choose based on how python installed on your machine. But most user, using `apt`
## How to contribute ## How to contribute
The instructions above are the instructions for how to build an official release of the AirGradient firmware using the Arduino IDE. If you intend to make changes that will you intent to contribute back to the main project, instead of installing the AirGradient library, check out the repo at `Documents/Arduino/libraries` (for Windows and Mac), or `~/Arduino/Libraries` (Linux). If you installed the library, you can remove it from the library manager in the Arduino IDE, or just delete the directory. The instructions above are the instructions for how to build an official release of the AirGradient firmware using the Arduino IDE. If you intend to make changes which you plan to contribute back to the main project, instead of installing the AirGradient library, check out the repository at Documents/Arduino/libraries (for Windows and Mac) or ~/Arduino/libraries (for Linux). If you installed the library, you can remove it from the library manager in the Arduino IDE, or just delete the directory.
**NOTE:** When cloning the repository, for version >= 3.3.0 it has submodule, please use `--recursive` flag like this: `git clone --recursive https://github.com/airgradienthq/arduino.git AirGradient_Air_Quality_Sensor` **NOTE:** When cloning the repository, for version >= 3.3.0 it has submodule, please use `--recursive` flag like this: `git clone --recursive https://github.com/airgradienthq/arduino.git AirGradient_Air_Quality_Sensor`
@@ -100,6 +100,3 @@ There are 2 environment options to compile this project, PlatformIO and ArduinoI
- For PlatformIO, it should work out of the box - For PlatformIO, it should work out of the box
- For arduino, files in `src` folder and also from `Examples` can be modified at `Documents/Arduino/libraries` for Windows and Mac, and `~/Arduino/Libraries` for Linux - For arduino, files in `src` folder and also from `Examples` can be modified at `Documents/Arduino/libraries` for Windows and Mac, and `~/Arduino/Libraries` for Linux

View File

@@ -106,7 +106,6 @@ Compensated values apply correction algorithms to make the sensor values more ac
"pm02": { "pm02": {
"correctionAlgorithm": "epa_2021", "correctionAlgorithm": "epa_2021",
"slr": {} "slr": {}
}
} }
} }
} }

View File

@@ -294,7 +294,7 @@ static bool sgp41Init(void) {
configuration.hasSensorSGP = true; configuration.hasSensorSGP = true;
return true; return true;
} else { } else {
Serial.println("Init SGP41 failuire"); Serial.println("Init SGP41 failure");
configuration.hasSensorSGP = false; configuration.hasSensorSGP = false;
} }
return false; return false;

View File

@@ -351,7 +351,7 @@ static bool sgp41Init(void) {
configuration.hasSensorSGP = true; configuration.hasSensorSGP = true;
return true; return true;
} else { } else {
Serial.println("Init SGP41 failuire"); Serial.println("Init SGP41 failure");
configuration.hasSensorSGP = false; configuration.hasSensorSGP = false;
} }
return false; return false;

View File

@@ -374,7 +374,7 @@ static bool sgp41Init(void) {
configuration.hasSensorSGP = true; configuration.hasSensorSGP = true;
return true; return true;
} else { } else {
Serial.println("Init SGP41 failuire"); Serial.println("Init SGP41 failure");
configuration.hasSensorSGP = false; configuration.hasSensorSGP = false;
} }
return false; return false;

View File

@@ -193,6 +193,7 @@ void setup() {
/** Initialize local configure */ /** Initialize local configure */
configuration.begin(); configuration.begin();
configuration.setConfigurationUpdatedCallback(configUpdateHandle);
/** Init I2C */ /** Init I2C */
Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN); Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN);
@@ -270,6 +271,7 @@ void setup() {
Serial.println("Display brightness: " + String(configuration.getDisplayBrightness())); Serial.println("Display brightness: " + String(configuration.getDisplayBrightness()));
oledDisplay.setBrightness(configuration.getDisplayBrightness()); oledDisplay.setBrightness(configuration.getDisplayBrightness());
delay(DISPLAY_DELAY_SHOW_CONTENT_MS);
} }
@@ -369,8 +371,11 @@ void loop() {
/** factory reset handle */ /** factory reset handle */
factoryConfigReset(); factoryConfigReset();
/** check that local configuration changed then do some action */ if (configuration.isCommandRequested()) {
configUpdateHandle(); // Each state machine already has an independent request command check
stateMachine.executeCo2Calibration();
stateMachine.executeLedBarTest();
}
} }
static void co2Update(void) { static void co2Update(void) {
@@ -554,7 +559,7 @@ static bool sgp41Init(void) {
configuration.hasSensorSGP = true; configuration.hasSensorSGP = true;
return true; return true;
} else { } else {
Serial.println("Init SGP41 failuire"); Serial.println("Init SGP41 failure");
configuration.hasSensorSGP = false; configuration.hasSensorSGP = false;
} }
return false; return false;
@@ -570,7 +575,7 @@ void checkForFirmwareUpdate(void) {
if (networkOption == UseWifi) { if (networkOption == UseWifi) {
agOta = new AirgradientOTAWifi; agOta = new AirgradientOTAWifi;
} else { } else {
agOta = new AirgradientOTACellular(cellularCard); agOta = new AirgradientOTACellular(cellularCard, agClient->getICCID());
} }
// Indicate main task that firmware update is in progress // Indicate main task that firmware update is in progress
@@ -947,6 +952,8 @@ static void boardInit(void) {
} else { } else {
Serial.println("Set S8 AbcDays failure"); Serial.println("Set S8 AbcDays failure");
} }
ag->s8.printInformation();
} }
localServer.setFwMode(fwMode); localServer.setFwMode(fwMode);
@@ -1038,10 +1045,17 @@ void initializeNetwork() {
return; return;
} }
// Send data for the first time to AG server at boot // Send data for the first time to AG server at boot only if postDataToAirgradient is enabled
sendDataToAg(); if (configuration.isPostDataToAirGradient()) {
sendDataToAg();
}
} }
// Skip fetch configuration if configuration control is set to "local" only
if (configuration.getConfigurationControl() == ConfigurationControl::ConfigurationControlLocal) {
ledBarEnabledUpdate();
return;
}
std::string config = agClient->httpFetchConfig(); std::string config = agClient->httpFetchConfig();
configSchedule.update(); configSchedule.update();
@@ -1073,8 +1087,8 @@ static void configurationUpdateSchedule(void) {
} }
std::string config = agClient->httpFetchConfig(); std::string config = agClient->httpFetchConfig();
if (agClient->isLastFetchConfigSucceed() && configuration.parse(config.c_str(), false)) { if (agClient->isLastFetchConfigSucceed()) {
configUpdateHandle(); configuration.parse(config.c_str(), false);
} }
} }
@@ -1083,8 +1097,6 @@ static void configUpdateHandle() {
return; return;
} }
stateMachine.executeCo2Calibration();
String mqttUri = configuration.getMqttBrokerUri(); String mqttUri = configuration.getMqttBrokerUri();
if (mqttClient.isCurrentUri(mqttUri) == false) { if (mqttClient.isCurrentUri(mqttUri) == false) {
mqttClient.end(); mqttClient.end();
@@ -1156,11 +1168,6 @@ static void configUpdateHandle() {
if (configuration.isDisplayBrightnessChanged()) { if (configuration.isDisplayBrightnessChanged()) {
oledDisplay.setBrightness(configuration.getDisplayBrightness()); oledDisplay.setBrightness(configuration.getDisplayBrightness());
} }
stateMachine.executeLedBarTest();
}
else if(ag->isOpenAir()) {
stateMachine.executeLedBarTest();
} }
// Update display and led bar notification based on updated configuration // Update display and led bar notification based on updated configuration
@@ -1428,13 +1435,17 @@ void postUsingCellular(bool forcePost) {
// Post success, remove the data that previously sent from queue // Post success, remove the data that previously sent from queue
xSemaphoreTake(mutexMeasurementCycleQueue, portMAX_DELAY); xSemaphoreTake(mutexMeasurementCycleQueue, portMAX_DELAY);
measurementCycleQueue.erase(measurementCycleQueue.begin(),
measurementCycleQueue.begin() + queueSize);
if (measurementCycleQueue.capacity() > RESERVED_MEASUREMENT_CYCLE_CAPACITY) { if (measurementCycleQueue.capacity() > RESERVED_MEASUREMENT_CYCLE_CAPACITY) {
Serial.println("measurementCycleQueue capacity more than reserved space, resizing.."); Serial.println("measurementCycleQueue capacity more than reserved space, resizing..");
measurementCycleQueue.resize(RESERVED_MEASUREMENT_CYCLE_CAPACITY); std::vector<Measurements::Measures> tmp;
tmp.reserve(RESERVED_MEASUREMENT_CYCLE_CAPACITY);
measurementCycleQueue.swap(tmp);
} else {
// If not more than the capacity, then just clear all the values
measurementCycleQueue.clear();
} }
xSemaphoreGive(mutexMeasurementCycleQueue); xSemaphoreGive(mutexMeasurementCycleQueue);
} }
@@ -1655,11 +1666,11 @@ void networkingTask(void *args) {
// Run scheduler // Run scheduler
networkSignalCheckSchedule.run(); networkSignalCheckSchedule.run();
configSchedule.run();
transmissionSchedule.run(); transmissionSchedule.run();
configSchedule.run();
checkForUpdateSchedule.run(); checkForUpdateSchedule.run();
delay(1000); delay(50);
} }
vTaskDelete(handleNetworkTask); vTaskDelete(handleNetworkTask);

View File

@@ -202,14 +202,14 @@ String OpenMetrics::getPayload(void) {
} }
if (utils::isValidNOx(nox)) { if (utils::isValidNOx(nox)) {
add_metric("nox_index", add_metric("nox_index",
"The processed Nitrous Oxide (NOx) index as measured by the " "The processed Nitrogen Oxide (NOx) index as measured by the "
"AirGradient SGP sensor", "AirGradient SGP sensor",
"gauge"); "gauge");
add_metric_point("", String(nox)); add_metric_point("", String(nox));
} }
if (utils::isValidNOx(noxRaw)) { if (utils::isValidNOx(noxRaw)) {
add_metric("nox_raw", add_metric("nox_raw",
"The raw input value to the Nitrous Oxide (NOx) index as " "The raw input value to the Nitrogen Oxide (NOx) index as "
"measured by the AirGradient SGP sensor", "measured by the AirGradient SGP sensor",
"gauge"); "gauge");
add_metric_point("", String(noxRaw)); add_metric_point("", String(noxRaw));

View File

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

View File

@@ -456,6 +456,10 @@ bool Configuration::begin(void) {
return true; return true;
} }
void Configuration::setConfigurationUpdatedCallback(ConfigurationUpdatedCallback_t callback) {
_callback = callback;
}
/** /**
* @brief Parse JSON configura string to local configure * @brief Parse JSON configura string to local configure
* *
@@ -951,15 +955,18 @@ bool Configuration::parse(String data, bool isLocal) {
changed = true; changed = true;
} }
if (ledBarTestRequested || co2CalibrationRequested) {
commandRequested = true;
updated = true;
}
if (changed) { if (changed) {
updated = true; updated = true;
saveConfig(); saveConfig();
printConfig(); printConfig();
} else { _callback();
if (ledBarTestRequested || co2CalibrationRequested) {
updated = true;
}
} }
return true; return true;
} }
@@ -1159,6 +1166,12 @@ bool Configuration::isUpdated(void) {
return updated; return updated;
} }
bool Configuration::isCommandRequested(void) {
bool oldState = this->commandRequested;
this->commandRequested = false;
return oldState;
}
String Configuration::jsonTypeInvalidMessage(String name, String type) { String Configuration::jsonTypeInvalidMessage(String name, String type) {
return "'" + name + "' type is invalid, expecting '" + type + "'"; return "'" + name + "' type is invalid, expecting '" + type + "'";
} }

View File

@@ -28,6 +28,7 @@ private:
bool co2CalibrationRequested; bool co2CalibrationRequested;
bool ledBarTestRequested; bool ledBarTestRequested;
bool updated; bool updated;
bool commandRequested = false;
String failedMessage; String failedMessage;
bool _noxLearnOffsetChanged; bool _noxLearnOffsetChanged;
bool _tvocLearningOffsetChanged; bool _tvocLearningOffsetChanged;
@@ -70,6 +71,9 @@ public:
bool hasSensorSGP = true; bool hasSensorSGP = true;
bool hasSensorSHT = true; bool hasSensorSHT = true;
typedef void (*ConfigurationUpdatedCallback_t)();
void setConfigurationUpdatedCallback(ConfigurationUpdatedCallback_t callback);
bool begin(void); bool begin(void);
bool parse(String data, bool isLocal); bool parse(String data, bool isLocal);
String toString(void); String toString(void);
@@ -90,6 +94,7 @@ public:
void reset(void); void reset(void);
String getModel(void); String getModel(void);
bool isUpdated(void); bool isUpdated(void);
bool isCommandRequested(void);
String getFailedMesage(void); String getFailedMesage(void);
void setPostToAirGradient(bool enable); void setPostToAirGradient(bool enable);
bool noxLearnOffsetChanged(void); bool noxLearnOffsetChanged(void);
@@ -116,6 +121,8 @@ public:
PMCorrection getPMCorrection(void); PMCorrection getPMCorrection(void);
TempHumCorrection getTempCorrection(void); TempHumCorrection getTempCorrection(void);
TempHumCorrection getHumCorrection(void); TempHumCorrection getHumCorrection(void);
private:
ConfigurationUpdatedCallback_t _callback;
}; };
#endif /** _AG_CONFIG_H_ */ #endif /** _AG_CONFIG_H_ */

View File

@@ -8,8 +8,8 @@ AgSchedule::~AgSchedule() {}
void AgSchedule::run(void) { void AgSchedule::run(void) {
uint32_t ms = (uint32_t)(millis() - count); uint32_t ms = (uint32_t)(millis() - count);
if (ms >= period) { if (ms >= period) {
handler();
count = millis(); count = millis();
handler();
} }
} }

View File

@@ -11,8 +11,8 @@
#define RGB_COLOR_R 255, 0, 0 /** Red */ #define RGB_COLOR_R 255, 0, 0 /** Red */
#define RGB_COLOR_G 0, 255, 0 /** Green */ #define RGB_COLOR_G 0, 255, 0 /** Green */
#define RGB_COLOR_Y 255, 150, 0 /** Yellow */ #define RGB_COLOR_Y 255, 255, 0 /** Yellow */
#define RGB_COLOR_O 255, 40, 0 /** Orange */ #define RGB_COLOR_O 255, 128, 0 /** Orange */
#define RGB_COLOR_P 180, 0, 255 /** Purple */ #define RGB_COLOR_P 180, 0, 255 /** Purple */
#define RGB_COLOR_CLEAR 0, 0, 0 /** No color */ #define RGB_COLOR_CLEAR 0, 0, 0 /** No color */

View File

@@ -656,59 +656,59 @@ void Measurements::printCurrentPMAverage(int ch) {
if (utils::isValidPm(_pm_01[idx].update.avg)) { if (utils::isValidPm(_pm_01[idx].update.avg)) {
Serial.printf("[%d] Atmospheric PM 1.0 = %.2f ug/m3\n", ch, _pm_01[idx].update.avg); Serial.printf("[%d] Atmospheric PM 1.0 = %.2f ug/m3\n", ch, _pm_01[idx].update.avg);
} else { } else {
Serial.printf("[%d] Atmospheric PM 1.0 = -\n"); Serial.printf("[%d] Atmospheric PM 1.0 = -\n", ch);
} }
if (utils::isValidPm(_pm_25[idx].update.avg)) { if (utils::isValidPm(_pm_25[idx].update.avg)) {
Serial.printf("[%d] Atmospheric PM 2.5 = %.2f ug/m3\n", ch, _pm_25[idx].update.avg); Serial.printf("[%d] Atmospheric PM 2.5 = %.2f ug/m3\n", ch, _pm_25[idx].update.avg);
} else { } else {
Serial.printf("[%d] Atmospheric PM 2.5 = -\n"); Serial.printf("[%d] Atmospheric PM 2.5 = -\n", ch);
} }
if (utils::isValidPm(_pm_10[idx].update.avg)) { if (utils::isValidPm(_pm_10[idx].update.avg)) {
Serial.printf("[%d] Atmospheric PM 10 = %.2f ug/m3\n", ch, _pm_10[idx].update.avg); Serial.printf("[%d] Atmospheric PM 10 = %.2f ug/m3\n", ch, _pm_10[idx].update.avg);
} else { } else {
Serial.printf("[%d] Atmospheric PM 10 = -\n"); Serial.printf("[%d] Atmospheric PM 10 = -\n", ch);
} }
if (utils::isValidPm(_pm_01_sp[idx].update.avg)) { if (utils::isValidPm(_pm_01_sp[idx].update.avg)) {
Serial.printf("[%d] Standard Particle PM 1.0 = %.2f ug/m3\n", ch, _pm_01_sp[idx].update.avg); Serial.printf("[%d] Standard Particle PM 1.0 = %.2f ug/m3\n", ch, _pm_01_sp[idx].update.avg);
} else { } else {
Serial.printf("[%d] Standard Particle PM 1.0 = -\n"); Serial.printf("[%d] Standard Particle PM 1.0 = -\n", ch);
} }
if (utils::isValidPm(_pm_25_sp[idx].update.avg)) { if (utils::isValidPm(_pm_25_sp[idx].update.avg)) {
Serial.printf("[%d] Standard Particle PM 2.5 = %.2f ug/m3\n", ch, _pm_25_sp[idx].update.avg); Serial.printf("[%d] Standard Particle PM 2.5 = %.2f ug/m3\n", ch, _pm_25_sp[idx].update.avg);
} else { } else {
Serial.printf("[%d] Standard Particle PM 2.5 = -\n"); Serial.printf("[%d] Standard Particle PM 2.5 = -\n", ch);
} }
if (utils::isValidPm(_pm_10_sp[idx].update.avg)) { if (utils::isValidPm(_pm_10_sp[idx].update.avg)) {
Serial.printf("[%d] Standard Particle PM 10 = %.2f ug/m3\n", ch, _pm_10_sp[idx].update.avg); Serial.printf("[%d] Standard Particle PM 10 = %.2f ug/m3\n", ch, _pm_10_sp[idx].update.avg);
} else { } else {
Serial.printf("[%d] Standard Particle PM 10 = -\n"); Serial.printf("[%d] Standard Particle PM 10 = -\n", ch);
} }
if (utils::isValidPm03Count(_pm_03_pc[idx].update.avg)) { if (utils::isValidPm03Count(_pm_03_pc[idx].update.avg)) {
Serial.printf("[%d] Particle Count 0.3 = %.1f\n", ch, _pm_03_pc[idx].update.avg); Serial.printf("[%d] Particle Count 0.3 = %.1f\n", ch, _pm_03_pc[idx].update.avg);
} else { } else {
Serial.printf("[%d] Particle Count 0.3 = -\n"); Serial.printf("[%d] Particle Count 0.3 = -\n", ch);
} }
if (utils::isValidPm03Count(_pm_05_pc[idx].update.avg)) { if (utils::isValidPm03Count(_pm_05_pc[idx].update.avg)) {
Serial.printf("[%d] Particle Count 0.5 = %.1f\n", ch, _pm_05_pc[idx].update.avg); Serial.printf("[%d] Particle Count 0.5 = %.1f\n", ch, _pm_05_pc[idx].update.avg);
} else { } else {
Serial.printf("[%d] Particle Count 0.5 = -\n"); Serial.printf("[%d] Particle Count 0.5 = -\n", ch);
} }
if (utils::isValidPm03Count(_pm_01_pc[idx].update.avg)) { if (utils::isValidPm03Count(_pm_01_pc[idx].update.avg)) {
Serial.printf("[%d] Particle Count 1.0 = %.1f\n", ch, _pm_01_pc[idx].update.avg); Serial.printf("[%d] Particle Count 1.0 = %.1f\n", ch, _pm_01_pc[idx].update.avg);
} else { } else {
Serial.printf("[%d] Particle Count 1.0 = -\n"); Serial.printf("[%d] Particle Count 1.0 = -\n", ch);
} }
if (utils::isValidPm03Count(_pm_25_pc[idx].update.avg)) { if (utils::isValidPm03Count(_pm_25_pc[idx].update.avg)) {
Serial.printf("[%d] Particle Count 2.5 = %.1f\n", ch, _pm_25_pc[idx].update.avg); Serial.printf("[%d] Particle Count 2.5 = %.1f\n", ch, _pm_25_pc[idx].update.avg);
} else { } else {
Serial.printf("[%d] Particle Count 2.5 = -\n"); Serial.printf("[%d] Particle Count 2.5 = -\n", ch);
} }
if (_pm_5_pc[idx].listValues.empty() == false) { if (_pm_5_pc[idx].listValues.empty() == false) {
if (utils::isValidPm03Count(_pm_5_pc[idx].update.avg)) { if (utils::isValidPm03Count(_pm_5_pc[idx].update.avg)) {
Serial.printf("[%d] Particle Count 5.0 = %.1f\n", ch, _pm_5_pc[idx].update.avg); Serial.printf("[%d] Particle Count 5.0 = %.1f\n", ch, _pm_5_pc[idx].update.avg);
} else { } else {
Serial.printf("[%d] Particle Count 5.0 = -\n"); Serial.printf("[%d] Particle Count 5.0 = -\n", ch);
} }
} }
@@ -716,7 +716,7 @@ void Measurements::printCurrentPMAverage(int ch) {
if (utils::isValidPm03Count(_pm_10_pc[idx].update.avg)) { if (utils::isValidPm03Count(_pm_10_pc[idx].update.avg)) {
Serial.printf("[%d] Particle Count 10 = %.1f\n", ch, _pm_10_pc[idx].update.avg); Serial.printf("[%d] Particle Count 10 = %.1f\n", ch, _pm_10_pc[idx].update.avg);
} else { } else {
Serial.printf("[%d] Particle Count 10 = -\n"); Serial.printf("[%d] Particle Count 10 = -\n", ch);
} }
} }
} }

View File

@@ -15,7 +15,7 @@
#include "Main/utils.h" #include "Main/utils.h"
#ifndef GIT_VERSION #ifndef GIT_VERSION
#define GIT_VERSION "3.3.7-snap" #define GIT_VERSION "3.3.9-snap"
#endif #endif

View File

@@ -260,13 +260,14 @@ bool MqttClient::connect(String id) {
connected = false; connected = false;
if (user.isEmpty()) { if (user.isEmpty()) {
logInfo("Connect without auth"); logInfo("Connect without auth");
if(CLIENT()->connect(id.c_str())) { connected = CLIENT()->connect(id.c_str());
connected = true; } else {
} logInfo("Connect with auth");
return connected; connected = CLIENT()->connect(id.c_str(), user.c_str(), password.c_str());
} }
return CLIENT()->connect(id.c_str(), user.c_str(), password.c_str()); return connected;
} }
void MqttClient::handle(void) { void MqttClient::handle(void) {
if (isBegin == false) { if (isBegin == false) {
return; return;

View File

@@ -835,3 +835,13 @@ bool S8::setAbcPeriod(int hours) {
* @return int Hour * @return int Hour
*/ */
int S8::getAbcPeriod(void) { return getCalibPeriodABC(); } int S8::getAbcPeriod(void) { return getCalibPeriodABC(); }
void S8::printInformation(void) {
Serial.print("S8 type ID: 0x");
Serial.println(getSensorTypeId(), HEX);
Serial.print("S8 serial number: 0x");
Serial.println(getSensorId(), HEX);
Serial.print("S8 memory map version: 0x");
Serial.println(getMemoryMapVersion(), HEX);
}

View File

@@ -80,6 +80,7 @@ public:
bool isBaseLineCalibrationDone(void); bool isBaseLineCalibrationDone(void);
bool setAbcPeriod(int hours); bool setAbcPeriod(int hours);
int getAbcPeriod(void); int getAbcPeriod(void);
void printInformation(void);
private: private:
/** Variables */ /** Variables */