mirror of
https://github.com/airgradienthq/arduino.git
synced 2025-09-25 12:10:56 +02:00
Merge pull request #342 from mtlynch/no-trailing-spaces
Eliminate trailing whitespace
This commit is contained in:
31
.github/workflows/check.yml
vendored
31
.github/workflows/check.yml
vendored
@@ -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
|
||||||
|
@@ -32,7 +32,7 @@ Each GitHub release note will also include the planned rollout date for wider av
|
|||||||
|
|
||||||
## 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/).
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
|
@@ -16,15 +16,15 @@ Arduino IDE version 2.x ([download](https://www.arduino.cc/en/software))
|
|||||||
|
|
||||||
#### Version < 3.2.0
|
#### Version < 3.2.0
|
||||||
|
|
||||||
Using library manager install the latest version (Tools ➝ Manage Libraries... ➝ search for `"airgradient"`)
|
Using library manager install the latest version (Tools ➝ Manage Libraries... ➝ search for `"airgradient"`)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### Version >= 3.3.0
|
#### Version >= 3.3.0
|
||||||
|
|
||||||
- From your terminal, go to Arduino libraries folder (windows and mac: `Documents/Arduino/libraries` or linux: `~/Arduino/Libraries`).
|
- From your terminal, go to Arduino libraries folder (windows and mac: `Documents/Arduino/libraries` or linux: `~/Arduino/Libraries`).
|
||||||
- With **git** cli, execute this command `git clone --recursive https://github.com/airgradienthq/arduino.git AirGradient_Air_Quality_Sensor`
|
- With **git** cli, execute this command `git clone --recursive https://github.com/airgradienthq/arduino.git AirGradient_Air_Quality_Sensor`
|
||||||
- Restart Arduino IDE
|
- Restart Arduino IDE
|
||||||
|
|
||||||
3. On tools tab, follow settings below
|
3. On tools tab, follow settings below
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ Upload Speed ➝ 921600
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
3. Install AirGradient library on library manager using the latest version (Tools ➝ Manage Libraries... ➝ search for `"airgradient"`)
|
3. Install AirGradient library on library manager using the latest version (Tools ➝ Manage Libraries... ➝ search for `"airgradient"`)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ Upload Speed ➝ 921600
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
5. Open sketch to compile (File ➝ Examples ➝ AirGradient Air Quality Sensor ➝ `<Model Option>`). Depends on the DIY model, either `BASIC`, `DiyProIndoorV3_3` and `DiyProIndoorV4_2`
|
5. Open sketch to compile (File ➝ Examples ➝ AirGradient Air Quality Sensor ➝ `<Model Option>`). Depends on the DIY model, either `BASIC`, `DiyProIndoorV3_3` and `DiyProIndoorV4_2`
|
||||||
6. Compile
|
6. Compile
|
||||||
|
|
||||||

|

|
||||||
@@ -78,13 +78,13 @@ ModuleNotFoundError: No module named ‘serial’
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
Make sure python pyserial module installed globally in the environment by executing:
|
Make sure python pyserial module installed globally in the environment by executing:
|
||||||
|
|
||||||
`$ sudo apt install -y python3-pyserial`
|
`$ sudo apt install -y python3-pyserial`
|
||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
`$ pip install pyserial`
|
`$ pip install pyserial`
|
||||||
|
|
||||||
Choose based on how python installed on your machine. But most user, using `apt` is better.
|
Choose based on how python installed on your machine. But most user, using `apt` is better.
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
## Local Server API
|
## Local Server API
|
||||||
|
|
||||||
From [firmware version 3.0.10](firmwares) onwards, the AirGradient ONE and Open Air monitors have below API available.
|
From [firmware version 3.0.10](firmwares) onwards, the AirGradient ONE and Open Air monitors have below API available.
|
||||||
|
|
||||||
### Discovery
|
### Discovery
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ 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
|
```json
|
||||||
{
|
{
|
||||||
"wifi": -46,
|
"wifi": -46,
|
||||||
"serialno": "ecda3b1eaaaf",
|
"serialno": "ecda3b1eaaaf",
|
||||||
@@ -84,7 +84,7 @@ Compensated values apply correction algorithms to make the sensor values more ac
|
|||||||
|
|
||||||
"/config" path returns the current configuration of the monitor.
|
"/config" path returns the current configuration of the monitor.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"country": "TH",
|
"country": "TH",
|
||||||
"pmStandard": "ugm3",
|
"pmStandard": "ugm3",
|
||||||
@@ -118,22 +118,22 @@ Configuration parameters can be changed with a PUT request to the monitor, e.g.
|
|||||||
Example to force CO2 calibration
|
Example to force CO2 calibration
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
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 Celsius
|
Example to set monitor to Celsius
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
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
|
||||||
```
|
```
|
||||||
|
|
||||||
If you use command prompt on Windows, you need to escape the quotes:
|
If you use command prompt on Windows, you need to escape the quotes:
|
||||||
|
|
||||||
``` -d "{\"param\":\"value\"}" ```
|
``` -d "{\"param\":\"value\"}" ```
|
||||||
|
|
||||||
### Avoiding Conflicts with Configuration on AirGradient Server
|
### Avoiding Conflicts with Configuration on AirGradient Server
|
||||||
|
|
||||||
If the monitor is set up on the AirGradient dashboard, it will also receive the configuration parameters 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 the configuration parameters 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)
|
||||||
|
|
||||||
@@ -204,34 +204,34 @@ Example correction configuration:
|
|||||||
Field Name: `pm02`
|
Field Name: `pm02`
|
||||||
|
|
||||||
| Algorithm | Value | Description | SLR required |
|
| Algorithm | Value | Description | SLR required |
|
||||||
|------------|-------------|------|---------|
|
|------------|-------------|------|---------|
|
||||||
| Raw | `"none"` | No correction (default) | No |
|
| Raw | `"none"` | No correction (default) | No |
|
||||||
| EPA 2021 | `"epa_2021"` | Use EPA 2021 correction factors on top of raw value | No |
|
| EPA 2021 | `"epa_2021"` | Use EPA 2021 correction factors on top of raw value | No |
|
||||||
| PMS5003_20240104 | `"slr_PMS5003_20240104"` | Correction for PMS5003 sensor batch 20240104| Yes |
|
| PMS5003_20240104 | `"slr_PMS5003_20240104"` | Correction for PMS5003 sensor batch 20240104| Yes |
|
||||||
| PMS5003_20231218 | `"slr_PMS5003_20231218"` | Correction for PMS5003 sensor batch 20231218| Yes |
|
| PMS5003_20231218 | `"slr_PMS5003_20231218"` | Correction for PMS5003 sensor batch 20231218| Yes |
|
||||||
| PMS5003_20231030 | `"slr_PMS5003_20231030"` | Correction for PMS5003 sensor batch 20231030| Yes |
|
| PMS5003_20231030 | `"slr_PMS5003_20231030"` | Correction for PMS5003 sensor batch 20231030| Yes |
|
||||||
|
|
||||||
**NOTES**:
|
**NOTES**:
|
||||||
|
|
||||||
- Set `useEpa2021` to `true` if want to apply EPA 2021 correction factors on top of SLR correction value, otherwise `false`
|
- Set `useEpa2021` to `true` if want to apply EPA 2021 correction factors on top of SLR correction value, otherwise `false`
|
||||||
- `intercept` and `scalingFactor` values can be obtained from [this article](https://www.airgradient.com/blog/low-readings-from-pms5003/)
|
- `intercept` and `scalingFactor` values can be obtained from [this article](https://www.airgradient.com/blog/low-readings-from-pms5003/)
|
||||||
- If `configurationControl` is set to `local` (eg. when using Home Assistant), correction need to be set manually, see examples below
|
- If `configurationControl` is set to `local` (eg. when using Home Assistant), correction need to be set manually, see examples below
|
||||||
|
|
||||||
**Examples**:
|
**Examples**:
|
||||||
|
|
||||||
- PMS5003_20231030
|
- PMS5003_20231030
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl --location -X PUT 'http://airgradient_84fce612eff4.local/config' --header 'Content-Type: application/json' --data '{"corrections":{"pm02":{"correctionAlgorithm":"slr_PMS5003_20231030","slr":{"intercept":0,"scalingFactor":0.02838,"useEpa2021":true}}}}'
|
curl --location -X PUT 'http://airgradient_84fce612eff4.local/config' --header 'Content-Type: application/json' --data '{"corrections":{"pm02":{"correctionAlgorithm":"slr_PMS5003_20231030","slr":{"intercept":0,"scalingFactor":0.02838,"useEpa2021":true}}}}'
|
||||||
```
|
```
|
||||||
|
|
||||||
- PMS5003_20231218
|
- PMS5003_20231218
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl --location -X PUT 'http://airgradient_84fce612eff4.local/config' --header 'Content-Type: application/json' --data '{"corrections":{"pm02":{"correctionAlgorithm":"slr_PMS5003_20231218","slr":{"intercept":0,"scalingFactor":0.03525,"useEpa2021":true}}}}'
|
curl --location -X PUT 'http://airgradient_84fce612eff4.local/config' --header 'Content-Type: application/json' --data '{"corrections":{"pm02":{"correctionAlgorithm":"slr_PMS5003_20231218","slr":{"intercept":0,"scalingFactor":0.03525,"useEpa2021":true}}}}'
|
||||||
```
|
```
|
||||||
|
|
||||||
- PMS5003_20240104
|
- PMS5003_20240104
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl --location -X PUT 'http://airgradient_84fce612eff4.local/config' --header 'Content-Type: application/json' --data '{"corrections":{"pm02":{"correctionAlgorithm":"slr_PMS5003_20240104","slr":{"intercept":0,"scalingFactor":0.02896,"useEpa2021":true}}}}'
|
curl --location -X PUT 'http://airgradient_84fce612eff4.local/config' --header 'Content-Type: application/json' --data '{"corrections":{"pm02":{"correctionAlgorithm":"slr_PMS5003_20240104","slr":{"intercept":0,"scalingFactor":0.02896,"useEpa2021":true}}}}'
|
||||||
@@ -244,10 +244,10 @@ Field Name:
|
|||||||
- Humidity: `rhum`
|
- Humidity: `rhum`
|
||||||
|
|
||||||
| Algorithm | Value | Description | SLR required |
|
| Algorithm | Value | Description | SLR required |
|
||||||
|------------|-------------|------|---------|
|
|------------|-------------|------|---------|
|
||||||
| Raw | `"none"` | No correction (default) | No |
|
| Raw | `"none"` | No correction (default) | No |
|
||||||
| AirGradient Standard Correction | `"ag_pms5003t_2024"` | Using standard airgradient correction (for outdoor monitor)| No |
|
| AirGradient Standard Correction | `"ag_pms5003t_2024"` | Using standard airgradient correction (for outdoor monitor)| No |
|
||||||
| Custom | `"custom"` | custom corrections constant, set `intercept` and `scalingFactor` manually | Yes |
|
| Custom | `"custom"` | custom corrections constant, set `intercept` and `scalingFactor` manually | Yes |
|
||||||
|
|
||||||
*Table above apply for both Temperature and Humidity*
|
*Table above apply for both Temperature and Humidity*
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
## OTA Updates
|
## OTA Updates
|
||||||
|
|
||||||
From [firmware version 3.1.1](https://github.com/airgradienthq/arduino/tree/3.1.1) onwards, the AirGradient ONE and Open Air monitors support over the air (OTA) updates.
|
From [firmware version 3.1.1](https://github.com/airgradienthq/arduino/tree/3.1.1) onwards, the AirGradient ONE and Open Air monitors support over the air (OTA) updates.
|
||||||
|
|
||||||
#### Mechanism
|
#### Mechanism
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ The device attempts to update to the latest version on startup and in regular in
|
|||||||
|
|
||||||
http://hw.airgradient.com/sensors/{deviceId}/generic/os/firmware.bin?current_firmware={GIT_VERSION}
|
http://hw.airgradient.com/sensors/{deviceId}/generic/os/firmware.bin?current_firmware={GIT_VERSION}
|
||||||
|
|
||||||
If does pass the version it is currently running on along to the server through URL parameter 'current_firmware'.
|
If does pass the version it is currently running on along to the server through URL parameter 'current_firmware'.
|
||||||
This allows the server to identify if the device is already running on the latest version or should update.
|
This allows the server to identify if the device is already running on the latest version or should update.
|
||||||
|
|
||||||
The following scenarios are possible
|
The following scenarios are possible
|
||||||
|
@@ -249,7 +249,7 @@ void loop() {
|
|||||||
configUpdateHandle();
|
configUpdateHandle();
|
||||||
|
|
||||||
localServer._handle();
|
localServer._handle();
|
||||||
|
|
||||||
if (configuration.hasSensorSGP) {
|
if (configuration.hasSensorSGP) {
|
||||||
ag.sgp41.handle();
|
ag.sgp41.handle();
|
||||||
}
|
}
|
||||||
|
@@ -75,8 +75,8 @@ CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License
|
|||||||
#define SENSOR_TEMP_HUM_UPDATE_INTERVAL 6000 /** ms */
|
#define SENSOR_TEMP_HUM_UPDATE_INTERVAL 6000 /** 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 */
|
#define FIRMWARE_CHECK_FOR_UPDATE_MS (60 * 60 * 1000) /** ms */
|
||||||
#define TIME_TO_START_POWER_CYCLE_CELLULAR_MODULE (1 * 60) /** minutes */
|
#define TIME_TO_START_POWER_CYCLE_CELLULAR_MODULE (1 * 60) /** minutes */
|
||||||
#define TIMEOUT_WAIT_FOR_CELLULAR_MODULE_READY (2 * 60) /** minutes */
|
#define TIMEOUT_WAIT_FOR_CELLULAR_MODULE_READY (2 * 60) /** minutes */
|
||||||
|
|
||||||
#define MEASUREMENT_TRANSMIT_CYCLE 3
|
#define MEASUREMENT_TRANSMIT_CYCLE 3
|
||||||
#define MAXIMUM_MEASUREMENT_CYCLE_QUEUE 80
|
#define MAXIMUM_MEASUREMENT_CYCLE_QUEUE 80
|
||||||
@@ -123,7 +123,7 @@ static uint32_t factoryBtnPressTime = 0;
|
|||||||
static AgFirmwareMode fwMode = FW_MODE_I_9PSL;
|
static AgFirmwareMode fwMode = FW_MODE_I_9PSL;
|
||||||
static bool ledBarButtonTest = false;
|
static bool ledBarButtonTest = false;
|
||||||
static String fwNewVersion;
|
static String fwNewVersion;
|
||||||
static int lastCellSignalQuality = 99; // CSQ
|
static int lastCellSignalQuality = 99; // CSQ
|
||||||
|
|
||||||
// Default value is 0, indicate its not started yet
|
// Default value is 0, indicate its not started yet
|
||||||
// In minutes
|
// In minutes
|
||||||
@@ -136,7 +136,7 @@ static void boardInit(void);
|
|||||||
static void initializeNetwork();
|
static void initializeNetwork();
|
||||||
static void failedHandler(String msg);
|
static void failedHandler(String msg);
|
||||||
static void configurationUpdateSchedule(void);
|
static void configurationUpdateSchedule(void);
|
||||||
static void configUpdateHandle(void);
|
static void configUpdateHandle(void);
|
||||||
static void updateDisplayAndLedBar(void);
|
static void updateDisplayAndLedBar(void);
|
||||||
static void updateTvoc(void);
|
static void updateTvoc(void);
|
||||||
static void updatePm(void);
|
static void updatePm(void);
|
||||||
@@ -157,7 +157,7 @@ static void displayExecuteOta(AirgradientOTA::OtaResult result, String msg, int
|
|||||||
static int calculateMaxPeriod(int updateInterval);
|
static int calculateMaxPeriod(int updateInterval);
|
||||||
static void setMeasurementMaxPeriod();
|
static void setMeasurementMaxPeriod();
|
||||||
static void newMeasurementCycle();
|
static void newMeasurementCycle();
|
||||||
static void restartIfCeClientIssueOverTwoHours();
|
static void restartIfCeClientIssueOverTwoHours();
|
||||||
static void networkSignalCheck();
|
static void networkSignalCheck();
|
||||||
static void networkingTask(void *args);
|
static void networkingTask(void *args);
|
||||||
|
|
||||||
@@ -180,7 +180,7 @@ void setup() {
|
|||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
delay(100); /** For bester show log */
|
delay(100); /** For bester show log */
|
||||||
|
|
||||||
// Enable cullular module power board
|
// Enable cullular module power board
|
||||||
pinMode(GPIO_EXPANSION_CARD_POWER, OUTPUT);
|
pinMode(GPIO_EXPANSION_CARD_POWER, OUTPUT);
|
||||||
digitalWrite(GPIO_EXPANSION_CARD_POWER, HIGH);
|
digitalWrite(GPIO_EXPANSION_CARD_POWER, HIGH);
|
||||||
|
|
||||||
@@ -284,7 +284,7 @@ void setup() {
|
|||||||
// Queue now only applied for cellular
|
// Queue now only applied for cellular
|
||||||
// Allocate queue memory to avoid always reallocation
|
// Allocate queue memory to avoid always reallocation
|
||||||
measurementCycleQueue.reserve(RESERVED_MEASUREMENT_CYCLE_CAPACITY);
|
measurementCycleQueue.reserve(RESERVED_MEASUREMENT_CYCLE_CAPACITY);
|
||||||
// Initialize mutex to access mesurementCycleQueue
|
// Initialize mutex to access mesurementCycleQueue
|
||||||
mutexMeasurementCycleQueue = xSemaphoreCreateMutex();
|
mutexMeasurementCycleQueue = xSemaphoreCreateMutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,7 +312,7 @@ void setup() {
|
|||||||
void loop() {
|
void loop() {
|
||||||
if (networkOption == UseCellular) {
|
if (networkOption == UseCellular) {
|
||||||
// Check if cellular client not ready until certain time
|
// Check if cellular client not ready until certain time
|
||||||
// Redundant check in both task to make sure its executed
|
// Redundant check in both task to make sure its executed
|
||||||
restartIfCeClientIssueOverTwoHours();
|
restartIfCeClientIssueOverTwoHours();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -725,7 +725,7 @@ static void sendDataToAg() {
|
|||||||
"task_led", 2048, NULL, 5, NULL);
|
"task_led", 2048, NULL, 5, NULL);
|
||||||
|
|
||||||
delay(1500);
|
delay(1500);
|
||||||
|
|
||||||
// Build payload to check connection to airgradient server
|
// Build payload to check connection to airgradient server
|
||||||
JSONVar root;
|
JSONVar root;
|
||||||
root["wifi"] = wifiConnector.RSSI();
|
root["wifi"] = wifiConnector.RSSI();
|
||||||
@@ -970,7 +970,7 @@ void initializeNetwork() {
|
|||||||
agSerial->init(GPIO_IIC_RESET);
|
agSerial->init(GPIO_IIC_RESET);
|
||||||
if (agSerial->open()) {
|
if (agSerial->open()) {
|
||||||
Serial.println("Cellular module found");
|
Serial.println("Cellular module found");
|
||||||
// Initialize cellular module and use cellular as agClient
|
// Initialize cellular module and use cellular as agClient
|
||||||
cellularCard = new CellularModuleA7672XX(agSerial, GPIO_POWER_MODULE_PIN);
|
cellularCard = new CellularModuleA7672XX(agSerial, GPIO_POWER_MODULE_PIN);
|
||||||
agClient = new AirgradientCellularClient(cellularCard);
|
agClient = new AirgradientCellularClient(cellularCard);
|
||||||
networkOption = UseCellular;
|
networkOption = UseCellular;
|
||||||
@@ -984,7 +984,7 @@ void initializeNetwork() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (networkOption == UseCellular) {
|
if (networkOption == UseCellular) {
|
||||||
// Enable serial stream debugging to check the AT command when doing registration
|
// Enable serial stream debugging to check the AT command when doing registration
|
||||||
agSerial->setDebug(true);
|
agSerial->setDebug(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1005,7 +1005,7 @@ void initializeNetwork() {
|
|||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Provide openmetrics to have access to last transmission result
|
// Provide openmetrics to have access to last transmission result
|
||||||
openMetrics.setAirgradientClient(agClient);
|
openMetrics.setAirgradientClient(agClient);
|
||||||
|
|
||||||
if (networkOption == UseCellular) {
|
if (networkOption == UseCellular) {
|
||||||
@@ -1018,7 +1018,7 @@ void initializeNetwork() {
|
|||||||
Serial.println("Cannot initiate wifi connection");
|
Serial.println("Cannot initiate wifi connection");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wifiConnector.isConnected()) {
|
if (!wifiConnector.isConnected()) {
|
||||||
Serial.println("Failed connect to WiFi");
|
Serial.println("Failed connect to WiFi");
|
||||||
if (wifiConnector.isConfigurePorttalTimeout()) {
|
if (wifiConnector.isConfigurePorttalTimeout()) {
|
||||||
@@ -1027,17 +1027,17 @@ void initializeNetwork() {
|
|||||||
oledDisplay.setText("", "", "");
|
oledDisplay.setText("", "", "");
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Directly return because the rest of the function applied if wifi is connect only
|
// Directly return because the rest of the function applied if wifi is connect only
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initiate local network configuration
|
// Initiate local network configuration
|
||||||
mdnsInit();
|
mdnsInit();
|
||||||
localServer.begin();
|
localServer.begin();
|
||||||
// Apply mqtt connection if configured
|
// Apply mqtt connection if configured
|
||||||
initMqtt();
|
initMqtt();
|
||||||
|
|
||||||
// Ignore the rest if cloud connection to AirGradient is disabled
|
// Ignore the rest if cloud connection to AirGradient is disabled
|
||||||
if (configuration.isCloudConnectionDisabled()) {
|
if (configuration.isCloudConnectionDisabled()) {
|
||||||
return;
|
return;
|
||||||
@@ -1202,7 +1202,7 @@ static void updateDisplayAndLedBar(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (configuration.isCloudConnectionDisabled()) {
|
if (configuration.isCloudConnectionDisabled()) {
|
||||||
// Ignore API related check since cloud is disabled
|
// Ignore API related check since cloud is disabled
|
||||||
stateMachine.displayHandle(AgStateMachineNormal);
|
stateMachine.displayHandle(AgStateMachineNormal);
|
||||||
stateMachine.handleLeds(AgStateMachineNormal);
|
stateMachine.handleLeds(AgStateMachineNormal);
|
||||||
return;
|
return;
|
||||||
@@ -1395,7 +1395,7 @@ void postUsingWifi() {
|
|||||||
void postUsingCellular(bool forcePost) {
|
void postUsingCellular(bool forcePost) {
|
||||||
// Aquire queue mutex to get queue size
|
// Aquire queue mutex to get queue size
|
||||||
xSemaphoreTake(mutexMeasurementCycleQueue, portMAX_DELAY);
|
xSemaphoreTake(mutexMeasurementCycleQueue, portMAX_DELAY);
|
||||||
|
|
||||||
// Make sure measurement cycle available
|
// Make sure measurement cycle available
|
||||||
int queueSize = measurementCycleQueue.size();
|
int queueSize = measurementCycleQueue.size();
|
||||||
if (queueSize == 0) {
|
if (queueSize == 0) {
|
||||||
@@ -1405,7 +1405,7 @@ void postUsingCellular(bool forcePost) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check queue size if its ready to transmit
|
// Check queue size if its ready to transmit
|
||||||
// It is ready if size is divisible by 3
|
// It is ready if size is divisible by 3
|
||||||
if (!forcePost && (queueSize % MEASUREMENT_TRANSMIT_CYCLE) > 0) {
|
if (!forcePost && (queueSize % MEASUREMENT_TRANSMIT_CYCLE) > 0) {
|
||||||
Serial.printf("Not ready to transmit, queue size are %d\n", queueSize);
|
Serial.printf("Not ready to transmit, queue size are %d\n", queueSize);
|
||||||
xSemaphoreGive(mutexMeasurementCycleQueue);
|
xSemaphoreGive(mutexMeasurementCycleQueue);
|
||||||
@@ -1426,7 +1426,7 @@ void postUsingCellular(bool forcePost) {
|
|||||||
|
|
||||||
// Attempt to send
|
// Attempt to send
|
||||||
if (agClient->httpPostMeasures(payload) == false) {
|
if (agClient->httpPostMeasures(payload) == false) {
|
||||||
// Consider network has a problem, retry in next schedule
|
// Consider network has a problem, retry in next schedule
|
||||||
Serial.println("Post measures failed, retry in next schedule");
|
Serial.println("Post measures failed, retry in next schedule");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1527,7 +1527,7 @@ void setMeasurementMaxPeriod() {
|
|||||||
|
|
||||||
int calculateMaxPeriod(int updateInterval) {
|
int calculateMaxPeriod(int updateInterval) {
|
||||||
// 0.8 is 80% reduced interval for max period
|
// 0.8 is 80% reduced interval for max period
|
||||||
// NOTE: Both network option use the same measurement interval
|
// NOTE: Both network option use the same measurement interval
|
||||||
return (WIFI_MEASUREMENT_INTERVAL - (WIFI_MEASUREMENT_INTERVAL * 0.8)) / updateInterval;
|
return (WIFI_MEASUREMENT_INTERVAL - (WIFI_MEASUREMENT_INTERVAL * 0.8)) / updateInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1544,7 +1544,7 @@ void networkSignalCheck() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save last signal quality
|
// Save last signal quality
|
||||||
lastCellSignalQuality = result.data;
|
lastCellSignalQuality = result.data;
|
||||||
|
|
||||||
if (result.data == 99) {
|
if (result.data == 99) {
|
||||||
// 99 indicate cellular not attached to network
|
// 99 indicate cellular not attached to network
|
||||||
@@ -1557,7 +1557,7 @@ void networkSignalCheck() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If in 2 hours cellular client still not ready, then restart system
|
* If in 2 hours cellular client still not ready, then restart system
|
||||||
*/
|
*/
|
||||||
void restartIfCeClientIssueOverTwoHours() {
|
void restartIfCeClientIssueOverTwoHours() {
|
||||||
if (agCeClientProblemDetectedTime > 0 &&
|
if (agCeClientProblemDetectedTime > 0 &&
|
||||||
@@ -1622,10 +1622,10 @@ void networkingTask(void *args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Enable at command debug
|
// Enable at command debug
|
||||||
agSerial->setDebug(true);
|
agSerial->setDebug(true);
|
||||||
|
|
||||||
// Check if cellular client not ready until certain time
|
// Check if cellular client not ready until certain time
|
||||||
// Redundant check in both task to make sure its executed
|
// Redundant check in both task to make sure its executed
|
||||||
restartIfCeClientIssueOverTwoHours();
|
restartIfCeClientIssueOverTwoHours();
|
||||||
|
|
||||||
// Power cycling cellular module due to network issues for more than 1 hour
|
// Power cycling cellular module due to network issues for more than 1 hour
|
||||||
@@ -1676,14 +1676,14 @@ void networkingTask(void *args) {
|
|||||||
|
|
||||||
void newMeasurementCycle() {
|
void newMeasurementCycle() {
|
||||||
if (xSemaphoreTake(mutexMeasurementCycleQueue, portMAX_DELAY) == pdTRUE) {
|
if (xSemaphoreTake(mutexMeasurementCycleQueue, portMAX_DELAY) == pdTRUE) {
|
||||||
// Make sure queue not overflow
|
// Make sure queue not overflow
|
||||||
if (measurementCycleQueue.size() >= MAXIMUM_MEASUREMENT_CYCLE_QUEUE) {
|
if (measurementCycleQueue.size() >= MAXIMUM_MEASUREMENT_CYCLE_QUEUE) {
|
||||||
// Remove the oldest data from queue if queue reach max
|
// Remove the oldest data from queue if queue reach max
|
||||||
measurementCycleQueue.erase(measurementCycleQueue.begin());
|
measurementCycleQueue.erase(measurementCycleQueue.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get current measures
|
// Get current measures
|
||||||
auto mc = measurements.getMeasures();
|
auto mc = measurements.getMeasures();
|
||||||
mc.signal = cellularCard->csqToDbm(lastCellSignalQuality); // convert to RSSI
|
mc.signal = cellularCard->csqToDbm(lastCellSignalQuality); // convert to RSSI
|
||||||
|
|
||||||
measurementCycleQueue.push_back(mc);
|
measurementCycleQueue.push_back(mc);
|
||||||
|
@@ -6,8 +6,8 @@ OpenMetrics::OpenMetrics(Measurements &measure, Configuration &config,
|
|||||||
|
|
||||||
OpenMetrics::~OpenMetrics() {}
|
OpenMetrics::~OpenMetrics() {}
|
||||||
|
|
||||||
void OpenMetrics::setAirGradient(AirGradient *ag) {
|
void OpenMetrics::setAirGradient(AirGradient *ag) {
|
||||||
this->ag = ag;
|
this->ag = ag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenMetrics::setAirgradientClient(AirgradientClient *client) {
|
void OpenMetrics::setAirgradientClient(AirgradientClient *client) {
|
||||||
|
@@ -15,7 +15,7 @@ framework = arduino
|
|||||||
build_flags = !echo '-D ARDUINO_USB_CDC_ON_BOOT=1 -D ARDUINO_USB_MODE=1 -D AG_LOG_LEVEL=AG_LOG_LEVEL_INFO -D GIT_VERSION=\\"'$(git describe --tags --always --dirty)'\\"'
|
build_flags = !echo '-D ARDUINO_USB_CDC_ON_BOOT=1 -D ARDUINO_USB_MODE=1 -D AG_LOG_LEVEL=AG_LOG_LEVEL_INFO -D GIT_VERSION=\\"'$(git describe --tags --always --dirty)'\\"'
|
||||||
board_build.partitions = partitions.csv
|
board_build.partitions = partitions.csv
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
lib_deps =
|
lib_deps =
|
||||||
aglib=symlink://../arduino
|
aglib=symlink://../arduino
|
||||||
EEPROM
|
EEPROM
|
||||||
WebServer
|
WebServer
|
||||||
@@ -32,7 +32,7 @@ platform = espressif8266
|
|||||||
board = d1_mini
|
board = d1_mini
|
||||||
framework = arduino
|
framework = arduino
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
lib_deps =
|
lib_deps =
|
||||||
aglib=symlink://../arduino
|
aglib=symlink://../arduino
|
||||||
EEPROM
|
EEPROM
|
||||||
ESP8266HTTPClient
|
ESP8266HTTPClient
|
||||||
|
@@ -47,7 +47,7 @@ bool AgApiClient::fetchServerConfiguration(void) {
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
HTTPClient client;
|
HTTPClient client;
|
||||||
client.setConnectTimeout(timeoutMs); // Set timeout when establishing connection to server
|
client.setConnectTimeout(timeoutMs); // Set timeout when establishing connection to server
|
||||||
client.setTimeout(timeoutMs); // Timeout when waiting for response from AG server
|
client.setTimeout(timeoutMs); // Timeout when waiting for response from AG server
|
||||||
if (apiRootChanged) {
|
if (apiRootChanged) {
|
||||||
// If apiRoot is changed, assume not using https
|
// If apiRoot is changed, assume not using https
|
||||||
@@ -114,7 +114,7 @@ bool AgApiClient::postToServer(String data) {
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
HTTPClient client;
|
HTTPClient client;
|
||||||
client.setConnectTimeout(timeoutMs); // Set timeout when establishing connection to server
|
client.setConnectTimeout(timeoutMs); // Set timeout when establishing connection to server
|
||||||
client.setTimeout(timeoutMs); // Timeout when waiting for response from AG server
|
client.setTimeout(timeoutMs); // Timeout when waiting for response from AG server
|
||||||
if (apiRootChanged) {
|
if (apiRootChanged) {
|
||||||
// If apiRoot is changed, assume not using https
|
// If apiRoot is changed, assume not using https
|
||||||
@@ -185,13 +185,13 @@ void AgApiClient::setAirGradient(AirGradient *ag) { this->ag = ag; }
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send the package to check the connection with cloud
|
* @brief Send the package to check the connection with cloud
|
||||||
*
|
*
|
||||||
* @param rssi WiFi RSSI
|
* @param rssi WiFi RSSI
|
||||||
* @param bootCount Boot count
|
* @param bootCount Boot count
|
||||||
* @return true Success
|
* @return true Success
|
||||||
* @return false Failure
|
* @return false Failure
|
||||||
*/
|
*/
|
||||||
bool AgApiClient::sendPing(int rssi, int bootCount) {
|
bool AgApiClient::sendPing(int rssi, int bootCount) {
|
||||||
JSONVar root;
|
JSONVar root;
|
||||||
root["wifi"] = rssi;
|
root["wifi"] = rssi;
|
||||||
root["boot"] = bootCount;
|
root["boot"] = bootCount;
|
||||||
|
@@ -114,7 +114,7 @@ PMCorrectionAlgorithm Configuration::matchPmAlgorithm(String algorithm) {
|
|||||||
|
|
||||||
const size_t enumSize = COR_ALGO_PM_SLR_CUSTOM + 1; // Get the actual size of the enum
|
const size_t enumSize = COR_ALGO_PM_SLR_CUSTOM + 1; // Get the actual size of the enum
|
||||||
PMCorrectionAlgorithm result = COR_ALGO_PM_UNKNOWN;;
|
PMCorrectionAlgorithm result = COR_ALGO_PM_UNKNOWN;;
|
||||||
|
|
||||||
// Loop through enum values
|
// Loop through enum values
|
||||||
for (size_t enumVal = 0; enumVal < enumSize; enumVal++) {
|
for (size_t enumVal = 0; enumVal < enumSize; enumVal++) {
|
||||||
if (algorithm == PM_CORRECTION_ALGORITHM_NAMES[enumVal]) {
|
if (algorithm == PM_CORRECTION_ALGORITHM_NAMES[enumVal]) {
|
||||||
@@ -122,7 +122,7 @@ PMCorrectionAlgorithm Configuration::matchPmAlgorithm(String algorithm) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If string not match from enum, check if correctionAlgorithm is one of the PM batch corrections
|
// If string not match from enum, check if correctionAlgorithm is one of the PM batch corrections
|
||||||
if (result == COR_ALGO_PM_UNKNOWN) {
|
if (result == COR_ALGO_PM_UNKNOWN) {
|
||||||
// Check the substring "slr_PMS5003_xxxxxxxx"
|
// Check the substring "slr_PMS5003_xxxxxxxx"
|
||||||
if (algorithm.substring(0, 11) == "slr_PMS5003") {
|
if (algorithm.substring(0, 11) == "slr_PMS5003") {
|
||||||
@@ -749,7 +749,7 @@ bool Configuration::parse(String data, bool isLocal) {
|
|||||||
}
|
}
|
||||||
else if (JSON.typeof_(root[jprop_mqttBrokerUrl]) == "null" and !isLocal) {
|
else if (JSON.typeof_(root[jprop_mqttBrokerUrl]) == "null" and !isLocal) {
|
||||||
// So if its not available on the json and json comes from aigradient server
|
// So if its not available on the json and json comes from aigradient server
|
||||||
// then set its value to default (empty)
|
// then set its value to default (empty)
|
||||||
jconfig[jprop_mqttBrokerUrl] = jprop_mqttBrokerUrl_default;
|
jconfig[jprop_mqttBrokerUrl] = jprop_mqttBrokerUrl_default;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1073,7 +1073,7 @@ String Configuration::getMqttBrokerUri(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get HTTP domain for post measures and get configuration
|
* @brief Get HTTP domain for post measures and get configuration
|
||||||
*
|
*
|
||||||
* @return String http domain, might be empty string
|
* @return String http domain, might be empty string
|
||||||
*/
|
*/
|
||||||
@@ -1562,13 +1562,13 @@ void Configuration::setDisableCloudConnection(bool disable) {
|
|||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Configuration::isLedBarModeChanged(void) {
|
bool Configuration::isLedBarModeChanged(void) {
|
||||||
bool changed = _ledBarModeChanged;
|
bool changed = _ledBarModeChanged;
|
||||||
_ledBarModeChanged = false;
|
_ledBarModeChanged = false;
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Configuration::isMonitorDisplayCompensatedValues(void) {
|
bool Configuration::isMonitorDisplayCompensatedValues(void) {
|
||||||
return jconfig[jprop_monitorDisplayCompensatedValues];
|
return jconfig[jprop_monitorDisplayCompensatedValues];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1591,8 +1591,8 @@ bool Configuration::isPMCorrectionChanged(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check if PM correction is enabled
|
* @brief Check if PM correction is enabled
|
||||||
*
|
*
|
||||||
* @return true if PM correction algorithm is not None, otherwise false
|
* @return true if PM correction algorithm is not None, otherwise false
|
||||||
*/
|
*/
|
||||||
bool Configuration::isPMCorrectionEnabled(void) {
|
bool Configuration::isPMCorrectionEnabled(void) {
|
||||||
|
@@ -568,7 +568,7 @@ float Measurements::getAverage(MeasurementType type, int ch) {
|
|||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return measurementAverage;
|
return measurementAverage;
|
||||||
}
|
}
|
||||||
|
|
||||||
String Measurements::pms5003FirmwareVersion(int fwCode) {
|
String Measurements::pms5003FirmwareVersion(int fwCode) {
|
||||||
@@ -895,7 +895,7 @@ std::string Measurements::buildMeasuresPayload(Measures &mc) {
|
|||||||
|
|
||||||
oss << ",";
|
oss << ",";
|
||||||
|
|
||||||
// Temperature
|
// Temperature
|
||||||
if (utils::isValidTemperature(mc.temperature[0]) && utils::isValidTemperature(mc.temperature[1])) {
|
if (utils::isValidTemperature(mc.temperature[0]) && utils::isValidTemperature(mc.temperature[1])) {
|
||||||
float temp = (mc.temperature[0] + mc.temperature[1]) / 2.0f;
|
float temp = (mc.temperature[0] + mc.temperature[1]) / 2.0f;
|
||||||
oss << std::round(temp * 10);
|
oss << std::round(temp * 10);
|
||||||
|
@@ -149,7 +149,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @param type measurement type that will be retrieve
|
* @param type measurement type that will be retrieve
|
||||||
* @param ch target type value channel
|
* @param ch target type value channel
|
||||||
* @return moving average value of target measurements type
|
* @return moving average value of target measurements type
|
||||||
*/
|
*/
|
||||||
float getAverage(MeasurementType type, int ch = 1);
|
float getAverage(MeasurementType type, int ch = 1);
|
||||||
|
|
||||||
|
@@ -358,7 +358,7 @@ bool WifiConnector::isConnected(void) { return WiFi.isConnected(); }
|
|||||||
* this method
|
* this method
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void WifiConnector::reset(void) {
|
void WifiConnector::reset(void) {
|
||||||
if(this->wifi == NULL) {
|
if(this->wifi == NULL) {
|
||||||
this->wifi = new WiFiManager();
|
this->wifi = new WiFiManager();
|
||||||
if(this->wifi == NULL){
|
if(this->wifi == NULL){
|
||||||
@@ -366,7 +366,7 @@ void WifiConnector::reset(void) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WIFI()->resetSettings();
|
WIFI()->resetSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -406,7 +406,7 @@ bool WifiConnector::isConfigurePorttalTimeout(void) { return connectorTimeout; }
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set wifi connect to default WiFi
|
* @brief Set wifi connect to default WiFi
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void WifiConnector::setDefault(void) {
|
void WifiConnector::setDefault(void) {
|
||||||
WiFi.begin("airgradient", "cleanair");
|
WiFi.begin("airgradient", "cleanair");
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
#include "AirGradient.h"
|
#include "AirGradient.h"
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
#else
|
#else
|
||||||
#include "WiFi.h"
|
#include "WiFi.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ String AirGradient::getBoardName(void) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Board Type is ONE_INDOOR
|
* @brief Board Type is ONE_INDOOR
|
||||||
*
|
*
|
||||||
* @return true ONE_INDOOR
|
* @return true ONE_INDOOR
|
||||||
* @return false Other
|
* @return false Other
|
||||||
*/
|
*/
|
||||||
@@ -65,15 +65,15 @@ bool AirGradient::isOne(void) {
|
|||||||
return boardType == BoardType::ONE_INDOOR;
|
return boardType == BoardType::ONE_INDOOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AirGradient::isOpenAir(void) {
|
bool AirGradient::isOpenAir(void) {
|
||||||
return boardType == BoardType::OPEN_AIR_OUTDOOR;
|
return boardType == BoardType::OPEN_AIR_OUTDOOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AirGradient::isPro4_2(void) {
|
bool AirGradient::isPro4_2(void) {
|
||||||
return boardType == BoardType::DIY_PRO_INDOOR_V4_2;
|
return boardType == BoardType::DIY_PRO_INDOOR_V4_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AirGradient::isPro3_3(void) {
|
bool AirGradient::isPro3_3(void) {
|
||||||
return boardType == BoardType::DIY_PRO_INDOOR_V3_3;
|
return boardType == BoardType::DIY_PRO_INDOOR_V3_3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -177,9 +177,9 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check that Airgradient object is OPEN_AIR
|
* @brief Check that Airgradient object is OPEN_AIR
|
||||||
*
|
*
|
||||||
* @return true
|
* @return true
|
||||||
* @return false
|
* @return false
|
||||||
*/
|
*/
|
||||||
bool isOpenAir(void);
|
bool isOpenAir(void);
|
||||||
|
|
||||||
|
@@ -27,7 +27,7 @@ enum BoardType {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Board definitions
|
* @brief Board definitions
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct BoardDef {
|
struct BoardDef {
|
||||||
/** Board Support CO2 SenseS8 */
|
/** Board Support CO2 SenseS8 */
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The class define how to handle the LED
|
* @brief The class define how to handle the LED
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class StatusLed {
|
class StatusLed {
|
||||||
public:
|
public:
|
||||||
|
@@ -316,10 +316,10 @@ int PMSBase::pm25ToAQI(int pm02) {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SLR correction for PM2.5
|
* @brief SLR correction for PM2.5
|
||||||
*
|
*
|
||||||
* Reference: https://www.airgradient.com/blog/low-readings-from-pms5003/
|
* Reference: https://www.airgradient.com/blog/low-readings-from-pms5003/
|
||||||
*
|
*
|
||||||
* @param pm25 PM2.5 raw value
|
* @param pm25 PM2.5 raw value
|
||||||
* @param pm003Count PM0.3 count
|
* @param pm003Count PM0.3 count
|
||||||
* @param scalingFactor Scaling factor
|
* @param scalingFactor Scaling factor
|
||||||
|
@@ -35,7 +35,7 @@ public:
|
|||||||
/** For PMS5003T*/
|
/** For PMS5003T*/
|
||||||
int16_t getTemp(void);
|
int16_t getTemp(void);
|
||||||
uint16_t getHum(void);
|
uint16_t getHum(void);
|
||||||
uint8_t getFirmwareVersion(void);
|
uint8_t getFirmwareVersion(void);
|
||||||
uint8_t getErrorCode(void);
|
uint8_t getErrorCode(void);
|
||||||
|
|
||||||
int pm25ToAQI(int pm02);
|
int pm25ToAQI(int pm02);
|
||||||
|
@@ -189,21 +189,21 @@ float PMS5003::compensate(float pm25, float humidity) { return pms.compensate(pm
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get sensor firmware version
|
* @brief Get sensor firmware version
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
int PMS5003::getFirmwareVersion(void) { return _ver; }
|
int PMS5003::getFirmwareVersion(void) { return _ver; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get sensor error code
|
* @brief Get sensor error code
|
||||||
*
|
*
|
||||||
* @return uint8_t
|
* @return uint8_t
|
||||||
*/
|
*/
|
||||||
uint8_t PMS5003::getErrorCode(void) { return pms.getErrorCode(); }
|
uint8_t PMS5003::getErrorCode(void) { return pms.getErrorCode(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Is sensor connect with device
|
* @brief Is sensor connect with device
|
||||||
*
|
*
|
||||||
* @return true Connected
|
* @return true Connected
|
||||||
* @return false Removed
|
* @return false Removed
|
||||||
*/
|
*/
|
||||||
@@ -255,14 +255,14 @@ void PMS5003::resetFailCount(void) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get number of fail count
|
* @brief Get number of fail count
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
int PMS5003::getFailCount(void) { return pms.getFailCount(); }
|
int PMS5003::getFailCount(void) { return pms.getFailCount(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get number of fail count max
|
* @brief Get number of fail count max
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
int PMS5003::getFailCountMax(void) { return pms.getFailCountMax(); }
|
int PMS5003::getFailCountMax(void) { return pms.getFailCountMax(); }
|
||||||
|
@@ -218,21 +218,21 @@ float PMS5003T::compensate(float pm25, float humidity) { return pms.compensate(p
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get module(s) firmware version
|
* @brief Get module(s) firmware version
|
||||||
*
|
*
|
||||||
* @return int Version code
|
* @return int Version code
|
||||||
*/
|
*/
|
||||||
int PMS5003T::getFirmwareVersion(void) { return _ver; }
|
int PMS5003T::getFirmwareVersion(void) { return _ver; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get sensor error code
|
* @brief Get sensor error code
|
||||||
*
|
*
|
||||||
* @return uint8_t
|
* @return uint8_t
|
||||||
*/
|
*/
|
||||||
uint8_t PMS5003T::getErrorCode(void) { return pms.getErrorCode(); }
|
uint8_t PMS5003T::getErrorCode(void) { return pms.getErrorCode(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Is sensor connect to device
|
* @brief Is sensor connect to device
|
||||||
*
|
*
|
||||||
* @return true Connected
|
* @return true Connected
|
||||||
* @return false Removed
|
* @return false Removed
|
||||||
*/
|
*/
|
||||||
@@ -281,14 +281,14 @@ void PMS5003T::resetFailCount(void) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get fail count
|
* @brief Get fail count
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
int PMS5003T::getFailCount(void) { return pms.getFailCount(); }
|
int PMS5003T::getFailCount(void) { return pms.getFailCount(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get fail count max
|
* @brief Get fail count max
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
int PMS5003T::getFailCountMax(void) { return pms.getFailCountMax(); }
|
int PMS5003T::getFailCountMax(void) { return pms.getFailCountMax(); }
|
||||||
|
@@ -6,11 +6,11 @@ PMS5003TBase::~PMS5003TBase() {}
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compensate the temperature
|
* @brief Compensate the temperature
|
||||||
*
|
*
|
||||||
* Reference formula: https://www.airgradient.com/documentation/correction-algorithms/
|
* Reference formula: https://www.airgradient.com/documentation/correction-algorithms/
|
||||||
*
|
*
|
||||||
* @param temp
|
* @param temp
|
||||||
* @return * float
|
* @return * float
|
||||||
*/
|
*/
|
||||||
float PMS5003TBase::compensateTemp(float temp) {
|
float PMS5003TBase::compensateTemp(float temp) {
|
||||||
if (temp < 10.0f) {
|
if (temp < 10.0f) {
|
||||||
@@ -21,11 +21,11 @@ float PMS5003TBase::compensateTemp(float temp) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compensate the humidity
|
* @brief Compensate the humidity
|
||||||
*
|
*
|
||||||
* Reference formula: https://www.airgradient.com/documentation/correction-algorithms/
|
* Reference formula: https://www.airgradient.com/documentation/correction-algorithms/
|
||||||
*
|
*
|
||||||
* @param temp
|
* @param temp
|
||||||
* @return * float
|
* @return * float
|
||||||
*/
|
*/
|
||||||
float PMS5003TBase::compensateHum(float hum) {
|
float PMS5003TBase::compensateHum(float hum) {
|
||||||
hum = hum * 1.259f + 7.34f;
|
hum = hum * 1.259f + 7.34f;
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
class PMS5003TBase
|
class PMS5003TBase
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PMS5003TBase();
|
PMS5003TBase();
|
||||||
~PMS5003TBase();
|
~PMS5003TBase();
|
||||||
|
@@ -140,7 +140,7 @@ void Sgp41::pause() {
|
|||||||
tvoc = utils::getInvalidVOC();
|
tvoc = utils::getInvalidVOC();
|
||||||
noxRaw = utils::getInvalidNOx();
|
noxRaw = utils::getInvalidNOx();
|
||||||
nox = utils::getInvalidNOx();
|
nox = utils::getInvalidNOx();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sgp41::resume() {
|
void Sgp41::resume() {
|
||||||
onPause = false;
|
onPause = false;
|
||||||
|
Reference in New Issue
Block a user