firmware/src/modules/Telemetry/EnvironmentTelemetry.cpp
Tom Fifield 3ca6d2f230 [WIP] Add RAK12035VB Soil Moisture Sensor support
Introduce the RAK12035 sensor as an environmental telemetry sensor,
including necessary calibration checks and default values. Update
relevant files to integrate the sensor into the existing telemetry system.

This hardware is not just one module, but a couple.. RAK12023 and
RAK12035 is the component stack, the RAK12023 does not seem to matter
much and allows for multiple RAK12035 devices to be used.

Co-Authored-By: @Justin-Mann
2025-03-22 11:11:10 +11:00

747 lines
29 KiB
C++

#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "Default.h"
#include "EnvironmentTelemetry.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "PowerFSM.h"
#include "RTC.h"
#include "Router.h"
#include "UnitConversions.h"
#include "main.h"
#include "power.h"
#include "sleep.h"
#include "target_specific.h"
#include <OLEDDisplay.h>
#include <OLEDDisplayUi.h>
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR_EXTERNAL
// Sensors
#include "Sensor/AHT10.h"
#include "Sensor/BME280Sensor.h"
#include "Sensor/BME680Sensor.h"
#include "Sensor/BMP085Sensor.h"
#include "Sensor/BMP280Sensor.h"
#include "Sensor/BMP3XXSensor.h"
#include "Sensor/CGRadSensSensor.h"
#include "Sensor/DFRobotGravitySensor.h"
#include "Sensor/DFRobotLarkSensor.h"
#include "Sensor/DPS310Sensor.h"
#include "Sensor/LPS22HBSensor.h"
#include "Sensor/MCP9808Sensor.h"
#include "Sensor/MLX90632Sensor.h"
#include "Sensor/NAU7802Sensor.h"
#include "Sensor/OPT3001Sensor.h"
#include "Sensor/RCWL9620Sensor.h"
#include "Sensor/SHT31Sensor.h"
#include "Sensor/SHT4XSensor.h"
#include "Sensor/SHTC3Sensor.h"
#include "Sensor/TSL2591Sensor.h"
#include "Sensor/VEML7700Sensor.h"
#ifdef RAK4630
#include "Sensor/RAK12035Sensor.h"
#endif
BMP085Sensor bmp085Sensor;
BMP280Sensor bmp280Sensor;
BME280Sensor bme280Sensor;
BME680Sensor bme680Sensor;
DPS310Sensor dps310Sensor;
MCP9808Sensor mcp9808Sensor;
SHTC3Sensor shtc3Sensor;
LPS22HBSensor lps22hbSensor;
SHT31Sensor sht31Sensor;
VEML7700Sensor veml7700Sensor;
TSL2591Sensor tsl2591Sensor;
OPT3001Sensor opt3001Sensor;
SHT4XSensor sht4xSensor;
RCWL9620Sensor rcwl9620Sensor;
AHT10Sensor aht10Sensor;
MLX90632Sensor mlx90632Sensor;
DFRobotLarkSensor dfRobotLarkSensor;
DFRobotGravitySensor dfRobotGravitySensor;
NAU7802Sensor nau7802Sensor;
BMP3XXSensor bmp3xxSensor;
CGRadSensSensor cgRadSens;
#ifdef RAK4630
RAK12035Sensor rak12035Sensor;
#endif
#endif
#ifdef T1000X_SENSOR_EN
#include "Sensor/T1000xSensor.h"
T1000xSensor t1000xSensor;
#endif
#ifdef SENSECAP_INDICATOR
#include "Sensor/IndicatorSensor.h"
IndicatorSensor indicatorSensor;
#endif
#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10
#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true
#include "graphics/ScreenFonts.h"
#include <Throttle.h>
int32_t EnvironmentTelemetryModule::runOnce()
{
if (sleepOnNextExecution == true) {
sleepOnNextExecution = false;
uint32_t nightyNightMs = Default::getConfiguredOrDefaultMs(moduleConfig.telemetry.environment_update_interval,
default_telemetry_broadcast_interval_secs);
LOG_DEBUG("Sleep for %ims, then awake to send metrics again", nightyNightMs);
doDeepSleep(nightyNightMs, true, false);
}
uint32_t result = UINT32_MAX;
/*
Uncomment the preferences below if you want to use the module
without having to configure it from the PythonAPI or WebUI.
*/
// moduleConfig.telemetry.environment_measurement_enabled = 1;
// moduleConfig.telemetry.environment_screen_enabled = 1;
// moduleConfig.telemetry.environment_update_interval = 15;
if (!(moduleConfig.telemetry.environment_measurement_enabled || moduleConfig.telemetry.environment_screen_enabled ||
ENVIRONMENTAL_TELEMETRY_MODULE_ENABLE)) {
// 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
firstTime = 0;
if (moduleConfig.telemetry.environment_measurement_enabled || ENVIRONMENTAL_TELEMETRY_MODULE_ENABLE) {
LOG_INFO("Environment Telemetry: init");
#ifdef SENSECAP_INDICATOR
result = indicatorSensor.runOnce();
#endif
#ifdef T1000X_SENSOR_EN
result = t1000xSensor.runOnce();
#elif !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR_EXTERNAL
if (dfRobotLarkSensor.hasSensor())
result = dfRobotLarkSensor.runOnce();
if (dfRobotGravitySensor.hasSensor())
result = dfRobotGravitySensor.runOnce();
if (bmp085Sensor.hasSensor())
result = bmp085Sensor.runOnce();
if (bmp280Sensor.hasSensor())
result = bmp280Sensor.runOnce();
if (bme280Sensor.hasSensor())
result = bme280Sensor.runOnce();
if (bmp3xxSensor.hasSensor())
result = bmp3xxSensor.runOnce();
if (bme680Sensor.hasSensor())
result = bme680Sensor.runOnce();
if (dps310Sensor.hasSensor())
result = dps310Sensor.runOnce();
if (mcp9808Sensor.hasSensor())
result = mcp9808Sensor.runOnce();
if (shtc3Sensor.hasSensor())
result = shtc3Sensor.runOnce();
if (lps22hbSensor.hasSensor())
result = lps22hbSensor.runOnce();
if (sht31Sensor.hasSensor())
result = sht31Sensor.runOnce();
if (sht4xSensor.hasSensor())
result = sht4xSensor.runOnce();
if (ina219Sensor.hasSensor())
result = ina219Sensor.runOnce();
if (ina260Sensor.hasSensor())
result = ina260Sensor.runOnce();
if (ina3221Sensor.hasSensor())
result = ina3221Sensor.runOnce();
if (veml7700Sensor.hasSensor())
result = veml7700Sensor.runOnce();
if (tsl2591Sensor.hasSensor())
result = tsl2591Sensor.runOnce();
if (opt3001Sensor.hasSensor())
result = opt3001Sensor.runOnce();
if (rcwl9620Sensor.hasSensor())
result = rcwl9620Sensor.runOnce();
if (aht10Sensor.hasSensor())
result = aht10Sensor.runOnce();
if (mlx90632Sensor.hasSensor())
result = mlx90632Sensor.runOnce();
if (nau7802Sensor.hasSensor())
result = nau7802Sensor.runOnce();
if (max17048Sensor.hasSensor())
result = max17048Sensor.runOnce();
if (cgRadSens.hasSensor())
result = cgRadSens.runOnce();
// this only works on the wismesh hub with the solar option. This is not an I2C sensor, so we don't need the
// sensormap here.
#ifdef HAS_RAKPROT
result = rak9154Sensor.runOnce();
#endif
#ifdef RAK4630
if (rak12035Sensor.hasSensor()) {
result = rak12035Sensor.runOnce();
}
#endif
#endif
}
// it's possible to have this module enabled, only for displaying values on the screen.
// therefore, we should only enable the sensor loop if measurement is also enabled
return result == UINT32_MAX ? disable() : setStartDelay();
} else {
// if we somehow got to a second run of this module with measurement disabled, then just wait forever
if (!moduleConfig.telemetry.environment_measurement_enabled && !ENVIRONMENTAL_TELEMETRY_MODULE_ENABLE) {
return disable();
} else {
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR_EXTERNAL
if (bme680Sensor.hasSensor())
result = bme680Sensor.runTrigger();
#endif
}
if (((lastSentToMesh == 0) ||
!Throttle::isWithinTimespanMs(lastSentToMesh, Default::getConfiguredOrDefaultMsScaled(
moduleConfig.telemetry.environment_update_interval,
default_telemetry_broadcast_interval_secs, numOnlineNodes))) &&
airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_SENSOR) &&
airTime->isTxAllowedAirUtil()) {
sendTelemetry();
lastSentToMesh = millis();
} else if (((lastSentToPhone == 0) || !Throttle::isWithinTimespanMs(lastSentToPhone, sendToPhoneIntervalMs)) &&
(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);
lastSentToPhone = millis();
}
}
return min(sendToPhoneIntervalMs, result);
}
bool EnvironmentTelemetryModule::wantUIFrame()
{
return moduleConfig.telemetry.environment_screen_enabled;
}
void EnvironmentTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL);
if (lastMeasurementPacket == nullptr) {
// If there's no valid packet, display "Environment"
display->drawString(x, y, "Environment");
display->drawString(x, y += _fontHeight(FONT_SMALL), "No measurement");
return;
}
// Decode the last measurement packet
meshtastic_Telemetry lastMeasurement;
uint32_t agoSecs = service->GetTimeSinceMeshPacket(lastMeasurementPacket);
const char *lastSender = getSenderShortName(*lastMeasurementPacket);
const meshtastic_Data &p = lastMeasurementPacket->decoded;
if (!pb_decode_from_bytes(p.payload.bytes, p.payload.size, &meshtastic_Telemetry_msg, &lastMeasurement)) {
display->drawString(x, y, "Measurement Error");
LOG_ERROR("Unable to decode last packet");
return;
}
// Display "Env. From: ..." on its own
display->drawString(x, y, "Env. From: " + String(lastSender) + " (" + String(agoSecs) + "s)");
// Prepare sensor data strings
String sensorData[10];
int sensorCount = 0;
if (lastMeasurement.variant.environment_metrics.has_temperature ||
lastMeasurement.variant.environment_metrics.has_relative_humidity) {
String last_temp = String(lastMeasurement.variant.environment_metrics.temperature, 0) + "°C";
if (moduleConfig.telemetry.environment_display_fahrenheit) {
last_temp =
String(UnitConversions::CelsiusToFahrenheit(lastMeasurement.variant.environment_metrics.temperature), 0) + "°F";
}
sensorData[sensorCount++] =
"Temp/Hum: " + last_temp + " / " + String(lastMeasurement.variant.environment_metrics.relative_humidity, 0) + "%";
}
if (lastMeasurement.variant.environment_metrics.barometric_pressure != 0) {
sensorData[sensorCount++] =
"Press: " + String(lastMeasurement.variant.environment_metrics.barometric_pressure, 0) + "hPA";
}
if (lastMeasurement.variant.environment_metrics.voltage != 0) {
sensorData[sensorCount++] = "Volt/Cur: " + String(lastMeasurement.variant.environment_metrics.voltage, 0) + "V / " +
String(lastMeasurement.variant.environment_metrics.current, 0) + "mA";
}
if (lastMeasurement.variant.environment_metrics.iaq != 0) {
sensorData[sensorCount++] = "IAQ: " + String(lastMeasurement.variant.environment_metrics.iaq);
}
if (lastMeasurement.variant.environment_metrics.distance != 0) {
sensorData[sensorCount++] = "Water Level: " + String(lastMeasurement.variant.environment_metrics.distance, 0) + "mm";
}
if (lastMeasurement.variant.environment_metrics.weight != 0) {
sensorData[sensorCount++] = "Weight: " + String(lastMeasurement.variant.environment_metrics.weight, 0) + "kg";
}
if (lastMeasurement.variant.environment_metrics.radiation != 0) {
sensorData[sensorCount++] = "Rad: " + String(lastMeasurement.variant.environment_metrics.radiation, 2) + "µR/h";
}
if (lastMeasurement.variant.environment_metrics.lux != 0) {
sensorData[sensorCount++] = "Illuminance: " + String(lastMeasurement.variant.environment_metrics.lux, 2) + "lx";
}
if (lastMeasurement.variant.environment_metrics.white_lux != 0) {
sensorData[sensorCount++] = "W_Lux: " + String(lastMeasurement.variant.environment_metrics.white_lux, 2) + "lx";
}
static int scrollOffset = 0;
static bool scrollingDown = true;
static uint32_t lastScrollTime = millis();
// Determine how many lines we can fit on display
// Calculated once only: display dimensions don't change during runtime.
static int maxLines = 0;
if (!maxLines) {
const int16_t paddingTop = _fontHeight(FONT_SMALL); // Heading text
const int16_t paddingBottom = 8; // Indicator dots
maxLines = (display->getHeight() - paddingTop - paddingBottom) / _fontHeight(FONT_SMALL);
assert(maxLines > 0);
}
// Draw as many lines of data as we can fit
int linesToShow = min(maxLines, sensorCount);
for (int i = 0; i < linesToShow; i++) {
int index = (scrollOffset + i) % sensorCount;
display->drawString(x, y += _fontHeight(FONT_SMALL), sensorData[index]);
}
// Only scroll if there are more than 3 sensor data lines
if (sensorCount > 3) {
// Update scroll offset every 5 seconds
if (millis() - lastScrollTime > 5000) {
if (scrollingDown) {
scrollOffset++;
if (scrollOffset + linesToShow >= sensorCount) {
scrollingDown = false;
}
} else {
scrollOffset--;
if (scrollOffset <= 0) {
scrollingDown = true;
}
}
lastScrollTime = millis();
}
}
}
bool EnvironmentTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *t)
{
if (t->which_variant == meshtastic_Telemetry_environment_metrics_tag) {
#ifdef DEBUG_PORT
const char *sender = getSenderShortName(mp);
LOG_INFO("(Received from %s): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, "
"temperature=%f",
sender, t->variant.environment_metrics.barometric_pressure, t->variant.environment_metrics.current,
t->variant.environment_metrics.gas_resistance, t->variant.environment_metrics.relative_humidity,
t->variant.environment_metrics.temperature);
LOG_INFO("(Received from %s): voltage=%f, IAQ=%d, distance=%f, lux=%f, white_lux=%f", sender,
t->variant.environment_metrics.voltage, t->variant.environment_metrics.iaq,
t->variant.environment_metrics.distance, t->variant.environment_metrics.lux,
t->variant.environment_metrics.white_lux);
LOG_INFO("(Received from %s): wind speed=%fm/s, direction=%d degrees, weight=%fkg", sender,
t->variant.environment_metrics.wind_speed, t->variant.environment_metrics.wind_direction,
t->variant.environment_metrics.weight);
LOG_INFO("(Received from %s): radiation=%fµR/h", sender, t->variant.environment_metrics.radiation);
#endif
// 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
}
bool EnvironmentTelemetryModule::getEnvironmentTelemetry(meshtastic_Telemetry *m)
{
bool valid = true;
bool hasSensor = false;
m->time = getTime();
m->which_variant = meshtastic_Telemetry_environment_metrics_tag;
m->variant.environment_metrics = meshtastic_EnvironmentMetrics_init_zero;
#ifdef SENSECAP_INDICATOR
valid = valid && indicatorSensor.getMetrics(m);
hasSensor = true;
#endif
#ifdef T1000X_SENSOR_EN // add by WayenWeng
valid = valid && t1000xSensor.getMetrics(m);
hasSensor = true;
#else
if (dfRobotLarkSensor.hasSensor()) {
valid = valid && dfRobotLarkSensor.getMetrics(m);
hasSensor = true;
}
if (dfRobotGravitySensor.hasSensor()) {
valid = valid && dfRobotGravitySensor.getMetrics(m);
hasSensor = true;
}
if (sht31Sensor.hasSensor()) {
valid = valid && sht31Sensor.getMetrics(m);
hasSensor = true;
}
if (sht4xSensor.hasSensor()) {
valid = valid && sht4xSensor.getMetrics(m);
hasSensor = true;
}
if (lps22hbSensor.hasSensor()) {
valid = valid && lps22hbSensor.getMetrics(m);
hasSensor = true;
}
if (shtc3Sensor.hasSensor()) {
valid = valid && shtc3Sensor.getMetrics(m);
hasSensor = true;
}
if (bmp085Sensor.hasSensor()) {
valid = valid && bmp085Sensor.getMetrics(m);
hasSensor = true;
}
if (bmp280Sensor.hasSensor()) {
valid = valid && bmp280Sensor.getMetrics(m);
hasSensor = true;
}
if (bme280Sensor.hasSensor()) {
valid = valid && bme280Sensor.getMetrics(m);
hasSensor = true;
}
if (bmp3xxSensor.hasSensor()) {
valid = valid && bmp3xxSensor.getMetrics(m);
hasSensor = true;
}
if (bme680Sensor.hasSensor()) {
valid = valid && bme680Sensor.getMetrics(m);
hasSensor = true;
}
if (dps310Sensor.hasSensor()) {
valid = valid && dps310Sensor.getMetrics(m);
hasSensor = true;
}
if (mcp9808Sensor.hasSensor()) {
valid = valid && mcp9808Sensor.getMetrics(m);
hasSensor = true;
}
if (ina219Sensor.hasSensor()) {
valid = valid && ina219Sensor.getMetrics(m);
hasSensor = true;
}
if (ina260Sensor.hasSensor()) {
valid = valid && ina260Sensor.getMetrics(m);
hasSensor = true;
}
if (ina3221Sensor.hasSensor()) {
valid = valid && ina3221Sensor.getMetrics(m);
hasSensor = true;
}
if (veml7700Sensor.hasSensor()) {
valid = valid && veml7700Sensor.getMetrics(m);
hasSensor = true;
}
if (tsl2591Sensor.hasSensor()) {
valid = valid && tsl2591Sensor.getMetrics(m);
hasSensor = true;
}
if (opt3001Sensor.hasSensor()) {
valid = valid && opt3001Sensor.getMetrics(m);
hasSensor = true;
}
if (mlx90632Sensor.hasSensor()) {
valid = valid && mlx90632Sensor.getMetrics(m);
hasSensor = true;
}
if (rcwl9620Sensor.hasSensor()) {
valid = valid && rcwl9620Sensor.getMetrics(m);
hasSensor = true;
}
if (nau7802Sensor.hasSensor()) {
valid = valid && nau7802Sensor.getMetrics(m);
hasSensor = true;
}
if (aht10Sensor.hasSensor()) {
if (!bmp280Sensor.hasSensor() && !bmp3xxSensor.hasSensor()) {
valid = valid && aht10Sensor.getMetrics(m);
hasSensor = true;
} else if (bmp280Sensor.hasSensor()) {
// prefer bmp280 temp if both sensors are present, fetch only humidity
meshtastic_Telemetry m_ahtx = meshtastic_Telemetry_init_zero;
LOG_INFO("AHTX0+BMP280 module detected: using temp from BMP280 and humy from AHTX0");
aht10Sensor.getMetrics(&m_ahtx);
m->variant.environment_metrics.relative_humidity = m_ahtx.variant.environment_metrics.relative_humidity;
m->variant.environment_metrics.has_relative_humidity = m_ahtx.variant.environment_metrics.has_relative_humidity;
} else {
// prefer bmp3xx temp if both sensors are present, fetch only humidity
meshtastic_Telemetry m_ahtx = meshtastic_Telemetry_init_zero;
LOG_INFO("AHTX0+BMP3XX module detected: using temp from BMP3XX and humy from AHTX0");
aht10Sensor.getMetrics(&m_ahtx);
m->variant.environment_metrics.relative_humidity = m_ahtx.variant.environment_metrics.relative_humidity;
m->variant.environment_metrics.has_relative_humidity = m_ahtx.variant.environment_metrics.has_relative_humidity;
}
}
if (max17048Sensor.hasSensor()) {
valid = valid && max17048Sensor.getMetrics(m);
hasSensor = true;
}
if (cgRadSens.hasSensor()) {
valid = valid && cgRadSens.getMetrics(m);
hasSensor = true;
}
#ifdef HAS_RAKPROT
valid = valid && rak9154Sensor.getMetrics(m);
hasSensor = true;
#endif
#ifdef RAK4630
if (rak12035Sensor.hasSensor()) {
valid = valid && rak12035Sensor.getMetrics(m);
hasSensor = true;
}
#endif
#endif
return valid && hasSensor;
}
meshtastic_MeshPacket *EnvironmentTelemetryModule::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 {
LOG_ERROR("Error decoding EnvironmentTelemetry module!");
return NULL;
}
// Check for a request for environment metrics
if (decoded->which_variant == meshtastic_Telemetry_environment_metrics_tag) {
meshtastic_Telemetry m = meshtastic_Telemetry_init_zero;
if (getEnvironmentTelemetry(&m)) {
LOG_INFO("Environment telemetry reply to request");
return allocDataProtobuf(m);
} else {
return NULL;
}
}
}
return NULL;
}
bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
{
meshtastic_Telemetry m = meshtastic_Telemetry_init_zero;
m.which_variant = meshtastic_Telemetry_environment_metrics_tag;
m.time = getTime();
#ifdef T1000X_SENSOR_EN
if (t1000xSensor.getMetrics(&m)) {
#else
if (getEnvironmentTelemetry(&m)) {
#endif
LOG_INFO("Send: barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, temperature=%f",
m.variant.environment_metrics.barometric_pressure, m.variant.environment_metrics.current,
m.variant.environment_metrics.gas_resistance, m.variant.environment_metrics.relative_humidity,
m.variant.environment_metrics.temperature);
LOG_INFO("Send: voltage=%f, IAQ=%d, distance=%f, lux=%f", m.variant.environment_metrics.voltage,
m.variant.environment_metrics.iaq, m.variant.environment_metrics.distance, m.variant.environment_metrics.lux);
LOG_INFO("Send: wind speed=%fm/s, direction=%d degrees, weight=%fkg", m.variant.environment_metrics.wind_speed,
m.variant.environment_metrics.wind_direction, m.variant.environment_metrics.weight);
LOG_INFO("Send: radiation=%fµR/h", m.variant.environment_metrics.radiation);
LOG_INFO("Send: soil_temperature=%f, soil_moisture=%u", m.variant.environment_metrics.soil_temperature,
m.variant.environment_metrics.soil_moisture);
sensor_read_error_count = 0;
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) {
LOG_INFO("Send packet to phone");
service->sendToPhone(p);
} else {
LOG_INFO("Send packet to mesh");
service->sendToMesh(p, RX_SRC_LOCAL, true);
if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR && config.power.is_power_saving) {
LOG_DEBUG("Start next execution in 5s, then sleep");
sleepOnNextExecution = true;
setIntervalFromNow(5000);
}
}
return true;
}
return false;
}
AdminMessageHandleResult EnvironmentTelemetryModule::handleAdminMessageForModule(const meshtastic_MeshPacket &mp,
meshtastic_AdminMessage *request,
meshtastic_AdminMessage *response)
{
AdminMessageHandleResult result = AdminMessageHandleResult::NOT_HANDLED;
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR_EXTERNAL
if (dfRobotLarkSensor.hasSensor()) {
result = dfRobotLarkSensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (dfRobotGravitySensor.hasSensor()) {
result = dfRobotGravitySensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (sht31Sensor.hasSensor()) {
result = sht31Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (lps22hbSensor.hasSensor()) {
result = lps22hbSensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (shtc3Sensor.hasSensor()) {
result = shtc3Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (bmp085Sensor.hasSensor()) {
result = bmp085Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (bmp280Sensor.hasSensor()) {
result = bmp280Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (bme280Sensor.hasSensor()) {
result = bme280Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (bmp3xxSensor.hasSensor()) {
result = bmp3xxSensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (bme680Sensor.hasSensor()) {
result = bme680Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (dps310Sensor.hasSensor()) {
result = dps310Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (mcp9808Sensor.hasSensor()) {
result = mcp9808Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (ina219Sensor.hasSensor()) {
result = ina219Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (ina260Sensor.hasSensor()) {
result = ina260Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (ina3221Sensor.hasSensor()) {
result = ina3221Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (veml7700Sensor.hasSensor()) {
result = veml7700Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (tsl2591Sensor.hasSensor()) {
result = tsl2591Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (opt3001Sensor.hasSensor()) {
result = opt3001Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (mlx90632Sensor.hasSensor()) {
result = mlx90632Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (rcwl9620Sensor.hasSensor()) {
result = rcwl9620Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (nau7802Sensor.hasSensor()) {
result = nau7802Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (aht10Sensor.hasSensor()) {
result = aht10Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (max17048Sensor.hasSensor()) {
result = max17048Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (cgRadSens.hasSensor()) {
result = cgRadSens.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
#ifdef RAK4630
if (rak12035Sensor.hasSensor()) {
result = rak12035Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
#endif
#endif
return result;
}
#endif