@@ -24,6 +24,14 @@ PMSA003ISensor pmsa003iSensor;
2424NullSensor pmsa003iSensor;
2525#endif
2626
27+ #if __has_include(<SensirionI2cScd4x.h>)
28+ #include " Sensor/SCD4XSensor.h"
29+ SCD4XSensor scd4xSensor;
30+ #else
31+ NullSensor scd4xSensor;
32+ #endif
33+
34+
2735int32_t AirQualityTelemetryModule::runOnce ()
2836{
2937 if (sleepOnNextExecution == true ) {
@@ -61,6 +69,9 @@ int32_t AirQualityTelemetryModule::runOnce()
6169
6270 if (pmsa003iSensor.hasSensor ())
6371 result = pmsa003iSensor.runOnce ();
72+
73+ if (scd4xSensor.hasSensor ())
74+ result = scd4xSensor.runOnce ();
6475 }
6576
6677 // it's possible to have this module enabled, only for displaying values on the screen.
@@ -143,7 +154,7 @@ void AirQualityTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiSta
143154
144155 // Check if any telemetry field has valid data
145156 bool hasAny = m.has_pm10_standard || m.has_pm25_standard || m.has_pm100_standard || m.has_pm10_environmental || m.has_pm25_environmental ||
146- m.has_pm100_environmental ;
157+ m.has_pm100_environmental || m. has_co2 ;
147158
148159 if (!hasAny) {
149160 display->drawString (x, currentY, " No Telemetry" );
@@ -170,6 +181,9 @@ void AirQualityTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiSta
170181 entries.push_back (" PM2.5: " + String (m.pm25_standard , 0 ) + " ug/m3" );
171182 if (m.has_pm100_standard )
172183 entries.push_back (" PM10.0: " + String (m.pm100_standard , 0 ) + " ug/m3" );
184+ if (m.has_co2 )
185+ entries.push_back (" CO2: " + String (m.co2 , 0 ) + " ppm" );
186+
173187
174188 // === Show first available metric on top-right of first line ===
175189 if (!entries.empty ()) {
@@ -210,6 +224,10 @@ bool AirQualityTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPack
210224 LOG_INFO (" | PM1.0(Environmental)=%i, PM2.5(Environmental)=%i, PM10.0(Environmental)=%i" ,
211225 t->variant .air_quality_metrics .pm10_environmental , t->variant .air_quality_metrics .pm25_environmental ,
212226 t->variant .air_quality_metrics .pm100_environmental );
227+
228+ LOG_INFO (" | CO2=%i, CO2_T=%f, CO2_H=%f" ,
229+ t->variant .air_quality_metrics .co2 , t->variant .air_quality_metrics .co2_temperature ,
230+ t->variant .air_quality_metrics .co2_humidity );
213231#endif
214232 // release previous packet before occupying a new spot
215233 if (lastMeasurementPacket != nullptr )
@@ -236,6 +254,11 @@ bool AirQualityTelemetryModule::getAirQualityTelemetry(meshtastic_Telemetry *m)
236254 hasSensor = true ;
237255 }
238256
257+ if (scd4xSensor.hasSensor ()) {
258+ valid = valid && scd4xSensor.getMetrics (m);
259+ hasSensor = true ;
260+ }
261+
239262 return valid && hasSensor;
240263}
241264
@@ -273,10 +296,24 @@ bool AirQualityTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
273296 m.which_variant = meshtastic_Telemetry_air_quality_metrics_tag;
274297 m.time = getTime ();
275298 if (getAirQualityTelemetry (&m)) {
276- LOG_INFO (" Send: pm10_standard=%f, pm25_standard=%f, pm100_standard=%f, pm10_environmental=%f, pm100_environmental=%f" ,
299+
300+ bool hasAnyPM = m.variant .air_quality_metrics .has_pm10_standard || m.variant .air_quality_metrics .has_pm25_standard || m.variant .air_quality_metrics .has_pm100_standard || m.variant .air_quality_metrics .has_pm10_environmental || m.variant .air_quality_metrics .has_pm25_environmental ||
301+ m.variant .air_quality_metrics .has_pm100_environmental ;
302+
303+ if (hasAnyPM) {
304+ LOG_INFO (" Send: pm10_standard=%f, pm25_standard=%f, pm100_standard=%f, pm10_environmental=%f, pm100_environmental=%f" ,
277305 m.variant .air_quality_metrics .pm10_standard , m.variant .air_quality_metrics .pm25_standard ,
278306 m.variant .air_quality_metrics .pm100_standard , m.variant .air_quality_metrics .pm10_environmental ,
279- m.variant .air_quality_metrics .pm100_environmental );
307+ m.variant .air_quality_metrics .pm25_environmental , m.variant .air_quality_metrics .pm100_environmental );
308+ }
309+
310+ bool hasAnyCO2 = m.variant .air_quality_metrics .has_co2 || m.variant .air_quality_metrics .has_co2_temperature || m.variant .air_quality_metrics .has_co2_humidity ;
311+
312+ if (hasAnyCO2) {
313+ LOG_INFO (" Send: co2=%i, co2_t=%f, co2_rh=%f" ,
314+ m.variant .air_quality_metrics .co2 , m.variant .air_quality_metrics .co2_temperature ,
315+ m.variant .air_quality_metrics .co2_humidity );
316+ }
280317
281318 meshtastic_MeshPacket *p = allocDataProtobuf (m);
282319 p->to = dest;
@@ -329,6 +366,11 @@ AdminMessageHandleResult AirQualityTelemetryModule::handleAdminMessageForModule(
329366 return result;
330367 }
331368
369+ if (scd4xSensor.hasSensor ()) {
370+ result = scd4xSensor.handleAdminMessage (mp, request, response);
371+ if (result != AdminMessageHandleResult::NOT_HANDLED)
372+ return result;
373+ }
332374
333375#endif
334376 return result;
0 commit comments