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 <benmmeadors@gmail.com>
This commit is contained in:
GUVWAF 2024-06-23 14:13:59 +02:00 committed by GitHub
parent eb6bd3a06f
commit 8078e03f5f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 222 additions and 94 deletions

View File

@ -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

View File

@ -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
*/

View File

@ -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;
}
}

View File

@ -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,

View File

@ -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
*/

View File

@ -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

View File

@ -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
*/

View File

@ -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