diff --git a/proto b/proto index 3e70448a0..c7bbc04ed 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 3e70448a0f31b2868dccbe13862df35bea939b74 +Subproject commit c7bbc04ed3902458aa5e9a3cf89c36a63fa1fc04 diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp index 863c6333a..c751a7c26 100644 --- a/src/mesh/MeshService.cpp +++ b/src/mesh/MeshService.cpp @@ -207,8 +207,7 @@ NodeInfo *MeshService::refreshMyNodeInfo() // For the time in the position field, only set that if we have a real GPS clock position.time = getValidTime(RTCQualityGPS); - position.battery_level = powerStatus->getBatteryChargePercent(); - updateBatteryLevel(position.battery_level); + updateBatteryLevel(powerStatus->getBatteryChargePercent()); return node; } @@ -238,11 +237,10 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus) // I KNOW this is redundant with refreshMyNodeInfo() above, but these are // inexpensive nonblocking calls and can be refactored in due course pos.time = getValidTime(RTCQualityGPS); - pos.battery_level = powerStatus->getBatteryChargePercent(); // In debug logs, identify position by @timestamp:stage (stage 4 = nodeDB) - DEBUG_MSG("onGPSChanged() pos@%x:4, time=%u, lat=%d, bat=%d\n", - pos.pos_timestamp, pos.time, pos.latitude_i, pos.battery_level); + DEBUG_MSG("onGPSChanged() pos@%x:4, time=%u, lat=%d\n", + pos.pos_timestamp, pos.time, pos.latitude_i); // Update our current position in the local DB nodeDB.updatePosition(nodeDB.getNodeNum(), pos, RX_SRC_LOCAL); diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 5bd7fe1f1..a53074c21 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -488,6 +488,28 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src) notifyObservers(true); // Force an update whether or not our node counts have changed } + +/** Update telemetry info for this node based on received metrics + */ +void NodeDB::updateTelemetry(uint32_t nodeId, const Telemetry &t, RxSource src) +{ + NodeInfo *info = getOrCreateNode(nodeId); + if (!info) { + return; + } + + if (src == RX_SRC_LOCAL) { + // Local packet, fully authoritative + DEBUG_MSG("updateTelemetry LOCAL\n"); + } else { + DEBUG_MSG("updateTelemetry REMOTE node=0x%x \n", nodeId); + } + info->telemetry = t; + info->has_telemetry = true; + updateGUIforNode = info; + notifyObservers(true); // Force an update whether or not our node counts have changed +} + /** Update user info for this node based on received user data */ void NodeDB::updateUser(uint32_t nodeId, const User &p) diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index 2724bf797..6e05a3d5e 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -61,6 +61,10 @@ class NodeDB */ void updatePosition(uint32_t nodeId, const Position &p, RxSource src = RX_SRC_RADIO); + /** Update telemetry info for this node based on received metrics + */ + void updateTelemetry(uint32_t nodeId, const Telemetry &t, RxSource src = RX_SRC_RADIO); + /** Update user info for this node based on received user data */ void updateUser(uint32_t nodeId, const User &p); @@ -164,6 +168,7 @@ extern NodeDB nodeDB; PREF_GET(send_owner_interval, IF_ROUTER(2, 4)) PREF_GET(position_broadcast_secs, IF_ROUTER(12 * 60 * 60, 15 * 60)) +PREF_GET(telemetry_module_update_interval, 2 * 60) // Each time we wake into the DARK state allow 1 minute to send and receive BLE packets to the phone PREF_GET(wait_bluetooth_secs, IF_ROUTER(1, 60)) diff --git a/src/mesh/generated/deviceonly.pb.h b/src/mesh/generated/deviceonly.pb.h index 471425cb0..f6fcf2a8c 100644 --- a/src/mesh/generated/deviceonly.pb.h +++ b/src/mesh/generated/deviceonly.pb.h @@ -87,7 +87,9 @@ extern const pb_msgdesc_t ChannelFile_msg; #define ChannelFile_fields &ChannelFile_msg /* Maximum encoded size of messages (where known) */ -#define DeviceState_size 9749 +#if defined(Telemetry_size) +#define DeviceState_size (9685 + 32*Telemetry_size) +#endif #define ChannelFile_size 832 #ifdef __cplusplus diff --git a/src/mesh/generated/mesh.pb.h b/src/mesh/generated/mesh.pb.h index c124e9619..2d0577709 100644 --- a/src/mesh/generated/mesh.pb.h +++ b/src/mesh/generated/mesh.pb.h @@ -5,6 +5,7 @@ #define PB_MESH_PB_H_INCLUDED #include #include "portnums.pb.h" +#include "telemetry.pb.h" #if PB_PROTO_HEADER_VERSION != 40 #error Regenerate this file with the current version of nanopb generator. @@ -175,7 +176,6 @@ typedef struct _Position { int32_t latitude_i; int32_t longitude_i; int32_t altitude; - int32_t battery_level; uint32_t time; Position_LocSource location_source; Position_AltSource altitude_source; @@ -246,8 +246,10 @@ typedef struct _NodeInfo { User user; bool has_position; Position position; - uint32_t last_heard; float snr; + uint32_t last_heard; + bool has_telemetry; + Telemetry telemetry; } NodeInfo; typedef struct _Routing { @@ -330,25 +332,25 @@ extern "C" { #endif /* Initializer values for message structs */ -#define Position_init_default {0, 0, 0, 0, 0, _Position_LocSource_MIN, _Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define Position_init_default {0, 0, 0, 0, _Position_LocSource_MIN, _Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define User_init_default {"", "", "", {0}, _HardwareModel_MIN, 0, _Team_MIN, 0, 0, 0} #define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}} #define Routing_init_default {0, {RouteDiscovery_init_default}} #define Data_init_default {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0} #define MeshPacket_init_default {0, 0, 0, 0, {Data_init_default}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN} -#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0} +#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0, false, Telemetry_init_default} #define MyNodeInfo_init_default {0, 0, "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0} #define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN} #define FromRadio_init_default {0, 0, {MyNodeInfo_init_default}} #define ToRadio_init_default {0, {MeshPacket_init_default}} #define ToRadio_PeerInfo_init_default {0, 0} -#define Position_init_zero {0, 0, 0, 0, 0, _Position_LocSource_MIN, _Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define Position_init_zero {0, 0, 0, 0, _Position_LocSource_MIN, _Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define User_init_zero {"", "", "", {0}, _HardwareModel_MIN, 0, _Team_MIN, 0, 0, 0} #define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}} #define Routing_init_zero {0, {RouteDiscovery_init_zero}} #define Data_init_zero {_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0} #define MeshPacket_init_zero {0, 0, 0, 0, {Data_init_zero}, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN, 0, _MeshPacket_Delayed_MIN} -#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0} +#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0, false, Telemetry_init_zero} #define MyNodeInfo_init_zero {0, 0, "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, 0, 0} #define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN} #define FromRadio_init_zero {0, 0, {MyNodeInfo_init_zero}} @@ -388,7 +390,6 @@ extern "C" { #define Position_latitude_i_tag 1 #define Position_longitude_i_tag 2 #define Position_altitude_tag 3 -#define Position_battery_level_tag 4 #define Position_time_tag 9 #define Position_location_source_tag 10 #define Position_altitude_source_tag 11 @@ -437,8 +438,9 @@ extern "C" { #define NodeInfo_num_tag 1 #define NodeInfo_user_tag 2 #define NodeInfo_position_tag 3 -#define NodeInfo_last_heard_tag 4 -#define NodeInfo_snr_tag 7 +#define NodeInfo_snr_tag 4 +#define NodeInfo_last_heard_tag 5 +#define NodeInfo_telemetry_tag 6 #define Routing_route_request_tag 1 #define Routing_route_reply_tag 2 #define Routing_error_reason_tag 3 @@ -459,7 +461,6 @@ extern "C" { X(a, STATIC, SINGULAR, SFIXED32, latitude_i, 1) \ X(a, STATIC, SINGULAR, SFIXED32, longitude_i, 2) \ X(a, STATIC, SINGULAR, INT32, altitude, 3) \ -X(a, STATIC, SINGULAR, INT32, battery_level, 4) \ X(a, STATIC, SINGULAR, FIXED32, time, 9) \ X(a, STATIC, SINGULAR, UENUM, location_source, 10) \ X(a, STATIC, SINGULAR, UENUM, altitude_source, 11) \ @@ -544,12 +545,14 @@ X(a, STATIC, SINGULAR, UENUM, delayed, 15) X(a, STATIC, SINGULAR, UINT32, num, 1) \ X(a, STATIC, OPTIONAL, MESSAGE, user, 2) \ X(a, STATIC, OPTIONAL, MESSAGE, position, 3) \ -X(a, STATIC, SINGULAR, FIXED32, last_heard, 4) \ -X(a, STATIC, SINGULAR, FLOAT, snr, 7) +X(a, STATIC, SINGULAR, FLOAT, snr, 4) \ +X(a, STATIC, SINGULAR, FIXED32, last_heard, 5) \ +X(a, STATIC, OPTIONAL, MESSAGE, telemetry, 6) #define NodeInfo_CALLBACK NULL #define NodeInfo_DEFAULT NULL #define NodeInfo_user_MSGTYPE User #define NodeInfo_position_MSGTYPE Position +#define NodeInfo_telemetry_MSGTYPE Telemetry #define MyNodeInfo_FIELDLIST(X, a) \ X(a, STATIC, SINGULAR, UINT32, my_node_num, 1) \ @@ -639,16 +642,16 @@ extern const pb_msgdesc_t ToRadio_PeerInfo_msg; #define ToRadio_PeerInfo_fields &ToRadio_PeerInfo_msg /* Maximum encoded size of messages (where known) */ -#define Position_size 153 +#define Position_size 142 #define User_size 97 #define RouteDiscovery_size 40 #define Routing_size 42 #define Data_size 267 #define MeshPacket_size 318 -#define NodeInfo_size 271 +#define NodeInfo_size 320 #define MyNodeInfo_size 210 #define LogRecord_size 81 -#define FromRadio_size 327 +#define FromRadio_size 329 #define ToRadio_size 321 #define ToRadio_PeerInfo_size 8 diff --git a/src/mesh/generated/radioconfig.pb.c b/src/mesh/generated/radioconfig.pb.c index 040c62fb2..26930ae3c 100644 --- a/src/mesh/generated/radioconfig.pb.c +++ b/src/mesh/generated/radioconfig.pb.c @@ -20,4 +20,3 @@ PB_BIND(RadioConfig_UserPreferences, RadioConfig_UserPreferences, 2) - diff --git a/src/mesh/generated/radioconfig.pb.h b/src/mesh/generated/radioconfig.pb.h index e93829d46..5a101787e 100644 --- a/src/mesh/generated/radioconfig.pb.h +++ b/src/mesh/generated/radioconfig.pb.h @@ -85,15 +85,16 @@ typedef enum _InputEventChar { } InputEventChar; typedef enum _RadioConfig_UserPreferences_TelemetrySensorType { - RadioConfig_UserPreferences_TelemetrySensorType_DHT11 = 0, - RadioConfig_UserPreferences_TelemetrySensorType_DS18B20 = 1, - RadioConfig_UserPreferences_TelemetrySensorType_DHT12 = 2, - RadioConfig_UserPreferences_TelemetrySensorType_DHT21 = 3, - RadioConfig_UserPreferences_TelemetrySensorType_DHT22 = 4, - RadioConfig_UserPreferences_TelemetrySensorType_BME280 = 5, - RadioConfig_UserPreferences_TelemetrySensorType_BME680 = 6, - RadioConfig_UserPreferences_TelemetrySensorType_MCP9808 = 7, - RadioConfig_UserPreferences_TelemetrySensorType_SHTC3 = 8 + RadioConfig_UserPreferences_TelemetrySensorType_None = 0, + RadioConfig_UserPreferences_TelemetrySensorType_DHT11 = 1, + RadioConfig_UserPreferences_TelemetrySensorType_DS18B20 = 2, + RadioConfig_UserPreferences_TelemetrySensorType_DHT12 = 3, + RadioConfig_UserPreferences_TelemetrySensorType_DHT21 = 4, + RadioConfig_UserPreferences_TelemetrySensorType_DHT22 = 5, + RadioConfig_UserPreferences_TelemetrySensorType_BME280 = 6, + RadioConfig_UserPreferences_TelemetrySensorType_BME680 = 7, + RadioConfig_UserPreferences_TelemetrySensorType_MCP9808 = 8, + RadioConfig_UserPreferences_TelemetrySensorType_SHTC3 = 9 } RadioConfig_UserPreferences_TelemetrySensorType; /* Struct definitions */ @@ -215,7 +216,7 @@ typedef struct _RadioConfig { #define _InputEventChar_MAX InputEventChar_KEY_BACK #define _InputEventChar_ARRAYSIZE ((InputEventChar)(InputEventChar_KEY_BACK+1)) -#define _RadioConfig_UserPreferences_TelemetrySensorType_MIN RadioConfig_UserPreferences_TelemetrySensorType_DHT11 +#define _RadioConfig_UserPreferences_TelemetrySensorType_MIN RadioConfig_UserPreferences_TelemetrySensorType_None #define _RadioConfig_UserPreferences_TelemetrySensorType_MAX RadioConfig_UserPreferences_TelemetrySensorType_SHTC3 #define _RadioConfig_UserPreferences_TelemetrySensorType_ARRAYSIZE ((RadioConfig_UserPreferences_TelemetrySensorType)(RadioConfig_UserPreferences_TelemetrySensorType_SHTC3+1)) diff --git a/src/mesh/generated/telemetry.pb.h b/src/mesh/generated/telemetry.pb.h index 6dbfec365..5b12cb9cf 100644 --- a/src/mesh/generated/telemetry.pb.h +++ b/src/mesh/generated/telemetry.pb.h @@ -11,6 +11,11 @@ /* Struct definitions */ typedef struct _Telemetry { + uint32_t time; + int32_t battery_level; + float channel_utilization; + float air_util_tx; + bool router_heartbeat; float temperature; float relative_humidity; float barometric_pressure; @@ -25,25 +30,35 @@ extern "C" { #endif /* Initializer values for message structs */ -#define Telemetry_init_default {0, 0, 0, 0, 0, 0} -#define Telemetry_init_zero {0, 0, 0, 0, 0, 0} +#define Telemetry_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define Telemetry_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} /* Field tags (for use in manual encoding/decoding) */ -#define Telemetry_temperature_tag 1 -#define Telemetry_relative_humidity_tag 2 -#define Telemetry_barometric_pressure_tag 3 -#define Telemetry_gas_resistance_tag 4 -#define Telemetry_voltage_tag 5 -#define Telemetry_current_tag 6 +#define Telemetry_time_tag 1 +#define Telemetry_battery_level_tag 2 +#define Telemetry_channel_utilization_tag 3 +#define Telemetry_air_util_tx_tag 4 +#define Telemetry_router_heartbeat_tag 5 +#define Telemetry_temperature_tag 6 +#define Telemetry_relative_humidity_tag 7 +#define Telemetry_barometric_pressure_tag 8 +#define Telemetry_gas_resistance_tag 9 +#define Telemetry_voltage_tag 10 +#define Telemetry_current_tag 11 /* Struct field encoding specification for nanopb */ #define Telemetry_FIELDLIST(X, a) \ -X(a, STATIC, SINGULAR, FLOAT, temperature, 1) \ -X(a, STATIC, SINGULAR, FLOAT, relative_humidity, 2) \ -X(a, STATIC, SINGULAR, FLOAT, barometric_pressure, 3) \ -X(a, STATIC, SINGULAR, FLOAT, gas_resistance, 4) \ -X(a, STATIC, SINGULAR, FLOAT, voltage, 5) \ -X(a, STATIC, SINGULAR, FLOAT, current, 6) +X(a, STATIC, SINGULAR, FIXED32, time, 1) \ +X(a, STATIC, SINGULAR, INT32, battery_level, 2) \ +X(a, STATIC, SINGULAR, FLOAT, channel_utilization, 3) \ +X(a, STATIC, SINGULAR, FLOAT, air_util_tx, 4) \ +X(a, STATIC, SINGULAR, BOOL, router_heartbeat, 5) \ +X(a, STATIC, SINGULAR, FLOAT, temperature, 6) \ +X(a, STATIC, SINGULAR, FLOAT, relative_humidity, 7) \ +X(a, STATIC, SINGULAR, FLOAT, barometric_pressure, 8) \ +X(a, STATIC, SINGULAR, FLOAT, gas_resistance, 9) \ +X(a, STATIC, SINGULAR, FLOAT, voltage, 10) \ +X(a, STATIC, SINGULAR, FLOAT, current, 11) #define Telemetry_CALLBACK NULL #define Telemetry_DEFAULT NULL @@ -53,7 +68,7 @@ extern const pb_msgdesc_t Telemetry_msg; #define Telemetry_fields &Telemetry_msg /* Maximum encoded size of messages (where known) */ -#define Telemetry_size 30 +#define Telemetry_size 58 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index e146b330c..da34ed69e 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -32,11 +32,11 @@ bool PositionModule::handleReceivedProtobuf(const MeshPacket &mp, Position *pptr } // Log packet size and list of fields - DEBUG_MSG("POSITION node=%08x l=%d %s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", getFrom(&mp), mp.decoded.payload.size, + DEBUG_MSG("POSITION node=%08x l=%d %s%s%s%s%s%s%s%s%s%s%s%s%s\n", getFrom(&mp), mp.decoded.payload.size, p.latitude_i ? "LAT " : "", p.longitude_i ? "LON " : "", p.altitude ? "MSL " : "", p.altitude_hae ? "HAE " : "", p.alt_geoid_sep ? "GEO " : "", p.PDOP ? "PDOP " : "", p.HDOP ? "HDOP " : "", p.VDOP ? "VDOP " : "", p.sats_in_view ? "SIV " : "", p.fix_quality ? "FXQ " : "", p.fix_type ? "FXT " : "", p.pos_timestamp ? "PTS " : "", - p.time ? "TIME " : "", p.battery_level ? "BAT " : ""); + p.time ? "TIME " : ""); if (p.time) { struct timeval tv; @@ -70,9 +70,6 @@ MeshPacket *PositionModule::allocReply() p.longitude_i = node->position.longitude_i; p.time = node->position.time; - if (pos_flags & PositionFlags_POS_BATTERY) - p.battery_level = node->position.battery_level; - if (pos_flags & PositionFlags_POS_ALTITUDE) { if (pos_flags & PositionFlags_POS_ALT_MSL) p.altitude = node->position.altitude; diff --git a/src/modules/Telemetry/Telemetry.cpp b/src/modules/Telemetry/Telemetry.cpp index d4d423543..948354fad 100644 --- a/src/modules/Telemetry/Telemetry.cpp +++ b/src/modules/Telemetry/Telemetry.cpp @@ -1,5 +1,6 @@ #include "Telemetry.h" #include "../mesh/generated/telemetry.pb.h" +#include "PowerFSM.h" #include "MeshService.h" #include "NodeDB.h" #include "RTC.h" @@ -41,7 +42,6 @@ MCP9808Sensor mcp9808Sensor; #define FONT_HEIGHT_SMALL fontHeight(FONT_SMALL) #define FONT_HEIGHT_MEDIUM fontHeight(FONT_MEDIUM) - int32_t TelemetryModule::runOnce() { #ifndef PORTDUINO @@ -50,70 +50,49 @@ int32_t TelemetryModule::runOnce() without having to configure it from the PythonAPI or WebUI. */ /* - radioConfig.preferences.telemetry_module_measurement_enabled = 1; radioConfig.preferences.telemetry_module_screen_enabled = 1; radioConfig.preferences.telemetry_module_read_error_count_threshold = 5; radioConfig.preferences.telemetry_module_update_interval = 600; radioConfig.preferences.telemetry_module_recovery_interval = 60; - radioConfig.preferences.telemetry_module_display_fahrenheit = false; - radioConfig.preferences.telemetry_module_sensor_pin = 13; - - radioConfig.preferences.telemetry_module_sensor_type = - RadioConfig_UserPreferences_TelemetrySensorType:: - RadioConfig_UserPreferences_TelemetrySensorType_BME280; + radioConfig.preferences.telemetry_module_sensor_pin = 13; // If one-wire + radioConfig.preferences.telemetry_module_sensor_type = RadioConfig_UserPreferences_TelemetrySensorType::RadioConfig_UserPreferences_TelemetrySensorType_BME280; */ - - if (!(radioConfig.preferences.telemetry_module_measurement_enabled || - radioConfig.preferences.telemetry_module_screen_enabled)) { - // If this module is not enabled, and the user doesn't want the display screen don't waste any OSThread time on it - return (INT32_MAX); - } if (firstTime) { // This is the first time the OSThread library has called this function, so do some setup firstTime = 0; - - if (radioConfig.preferences.telemetry_module_measurement_enabled) { - DEBUG_MSG("Telemetry: Initializing\n"); - // 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 - switch (radioConfig.preferences.telemetry_module_sensor_type) { - - case RadioConfig_UserPreferences_TelemetrySensorType_DHT11: - case RadioConfig_UserPreferences_TelemetrySensorType_DHT12: - case RadioConfig_UserPreferences_TelemetrySensorType_DHT21: - case RadioConfig_UserPreferences_TelemetrySensorType_DHT22: - return dhtSensor.runOnce(); - case RadioConfig_UserPreferences_TelemetrySensorType_DS18B20: - return dallasSensor.runOnce(); - case RadioConfig_UserPreferences_TelemetrySensorType_BME280: - return bme280Sensor.runOnce(); - case RadioConfig_UserPreferences_TelemetrySensorType_BME680: - return bme680Sensor.runOnce(); - case RadioConfig_UserPreferences_TelemetrySensorType_MCP9808: - return mcp9808Sensor.runOnce(); - default: - DEBUG_MSG("Telemetry: Invalid sensor type selected; Disabling module"); - return (INT32_MAX); - break; - } + DEBUG_MSG("Telemetry: Initializing\n"); + // therefore, we should only enable the sensor loop if measurement is also enabled + switch (radioConfig.preferences.telemetry_module_sensor_type) { + case RadioConfig_UserPreferences_TelemetrySensorType_DHT11: + case RadioConfig_UserPreferences_TelemetrySensorType_DHT12: + case RadioConfig_UserPreferences_TelemetrySensorType_DHT21: + case RadioConfig_UserPreferences_TelemetrySensorType_DHT22: + dhtSensor.runOnce(); + case RadioConfig_UserPreferences_TelemetrySensorType_DS18B20: + dallasSensor.runOnce(); + case RadioConfig_UserPreferences_TelemetrySensorType_BME280: + bme280Sensor.runOnce(); + case RadioConfig_UserPreferences_TelemetrySensorType_BME680: + bme680Sensor.runOnce(); + case RadioConfig_UserPreferences_TelemetrySensorType_MCP9808: + mcp9808Sensor.runOnce(); + default: + DEBUG_MSG("Telemetry: No external sensor types selected;"); + break; } - return (INT32_MAX); } else { - // if we somehow got to a second run of this module with measurement disabled, then just wait forever - if (!radioConfig.preferences.telemetry_module_measurement_enabled) - return (INT32_MAX); // this is not the first time OSThread library has called this function // so just do what we intend to do on the interval if (sensor_read_error_count > radioConfig.preferences.telemetry_module_read_error_count_threshold) { - if (radioConfig.preferences.telemetry_module_recovery_interval > 0) { + if (getPref_telemetry_module_update_interval() > 0) { DEBUG_MSG("Telemetry: TEMPORARILY DISABLED; The " "telemetry_module_read_error_count_threshold has been exceed: %d. Will retry reads in " "%d seconds\n", radioConfig.preferences.telemetry_module_read_error_count_threshold, - radioConfig.preferences.telemetry_module_recovery_interval); + getPref_telemetry_module_update_interval()); sensor_read_error_count = 0; - return (radioConfig.preferences.telemetry_module_recovery_interval * 1000); + return (getPref_telemetry_module_update_interval() * 1000); } DEBUG_MSG("Telemetry: DISABLED; The telemetry_module_read_error_count_threshold has " "been exceed: %d. Reads will not be retried until after device reset\n", @@ -126,32 +105,10 @@ int32_t TelemetryModule::runOnce() radioConfig.preferences.telemetry_module_read_error_count_threshold - sensor_read_error_count); } - if (!sendOurTelemetry()) { - // if we failed to read the sensor, then try again - // as soon as we can according to the maximum polling frequency - - switch (radioConfig.preferences.telemetry_module_sensor_type) { - case RadioConfig_UserPreferences_TelemetrySensorType_DHT11: - case RadioConfig_UserPreferences_TelemetrySensorType_DHT12: - case RadioConfig_UserPreferences_TelemetrySensorType_DHT21: - case RadioConfig_UserPreferences_TelemetrySensorType_DHT22: - return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); - case RadioConfig_UserPreferences_TelemetrySensorType_DS18B20: - return (DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); - case RadioConfig_UserPreferences_TelemetrySensorType_BME280: - case RadioConfig_UserPreferences_TelemetrySensorType_BME680: - return (BME_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); - case RadioConfig_UserPreferences_TelemetrySensorType_MCP9808: - return (MCP_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); - default: - return (DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); - } - } + sendOurTelemetry(); } - // The return of runOnce is an int32 representing the desired number of - // miliseconds until the function should be called again by the // OSThread library. Multiply the preference value by 1000 to convert seconds to miliseconds - return (radioConfig.preferences.telemetry_module_update_interval * 1000); + return (getPref_telemetry_module_update_interval() * 1000); #endif } @@ -225,34 +182,45 @@ void TelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, display->drawString(x, y += fontHeight(FONT_SMALL),"Press: " + String(lastMeasurement.barometric_pressure, 0) + "hPA"); } -bool TelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Telemetry *p) +bool TelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Telemetry *t) { - if (!(radioConfig.preferences.telemetry_module_measurement_enabled || - radioConfig.preferences.telemetry_module_screen_enabled)) { - // If this module is not enabled in any capacity, don't handle the packet, and allow other modules to consume - return false; - } - String sender = GetSenderName(mp); + DEBUG_MSG("-----------------------------------------\n"); DEBUG_MSG("Telemetry: Received data from %s\n", sender); - DEBUG_MSG("Telemetry->relative_humidity: %f\n", p->relative_humidity); - DEBUG_MSG("Telemetry->temperature: %f\n", p->temperature); - DEBUG_MSG("Telemetry->barometric_pressure: %f\n", p->barometric_pressure); - DEBUG_MSG("Telemetry->gas_resistance: %f\n", p->gas_resistance); + DEBUG_MSG("Telemetry->air_util_tx: %f\n", t->air_util_tx); + DEBUG_MSG("Telemetry->barometric_pressure: %f\n", t->barometric_pressure); + DEBUG_MSG("Telemetry->battery_level: %i\n", t->battery_level); + DEBUG_MSG("Telemetry->channel_utilization: %f\n", t->channel_utilization); + DEBUG_MSG("Telemetry->current: %f\n", t->current); + DEBUG_MSG("Telemetry->gas_resistance: %f\n", t->gas_resistance); + DEBUG_MSG("Telemetry->relative_humidity: %f\n", t->relative_humidity); + DEBUG_MSG("Telemetry->router_heartbeat: %i\n", t->router_heartbeat); + DEBUG_MSG("Telemetry->temperature: %f\n", t->temperature); + DEBUG_MSG("Telemetry->voltage: %f\n", t->voltage); lastMeasurementPacket = packetPool.allocCopy(mp); + nodeDB.updateTelemetry(getFrom(&mp), *t, RX_SRC_RADIO); + return false; // Let others look at this message also if they want } bool TelemetryModule::sendOurTelemetry(NodeNum dest, bool wantReplies) { Telemetry m; + m.air_util_tx = 0; m.barometric_pressure = 0; + m.battery_level = 0; + m.channel_utilization = 0; + m.current = 0; m.gas_resistance = 0; - DEBUG_MSG("-----------------------------------------\n"); + m.relative_humidity = 0; + m.router_heartbeat = 0; + m.temperature = 0; + m.voltage = 0; + DEBUG_MSG("-----------------------------------------\n"); DEBUG_MSG("Telemetry: Read data\n"); switch (radioConfig.preferences.telemetry_module_sensor_type) { @@ -277,14 +245,23 @@ bool TelemetryModule::sendOurTelemetry(NodeNum dest, bool wantReplies) mcp9808Sensor.getMeasurement(&m); break; default: - DEBUG_MSG("Telemetry: Invalid sensor type selected; Disabling module"); - return false; + DEBUG_MSG("Telemetry: No external sensor type selected; Only sending internal metrics\n"); } - DEBUG_MSG("Telemetry->relative_humidity: %f\n", m.relative_humidity); - DEBUG_MSG("Telemetry->temperature: %f\n", m.temperature); + m.air_util_tx = myNodeInfo.air_util_tx; + m.channel_utilization = myNodeInfo.channel_utilization; + m.battery_level = powerStatus->getBatteryChargePercent(); + + DEBUG_MSG("Telemetry->air_util_tx: %f\n", m.air_util_tx); DEBUG_MSG("Telemetry->barometric_pressure: %f\n", m.barometric_pressure); + DEBUG_MSG("Telemetry->battery_level: %i\n", m.battery_level); + DEBUG_MSG("Telemetry->channel_utilization: %f\n", m.channel_utilization); + DEBUG_MSG("Telemetry->current: %f\n", m.current); DEBUG_MSG("Telemetry->gas_resistance: %f\n", m.gas_resistance); + DEBUG_MSG("Telemetry->relative_humidity: %f\n", m.relative_humidity); + DEBUG_MSG("Telemetry->router_heartbeat: %f\n", m.router_heartbeat); + DEBUG_MSG("Telemetry->temperature: %f\n", m.temperature); + DEBUG_MSG("Telemetry->voltage: %f\n", m.voltage); sensor_read_error_count = 0; diff --git a/src/modules/esp32/RangeTestModule.cpp b/src/modules/esp32/RangeTestModule.cpp index e9b32a02b..3ce06d537 100644 --- a/src/modules/esp32/RangeTestModule.cpp +++ b/src/modules/esp32/RangeTestModule.cpp @@ -164,7 +164,6 @@ ProcessMessage RangeTestModuleRadio::handleReceived(const MeshPacket &mp) DEBUG_MSG("n->has_position %d\n", n->has_position); DEBUG_MSG("n->position.latitude_i %d\n", n->position.latitude_i); DEBUG_MSG("n->position.longitude_i %d\n", n->position.longitude_i); - DEBUG_MSG("n->position.battery_level %d\n", n->position.battery_level); DEBUG_MSG("---- Current device location information:\n"); DEBUG_MSG("gpsStatus->getLatitude() %d\n", gpsStatus->getLatitude()); DEBUG_MSG("gpsStatus->getLongitude() %d\n", gpsStatus->getLongitude()); @@ -205,7 +204,6 @@ bool RangeTestModuleRadio::appendFile(const MeshPacket &mp) DEBUG_MSG("n->has_position %d\n", n->has_position); DEBUG_MSG("n->position.latitude_i %d\n", n->position.latitude_i); DEBUG_MSG("n->position.longitude_i %d\n", n->position.longitude_i); - DEBUG_MSG("n->position.battery_level %d\n", n->position.battery_level); DEBUG_MSG("---- Current device location information:\n"); DEBUG_MSG("gpsStatus->getLatitude() %d\n", gpsStatus->getLatitude()); DEBUG_MSG("gpsStatus->getLongitude() %d\n", gpsStatus->getLongitude());