From 9a585c08f925e61321db6fe9ea3ef1d9f99351ac Mon Sep 17 00:00:00 2001 From: Matthias Prinke Date: Tue, 13 Feb 2024 20:31:50 +0100 Subject: [PATCH 1/2] dded PM1.0 to Air Quality (Particulate Matter) Sensor decoder --- .../BresserWeatherSensorBasic.ino | 7 +++++++ .../BresserWeatherSensorMQTT/BresserWeatherSensorMQTT.ino | 6 +++++- .../BresserWeatherSensorMQTTCustom.ino | 4 +++- .../BresserWeatherSensorMQTTWifiMgr.ino | 6 +++++- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/examples/BresserWeatherSensorBasic/BresserWeatherSensorBasic.ino b/examples/BresserWeatherSensorBasic/BresserWeatherSensorBasic.ino index 6f689e41..c722887d 100644 --- a/examples/BresserWeatherSensorBasic/BresserWeatherSensorBasic.ino +++ b/examples/BresserWeatherSensorBasic/BresserWeatherSensorBasic.ino @@ -48,6 +48,8 @@ // 20230804 Added Bresser Water Leakage Sensor decoder // 20231023 Modified detection of Lightning Sensor // 20231025 Added Bresser Air Quality (Particulate Matter) Sensor decoder +// 20240209 Added Leakage, Air Quality (HCHO/VOC) and CO2 Sensors +// 20240213 Added PM1.0 to Air Quality (Particulate Matter) Sensor decoder // // ToDo: // - @@ -112,6 +114,11 @@ void loop() } else if (ws.sensor[i].s_type == SENSOR_TYPE_AIR_PM) { // Air Quality (Particular Matter) Sensor + if (ws.sensor[i].pm.pm_1_0_init) { + Serial.printf("PM1.0: [init] "); + } else { + Serial.printf("PM1.0: [%uµg/m³] ", ws.sensor[i].pm.pm_1_0); + } if (ws.sensor[i].pm.pm_2_5_init) { Serial.printf("PM2.5: [init] "); } else { diff --git a/examples/BresserWeatherSensorMQTT/BresserWeatherSensorMQTT.ino b/examples/BresserWeatherSensorMQTT/BresserWeatherSensorMQTT.ino index d570d0f8..43b6bd0f 100644 --- a/examples/BresserWeatherSensorMQTT/BresserWeatherSensorMQTT.ino +++ b/examples/BresserWeatherSensorMQTT/BresserWeatherSensorMQTT.ino @@ -108,6 +108,8 @@ // 20231228 Fixed entering sleep mode before sensor data was published // 20240113 Added post-processed lightning data to payload // 20240122 Added lightning post-processing reset +// 20240209 Added Leakage, Air Quality (HCHO/VOC) and CO2 Sensors +// 20240213 Added PM1.0 to Air Quality (Particulate Matter) Sensor decoder // // ToDo: // @@ -589,9 +591,11 @@ void publishWeatherdata(bool complete) } else if (weatherSensor.sensor[i].s_type == SENSOR_TYPE_AIR_PM) { // Air Quality (Particular Matter) Sensor + if (!weatherSensor.sensor[i].pm.pm_1_0_init) { + mqtt_payload += String(",\"pm1_0_ug_m3\":") + String(weatherSensor.sensor[i].pm.pm_1_0); + } if (!weatherSensor.sensor[i].pm.pm_2_5_init) { mqtt_payload += String(",\"pm2_5_ug_m3\":") + String(weatherSensor.sensor[i].pm.pm_2_5); - } if (!weatherSensor.sensor[i].pm.pm_10_init) { mqtt_payload += String(",\"pm10_ug_m3\":") + String(weatherSensor.sensor[i].pm.pm_10); diff --git a/examples/BresserWeatherSensorMQTTCustom/BresserWeatherSensorMQTTCustom.ino b/examples/BresserWeatherSensorMQTTCustom/BresserWeatherSensorMQTTCustom.ino index 397f3b7d..f008a34a 100644 --- a/examples/BresserWeatherSensorMQTTCustom/BresserWeatherSensorMQTTCustom.ino +++ b/examples/BresserWeatherSensorMQTTCustom/BresserWeatherSensorMQTTCustom.ino @@ -589,9 +589,11 @@ void publishWeatherdata(bool complete) } else if (weatherSensor.sensor[i].s_type == SENSOR_TYPE_AIR_PM) { // Air Quality (Particular Matter) Sensor + if (!weatherSensor.sensor[i].pm.pm_1_0_init) { + mqtt_payload += String(",\"pm1_0_ug_m3\":") + String(weatherSensor.sensor[i].pm.pm_1_0); + } if (!weatherSensor.sensor[i].pm.pm_2_5_init) { mqtt_payload += String(",\"pm2_5_ug_m3\":") + String(weatherSensor.sensor[i].pm.pm_2_5); - } if (!weatherSensor.sensor[i].pm.pm_10_init) { mqtt_payload += String(",\"pm10_ug_m3\":") + String(weatherSensor.sensor[i].pm.pm_10); diff --git a/examples/BresserWeatherSensorMQTTWifiMgr/BresserWeatherSensorMQTTWifiMgr.ino b/examples/BresserWeatherSensorMQTTWifiMgr/BresserWeatherSensorMQTTWifiMgr.ino index 96fea062..545737c7 100644 --- a/examples/BresserWeatherSensorMQTTWifiMgr/BresserWeatherSensorMQTTWifiMgr.ino +++ b/examples/BresserWeatherSensorMQTTWifiMgr/BresserWeatherSensorMQTTWifiMgr.ino @@ -93,6 +93,8 @@ // 20240122 Added lightning post-processing reset // 20240129 Replaced SPIFFS by LittleFS // Added formatting of LittleFS partition if mounting failed +// 20240209 Added Leakage, Air Quality (HCHO/VOC) and CO2 Sensors +// 20240213 Added PM1.0 to Air Quality (Particulate Matter) Sensor decoder // // ToDo: // @@ -780,9 +782,11 @@ void publishWeatherdata(bool complete) } else if (weatherSensor.sensor[i].s_type == SENSOR_TYPE_AIR_PM) { // Air Quality (Particular Matter) Sensor + if (!weatherSensor.sensor[i].pm.pm_1_0_init) { + mqtt_payload += String(",\"pm1_0_ug_m3\":") + String(weatherSensor.sensor[i].pm.pm_1_0); + } if (!weatherSensor.sensor[i].pm.pm_2_5_init) { mqtt_payload += String(",\"pm2_5_ug_m3\":") + String(weatherSensor.sensor[i].pm.pm_2_5); - } if (!weatherSensor.sensor[i].pm.pm_10_init) { mqtt_payload += String(",\"pm10_ug_m3\":") + String(weatherSensor.sensor[i].pm.pm_10); From e1ed820d81e4d31beb24fc2269b1bcaa309a7a48 Mon Sep 17 00:00:00 2001 From: Matthias Prinke Date: Tue, 13 Feb 2024 20:36:01 +0100 Subject: [PATCH 2/2] Added PM1.0 to air quality (PM) sensor decoder --- .../BresserWeatherSensorMQTTCustom/src/WeatherSensor.cpp | 9 +++++++++ .../BresserWeatherSensorMQTTCustom/src/WeatherSensor.h | 3 +++ src/WeatherSensor.cpp | 9 +++++++++ src/WeatherSensor.h | 3 +++ 4 files changed, 24 insertions(+) diff --git a/examples/BresserWeatherSensorMQTTCustom/src/WeatherSensor.cpp b/examples/BresserWeatherSensorMQTTCustom/src/WeatherSensor.cpp index 0e47635f..d5a40e28 100644 --- a/examples/BresserWeatherSensorMQTTCustom/src/WeatherSensor.cpp +++ b/examples/BresserWeatherSensorMQTTCustom/src/WeatherSensor.cpp @@ -84,6 +84,7 @@ // 20240208 Added sensors for CO2, P/N 7009977 and HCHO/VOC, P/N 7009978 to 7-in-1 decoder // see https://github.com/merbanan/rtl_433/pull/2815 // & https://github.com/merbanan/rtl_433/pull/2817 +// 20240213 Added PM1.0 to air quality (PM) sensor decoder // // ToDo: // - @@ -1205,8 +1206,16 @@ DecodeStatus WeatherSensor::decodeBresser7In1Payload(const uint8_t *msg, uint8_t } else if (s_type == SENSOR_TYPE_AIR_PM) { + #if CORE_DEBUG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG + uint16_t pn1 = (msgw[14] & 0x0f) * 1000 + (msgw[15] >> 4) * 100 + (msgw[15] & 0x0f) * 10 + (msgw[16] >> 4); + uint16_t pn2 = (msgw[17] >> 4) * 100 + (msgw[17] & 0x0f) * 10 + (msgw[18] >> 4); + uint16_t pn3 = (msgw[19] >> 4) * 100 + (msgw[19] & 0x0f) * 10 + (msgw[20] >> 4); + #endif + log_d("PN1: %04d PN2: %04d PN3: %04d", pn1, pn2, pn3); + sensor[slot].pm.pm_1_0 = (msgw[8] & 0x0f) * 1000 + (msgw[9] >> 4) * 100 + (msgw[9] & 0x0f) * 10 + (msgw[10] >> 4); sensor[slot].pm.pm_2_5 = (msgw[10] & 0x0f) * 1000 + (msgw[11] >> 4) * 100 + (msgw[11] & 0x0f) * 10 + (msgw[12] >> 4); sensor[slot].pm.pm_10 = (msgw[12] & 0x0f) * 1000 + (msgw[13] >> 4) * 100 + (msgw[13] & 0x0f) * 10 + (msgw[14] >> 4); + sensor[slot].pm.pm_1_0_init = ((msgw[10] >> 4) & 0x0f) == 0x0f; sensor[slot].pm.pm_2_5_init = ((msgw[12] >> 4) & 0x0f) == 0x0f; sensor[slot].pm.pm_10_init = ((msgw[14] >> 4) & 0x0f) == 0x0f; } diff --git a/examples/BresserWeatherSensorMQTTCustom/src/WeatherSensor.h b/examples/BresserWeatherSensorMQTTCustom/src/WeatherSensor.h index b1400bb0..f9614c88 100644 --- a/examples/BresserWeatherSensorMQTTCustom/src/WeatherSensor.h +++ b/examples/BresserWeatherSensorMQTTCustom/src/WeatherSensor.h @@ -72,6 +72,7 @@ // 20240207 Added sensors for CO2, P/N 7009977 and HCHO/VOC, P/N 7009978 // see https://github.com/merbanan/rtl_433/pull/2815 // & https://github.com/merbanan/rtl_433/pull/2817 +// 20240213 Added PM1.0 to air quality (PM) sensor decoder // // ToDo: // - @@ -247,8 +248,10 @@ class WeatherSensor { }; struct AirPM { + uint16_t pm_1_0; //!< air quality PM1.0 in µg/m³ uint16_t pm_2_5; //!< air quality PM2.5 in µg/m³ uint16_t pm_10; //!< air quality PM10 in µg/m³ + uint16_t pm_1_0_init; //!< measurement value invalid due to initialization bool pm_2_5_init; //!< measurement value invalid due to initialization bool pm_10_init; //!< measurement value invalid due to initialization }; diff --git a/src/WeatherSensor.cpp b/src/WeatherSensor.cpp index 0e47635f..d5a40e28 100644 --- a/src/WeatherSensor.cpp +++ b/src/WeatherSensor.cpp @@ -84,6 +84,7 @@ // 20240208 Added sensors for CO2, P/N 7009977 and HCHO/VOC, P/N 7009978 to 7-in-1 decoder // see https://github.com/merbanan/rtl_433/pull/2815 // & https://github.com/merbanan/rtl_433/pull/2817 +// 20240213 Added PM1.0 to air quality (PM) sensor decoder // // ToDo: // - @@ -1205,8 +1206,16 @@ DecodeStatus WeatherSensor::decodeBresser7In1Payload(const uint8_t *msg, uint8_t } else if (s_type == SENSOR_TYPE_AIR_PM) { + #if CORE_DEBUG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG + uint16_t pn1 = (msgw[14] & 0x0f) * 1000 + (msgw[15] >> 4) * 100 + (msgw[15] & 0x0f) * 10 + (msgw[16] >> 4); + uint16_t pn2 = (msgw[17] >> 4) * 100 + (msgw[17] & 0x0f) * 10 + (msgw[18] >> 4); + uint16_t pn3 = (msgw[19] >> 4) * 100 + (msgw[19] & 0x0f) * 10 + (msgw[20] >> 4); + #endif + log_d("PN1: %04d PN2: %04d PN3: %04d", pn1, pn2, pn3); + sensor[slot].pm.pm_1_0 = (msgw[8] & 0x0f) * 1000 + (msgw[9] >> 4) * 100 + (msgw[9] & 0x0f) * 10 + (msgw[10] >> 4); sensor[slot].pm.pm_2_5 = (msgw[10] & 0x0f) * 1000 + (msgw[11] >> 4) * 100 + (msgw[11] & 0x0f) * 10 + (msgw[12] >> 4); sensor[slot].pm.pm_10 = (msgw[12] & 0x0f) * 1000 + (msgw[13] >> 4) * 100 + (msgw[13] & 0x0f) * 10 + (msgw[14] >> 4); + sensor[slot].pm.pm_1_0_init = ((msgw[10] >> 4) & 0x0f) == 0x0f; sensor[slot].pm.pm_2_5_init = ((msgw[12] >> 4) & 0x0f) == 0x0f; sensor[slot].pm.pm_10_init = ((msgw[14] >> 4) & 0x0f) == 0x0f; } diff --git a/src/WeatherSensor.h b/src/WeatherSensor.h index b1400bb0..f9614c88 100644 --- a/src/WeatherSensor.h +++ b/src/WeatherSensor.h @@ -72,6 +72,7 @@ // 20240207 Added sensors for CO2, P/N 7009977 and HCHO/VOC, P/N 7009978 // see https://github.com/merbanan/rtl_433/pull/2815 // & https://github.com/merbanan/rtl_433/pull/2817 +// 20240213 Added PM1.0 to air quality (PM) sensor decoder // // ToDo: // - @@ -247,8 +248,10 @@ class WeatherSensor { }; struct AirPM { + uint16_t pm_1_0; //!< air quality PM1.0 in µg/m³ uint16_t pm_2_5; //!< air quality PM2.5 in µg/m³ uint16_t pm_10; //!< air quality PM10 in µg/m³ + uint16_t pm_1_0_init; //!< measurement value invalid due to initialization bool pm_2_5_init; //!< measurement value invalid due to initialization bool pm_10_init; //!< measurement value invalid due to initialization };