From 8078e03f5fea2af1e6dbc217c9fac5d3eb4d1029 Mon Sep 17 00:00:00 2001 From: GUVWAF <78759985+GUVWAF@users.noreply.github.com> Date: Sun, 23 Jun 2024 14:13:59 +0200 Subject: [PATCH] Implement replies for all telemetry types based on variant tag (#4164) * Implement replies for all telemetry types based on variant tag * Remove check for `ignoreRequest`: modules can set this, don't need to check --------- Co-authored-by: Ben Meadors --- src/modules/Telemetry/AirQualityTelemetry.cpp | 105 ++++++++++++------ src/modules/Telemetry/AirQualityTelemetry.h | 5 + src/modules/Telemetry/DeviceTelemetry.cpp | 29 +++-- .../Telemetry/EnvironmentTelemetry.cpp | 84 +++++++++----- src/modules/Telemetry/EnvironmentTelemetry.h | 5 + src/modules/Telemetry/PowerTelemetry.cpp | 77 +++++++++---- src/modules/Telemetry/PowerTelemetry.h | 5 + src/modules/esp32/PaxcounterModule.cpp | 6 +- 8 files changed, 222 insertions(+), 94 deletions(-) diff --git a/src/modules/Telemetry/AirQualityTelemetry.cpp b/src/modules/Telemetry/AirQualityTelemetry.cpp index 4f5fbcd13..ba043feab 100644 --- a/src/modules/Telemetry/AirQualityTelemetry.cpp +++ b/src/modules/Telemetry/AirQualityTelemetry.cpp @@ -85,53 +85,90 @@ bool AirQualityTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPack return false; // Let others look at this message also if they want } -bool AirQualityTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) +bool AirQualityTelemetryModule::getAirQualityTelemetry(meshtastic_Telemetry *m) { if (!aqi.read(&data)) { LOG_WARN("Skipping send measurements. Could not read AQIn\n"); return false; } - meshtastic_Telemetry m = meshtastic_Telemetry_init_zero; - m.time = getTime(); - m.which_variant = meshtastic_Telemetry_air_quality_metrics_tag; - m.variant.air_quality_metrics.pm10_standard = data.pm10_standard; - m.variant.air_quality_metrics.pm25_standard = data.pm25_standard; - m.variant.air_quality_metrics.pm100_standard = data.pm100_standard; + m->time = getTime(); + m->which_variant = meshtastic_Telemetry_air_quality_metrics_tag; + m->variant.air_quality_metrics.pm10_standard = data.pm10_standard; + m->variant.air_quality_metrics.pm25_standard = data.pm25_standard; + m->variant.air_quality_metrics.pm100_standard = data.pm100_standard; - m.variant.air_quality_metrics.pm10_environmental = data.pm10_env; - m.variant.air_quality_metrics.pm25_environmental = data.pm25_env; - m.variant.air_quality_metrics.pm100_environmental = data.pm100_env; + m->variant.air_quality_metrics.pm10_environmental = data.pm10_env; + m->variant.air_quality_metrics.pm25_environmental = data.pm25_env; + m->variant.air_quality_metrics.pm100_environmental = data.pm100_env; LOG_INFO("(Sending): PM1.0(Standard)=%i, PM2.5(Standard)=%i, PM10.0(Standard)=%i\n", - m.variant.air_quality_metrics.pm10_standard, m.variant.air_quality_metrics.pm25_standard, - m.variant.air_quality_metrics.pm100_standard); + m->variant.air_quality_metrics.pm10_standard, m->variant.air_quality_metrics.pm25_standard, + m->variant.air_quality_metrics.pm100_standard); LOG_INFO(" | PM1.0(Environmental)=%i, PM2.5(Environmental)=%i, PM10.0(Environmental)=%i\n", - m.variant.air_quality_metrics.pm10_environmental, m.variant.air_quality_metrics.pm25_environmental, - m.variant.air_quality_metrics.pm100_environmental); + m->variant.air_quality_metrics.pm10_environmental, m->variant.air_quality_metrics.pm25_environmental, + m->variant.air_quality_metrics.pm100_environmental); - 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("Sending packet to phone\n"); - service.sendToPhone(p); - } else { - LOG_INFO("Sending packet to mesh\n"); - service.sendToMesh(p, RX_SRC_LOCAL, true); - } return true; } +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 { + LOG_ERROR("Error decoding AirQualityTelemetry module!\n"); + 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)) { + LOG_INFO("Air quality telemetry replying to request\n"); + 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) { + LOG_INFO("Sending packet to phone\n"); + service.sendToPhone(p); + } else { + LOG_INFO("Sending packet to mesh\n"); + service.sendToMesh(p, RX_SRC_LOCAL, true); + } + return true; + } + + return false; +} + #endif \ No newline at end of file diff --git a/src/modules/Telemetry/AirQualityTelemetry.h b/src/modules/Telemetry/AirQualityTelemetry.h index eb0355001..9d09078b1 100644 --- a/src/modules/Telemetry/AirQualityTelemetry.h +++ b/src/modules/Telemetry/AirQualityTelemetry.h @@ -26,6 +26,11 @@ class AirQualityTelemetryModule : private concurrency::OSThread, public Protobuf */ virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *p) override; virtual int32_t runOnce() override; + /** Called to get current Air Quality data + @return true if it contains valid data + */ + bool getAirQualityTelemetry(meshtastic_Telemetry *m); + virtual meshtastic_MeshPacket *allocReply() override; /** * Send our Telemetry into the mesh */ diff --git a/src/modules/Telemetry/DeviceTelemetry.cpp b/src/modules/Telemetry/DeviceTelemetry.cpp index b64e8d113..9cc4bf6ea 100644 --- a/src/modules/Telemetry/DeviceTelemetry.cpp +++ b/src/modules/Telemetry/DeviceTelemetry.cpp @@ -52,14 +52,27 @@ bool DeviceTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket & meshtastic_MeshPacket *DeviceTelemetryModule::allocReply() { - if (ignoreRequest) { - return NULL; + 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 DeviceTelemetry module!\n"); + return NULL; + } + // Check for a request for device metrics + if (decoded->which_variant == meshtastic_Telemetry_device_metrics_tag) { + LOG_INFO("Device telemetry replying to request\n"); + + meshtastic_Telemetry telemetry = getDeviceTelemetry(); + return allocDataProtobuf(telemetry); + } } - - LOG_INFO("Device telemetry replying to request\n"); - - meshtastic_Telemetry telemetry = getDeviceTelemetry(); - return allocDataProtobuf(telemetry); + return NULL; } meshtastic_Telemetry DeviceTelemetryModule::getDeviceTelemetry() @@ -104,4 +117,4 @@ bool DeviceTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) service.sendToMesh(p, RX_SRC_LOCAL, true); } return true; -} +} \ No newline at end of file diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index ff3202067..8f899401b 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -270,98 +270,129 @@ bool EnvironmentTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPac return false; // Let others look at this message also if they want } -bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) +bool EnvironmentTelemetryModule::getEnvironmentTelemetry(meshtastic_Telemetry *m) { - meshtastic_Telemetry m = meshtastic_Telemetry_init_zero; bool valid = true; bool hasSensor = false; - m.time = getTime(); - m.which_variant = meshtastic_Telemetry_environment_metrics_tag; + m->time = getTime(); + m->which_variant = meshtastic_Telemetry_environment_metrics_tag; if (dfRobotLarkSensor.hasSensor()) { - valid = valid && dfRobotLarkSensor.getMetrics(&m); + valid = valid && dfRobotLarkSensor.getMetrics(m); hasSensor = true; } if (sht31Sensor.hasSensor()) { - valid = valid && sht31Sensor.getMetrics(&m); + valid = valid && sht31Sensor.getMetrics(m); hasSensor = true; } if (lps22hbSensor.hasSensor()) { - valid = valid && lps22hbSensor.getMetrics(&m); + valid = valid && lps22hbSensor.getMetrics(m); hasSensor = true; } if (shtc3Sensor.hasSensor()) { - valid = valid && shtc3Sensor.getMetrics(&m); + valid = valid && shtc3Sensor.getMetrics(m); hasSensor = true; } if (bmp085Sensor.hasSensor()) { - valid = valid && bmp085Sensor.getMetrics(&m); + valid = valid && bmp085Sensor.getMetrics(m); hasSensor = true; } if (bmp280Sensor.hasSensor()) { - valid = valid && bmp280Sensor.getMetrics(&m); + valid = valid && bmp280Sensor.getMetrics(m); hasSensor = true; } if (bme280Sensor.hasSensor()) { - valid = valid && bme280Sensor.getMetrics(&m); + valid = valid && bme280Sensor.getMetrics(m); hasSensor = true; } if (bme680Sensor.hasSensor()) { - valid = valid && bme680Sensor.getMetrics(&m); + valid = valid && bme680Sensor.getMetrics(m); hasSensor = true; } if (mcp9808Sensor.hasSensor()) { - valid = valid && mcp9808Sensor.getMetrics(&m); + valid = valid && mcp9808Sensor.getMetrics(m); hasSensor = true; } if (ina219Sensor.hasSensor()) { - valid = valid && ina219Sensor.getMetrics(&m); + valid = valid && ina219Sensor.getMetrics(m); hasSensor = true; } if (ina260Sensor.hasSensor()) { - valid = valid && ina260Sensor.getMetrics(&m); + valid = valid && ina260Sensor.getMetrics(m); hasSensor = true; } if (veml7700Sensor.hasSensor()) { - valid = valid && veml7700Sensor.getMetrics(&m); + valid = valid && veml7700Sensor.getMetrics(m); hasSensor = true; } if (tsl2591Sensor.hasSensor()) { - valid = valid && tsl2591Sensor.getMetrics(&m); + valid = valid && tsl2591Sensor.getMetrics(m); hasSensor = true; } if (opt3001Sensor.hasSensor()) { - valid = valid && opt3001Sensor.getMetrics(&m); + valid = valid && opt3001Sensor.getMetrics(m); hasSensor = true; } if (mlx90632Sensor.hasSensor()) { - valid = valid && mlx90632Sensor.getMetrics(&m); + valid = valid && mlx90632Sensor.getMetrics(m); hasSensor = true; } if (rcwl9620Sensor.hasSensor()) { - valid = valid && rcwl9620Sensor.getMetrics(&m); + valid = valid && rcwl9620Sensor.getMetrics(m); hasSensor = true; } if (nau7802Sensor.hasSensor()) { - valid = valid && nau7802Sensor.getMetrics(&m); + valid = valid && nau7802Sensor.getMetrics(m); hasSensor = true; } if (aht10Sensor.hasSensor()) { if (!bmp280Sensor.hasSensor()) { - valid = valid && aht10Sensor.getMetrics(&m); + valid = valid && aht10Sensor.getMetrics(m); hasSensor = true; } else { // 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\n"); aht10Sensor.getMetrics(&m_ahtx); - m.variant.environment_metrics.relative_humidity = m_ahtx.variant.environment_metrics.relative_humidity; + m->variant.environment_metrics.relative_humidity = m_ahtx.variant.environment_metrics.relative_humidity; } } - valid = valid && hasSensor; + return valid && hasSensor; +} - if (valid) { +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!\n"); + 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 replying to request\n"); + return allocDataProtobuf(m); + } else { + return NULL; + } + } + } + return NULL; +} + +bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) +{ + meshtastic_Telemetry m = meshtastic_Telemetry_init_zero; + if (getEnvironmentTelemetry(&m)) { LOG_INFO("(Sending): barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, temperature=%f\n", m.variant.environment_metrics.barometric_pressure, m.variant.environment_metrics.current, m.variant.environment_metrics.gas_resistance, m.variant.environment_metrics.relative_humidity, @@ -399,8 +430,9 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) setIntervalFromNow(5000); } } + return true; } - return valid; + return false; } AdminMessageHandleResult EnvironmentTelemetryModule::handleAdminMessageForModule(const meshtastic_MeshPacket &mp, diff --git a/src/modules/Telemetry/EnvironmentTelemetry.h b/src/modules/Telemetry/EnvironmentTelemetry.h index ca150347e..ced617c2f 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.h +++ b/src/modules/Telemetry/EnvironmentTelemetry.h @@ -32,6 +32,11 @@ class EnvironmentTelemetryModule : private concurrency::OSThread, public Protobu */ virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *p) override; virtual int32_t runOnce() override; + /** Called to get current Environment telemetry data + @return true if it contains valid data + */ + bool getEnvironmentTelemetry(meshtastic_Telemetry *m); + virtual meshtastic_MeshPacket *allocReply() override; /** * Send our Telemetry into the mesh */ diff --git a/src/modules/Telemetry/PowerTelemetry.cpp b/src/modules/Telemetry/PowerTelemetry.cpp index 826de8a4a..cb864f4f3 100644 --- a/src/modules/Telemetry/PowerTelemetry.cpp +++ b/src/modules/Telemetry/PowerTelemetry.cpp @@ -163,29 +163,63 @@ bool PowerTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &m return false; // Let others look at this message also if they want } +bool PowerTelemetryModule::getPowerTelemetry(meshtastic_Telemetry *m) +{ + bool valid = false; + m->time = getTime(); + m->which_variant = meshtastic_Telemetry_power_metrics_tag; + + m->variant.power_metrics.ch1_voltage = 0; + m->variant.power_metrics.ch1_current = 0; + m->variant.power_metrics.ch2_voltage = 0; + m->variant.power_metrics.ch2_current = 0; + m->variant.power_metrics.ch3_voltage = 0; + m->variant.power_metrics.ch3_current = 0; +#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) + if (ina219Sensor.hasSensor()) + valid = ina219Sensor.getMetrics(m); + if (ina260Sensor.hasSensor()) + valid = ina260Sensor.getMetrics(m); + if (ina3221Sensor.hasSensor()) + valid = ina3221Sensor.getMetrics(m); +#endif + + return valid; +} + +meshtastic_MeshPacket *PowerTelemetryModule::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 PowerTelemetry module!\n"); + return NULL; + } + // Check for a request for power metrics + if (decoded->which_variant == meshtastic_Telemetry_power_metrics_tag) { + meshtastic_Telemetry m = meshtastic_Telemetry_init_zero; + if (getPowerTelemetry(&m)) { + LOG_INFO("Power telemetry replying to request\n"); + return allocDataProtobuf(m); + } else { + return NULL; + } + } + } + + return NULL; +} + bool PowerTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) { meshtastic_Telemetry m = meshtastic_Telemetry_init_zero; - bool valid = false; - m.time = getTime(); - m.which_variant = meshtastic_Telemetry_power_metrics_tag; - - m.variant.power_metrics.ch1_voltage = 0; - m.variant.power_metrics.ch1_current = 0; - m.variant.power_metrics.ch2_voltage = 0; - m.variant.power_metrics.ch2_current = 0; - m.variant.power_metrics.ch3_voltage = 0; - m.variant.power_metrics.ch3_current = 0; -#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) - if (ina219Sensor.hasSensor()) - valid = ina219Sensor.getMetrics(&m); - if (ina260Sensor.hasSensor()) - valid = ina260Sensor.getMetrics(&m); - if (ina3221Sensor.hasSensor()) - valid = ina3221Sensor.getMetrics(&m); -#endif - - if (valid) { + if (getPowerTelemetry(&m)) { LOG_INFO("(Sending): ch1_voltage=%f, ch1_current=%f, ch2_voltage=%f, ch2_current=%f, " "ch3_voltage=%f, ch3_current=%f\n", m.variant.power_metrics.ch1_voltage, m.variant.power_metrics.ch1_current, m.variant.power_metrics.ch2_voltage, @@ -218,8 +252,9 @@ bool PowerTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) setIntervalFromNow(5000); } } + return true; } - return valid; + return false; } #endif \ No newline at end of file diff --git a/src/modules/Telemetry/PowerTelemetry.h b/src/modules/Telemetry/PowerTelemetry.h index 3d6b686f2..1b68847db 100644 --- a/src/modules/Telemetry/PowerTelemetry.h +++ b/src/modules/Telemetry/PowerTelemetry.h @@ -33,6 +33,11 @@ class PowerTelemetryModule : private concurrency::OSThread, public ProtobufModul */ virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *p) override; virtual int32_t runOnce() override; + /** Called to get current Power telemetry data + @return true if it contains valid data + */ + bool getPowerTelemetry(meshtastic_Telemetry *m); + virtual meshtastic_MeshPacket *allocReply() override; /** * Send our Telemetry into the mesh */ diff --git a/src/modules/esp32/PaxcounterModule.cpp b/src/modules/esp32/PaxcounterModule.cpp index e6712871d..0bae515df 100644 --- a/src/modules/esp32/PaxcounterModule.cpp +++ b/src/modules/esp32/PaxcounterModule.cpp @@ -66,10 +66,6 @@ bool PaxcounterModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, m meshtastic_MeshPacket *PaxcounterModule::allocReply() { - if (ignoreRequest) { - return NULL; - } - meshtastic_Paxcount pl = meshtastic_Paxcount_init_default; pl.wifi = count_from_libpax.wifi_count; pl.ble = count_from_libpax.ble_count; @@ -131,4 +127,4 @@ void PaxcounterModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state } #endif // HAS_SCREEN -#endif +#endif \ No newline at end of file