2024-04-29 22:10:49 +12:00
|
|
|
|
#include "configuration.h"
|
|
|
|
|
|
|
Unify the native display config between legacy display and MUI (#6838)
* Add missed include
* Another Warning fix
* Add another HAS_SCREEN
* Namespace fixes
* Removed depricated destination types and re-factored destination screen
* Get rid of Arduino Strings
* Clean up after Copilot
* SixthLine Def, Screen Rename
Added Sixth Line Definition Screen Rename, and Automatic Line Adjustment
* Consistency is hard - fixed "Sixth"
* System Frame Updates
Adjusted line construction to ensure we fit maximum content per screen.
* Fix up notifications
* Add a couple more ifdef HAS_SCREEN lines
* Add screen->isOverlayBannerShowing()
* Don't forget the invert!
* Adjust Nodelist Center Divider
Adjust Nodelist Center Divider
* Fix variable casting
* Fix entryText variable as empty before update to fix validation
* Altitude is int32_t
* Update PowerTelemetry to have correct data type
* Fix cppcheck warnings (#6945)
* Fix cppcheck warnings
* Adjust logic in Power.cpp for power sensor
---------
Co-authored-by: Jason P <applewiz@mac.com>
* More pixel wrangling so things line up NodeList edition
* Adjust NodeList alignments and plumb some background padding for a possible title fix
* Better alignment for banner notifications
* Move title into drawCommonHeader; initial screen tested
* Fonts make spacing items difficult
* Improved beeping booping and other buzzer based feedback (#6947)
* Improved beeping booping and other buzzer based feedback
* audible button feedback (#6949)
* Refactor
---------
Co-authored-by: todd-herbert <herbert.todd@gmail.com>
* Sandpapered the corners of the notification popup
* Finalize drawCommonHeader migration
* Update Title of Favorite Node Screens
* Update node metric alignment on LoRa screen
* Update the border for popups to separate it from background
* Update PaxcounterModule.cpp with CommonHeader
* Update WiFi screen with CommonHeader and related data reflow
* It was not, in fact, pointing up
* Fix build on wismeshtap
* T-deck trackball debounce
* Fix uptime on Device Focused page to actually detail
* Update Sys screen for new uptime, add label to Freq/Chan on LoRa
* Don't display DOP any longer, make Uptime consistent
* Revert Uptime change on Favorites, Apply to Device Focused
* Label the satelite number to avoid confusion
* Boop boop boop boop
* Correct GPS positioning and string consistency across strings for GPS
* Fix GPS text alignment
* Enable canned messages by default
* Don't wake screen on new nodes
* Cannedmessage list emote support added
* Fn+e emote picker for freetext screen
* Actually block CannedInput actions while display is shown
* Add selection menu to bannerOverlay
* Off by one
* Move to unified text layouts and spacing
* Still my Fav without an "e"
* Fully remove EVENT_NODEDB_UPDATED
* Simply LoRa screen
* Make some char pointers const to fix compilation on native targets
* Update drawCompassNorth to include radius
* Fix warning
* button thread cleanup
* Pull OneButton handling from PowerFSM and add MUI switch (#6973)
* Trunk
* Onebutton Menu Support
* Add temporary clock icon
* Add gps location to fsi
* Banner message state reset
* Cast to char to satisfy compiler
* Better fast handling of input during banner
* Fix warning
* Derp
* oops
* Update ref
* Wire buzzer_mode
* remove legacy string->print()
* Only init screen if one found
* Unsigned Char
* More buttonThread cleaning
* screen.cpp button handling cleanup
* The Great Event Rename of 2025
* Fix the Radiomaster
* Missed trackball type change
* Remove unused function
* Make ButtonThread an InputBroker
* Coffee hadn't kicked in yet
* Add clock icon for Navigation Bar
* Restore clock screen definition code - whoops
* ExternalNotifications now observe inputBroker
* Clock rework (#6992)
* Move Clock bits into ClockRenderer space
* Rework clock into all device navigation
* T-Watch Actually Builds Different
* Compile fix
---------
Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
* Add AM/PM to Digital Clock
* Flip Seconds and AM/PM on Clock Display
* Tik-tok pixels are hard
* Fix builds on Thinknode M1
* Check for GPS and don't crash
* Don't endif til the end
* Rework the OneButton thread to be much less of a mess. (#6997)
* Rework the OneButton thread to be much less of a mess. And break lots of targets temporarily
* Update src/input/ButtonThread.h
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix GPS toggle
* Send the shutdown event, not just the kbchar
* Honor the back button in a notificaiton popup
* Draw the right size box for popup with options
* Try to un-break all the things
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* 24-hour Clock Should have leading zero, but not 12-hour
* Fixup some compile errors
* Add intRoutine to ButtonThread init, to get more responsive user button back
* Add Timezone picker
* Fix Warning
* Optionally set the initial selection for the chooser popup
* Make back buttons work in canned messages
* Drop the wrapper classes
* LonPressTime now configurable
* Clock Frame can not longer be blank; just add valid time
* Back buttons everywhere!
* Key Verification confirm banner
* Make Elecrow M* top button a back button
* Add settings saves
* EInk responsiveness fixes
* Linux Input Fixes
* Add Native Trackball/Joystick support, and move UserButton to Input
* No Flight Stick Mode
* Send input event
* Add Channel Utilization to Device Focused frame
* Don't shift screens when we draw new ones
* Add showOverlayBanner arguments to no-op
* trunk
* Default Native trackball to NC
* Fix crash in simulator mode
* Add longLong button press
* Get the args right
* Adjust Bluetooth Pairing Screen to account for bottom navigation.
* Trackball everywhere, and unPhone buttons
* Remap visionmaster secondary button to TB_UP
* Kill ScanAndSelect
* trunk
* No longer need the canned messages input filter
* All Canned All the time
* Fix stm32 compile error regarding inputBroker
* Unify tft lineheights (#7033)
* Create variable line heights based upon SCREEN_HEIGHT
* Refactor textPositions into method -> getTextPositions
* Update SharedUIDisplay.h
---------
Co-authored-by: Jason P <applewiz@mac.com>
* Adjust top distance for larger displays
* Adjust icon sizes for larger displays
* Fix Paxcounter compile errors after code updates
* Pixel wrangling to make larger screens fit better
* Alert frame has precedence over banner -- for now
* Unify on ALT_BUTTON
* Align AM/PM to the digit, not the segment on larger displays
* Move some global pin defines into configuration.h
* Scaffolding for BMM150 9-axis gyro
* Alt button behavior
* Don't add the blank GPS frames without HAS_GPS
* EVENT_NODEDB_UPDATED has been retired
* Clean out LOG_WARN messages from debugging
* Add dismiss message function
* Minor buttonThread cleanup
* Add BMM150 support
* Clean up last warning from dev
* Simplify bmm150 init return logic
* Add option to reply to messages
* Add minimal menu upon selecting home screen
* Move Messages to slot 2, rename GPS to Position, move variables nearer functional usage in Screen.cpp
* Properly dismiss message
* T-Deck Trackball press is not user button
* Add select on favorite frame to launch cannedMessage DM
* Minor wording change
* Less capital letters
* Fix empty message check, time isn't reliable
* drop dead code
* Make UIRenderer a static class instead of namespace
* Fix the select on favorite
* Check if message is empty early and then 'return'
* Add kb_found, and show the option to launch freetype if appropriate
* Ignore impossible touchscreen touches
* Auto scroll fix
* Move linebreak after "from" for banners to maximize screen usage.
* Center "No messages to show" on Message frame
* Start consolidating buzzer behavior
* Fixed signed / unsigned warning
* Cast second parameter of max() to make some targets happy
* Cast kbchar to (char) to make arduino string happy
* Shorten the notice of "No messages"
* Add buzzer mode chooser
* Add regionPicker to Lora icon
* Reduce line spacing and reorder Position screen to resolve overlapping issues
* Update message titles, fix GPS icons, add Back options
* Leftover boops
* Remove chirp
* Make the region selection dismissable when a region is already set
* Add read-aloud functionality on messages w/ esp8266sam
* "Last Heard" is a better label
* tweak the beep
* 5 options
* properly tear down freetext upon cancel
* de-convelute canned messages just a bit
* Correct height of Mail icon in navigation bar
* Remove unused warning
* Consolidate time methods into TimeFormatters
* Oops
* Change LoRa Picker Cancel to Back
* Tweak selection characters on Banner
* Message render not scrolling on 5th line
* More fixes for message scrolling
* Remove the safety next on text overflow - we found that root cause
* Add pin definitions to fix compilation for obscure target
* Don't let the touchscreen send unitialized kbchar values
* Make virtual KB just a bit quicker
* No more double tap, swipe!
* Left is left, and Right is right
* Update horizontal lightning bolt design
* Move from solid to dashed separator for Message Frame
* Single emote feature fix
* Manually sort overlapping elements for now
* Freetext and clearer choices
* Fix ESP32 InkHUD builds on the unify-tft branch (#7087)
* Remove BaseUI branding
* Capitalization is fun
* Revert Meshtastic Boot Frame Changes
* Add ANZ_433 LoRa region to picker
* Update settings.json
---------
Co-authored-by: HarukiToreda <116696711+HarukiToreda@users.noreply.github.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Jason P <applewiz@mac.com>
Co-authored-by: todd-herbert <herbert.todd@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-06-21 06:36:04 -05:00
|
|
|
|
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include("Adafruit_PM25AQI.h")
|
2024-04-27 18:05:39 +12:00
|
|
|
|
|
2023-02-04 13:07:14 -06:00
|
|
|
|
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
2024-05-03 14:26:57 +02:00
|
|
|
|
#include "AirQualityTelemetry.h"
|
2024-03-17 08:18:30 -05:00
|
|
|
|
#include "Default.h"
|
2023-02-04 13:07:14 -06:00
|
|
|
|
#include "MeshService.h"
|
|
|
|
|
|
#include "NodeDB.h"
|
|
|
|
|
|
#include "PowerFSM.h"
|
|
|
|
|
|
#include "RTC.h"
|
|
|
|
|
|
#include "Router.h"
|
2024-09-18 23:12:49 +08:00
|
|
|
|
#include "detect/ScanI2CTwoWire.h"
|
2023-02-04 13:07:14 -06:00
|
|
|
|
#include "main.h"
|
2024-09-23 08:58:14 -05:00
|
|
|
|
#include <Throttle.h>
|
2023-02-04 13:07:14 -06:00
|
|
|
|
|
2025-04-29 04:31:01 -07:00
|
|
|
|
#ifndef PMSA003I_WARMUP_MS
|
|
|
|
|
|
// from the PMSA003I datasheet:
|
|
|
|
|
|
// "Stable data should be got at least 30 seconds after the sensor wakeup
|
|
|
|
|
|
// from the sleep mode because of the fan’s performance."
|
|
|
|
|
|
#define PMSA003I_WARMUP_MS 30000
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2023-02-04 13:07:14 -06:00
|
|
|
|
int32_t AirQualityTelemetryModule::runOnce()
|
|
|
|
|
|
{
|
|
|
|
|
|
/*
|
|
|
|
|
|
Uncomment the preferences below if you want to use the module
|
|
|
|
|
|
without having to configure it from the PythonAPI or WebUI.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2023-02-23 13:05:24 -06:00
|
|
|
|
// moduleConfig.telemetry.air_quality_enabled = 1;
|
2023-02-04 13:07:14 -06:00
|
|
|
|
|
2023-02-23 13:05:24 -06:00
|
|
|
|
if (!(moduleConfig.telemetry.air_quality_enabled)) {
|
2023-02-04 13:07:14 -06:00
|
|
|
|
// If this module is not enabled, and the user doesn't want the display screen don't waste any OSThread time on it
|
|
|
|
|
|
return disable();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (firstTime) {
|
|
|
|
|
|
// This is the first time the OSThread library has called this function, so do some setup
|
2024-09-18 23:12:49 +08:00
|
|
|
|
firstTime = false;
|
2023-02-04 13:07:14 -06:00
|
|
|
|
|
2023-02-23 13:05:24 -06:00
|
|
|
|
if (moduleConfig.telemetry.air_quality_enabled) {
|
2024-11-04 12:16:25 -06:00
|
|
|
|
LOG_INFO("Air quality Telemetry: init");
|
2025-04-29 04:31:01 -07:00
|
|
|
|
|
|
|
|
|
|
#ifdef PMSA003I_ENABLE_PIN
|
|
|
|
|
|
// put the sensor to sleep on startup
|
|
|
|
|
|
pinMode(PMSA003I_ENABLE_PIN, OUTPUT);
|
|
|
|
|
|
digitalWrite(PMSA003I_ENABLE_PIN, LOW);
|
|
|
|
|
|
#endif /* PMSA003I_ENABLE_PIN */
|
|
|
|
|
|
|
2023-02-04 13:07:14 -06:00
|
|
|
|
if (!aqi.begin_I2C()) {
|
2024-10-26 12:03:28 +02:00
|
|
|
|
#ifndef I2C_NO_RESCAN
|
2024-11-04 19:15:59 -06:00
|
|
|
|
LOG_WARN("Could not establish i2c connection to AQI sensor. Rescan");
|
2024-09-18 23:12:49 +08:00
|
|
|
|
// rescan for late arriving sensors. AQI Module starts about 10 seconds into the boot so this is plenty.
|
|
|
|
|
|
uint8_t i2caddr_scan[] = {PMSA0031_ADDR};
|
|
|
|
|
|
uint8_t i2caddr_asize = 1;
|
|
|
|
|
|
auto i2cScanner = std::unique_ptr<ScanI2CTwoWire>(new ScanI2CTwoWire());
|
|
|
|
|
|
#if defined(I2C_SDA1)
|
|
|
|
|
|
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE1, i2caddr_scan, i2caddr_asize);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE, i2caddr_scan, i2caddr_asize);
|
|
|
|
|
|
auto found = i2cScanner->find(ScanI2C::DeviceType::PMSA0031);
|
|
|
|
|
|
if (found.type != ScanI2C::DeviceType::NONE) {
|
|
|
|
|
|
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I].first = found.address.address;
|
|
|
|
|
|
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I].second =
|
|
|
|
|
|
i2cScanner->fetchI2CBus(found.address);
|
2025-01-26 20:59:59 +01:00
|
|
|
|
return setStartDelay();
|
2024-09-18 23:12:49 +08:00
|
|
|
|
}
|
2024-10-26 12:03:28 +02:00
|
|
|
|
#endif
|
2023-02-04 13:07:14 -06:00
|
|
|
|
return disable();
|
|
|
|
|
|
}
|
2025-01-26 20:59:59 +01:00
|
|
|
|
return setStartDelay();
|
2023-02-04 13:07:14 -06:00
|
|
|
|
}
|
2024-09-18 23:12:49 +08:00
|
|
|
|
return disable();
|
2023-02-04 13:07:14 -06:00
|
|
|
|
} else {
|
|
|
|
|
|
// if we somehow got to a second run of this module with measurement disabled, then just wait forever
|
2023-02-23 13:05:24 -06:00
|
|
|
|
if (!moduleConfig.telemetry.air_quality_enabled)
|
2024-09-18 23:12:49 +08:00
|
|
|
|
return disable();
|
2023-02-04 13:07:14 -06:00
|
|
|
|
|
2025-04-29 04:31:01 -07:00
|
|
|
|
switch (state) {
|
|
|
|
|
|
#ifdef PMSA003I_ENABLE_PIN
|
|
|
|
|
|
case State::IDLE:
|
|
|
|
|
|
// sensor is in standby; fire it up and sleep
|
|
|
|
|
|
LOG_DEBUG("runOnce(): state = idle");
|
|
|
|
|
|
digitalWrite(PMSA003I_ENABLE_PIN, HIGH);
|
|
|
|
|
|
state = State::ACTIVE;
|
|
|
|
|
|
|
|
|
|
|
|
return PMSA003I_WARMUP_MS;
|
|
|
|
|
|
#endif /* PMSA003I_ENABLE_PIN */
|
|
|
|
|
|
case State::ACTIVE:
|
|
|
|
|
|
// sensor is already warmed up; grab telemetry and send it
|
|
|
|
|
|
LOG_DEBUG("runOnce(): state = active");
|
|
|
|
|
|
|
|
|
|
|
|
if (((lastSentToMesh == 0) ||
|
|
|
|
|
|
!Throttle::isWithinTimespanMs(lastSentToMesh, Default::getConfiguredOrDefaultMsScaled(
|
|
|
|
|
|
moduleConfig.telemetry.air_quality_interval,
|
|
|
|
|
|
default_telemetry_broadcast_interval_secs, numOnlineNodes))) &&
|
|
|
|
|
|
airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_SENSOR) &&
|
|
|
|
|
|
airTime->isTxAllowedAirUtil()) {
|
|
|
|
|
|
sendTelemetry();
|
|
|
|
|
|
lastSentToMesh = millis();
|
|
|
|
|
|
} else if (service->isToPhoneQueueEmpty()) {
|
|
|
|
|
|
// Just send to phone when it's not our time to send to mesh yet
|
|
|
|
|
|
// Only send while queue is empty (phone assumed connected)
|
|
|
|
|
|
sendTelemetry(NODENUM_BROADCAST, true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef PMSA003I_ENABLE_PIN
|
|
|
|
|
|
// put sensor back to sleep
|
|
|
|
|
|
digitalWrite(PMSA003I_ENABLE_PIN, LOW);
|
|
|
|
|
|
state = State::IDLE;
|
|
|
|
|
|
#endif /* PMSA003I_ENABLE_PIN */
|
|
|
|
|
|
|
|
|
|
|
|
return sendToPhoneIntervalMs;
|
|
|
|
|
|
default:
|
|
|
|
|
|
return disable();
|
2023-02-04 13:07:14 -06:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool AirQualityTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *t)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (t->which_variant == meshtastic_Telemetry_air_quality_metrics_tag) {
|
2025-07-28 23:51:38 +01:00
|
|
|
|
#if defined(DEBUG_PORT) && !defined(DEBUG_MUTE)
|
2023-02-04 13:07:14 -06:00
|
|
|
|
const char *sender = getSenderShortName(mp);
|
|
|
|
|
|
|
2024-10-14 06:11:43 +02:00
|
|
|
|
LOG_INFO("(Received from %s): pm10_standard=%i, pm25_standard=%i, pm100_standard=%i", sender,
|
2023-02-04 13:07:14 -06:00
|
|
|
|
t->variant.air_quality_metrics.pm10_standard, t->variant.air_quality_metrics.pm25_standard,
|
|
|
|
|
|
t->variant.air_quality_metrics.pm100_standard);
|
|
|
|
|
|
|
2024-10-14 06:11:43 +02:00
|
|
|
|
LOG_INFO(" | PM1.0(Environmental)=%i, PM2.5(Environmental)=%i, PM10.0(Environmental)=%i",
|
2023-02-04 13:07:14 -06:00
|
|
|
|
t->variant.air_quality_metrics.pm10_environmental, t->variant.air_quality_metrics.pm25_environmental,
|
|
|
|
|
|
t->variant.air_quality_metrics.pm100_environmental);
|
2023-05-13 13:33:14 +03:00
|
|
|
|
#endif
|
2023-02-04 13:07:14 -06:00
|
|
|
|
// release previous packet before occupying a new spot
|
|
|
|
|
|
if (lastMeasurementPacket != nullptr)
|
|
|
|
|
|
packetPool.release(lastMeasurementPacket);
|
|
|
|
|
|
|
|
|
|
|
|
lastMeasurementPacket = packetPool.allocCopy(mp);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false; // Let others look at this message also if they want
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-23 14:13:59 +02:00
|
|
|
|
bool AirQualityTelemetryModule::getAirQualityTelemetry(meshtastic_Telemetry *m)
|
2023-02-04 13:07:14 -06:00
|
|
|
|
{
|
|
|
|
|
|
if (!aqi.read(&data)) {
|
2024-11-04 19:15:59 -06:00
|
|
|
|
LOG_WARN("Skip send measurements. Could not read AQIn");
|
2023-02-04 13:07:14 -06:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-06-23 14:13:59 +02:00
|
|
|
|
m->time = getTime();
|
|
|
|
|
|
m->which_variant = meshtastic_Telemetry_air_quality_metrics_tag;
|
2024-12-15 09:59:14 -06:00
|
|
|
|
m->variant.air_quality_metrics.has_pm10_standard = true;
|
2024-06-23 14:13:59 +02:00
|
|
|
|
m->variant.air_quality_metrics.pm10_standard = data.pm10_standard;
|
2024-12-15 09:59:14 -06:00
|
|
|
|
m->variant.air_quality_metrics.has_pm25_standard = true;
|
2024-06-23 14:13:59 +02:00
|
|
|
|
m->variant.air_quality_metrics.pm25_standard = data.pm25_standard;
|
2024-12-15 09:59:14 -06:00
|
|
|
|
m->variant.air_quality_metrics.has_pm100_standard = true;
|
2024-06-23 14:13:59 +02:00
|
|
|
|
m->variant.air_quality_metrics.pm100_standard = data.pm100_standard;
|
2023-02-04 13:07:14 -06:00
|
|
|
|
|
2024-12-15 09:59:14 -06:00
|
|
|
|
m->variant.air_quality_metrics.has_pm10_environmental = true;
|
2024-06-23 14:13:59 +02:00
|
|
|
|
m->variant.air_quality_metrics.pm10_environmental = data.pm10_env;
|
2024-12-15 09:59:14 -06:00
|
|
|
|
m->variant.air_quality_metrics.has_pm25_environmental = true;
|
2024-06-23 14:13:59 +02:00
|
|
|
|
m->variant.air_quality_metrics.pm25_environmental = data.pm25_env;
|
2024-12-15 09:59:14 -06:00
|
|
|
|
m->variant.air_quality_metrics.has_pm100_environmental = true;
|
2024-06-23 14:13:59 +02:00
|
|
|
|
m->variant.air_quality_metrics.pm100_environmental = data.pm100_env;
|
2023-02-04 13:07:14 -06:00
|
|
|
|
|
2024-11-04 19:15:59 -06:00
|
|
|
|
LOG_INFO("Send: PM1.0(Standard)=%i, PM2.5(Standard)=%i, PM10.0(Standard)=%i", m->variant.air_quality_metrics.pm10_standard,
|
|
|
|
|
|
m->variant.air_quality_metrics.pm25_standard, m->variant.air_quality_metrics.pm100_standard);
|
2023-02-04 13:07:14 -06:00
|
|
|
|
|
2024-10-14 06:11:43 +02:00
|
|
|
|
LOG_INFO(" | PM1.0(Environmental)=%i, PM2.5(Environmental)=%i, PM10.0(Environmental)=%i",
|
2024-06-23 14:13:59 +02:00
|
|
|
|
m->variant.air_quality_metrics.pm10_environmental, m->variant.air_quality_metrics.pm25_environmental,
|
|
|
|
|
|
m->variant.air_quality_metrics.pm100_environmental);
|
|
|
|
|
|
|
2023-02-04 13:07:14 -06:00
|
|
|
|
return true;
|
|
|
|
|
|
}
|
2024-04-27 18:05:39 +12:00
|
|
|
|
|
2024-06-23 14:13:59 +02:00
|
|
|
|
meshtastic_MeshPacket *AirQualityTelemetryModule::allocReply()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (currentRequest) {
|
|
|
|
|
|
auto req = *currentRequest;
|
|
|
|
|
|
const auto &p = req.decoded;
|
|
|
|
|
|
meshtastic_Telemetry scratch;
|
|
|
|
|
|
meshtastic_Telemetry *decoded = NULL;
|
|
|
|
|
|
memset(&scratch, 0, sizeof(scratch));
|
|
|
|
|
|
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, &meshtastic_Telemetry_msg, &scratch)) {
|
|
|
|
|
|
decoded = &scratch;
|
|
|
|
|
|
} else {
|
2024-10-14 06:11:43 +02:00
|
|
|
|
LOG_ERROR("Error decoding AirQualityTelemetry module!");
|
2024-06-23 14:13:59 +02:00
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
// Check for a request for air quality metrics
|
|
|
|
|
|
if (decoded->which_variant == meshtastic_Telemetry_air_quality_metrics_tag) {
|
|
|
|
|
|
meshtastic_Telemetry m = meshtastic_Telemetry_init_zero;
|
|
|
|
|
|
if (getAirQualityTelemetry(&m)) {
|
2024-11-04 19:15:59 -06:00
|
|
|
|
LOG_INFO("Air quality telemetry reply to request");
|
2024-06-23 14:13:59 +02:00
|
|
|
|
return allocDataProtobuf(m);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool AirQualityTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
|
|
|
|
|
|
{
|
|
|
|
|
|
meshtastic_Telemetry m = meshtastic_Telemetry_init_zero;
|
|
|
|
|
|
if (getAirQualityTelemetry(&m)) {
|
|
|
|
|
|
meshtastic_MeshPacket *p = allocDataProtobuf(m);
|
|
|
|
|
|
p->to = dest;
|
|
|
|
|
|
p->decoded.want_response = false;
|
|
|
|
|
|
if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR)
|
|
|
|
|
|
p->priority = meshtastic_MeshPacket_Priority_RELIABLE;
|
|
|
|
|
|
else
|
|
|
|
|
|
p->priority = meshtastic_MeshPacket_Priority_BACKGROUND;
|
|
|
|
|
|
|
|
|
|
|
|
// release previous packet before occupying a new spot
|
|
|
|
|
|
if (lastMeasurementPacket != nullptr)
|
|
|
|
|
|
packetPool.release(lastMeasurementPacket);
|
|
|
|
|
|
|
|
|
|
|
|
lastMeasurementPacket = packetPool.allocCopy(*p);
|
|
|
|
|
|
if (phoneOnly) {
|
2024-11-04 12:16:25 -06:00
|
|
|
|
LOG_INFO("Send packet to phone");
|
2024-08-01 19:29:49 -05:00
|
|
|
|
service->sendToPhone(p);
|
2024-06-23 14:13:59 +02:00
|
|
|
|
} else {
|
2024-11-04 12:16:25 -06:00
|
|
|
|
LOG_INFO("Send packet to mesh");
|
2024-08-01 19:29:49 -05:00
|
|
|
|
service->sendToMesh(p, RX_SRC_LOCAL, true);
|
2024-06-23 14:13:59 +02:00
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-27 18:05:39 +12:00
|
|
|
|
#endif
|