mirror of
https://github.com/airgradienthq/arduino.git
synced 2025-12-17 19:18:27 +01:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99fca71c6b | ||
|
|
ea8a71d4c3 | ||
|
|
7c8080ac90 | ||
|
|
72bf812235 | ||
|
|
2c37ab9895 | ||
|
|
565a7fa9fd | ||
|
|
9e07b67951 | ||
|
|
23f8c383fd | ||
|
|
c0ad1dbfad | ||
|
|
75be7d9fc5 | ||
|
|
309d322100 | ||
|
|
89ebe6c39f | ||
|
|
29db5469f5 |
31
.github/workflows/check.yml
vendored
31
.github/workflows/check.yml
vendored
@@ -1,5 +1,36 @@
|
||||
on: [push, pull_request]
|
||||
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:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
@@ -294,7 +294,7 @@ static bool sgp41Init(void) {
|
||||
configuration.hasSensorSGP = true;
|
||||
return true;
|
||||
} else {
|
||||
Serial.println("Init SGP41 failuire");
|
||||
Serial.println("Init SGP41 failure");
|
||||
configuration.hasSensorSGP = false;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -351,7 +351,7 @@ static bool sgp41Init(void) {
|
||||
configuration.hasSensorSGP = true;
|
||||
return true;
|
||||
} else {
|
||||
Serial.println("Init SGP41 failuire");
|
||||
Serial.println("Init SGP41 failure");
|
||||
configuration.hasSensorSGP = false;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -374,7 +374,7 @@ static bool sgp41Init(void) {
|
||||
configuration.hasSensorSGP = true;
|
||||
return true;
|
||||
} else {
|
||||
Serial.println("Init SGP41 failuire");
|
||||
Serial.println("Init SGP41 failure");
|
||||
configuration.hasSensorSGP = false;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -559,7 +559,7 @@ static bool sgp41Init(void) {
|
||||
configuration.hasSensorSGP = true;
|
||||
return true;
|
||||
} else {
|
||||
Serial.println("Init SGP41 failuire");
|
||||
Serial.println("Init SGP41 failure");
|
||||
configuration.hasSensorSGP = false;
|
||||
}
|
||||
return false;
|
||||
@@ -952,6 +952,8 @@ static void boardInit(void) {
|
||||
} else {
|
||||
Serial.println("Set S8 AbcDays failure");
|
||||
}
|
||||
|
||||
ag->s8.printInformation();
|
||||
}
|
||||
|
||||
localServer.setFwMode(fwMode);
|
||||
@@ -1414,18 +1416,19 @@ void postUsingCellular(bool forcePost) {
|
||||
|
||||
// Build payload include all measurements from queue
|
||||
std::string payload;
|
||||
bool extendPmMeasures = configuration.isExtendedPmMeasuresEnabled();
|
||||
payload += std::to_string(CELLULAR_MEASUREMENT_INTERVAL / 1000); // Convert to seconds
|
||||
for (int i = 0; i < queueSize; i++) {
|
||||
auto mc = measurementCycleQueue.at(i);
|
||||
payload += ",";
|
||||
payload += measurements.buildMeasuresPayload(mc);
|
||||
payload += measurements.buildMeasuresPayload(mc, extendPmMeasures);
|
||||
}
|
||||
|
||||
// Release before actually post measures that might takes too long
|
||||
xSemaphoreGive(mutexMeasurementCycleQueue);
|
||||
|
||||
// Attempt to send
|
||||
if (agClient->httpPostMeasures(payload) == false) {
|
||||
if (agClient->httpPostMeasures(payload, extendPmMeasures) == false) {
|
||||
// Consider network has a problem, retry in next schedule
|
||||
Serial.println("Post measures failed, retry in next schedule");
|
||||
return;
|
||||
|
||||
@@ -60,6 +60,7 @@ JSON_PROP_DEF(monitorDisplayCompensatedValues);
|
||||
JSON_PROP_DEF(corrections);
|
||||
JSON_PROP_DEF(atmp);
|
||||
JSON_PROP_DEF(rhum);
|
||||
JSON_PROP_DEF(extendedPmMeasures);
|
||||
|
||||
#define jprop_model_default ""
|
||||
#define jprop_country_default "TH"
|
||||
@@ -78,6 +79,7 @@ JSON_PROP_DEF(rhum);
|
||||
#define jprop_displayBrightness_default 100
|
||||
#define jprop_offlineMode_default false
|
||||
#define jprop_monitorDisplayCompensatedValues_default false
|
||||
#define jprop_extendedPmMeasures_default false
|
||||
|
||||
JSONVar jconfig;
|
||||
|
||||
@@ -400,6 +402,7 @@ void Configuration::defaultConfig(void) {
|
||||
jconfig[jprop_model] = jprop_model_default;
|
||||
jconfig[jprop_offlineMode] = jprop_offlineMode_default;
|
||||
jconfig[jprop_monitorDisplayCompensatedValues] = jprop_monitorDisplayCompensatedValues_default;
|
||||
jconfig[jprop_extendedPmMeasures] = jprop_extendedPmMeasures_default;
|
||||
|
||||
// PM2.5 default correction
|
||||
pmCorrection.algorithm = COR_ALGO_PM_NONE;
|
||||
@@ -940,6 +943,32 @@ bool Configuration::parse(String data, bool isLocal) {
|
||||
}
|
||||
}
|
||||
|
||||
if (JSON.typeof_(root[jprop_extendedPmMeasures]) == "boolean") {
|
||||
bool value = root[jprop_extendedPmMeasures];
|
||||
bool oldValue = jconfig[jprop_extendedPmMeasures];
|
||||
if (value != oldValue) {
|
||||
changed = true;
|
||||
configLogInfo(String(jprop_extendedPmMeasures),
|
||||
String(oldValue ? "true" : "false"),
|
||||
String(value ? "true" : "false"));
|
||||
jconfig[jprop_extendedPmMeasures] = value;
|
||||
}
|
||||
}
|
||||
else if (JSON.typeof_(root[jprop_extendedPmMeasures]) == "null" and !isLocal) {
|
||||
// So if its not available on the json and json comes from aigradient server
|
||||
// then set its value to default (false)
|
||||
jconfig[jprop_extendedPmMeasures] = jprop_extendedPmMeasures_default;
|
||||
}
|
||||
else {
|
||||
if (jsonTypeInvalid(root[jprop_extendedPmMeasures], "boolean")) {
|
||||
failedMessage = jsonTypeInvalidMessage(
|
||||
String(jprop_extendedPmMeasures), "boolean");
|
||||
jsonInvalid();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// PM2.5 Corrections
|
||||
if (updatePmCorrection(root)) {
|
||||
changed = true;
|
||||
@@ -1002,6 +1031,11 @@ bool Configuration::isTemperatureUnitInF(void) {
|
||||
return (unit == "f");
|
||||
}
|
||||
|
||||
|
||||
bool Configuration::isExtendedPmMeasuresEnabled(void) {
|
||||
return jconfig[jprop_extendedPmMeasures];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Country name, it's short name ex: TH = Thailand
|
||||
*
|
||||
@@ -1368,6 +1402,18 @@ void Configuration::toConfig(const char *buf) {
|
||||
logInfo("toConfig: disableCloudConnection changed");
|
||||
}
|
||||
|
||||
/** validate extendedPmMeasures configuration */
|
||||
if (JSON.typeof_(jconfig[jprop_extendedPmMeasures]) != "boolean") {
|
||||
isConfigFieldInvalid = true;
|
||||
} else {
|
||||
isConfigFieldInvalid = false;
|
||||
}
|
||||
if (isConfigFieldInvalid) {
|
||||
jconfig[jprop_extendedPmMeasures] = jprop_extendedPmMeasures_default;
|
||||
changed = true;
|
||||
logInfo("toConfig: extendedPmMeasures changed");
|
||||
}
|
||||
|
||||
/** validate configuration control */
|
||||
if (JSON.typeof_(jprop_configurationControl) != "string") {
|
||||
isConfigFieldInvalid = true;
|
||||
|
||||
@@ -79,6 +79,7 @@ public:
|
||||
String toString(void);
|
||||
String toString(AgFirmwareMode fwMode);
|
||||
bool isTemperatureUnitInF(void);
|
||||
bool isExtendedPmMeasuresEnabled(void);
|
||||
String getCountry(void);
|
||||
bool isPmStandardInUSAQI(void);
|
||||
int getCO2CalibrationAbcDays(void);
|
||||
|
||||
@@ -885,7 +885,7 @@ Measurements::Measures Measurements::getMeasures() {
|
||||
return mc;
|
||||
}
|
||||
|
||||
std::string Measurements::buildMeasuresPayload(Measures &mc) {
|
||||
std::string Measurements::buildMeasuresPayload(Measures &mc, bool extendedPmMeasures) {
|
||||
std::ostringstream oss;
|
||||
|
||||
// CO2
|
||||
@@ -984,6 +984,76 @@ std::string Measurements::buildMeasuresPayload(Measures &mc) {
|
||||
oss << mc.signal;
|
||||
}
|
||||
|
||||
|
||||
if (extendedPmMeasures) {
|
||||
oss << ",,,,,,,,"; // Add placeholder for MAX payload (BMS & O3/NO2)
|
||||
|
||||
/// PM 0.5 particle count
|
||||
if (utils::isValidPm03Count(mc.pm_05_pc[0]) && utils::isValidPm03Count(mc.pm_05_pc[1])) {
|
||||
oss << std::round((mc.pm_05_pc[0] + mc.pm_05_pc[1]) / 2.0f);
|
||||
} else if (utils::isValidPm03Count(mc.pm_05_pc[0])) {
|
||||
oss << std::round(mc.pm_05_pc[0]);
|
||||
} else if (utils::isValidPm03Count(mc.pm_05_pc[1])) {
|
||||
oss << std::round(mc.pm_05_pc[1]);
|
||||
}
|
||||
|
||||
oss << ",";
|
||||
|
||||
/// PM 1.0 particle count
|
||||
if (utils::isValidPm03Count(mc.pm_01_pc[0]) && utils::isValidPm03Count(mc.pm_01_pc[1])) {
|
||||
oss << std::round((mc.pm_01_pc[0] + mc.pm_01_pc[1]) / 2.0f);
|
||||
} else if (utils::isValidPm03Count(mc.pm_01_pc[0])) {
|
||||
oss << std::round(mc.pm_01_pc[0]);
|
||||
} else if (utils::isValidPm03Count(mc.pm_01_pc[1])) {
|
||||
oss << std::round(mc.pm_01_pc[1]);
|
||||
}
|
||||
|
||||
oss << ",";
|
||||
|
||||
/// PM 2.5 particle count
|
||||
if (utils::isValidPm03Count(mc.pm_25_pc[0]) && utils::isValidPm03Count(mc.pm_25_pc[1])) {
|
||||
oss << std::round((mc.pm_25_pc[0] + mc.pm_25_pc[1]) / 2.0f);
|
||||
} else if (utils::isValidPm03Count(mc.pm_25_pc[0])) {
|
||||
oss << std::round(mc.pm_25_pc[0]);
|
||||
} else if (utils::isValidPm03Count(mc.pm_25_pc[1])) {
|
||||
oss << std::round(mc.pm_25_pc[1]);
|
||||
}
|
||||
|
||||
oss << ",";
|
||||
|
||||
/// PM 5.0 particle count
|
||||
if (utils::isValidPm03Count(mc.pm_5_pc[0]) && utils::isValidPm03Count(mc.pm_5_pc[1])) {
|
||||
oss << std::round((mc.pm_5_pc[0] + mc.pm_5_pc[1]) / 2.0f);
|
||||
} else if (utils::isValidPm03Count(mc.pm_5_pc[0])) {
|
||||
oss << std::round(mc.pm_5_pc[0]);
|
||||
} else if (utils::isValidPm03Count(mc.pm_5_pc[1])) {
|
||||
oss << std::round(mc.pm_5_pc[1]);
|
||||
}
|
||||
|
||||
oss << ",";
|
||||
|
||||
/// PM 10 particle count
|
||||
if (utils::isValidPm03Count(mc.pm_10_pc[0]) && utils::isValidPm03Count(mc.pm_10_pc[1])) {
|
||||
oss << std::round((mc.pm_10_pc[0] + mc.pm_10_pc[1]) / 2.0f);
|
||||
} else if (utils::isValidPm03Count(mc.pm_10_pc[0])) {
|
||||
oss << std::round(mc.pm_10_pc[0]);
|
||||
} else if (utils::isValidPm03Count(mc.pm_10_pc[1])) {
|
||||
oss << std::round(mc.pm_10_pc[1]);
|
||||
}
|
||||
|
||||
oss << ",";
|
||||
|
||||
/// PM2.5 standard particle
|
||||
if (utils::isValidPm(mc.pm_25_sp[0]) && utils::isValidPm(mc.pm_25_sp[1])) {
|
||||
float pm10 = (mc.pm_25_sp[0] + mc.pm_25_sp[1]) / 2.0f;
|
||||
oss << std::round(pm10 * 10);
|
||||
} else if (utils::isValidPm(mc.pm_25_sp[0])) {
|
||||
oss << std::round(mc.pm_25_sp[0] * 10);
|
||||
} else if (utils::isValidPm(mc.pm_25_sp[1])) {
|
||||
oss << std::round(mc.pm_25_sp[1] * 10);
|
||||
}
|
||||
}
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ public:
|
||||
|
||||
Measures getMeasures();
|
||||
|
||||
std::string buildMeasuresPayload(Measures &measures);
|
||||
std::string buildMeasuresPayload(Measures &mc, bool extendedPmMeasures);
|
||||
|
||||
/**
|
||||
* Set to true if want to debug every update value
|
||||
|
||||
Submodule src/Libraries/airgradient-client updated: c23bb2ceac...0a2ff8abbb
@@ -835,3 +835,13 @@ bool S8::setAbcPeriod(int hours) {
|
||||
* @return int Hour
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ public:
|
||||
bool isBaseLineCalibrationDone(void);
|
||||
bool setAbcPeriod(int hours);
|
||||
int getAbcPeriod(void);
|
||||
void printInformation(void);
|
||||
|
||||
private:
|
||||
/** Variables */
|
||||
|
||||
Reference in New Issue
Block a user