mirror of
https://github.com/meshtastic/firmware.git
synced 2025-04-23 17:13:38 +00:00
Reworked metrics structure and split telemetry into device or environ… (#1331)
* Reworked metrics structure and split telemetry into device or environment * Comment cleanup
This commit is contained in:
parent
7b8096f5b2
commit
ba2fa84ebd
2
proto
2
proto
@ -1 +1 @@
|
||||
Subproject commit 3689ca4bde316dca2601c2a2f91fa71204f7fa43
|
||||
Subproject commit 6d355041bb0a30d3fdb3f15a0c03963ec3fe2bf3
|
@ -490,11 +490,13 @@ void NodeDB::updatePosition(uint32_t nodeId, const Position &p, RxSource src)
|
||||
|
||||
|
||||
/** Update telemetry info for this node based on received metrics
|
||||
* We only care about device telemetry here
|
||||
*/
|
||||
void NodeDB::updateTelemetry(uint32_t nodeId, const Telemetry &t, RxSource src)
|
||||
{
|
||||
NodeInfo *info = getOrCreateNode(nodeId);
|
||||
if (!info) {
|
||||
// Environment metrics should never go to NodeDb but we'll safegaurd anyway
|
||||
if (!info || t.which_variant != Telemetry_device_metrics_tag) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -168,7 +168,10 @@ 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)
|
||||
// Defaulting Telemetry to the same as position interval for now
|
||||
PREF_GET(telemetry_module_device_update_interval, IF_ROUTER(12 * 60 * 60, 15 * 60))
|
||||
PREF_GET(telemetry_module_environment_update_interval, IF_ROUTER(12 * 60 * 60, 15 * 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))
|
||||
|
@ -22,6 +22,8 @@ template <class T> class ProtobufModule : protected SinglePortModule
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
/**
|
||||
* Handle a received message, the data field in the message is already decoded and is provided
|
||||
*
|
||||
|
@ -129,7 +129,7 @@ extern const pb_msgdesc_t AdminMessage_msg;
|
||||
#define AdminMessage_fields &AdminMessage_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define AdminMessage_size 603
|
||||
#define AdminMessage_size 610
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -108,7 +108,7 @@ extern const pb_msgdesc_t ChannelFile_msg;
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define ChannelFile_size 832
|
||||
#define DeviceState_size 11199
|
||||
#define DeviceState_size 10687
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -27,7 +27,7 @@ PB_BIND(Location, Location, AUTO)
|
||||
PB_BIND(MeshPacket, MeshPacket, 2)
|
||||
|
||||
|
||||
PB_BIND(NodeInfo, NodeInfo, 2)
|
||||
PB_BIND(NodeInfo, NodeInfo, AUTO)
|
||||
|
||||
|
||||
PB_BIND(MyNodeInfo, MyNodeInfo, AUTO)
|
||||
|
@ -574,7 +574,7 @@ typedef struct _NodeInfo {
|
||||
float snr;
|
||||
/* Set to indicate the last time we received a packet from this node */
|
||||
uint32_t last_heard;
|
||||
/* The latest telemetry data for the node. */
|
||||
/* The latest device telemetry data for the node. */
|
||||
bool has_telemetry;
|
||||
Telemetry telemetry;
|
||||
} NodeInfo;
|
||||
@ -1079,7 +1079,7 @@ extern const pb_msgdesc_t ToRadio_PeerInfo_msg;
|
||||
#define LogRecord_size 81
|
||||
#define MeshPacket_size 347
|
||||
#define MyNodeInfo_size 210
|
||||
#define NodeInfo_size 315
|
||||
#define NodeInfo_size 299
|
||||
#define Position_size 142
|
||||
#define RouteDiscovery_size 40
|
||||
#define Routing_size 42
|
||||
|
@ -299,14 +299,14 @@ typedef struct _RadioConfig_UserPreferences {
|
||||
uint32_t store_forward_module_records;
|
||||
uint32_t store_forward_module_history_return_max;
|
||||
uint32_t store_forward_module_history_return_window;
|
||||
bool telemetry_module_measurement_enabled;
|
||||
bool telemetry_module_screen_enabled;
|
||||
uint32_t telemetry_module_read_error_count_threshold;
|
||||
uint32_t telemetry_module_update_interval;
|
||||
uint32_t telemetry_module_recovery_interval;
|
||||
bool telemetry_module_display_fahrenheit;
|
||||
RadioConfig_UserPreferences_TelemetrySensorType telemetry_module_sensor_type;
|
||||
uint32_t telemetry_module_sensor_pin;
|
||||
bool telemetry_module_environment_measurement_enabled;
|
||||
bool telemetry_module_environment_screen_enabled;
|
||||
uint32_t telemetry_module_environment_read_error_count_threshold;
|
||||
uint32_t telemetry_module_device_update_interval;
|
||||
uint32_t telemetry_module_environment_recovery_interval;
|
||||
bool telemetry_module_environment_display_fahrenheit;
|
||||
RadioConfig_UserPreferences_TelemetrySensorType telemetry_module_environment_sensor_type;
|
||||
uint32_t telemetry_module_environment_sensor_pin;
|
||||
bool store_forward_module_enabled;
|
||||
bool store_forward_module_heartbeat;
|
||||
uint32_t position_flags;
|
||||
@ -332,6 +332,7 @@ typedef struct _RadioConfig_UserPreferences {
|
||||
bool mqtt_encryption_enabled;
|
||||
float adc_multiplier_override;
|
||||
RadioConfig_UserPreferences_Serial_Baud serial_module_baud;
|
||||
uint32_t telemetry_module_environment_update_interval;
|
||||
} RadioConfig_UserPreferences;
|
||||
|
||||
/* The entire set of user settable/readable settings for our radio device.
|
||||
@ -388,9 +389,9 @@ extern "C" {
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default}
|
||||
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _Role_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_Serial_Mode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_TelemetrySensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, 0, 0, 0, 0, _InputEventChar_MIN, _InputEventChar_MIN, _InputEventChar_MIN, 0, 0, "", 0, 0, 0, _RadioConfig_UserPreferences_Serial_Baud_MIN}
|
||||
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _Role_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_Serial_Mode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_TelemetrySensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, 0, 0, 0, 0, _InputEventChar_MIN, _InputEventChar_MIN, _InputEventChar_MIN, 0, 0, "", 0, 0, 0, _RadioConfig_UserPreferences_Serial_Baud_MIN, 0}
|
||||
#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero}
|
||||
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _Role_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_Serial_Mode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_TelemetrySensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, 0, 0, 0, 0, _InputEventChar_MIN, _InputEventChar_MIN, _InputEventChar_MIN, 0, 0, "", 0, 0, 0, _RadioConfig_UserPreferences_Serial_Baud_MIN}
|
||||
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _Role_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_Serial_Mode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_TelemetrySensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, 0, 0, 0, 0, 0, _InputEventChar_MIN, _InputEventChar_MIN, _InputEventChar_MIN, 0, 0, "", 0, 0, 0, _RadioConfig_UserPreferences_Serial_Baud_MIN, 0}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define RadioConfig_UserPreferences_position_broadcast_secs_tag 1
|
||||
@ -444,14 +445,14 @@ extern "C" {
|
||||
#define RadioConfig_UserPreferences_store_forward_module_records_tag 137
|
||||
#define RadioConfig_UserPreferences_store_forward_module_history_return_max_tag 138
|
||||
#define RadioConfig_UserPreferences_store_forward_module_history_return_window_tag 139
|
||||
#define RadioConfig_UserPreferences_telemetry_module_measurement_enabled_tag 140
|
||||
#define RadioConfig_UserPreferences_telemetry_module_screen_enabled_tag 141
|
||||
#define RadioConfig_UserPreferences_telemetry_module_read_error_count_threshold_tag 142
|
||||
#define RadioConfig_UserPreferences_telemetry_module_update_interval_tag 143
|
||||
#define RadioConfig_UserPreferences_telemetry_module_recovery_interval_tag 144
|
||||
#define RadioConfig_UserPreferences_telemetry_module_display_fahrenheit_tag 145
|
||||
#define RadioConfig_UserPreferences_telemetry_module_sensor_type_tag 146
|
||||
#define RadioConfig_UserPreferences_telemetry_module_sensor_pin_tag 147
|
||||
#define RadioConfig_UserPreferences_telemetry_module_environment_measurement_enabled_tag 140
|
||||
#define RadioConfig_UserPreferences_telemetry_module_environment_screen_enabled_tag 141
|
||||
#define RadioConfig_UserPreferences_telemetry_module_environment_read_error_count_threshold_tag 142
|
||||
#define RadioConfig_UserPreferences_telemetry_module_device_update_interval_tag 143
|
||||
#define RadioConfig_UserPreferences_telemetry_module_environment_recovery_interval_tag 144
|
||||
#define RadioConfig_UserPreferences_telemetry_module_environment_display_fahrenheit_tag 145
|
||||
#define RadioConfig_UserPreferences_telemetry_module_environment_sensor_type_tag 146
|
||||
#define RadioConfig_UserPreferences_telemetry_module_environment_sensor_pin_tag 147
|
||||
#define RadioConfig_UserPreferences_store_forward_module_enabled_tag 148
|
||||
#define RadioConfig_UserPreferences_store_forward_module_heartbeat_tag 149
|
||||
#define RadioConfig_UserPreferences_position_flags_tag 150
|
||||
@ -477,6 +478,7 @@ extern "C" {
|
||||
#define RadioConfig_UserPreferences_mqtt_encryption_enabled_tag 174
|
||||
#define RadioConfig_UserPreferences_adc_multiplier_override_tag 175
|
||||
#define RadioConfig_UserPreferences_serial_module_baud_tag 176
|
||||
#define RadioConfig_UserPreferences_telemetry_module_environment_update_interval_tag 177
|
||||
#define RadioConfig_preferences_tag 1
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
@ -538,14 +540,14 @@ X(a, STATIC, SINGULAR, BOOL, range_test_module_save, 134) \
|
||||
X(a, STATIC, SINGULAR, UINT32, store_forward_module_records, 137) \
|
||||
X(a, STATIC, SINGULAR, UINT32, store_forward_module_history_return_max, 138) \
|
||||
X(a, STATIC, SINGULAR, UINT32, store_forward_module_history_return_window, 139) \
|
||||
X(a, STATIC, SINGULAR, BOOL, telemetry_module_measurement_enabled, 140) \
|
||||
X(a, STATIC, SINGULAR, BOOL, telemetry_module_screen_enabled, 141) \
|
||||
X(a, STATIC, SINGULAR, UINT32, telemetry_module_read_error_count_threshold, 142) \
|
||||
X(a, STATIC, SINGULAR, UINT32, telemetry_module_update_interval, 143) \
|
||||
X(a, STATIC, SINGULAR, UINT32, telemetry_module_recovery_interval, 144) \
|
||||
X(a, STATIC, SINGULAR, BOOL, telemetry_module_display_fahrenheit, 145) \
|
||||
X(a, STATIC, SINGULAR, UENUM, telemetry_module_sensor_type, 146) \
|
||||
X(a, STATIC, SINGULAR, UINT32, telemetry_module_sensor_pin, 147) \
|
||||
X(a, STATIC, SINGULAR, BOOL, telemetry_module_environment_measurement_enabled, 140) \
|
||||
X(a, STATIC, SINGULAR, BOOL, telemetry_module_environment_screen_enabled, 141) \
|
||||
X(a, STATIC, SINGULAR, UINT32, telemetry_module_environment_read_error_count_threshold, 142) \
|
||||
X(a, STATIC, SINGULAR, UINT32, telemetry_module_device_update_interval, 143) \
|
||||
X(a, STATIC, SINGULAR, UINT32, telemetry_module_environment_recovery_interval, 144) \
|
||||
X(a, STATIC, SINGULAR, BOOL, telemetry_module_environment_display_fahrenheit, 145) \
|
||||
X(a, STATIC, SINGULAR, UENUM, telemetry_module_environment_sensor_type, 146) \
|
||||
X(a, STATIC, SINGULAR, UINT32, telemetry_module_environment_sensor_pin, 147) \
|
||||
X(a, STATIC, SINGULAR, BOOL, store_forward_module_enabled, 148) \
|
||||
X(a, STATIC, SINGULAR, BOOL, store_forward_module_heartbeat, 149) \
|
||||
X(a, STATIC, SINGULAR, UINT32, position_flags, 150) \
|
||||
@ -570,7 +572,8 @@ X(a, STATIC, SINGULAR, STRING, canned_message_module_allow_input_source, 171
|
||||
X(a, STATIC, SINGULAR, BOOL, canned_message_module_send_bell, 173) \
|
||||
X(a, STATIC, SINGULAR, BOOL, mqtt_encryption_enabled, 174) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, adc_multiplier_override, 175) \
|
||||
X(a, STATIC, SINGULAR, UENUM, serial_module_baud, 176)
|
||||
X(a, STATIC, SINGULAR, UENUM, serial_module_baud, 176) \
|
||||
X(a, STATIC, SINGULAR, UINT32, telemetry_module_environment_update_interval, 177)
|
||||
#define RadioConfig_UserPreferences_CALLBACK NULL
|
||||
#define RadioConfig_UserPreferences_DEFAULT NULL
|
||||
|
||||
@ -582,8 +585,8 @@ extern const pb_msgdesc_t RadioConfig_UserPreferences_msg;
|
||||
#define RadioConfig_UserPreferences_fields &RadioConfig_UserPreferences_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define RadioConfig_UserPreferences_size 597
|
||||
#define RadioConfig_size 600
|
||||
#define RadioConfig_UserPreferences_size 604
|
||||
#define RadioConfig_size 607
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -6,6 +6,12 @@
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
PB_BIND(DeviceMetrics, DeviceMetrics, AUTO)
|
||||
|
||||
|
||||
PB_BIND(EnvironmentMetrics, EnvironmentMetrics, AUTO)
|
||||
|
||||
|
||||
PB_BIND(Telemetry, Telemetry, AUTO)
|
||||
|
||||
|
||||
|
@ -10,23 +10,20 @@
|
||||
#endif
|
||||
|
||||
/* Struct definitions */
|
||||
/* TODO: REPLACE */
|
||||
typedef struct _Telemetry {
|
||||
/* This is usually not sent over the mesh (to save space), but it is sent
|
||||
from the phone so that the local device can set its RTC If it is sent over
|
||||
the mesh (because there are devices on the mesh without GPS), it will only
|
||||
be sent by devices which has a hardware GPS clock (IE Mobile Phone).
|
||||
seconds since 1970 */
|
||||
uint32_t time;
|
||||
/* Key native device metrics such as battery level */
|
||||
typedef struct _DeviceMetrics {
|
||||
/* 1-100 (0 means powered) */
|
||||
uint32_t battery_level;
|
||||
/* Voltage measured */
|
||||
float voltage;
|
||||
/* Utilization for the current channel, including well formed TX, RX and malformed RX (aka noise). */
|
||||
float channel_utilization;
|
||||
/* Percent of airtime for transmission used within the last hour. */
|
||||
float air_util_tx;
|
||||
/* This is sent by node only if it a router and if hop_limit is set to 0
|
||||
and is not being sent as a reliable message. */
|
||||
bool router_heartbeat;
|
||||
} DeviceMetrics;
|
||||
|
||||
/* Weather station or other environmental metrics */
|
||||
typedef struct _EnvironmentMetrics {
|
||||
/* Temperature measured */
|
||||
float temperature;
|
||||
/* Relative humidity percent measured */
|
||||
@ -39,6 +36,22 @@ typedef struct _Telemetry {
|
||||
float voltage;
|
||||
/* Current measured */
|
||||
float current;
|
||||
} EnvironmentMetrics;
|
||||
|
||||
/* Types of Measurements the telemetry module is equipped to handle */
|
||||
typedef struct _Telemetry {
|
||||
/* This is usually not sent over the mesh (to save space), but it is sent
|
||||
from the phone so that the local device can set its RTC If it is sent over
|
||||
the mesh (because there are devices on the mesh without GPS), it will only
|
||||
be sent by devices which has a hardware GPS clock (IE Mobile Phone).
|
||||
seconds since 1970 */
|
||||
uint32_t time;
|
||||
/* Key native device metrics such as battery level */
|
||||
pb_size_t which_variant;
|
||||
union {
|
||||
DeviceMetrics device_metrics;
|
||||
EnvironmentMetrics environment_metrics;
|
||||
} variant;
|
||||
} Telemetry;
|
||||
|
||||
|
||||
@ -47,45 +60,69 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#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}
|
||||
#define DeviceMetrics_init_default {0, 0, 0, 0}
|
||||
#define EnvironmentMetrics_init_default {0, 0, 0, 0, 0, 0}
|
||||
#define Telemetry_init_default {0, 0, {DeviceMetrics_init_default}}
|
||||
#define DeviceMetrics_init_zero {0, 0, 0, 0}
|
||||
#define EnvironmentMetrics_init_zero {0, 0, 0, 0, 0, 0}
|
||||
#define Telemetry_init_zero {0, 0, {DeviceMetrics_init_zero}}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define DeviceMetrics_battery_level_tag 1
|
||||
#define DeviceMetrics_voltage_tag 2
|
||||
#define DeviceMetrics_channel_utilization_tag 3
|
||||
#define DeviceMetrics_air_util_tx_tag 4
|
||||
#define EnvironmentMetrics_temperature_tag 1
|
||||
#define EnvironmentMetrics_relative_humidity_tag 2
|
||||
#define EnvironmentMetrics_barometric_pressure_tag 3
|
||||
#define EnvironmentMetrics_gas_resistance_tag 4
|
||||
#define EnvironmentMetrics_voltage_tag 5
|
||||
#define EnvironmentMetrics_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
|
||||
#define Telemetry_device_metrics_tag 2
|
||||
#define Telemetry_environment_metrics_tag 3
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define DeviceMetrics_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, battery_level, 1) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, voltage, 2) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, channel_utilization, 3) \
|
||||
X(a, STATIC, SINGULAR, FLOAT, air_util_tx, 4)
|
||||
#define DeviceMetrics_CALLBACK NULL
|
||||
#define DeviceMetrics_DEFAULT NULL
|
||||
|
||||
#define EnvironmentMetrics_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)
|
||||
#define EnvironmentMetrics_CALLBACK NULL
|
||||
#define EnvironmentMetrics_DEFAULT NULL
|
||||
|
||||
#define Telemetry_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, time, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, 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)
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,device_metrics,variant.device_metrics), 2) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,environment_metrics,variant.environment_metrics), 3)
|
||||
#define Telemetry_CALLBACK NULL
|
||||
#define Telemetry_DEFAULT NULL
|
||||
#define Telemetry_variant_device_metrics_MSGTYPE DeviceMetrics
|
||||
#define Telemetry_variant_environment_metrics_MSGTYPE EnvironmentMetrics
|
||||
|
||||
extern const pb_msgdesc_t DeviceMetrics_msg;
|
||||
extern const pb_msgdesc_t EnvironmentMetrics_msg;
|
||||
extern const pb_msgdesc_t Telemetry_msg;
|
||||
|
||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||
#define DeviceMetrics_fields &DeviceMetrics_msg
|
||||
#define EnvironmentMetrics_fields &EnvironmentMetrics_msg
|
||||
#define Telemetry_fields &Telemetry_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define Telemetry_size 53
|
||||
#define DeviceMetrics_size 21
|
||||
#define EnvironmentMetrics_size 30
|
||||
#define Telemetry_size 37
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -12,7 +12,8 @@
|
||||
#include "modules/RoutingModule.h"
|
||||
#include "modules/TextMessageModule.h"
|
||||
#ifndef PORTDUINO
|
||||
#include "modules/Telemetry/Telemetry.h"
|
||||
#include "modules/Telemetry/DeviceTelemetry.h"
|
||||
#include "modules/Telemetry/EnvironmentTelemetry.h"
|
||||
#endif
|
||||
#ifndef NO_ESP32
|
||||
#include "modules/esp32/RangeTestModule.h"
|
||||
@ -42,7 +43,8 @@ void setupModules()
|
||||
upDownInterruptImpl1->init();
|
||||
cannedMessageModule = new CannedMessageModule();
|
||||
#ifndef PORTDUINO
|
||||
new TelemetryModule();
|
||||
new DeviceTelemetryModule();
|
||||
new EnvironmentTelemetryModule();
|
||||
#endif
|
||||
#ifndef NO_ESP32
|
||||
// Only run on an esp32 based device.
|
||||
|
89
src/modules/Telemetry/DeviceTelemetry.cpp
Normal file
89
src/modules/Telemetry/DeviceTelemetry.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
#include "DeviceTelemetry.h"
|
||||
#include "../mesh/generated/telemetry.pb.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "RTC.h"
|
||||
#include "Router.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include <OLEDDisplay.h>
|
||||
#include <OLEDDisplayUi.h>
|
||||
|
||||
int32_t DeviceTelemetryModule::runOnce()
|
||||
{
|
||||
#ifndef PORTDUINO
|
||||
if (firstTime) {
|
||||
// This is the first time the OSThread library has called this function, so do some setup
|
||||
firstTime = 0;
|
||||
DEBUG_MSG("Device Telemetry: Initializing\n");
|
||||
}
|
||||
sendOurTelemetry();
|
||||
// OSThread library. Multiply the preference value by 1000 to convert seconds to miliseconds
|
||||
return (getPref_telemetry_module_device_update_interval() * 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool DeviceTelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Telemetry *t)
|
||||
{
|
||||
if (t->which_variant == Telemetry_device_metrics_tag) {
|
||||
String sender = getSenderName(mp);
|
||||
|
||||
DEBUG_MSG("-----------------------------------------\n");
|
||||
DEBUG_MSG("Device Telemetry: Received data from %s\n", sender);
|
||||
DEBUG_MSG("Telemetry->time: %i\n", t->time);
|
||||
DEBUG_MSG("Telemetry->air_util_tx: %f\n", t->variant.device_metrics.air_util_tx );
|
||||
DEBUG_MSG("Telemetry->battery_level: %i\n", t->variant.device_metrics.battery_level);
|
||||
DEBUG_MSG("Telemetry->channel_utilization: %f\n", t->variant.device_metrics.channel_utilization);
|
||||
DEBUG_MSG("Telemetry->voltage: %f\n", t->variant.device_metrics.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
|
||||
}
|
||||
|
||||
String DeviceTelemetryModule::getSenderName(const MeshPacket &mp)
|
||||
{
|
||||
String sender;
|
||||
|
||||
auto node = nodeDB.getNode(getFrom(&mp));
|
||||
if (node) {
|
||||
sender = node->user.short_name;
|
||||
} else {
|
||||
sender = "UNK";
|
||||
}
|
||||
return sender;
|
||||
}
|
||||
|
||||
bool DeviceTelemetryModule::sendOurTelemetry(NodeNum dest, bool wantReplies)
|
||||
{
|
||||
Telemetry m;
|
||||
|
||||
m.time = getTime();
|
||||
m.which_variant = Telemetry_device_metrics_tag;
|
||||
|
||||
m.variant.device_metrics.air_util_tx = myNodeInfo.air_util_tx;
|
||||
m.variant.device_metrics.battery_level = powerStatus->getBatteryChargePercent();
|
||||
m.variant.device_metrics.channel_utilization = myNodeInfo.channel_utilization;
|
||||
m.variant.device_metrics.voltage = powerStatus->getBatteryVoltageMv() / 1000.0;
|
||||
|
||||
DEBUG_MSG("-----------------------------------------\n");
|
||||
DEBUG_MSG("Device Telemetry: Read data\n");
|
||||
|
||||
DEBUG_MSG("Telemetry->time: %i\n", m.time);
|
||||
DEBUG_MSG("Telemetry->air_util_tx: %f\n", m.variant.device_metrics.air_util_tx);
|
||||
DEBUG_MSG("Telemetry->battery_level: %i\n", m.variant.device_metrics.battery_level);
|
||||
DEBUG_MSG("Telemetry->channel_utilization: %f\n", m.variant.device_metrics.channel_utilization);
|
||||
DEBUG_MSG("Telemetry->voltage: %f\n", m.variant.device_metrics.voltage);
|
||||
|
||||
MeshPacket *p = allocDataProtobuf(m);
|
||||
p->to = dest;
|
||||
p->decoded.want_response = wantReplies;
|
||||
|
||||
lastMeasurementPacket = packetPool.allocCopy(*p);
|
||||
DEBUG_MSG("Device Telemetry: Sending packet to mesh");
|
||||
service.sendToMesh(p);
|
||||
return true;
|
||||
}
|
33
src/modules/Telemetry/DeviceTelemetry.h
Normal file
33
src/modules/Telemetry/DeviceTelemetry.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
#include "../mesh/generated/telemetry.pb.h"
|
||||
#include "ProtobufModule.h"
|
||||
#include <OLEDDisplay.h>
|
||||
#include <OLEDDisplayUi.h>
|
||||
|
||||
class DeviceTelemetryModule : private concurrency::OSThread, public ProtobufModule<Telemetry>
|
||||
{
|
||||
public:
|
||||
DeviceTelemetryModule()
|
||||
: concurrency::OSThread("DeviceTelemetryModule"),
|
||||
ProtobufModule("DeviceTelemetry", PortNum_TELEMETRY_APP, &Telemetry_msg)
|
||||
{
|
||||
lastMeasurementPacket = nullptr;
|
||||
}
|
||||
virtual bool wantUIFrame() { return false; }
|
||||
|
||||
protected:
|
||||
/** Called to handle a particular incoming message
|
||||
@return true if you've guaranteed you've handled this message and no other handlers should be considered for it
|
||||
*/
|
||||
virtual bool handleReceivedProtobuf(const MeshPacket &mp, Telemetry *p) override;
|
||||
virtual int32_t runOnce() override;
|
||||
/**
|
||||
* Send our Telemetry into the mesh
|
||||
*/
|
||||
bool sendOurTelemetry(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false);
|
||||
|
||||
private:
|
||||
String getSenderName(const MeshPacket &mp);
|
||||
bool firstTime = 1;
|
||||
const MeshPacket *lastMeasurementPacket;
|
||||
};
|
302
src/modules/Telemetry/EnvironmentTelemetry.cpp
Normal file
302
src/modules/Telemetry/EnvironmentTelemetry.cpp
Normal file
@ -0,0 +1,302 @@
|
||||
#include "EnvironmentTelemetry.h"
|
||||
#include "../mesh/generated/telemetry.pb.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "RTC.h"
|
||||
#include "Router.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include <OLEDDisplay.h>
|
||||
#include <OLEDDisplayUi.h>
|
||||
|
||||
// Sensors
|
||||
#include "Sensor/BME280Sensor.h"
|
||||
#include "Sensor/BME680Sensor.h"
|
||||
#include "Sensor/DHTSensor.h"
|
||||
#include "Sensor/DallasSensor.h"
|
||||
#include "Sensor/MCP9808Sensor.h"
|
||||
|
||||
BME280Sensor bme280Sensor;
|
||||
BME680Sensor bme680Sensor;
|
||||
DHTSensor dhtSensor;
|
||||
DallasSensor dallasSensor;
|
||||
MCP9808Sensor mcp9808Sensor;
|
||||
|
||||
#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10
|
||||
#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true
|
||||
|
||||
#ifdef HAS_EINK
|
||||
// The screen is bigger so use bigger fonts
|
||||
#define FONT_SMALL ArialMT_Plain_16
|
||||
#define FONT_MEDIUM ArialMT_Plain_24
|
||||
#define FONT_LARGE ArialMT_Plain_24
|
||||
#else
|
||||
#define FONT_SMALL ArialMT_Plain_10
|
||||
#define FONT_MEDIUM ArialMT_Plain_16
|
||||
#define FONT_LARGE ArialMT_Plain_24
|
||||
#endif
|
||||
|
||||
#define fontHeight(font) ((font)[1] + 1) // height is position 1
|
||||
|
||||
#define FONT_HEIGHT_SMALL fontHeight(FONT_SMALL)
|
||||
#define FONT_HEIGHT_MEDIUM fontHeight(FONT_MEDIUM)
|
||||
|
||||
int32_t EnvironmentTelemetryModule::runOnce()
|
||||
{
|
||||
#ifndef PORTDUINO
|
||||
/*
|
||||
Uncomment the preferences below if you want to use the module
|
||||
without having to configure it from the PythonAPI or WebUI.
|
||||
*/
|
||||
/*
|
||||
radioConfig.preferences.telemetry_module_environment_measurement_enabled = 1;
|
||||
radioConfig.preferences.telemetry_module_environment_screen_enabled = 1;
|
||||
radioConfig.preferences.telemetry_module_environment_read_error_count_threshold = 5;
|
||||
radioConfig.preferences.telemetry_module_environment_update_interval = 600;
|
||||
radioConfig.preferences.telemetry_module_environment_recovery_interval = 60;
|
||||
radioConfig.preferences.telemetry_module_environment_sensor_pin = 13; // If one-wire
|
||||
radioConfig.preferences.telemetry_module_environment_sensor_type = RadioConfig_UserPreferences_TelemetrySensorType::RadioConfig_UserPreferences_TelemetrySensorType_BME280;
|
||||
*/
|
||||
|
||||
if (!(radioConfig.preferences.telemetry_module_environment_measurement_enabled ||
|
||||
radioConfig.preferences.telemetry_module_environment_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_environment_measurement_enabled) {
|
||||
DEBUG_MSG("Environment 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_environment_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("Environment Telemetry: Invalid sensor type selected; Disabling module");
|
||||
return (INT32_MAX);
|
||||
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_environment_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_environment_read_error_count_threshold) {
|
||||
if (radioConfig.preferences.telemetry_module_environment_recovery_interval > 0) {
|
||||
DEBUG_MSG("Environment Telemetry: TEMPORARILY DISABLED; The "
|
||||
"telemetry_module_environment_read_error_count_threshold has been exceed: %d. Will retry reads in "
|
||||
"%d seconds\n",
|
||||
radioConfig.preferences.telemetry_module_environment_read_error_count_threshold,
|
||||
radioConfig.preferences.telemetry_module_environment_recovery_interval);
|
||||
sensor_read_error_count = 0;
|
||||
return (radioConfig.preferences.telemetry_module_environment_recovery_interval * 1000);
|
||||
}
|
||||
DEBUG_MSG("Environment Telemetry: DISABLED; The telemetry_module_environment_read_error_count_threshold has "
|
||||
"been exceed: %d. Reads will not be retried until after device reset\n",
|
||||
radioConfig.preferences.telemetry_module_environment_read_error_count_threshold);
|
||||
return (INT32_MAX);
|
||||
|
||||
} else if (sensor_read_error_count > 0) {
|
||||
DEBUG_MSG("Environment Telemetry: There have been %d sensor read failures. Will retry %d more times\n",
|
||||
sensor_read_error_count, sensor_read_error_count, sensor_read_error_count,
|
||||
radioConfig.preferences.telemetry_module_environment_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_environment_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);
|
||||
}
|
||||
}
|
||||
}
|
||||
// OSThread library. Multiply the preference value by 1000 to convert seconds to miliseconds
|
||||
return (getPref_telemetry_module_environment_update_interval() * 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
String GetSenderName(const MeshPacket &mp)
|
||||
{
|
||||
String sender;
|
||||
|
||||
auto node = nodeDB.getNode(getFrom(&mp));
|
||||
if (node) {
|
||||
sender = node->user.short_name;
|
||||
} else {
|
||||
sender = "UNK";
|
||||
}
|
||||
return sender;
|
||||
}
|
||||
|
||||
uint32_t GetTimeSinceMeshPacket(const MeshPacket *mp)
|
||||
{
|
||||
uint32_t now = getTime();
|
||||
|
||||
uint32_t last_seen = mp->rx_time;
|
||||
int delta = (int)(now - last_seen);
|
||||
if (delta < 0) // our clock must be slightly off still - not set from GPS yet
|
||||
delta = 0;
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
bool EnvironmentTelemetryModule::wantUIFrame()
|
||||
{
|
||||
return radioConfig.preferences.telemetry_module_environment_screen_enabled;
|
||||
}
|
||||
|
||||
float EnvironmentTelemetryModule::CelsiusToFahrenheit(float c)
|
||||
{
|
||||
return (c * 9) / 5 + 32;
|
||||
}
|
||||
|
||||
void EnvironmentTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||
{
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display->setFont(FONT_MEDIUM);
|
||||
display->drawString(x, y, "Environment");
|
||||
if (lastMeasurementPacket == nullptr) {
|
||||
display->setFont(FONT_SMALL);
|
||||
display->drawString(x, y += fontHeight(FONT_MEDIUM), "No measurement");
|
||||
return;
|
||||
}
|
||||
|
||||
Telemetry lastMeasurement;
|
||||
|
||||
uint32_t agoSecs = GetTimeSinceMeshPacket(lastMeasurementPacket);
|
||||
String lastSender = GetSenderName(*lastMeasurementPacket);
|
||||
|
||||
auto &p = lastMeasurementPacket->decoded;
|
||||
if (!pb_decode_from_bytes(p.payload.bytes, p.payload.size, Telemetry_fields, &lastMeasurement)) {
|
||||
display->setFont(FONT_SMALL);
|
||||
display->drawString(x, y += fontHeight(FONT_MEDIUM), "Measurement Error");
|
||||
DEBUG_MSG("Environment Telemetry: unable to decode last packet");
|
||||
return;
|
||||
}
|
||||
|
||||
display->setFont(FONT_SMALL);
|
||||
String last_temp = String(lastMeasurement.variant.environment_metrics.temperature, 0) + "°C";
|
||||
if (radioConfig.preferences.telemetry_module_environment_display_fahrenheit) {
|
||||
last_temp = String(CelsiusToFahrenheit(lastMeasurement.variant.environment_metrics.temperature), 0) + "°F";
|
||||
}
|
||||
display->drawString(x, y += fontHeight(FONT_MEDIUM) - 2, "From: " + lastSender + "(" + String(agoSecs) + "s)");
|
||||
display->drawString(x, y += fontHeight(FONT_SMALL) - 2,"Temp/Hum: " + last_temp + " / " + String(lastMeasurement.variant.environment_metrics.relative_humidity, 0) + "%");
|
||||
if (lastMeasurement.variant.environment_metrics.barometric_pressure != 0)
|
||||
display->drawString(x, y += fontHeight(FONT_SMALL),"Press: " + String(lastMeasurement.variant.environment_metrics.barometric_pressure, 0) + "hPA");
|
||||
}
|
||||
|
||||
bool EnvironmentTelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Telemetry *t)
|
||||
{
|
||||
if (t->which_variant == Telemetry_environment_metrics_tag) {
|
||||
String sender = GetSenderName(mp);
|
||||
|
||||
DEBUG_MSG("-----------------------------------------\n");
|
||||
DEBUG_MSG("Environment Telemetry: Received data from %s\n", sender);
|
||||
DEBUG_MSG("Telemetry->time: %i\n", t->time);
|
||||
DEBUG_MSG("Telemetry->barometric_pressure: %f\n", t->variant.environment_metrics.barometric_pressure);
|
||||
DEBUG_MSG("Telemetry->current: %f\n", t->variant.environment_metrics.current);
|
||||
DEBUG_MSG("Telemetry->gas_resistance: %f\n", t->variant.environment_metrics.gas_resistance);
|
||||
DEBUG_MSG("Telemetry->relative_humidity: %f\n", t->variant.environment_metrics.relative_humidity);
|
||||
DEBUG_MSG("Telemetry->temperature: %f\n", t->variant.environment_metrics.temperature);
|
||||
DEBUG_MSG("Telemetry->voltage: %f\n", t->variant.environment_metrics.voltage);
|
||||
|
||||
lastMeasurementPacket = packetPool.allocCopy(mp);
|
||||
}
|
||||
|
||||
return false; // Let others look at this message also if they want
|
||||
}
|
||||
|
||||
bool EnvironmentTelemetryModule::sendOurTelemetry(NodeNum dest, bool wantReplies)
|
||||
{
|
||||
Telemetry m;
|
||||
m.time = getTime();
|
||||
m.which_variant = Telemetry_environment_metrics_tag;
|
||||
|
||||
m.variant.environment_metrics.barometric_pressure = 0;
|
||||
m.variant.environment_metrics.current = 0;
|
||||
m.variant.environment_metrics.gas_resistance = 0;
|
||||
m.variant.environment_metrics.relative_humidity = 0;
|
||||
m.variant.environment_metrics.temperature = 0;
|
||||
m.variant.environment_metrics.voltage = 0;
|
||||
|
||||
DEBUG_MSG("-----------------------------------------\n");
|
||||
DEBUG_MSG("Environment Telemetry: Read data\n");
|
||||
|
||||
switch (radioConfig.preferences.telemetry_module_environment_sensor_type) {
|
||||
case RadioConfig_UserPreferences_TelemetrySensorType_DS18B20:
|
||||
if (!dallasSensor.getMeasurement(&m))
|
||||
sensor_read_error_count++;
|
||||
break;
|
||||
case RadioConfig_UserPreferences_TelemetrySensorType_DHT11:
|
||||
case RadioConfig_UserPreferences_TelemetrySensorType_DHT12:
|
||||
case RadioConfig_UserPreferences_TelemetrySensorType_DHT21:
|
||||
case RadioConfig_UserPreferences_TelemetrySensorType_DHT22:
|
||||
if (!dhtSensor.getMeasurement(&m))
|
||||
sensor_read_error_count++;
|
||||
break;
|
||||
case RadioConfig_UserPreferences_TelemetrySensorType_BME280:
|
||||
bme280Sensor.getMeasurement(&m);
|
||||
break;
|
||||
case RadioConfig_UserPreferences_TelemetrySensorType_BME680:
|
||||
bme680Sensor.getMeasurement(&m);
|
||||
break;
|
||||
case RadioConfig_UserPreferences_TelemetrySensorType_MCP9808:
|
||||
mcp9808Sensor.getMeasurement(&m);
|
||||
break;
|
||||
default:
|
||||
DEBUG_MSG("Environment Telemetry: No external sensor type selected; Only sending internal metrics\n");
|
||||
}
|
||||
|
||||
DEBUG_MSG("Telemetry->time: %i\n", m.time);
|
||||
DEBUG_MSG("Telemetry->barometric_pressure: %f\n", m.variant.environment_metrics.barometric_pressure);
|
||||
DEBUG_MSG("Telemetry->current: %f\n", m.variant.environment_metrics.current);
|
||||
DEBUG_MSG("Telemetry->gas_resistance: %f\n", m.variant.environment_metrics.gas_resistance);
|
||||
DEBUG_MSG("Telemetry->relative_humidity: %f\n", m.variant.environment_metrics.relative_humidity);
|
||||
DEBUG_MSG("Telemetry->temperature: %f\n", m.variant.environment_metrics.temperature);
|
||||
DEBUG_MSG("Telemetry->voltage: %f\n", m.variant.environment_metrics.voltage);
|
||||
|
||||
sensor_read_error_count = 0;
|
||||
|
||||
MeshPacket *p = allocDataProtobuf(m);
|
||||
p->to = dest;
|
||||
p->decoded.want_response = wantReplies;
|
||||
|
||||
lastMeasurementPacket = packetPool.allocCopy(*p);
|
||||
DEBUG_MSG("Environment Telemetry: Sending packet to mesh");
|
||||
service.sendToMesh(p);
|
||||
return true;
|
||||
}
|
@ -4,12 +4,12 @@
|
||||
#include <OLEDDisplay.h>
|
||||
#include <OLEDDisplayUi.h>
|
||||
|
||||
class TelemetryModule : private concurrency::OSThread, public ProtobufModule<Telemetry>
|
||||
class EnvironmentTelemetryModule : private concurrency::OSThread, public ProtobufModule<Telemetry>
|
||||
{
|
||||
public:
|
||||
TelemetryModule()
|
||||
: concurrency::OSThread("TelemetryModule"),
|
||||
ProtobufModule("Telemetry", PortNum_TELEMETRY_APP, &Telemetry_msg)
|
||||
EnvironmentTelemetryModule()
|
||||
: concurrency::OSThread("EnvironmentTelemetryModule"),
|
||||
ProtobufModule("EnvironmentTelemetry", PortNum_TELEMETRY_APP, &Telemetry_msg)
|
||||
{
|
||||
lastMeasurementPacket = nullptr;
|
||||
}
|
@ -21,9 +21,9 @@ int32_t BME280Sensor::runOnce() {
|
||||
}
|
||||
|
||||
bool BME280Sensor::getMeasurement(Telemetry *measurement) {
|
||||
measurement->temperature = bme280.readTemperature();
|
||||
measurement->relative_humidity = bme280.readHumidity();
|
||||
measurement->barometric_pressure = bme280.readPressure() / 100.0F;
|
||||
measurement->variant.environment_metrics.temperature = bme280.readTemperature();
|
||||
measurement->variant.environment_metrics.relative_humidity = bme280.readHumidity();
|
||||
measurement->variant.environment_metrics.barometric_pressure = bme280.readPressure() / 100.0F;
|
||||
|
||||
return true;
|
||||
}
|
@ -27,10 +27,10 @@ int32_t BME680Sensor::runOnce() {
|
||||
}
|
||||
|
||||
bool BME680Sensor::getMeasurement(Telemetry *measurement) {
|
||||
measurement->temperature = bme680.readTemperature();
|
||||
measurement->relative_humidity = bme680.readHumidity();
|
||||
measurement->barometric_pressure = bme680.readPressure() / 100.0F;
|
||||
measurement->gas_resistance = bme680.readGas() / 1000.0;
|
||||
measurement->variant.environment_metrics.temperature = bme680.readTemperature();
|
||||
measurement->variant.environment_metrics.relative_humidity = bme680.readHumidity();
|
||||
measurement->variant.environment_metrics.barometric_pressure = bme680.readPressure() / 100.0F;
|
||||
measurement->variant.environment_metrics.gas_resistance = bme680.readGas() / 1000.0;
|
||||
|
||||
return true;
|
||||
}
|
@ -11,16 +11,16 @@ DHTSensor::DHTSensor() : TelemetrySensor {} {
|
||||
int32_t DHTSensor::runOnce() {
|
||||
if (RadioConfig_UserPreferences_TelemetrySensorType_DHT11 ||
|
||||
RadioConfig_UserPreferences_TelemetrySensorType_DHT12) {
|
||||
dht = new DHT(radioConfig.preferences.telemetry_module_sensor_pin, DHT11);
|
||||
dht = new DHT(radioConfig.preferences.telemetry_module_environment_sensor_pin, DHT11);
|
||||
}
|
||||
else {
|
||||
dht = new DHT(radioConfig.preferences.telemetry_module_sensor_pin, DHT22);
|
||||
dht = new DHT(radioConfig.preferences.telemetry_module_environment_sensor_pin, DHT22);
|
||||
}
|
||||
|
||||
dht->begin();
|
||||
dht->read();
|
||||
DEBUG_MSG("Telemetry: Opened DHT11/DHT12 on pin: %d\n",
|
||||
radioConfig.preferences.telemetry_module_sensor_pin);
|
||||
radioConfig.preferences.telemetry_module_environment_sensor_pin);
|
||||
|
||||
return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
|
||||
}
|
||||
@ -30,7 +30,7 @@ bool DHTSensor::getMeasurement(Telemetry *measurement) {
|
||||
DEBUG_MSG("Telemetry: FAILED TO READ DATA\n");
|
||||
return false;
|
||||
}
|
||||
measurement->relative_humidity = dht->readHumidity();
|
||||
measurement->temperature = dht->readTemperature();
|
||||
measurement->variant.environment_metrics.relative_humidity = dht->readHumidity();
|
||||
measurement->variant.environment_metrics.temperature = dht->readTemperature();
|
||||
return true;
|
||||
}
|
@ -10,20 +10,20 @@ DallasSensor::DallasSensor() : TelemetrySensor {} {
|
||||
}
|
||||
|
||||
int32_t DallasSensor::runOnce() {
|
||||
oneWire = new OneWire(radioConfig.preferences.telemetry_module_sensor_pin);
|
||||
oneWire = new OneWire(radioConfig.preferences.telemetry_module_environment_sensor_pin);
|
||||
ds18b20 = new DS18B20(oneWire);
|
||||
ds18b20->begin();
|
||||
ds18b20->setResolution(12);
|
||||
ds18b20->requestTemperatures();
|
||||
DEBUG_MSG("Telemetry: Opened DS18B20 on pin: %d\n",
|
||||
radioConfig.preferences.telemetry_module_sensor_pin);
|
||||
radioConfig.preferences.telemetry_module_environment_sensor_pin);
|
||||
return (DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
|
||||
}
|
||||
|
||||
bool DallasSensor::getMeasurement(Telemetry *measurement) {
|
||||
if (ds18b20->isConversionComplete()) {
|
||||
measurement->temperature = ds18b20->getTempC();
|
||||
measurement->relative_humidity = 0;
|
||||
measurement->variant.environment_metrics.temperature = ds18b20->getTempC();
|
||||
measurement->variant.environment_metrics.relative_humidity = 0;
|
||||
ds18b20->requestTemperatures();
|
||||
return true;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ int32_t MCP9808Sensor::runOnce() {
|
||||
}
|
||||
|
||||
bool MCP9808Sensor::getMeasurement(Telemetry *measurement) {
|
||||
measurement->temperature = mcp9808.readTempC();
|
||||
measurement->variant.environment_metrics.temperature = mcp9808.readTempC();
|
||||
|
||||
return true;
|
||||
}
|
@ -1,276 +0,0 @@
|
||||
#include "Telemetry.h"
|
||||
#include "../mesh/generated/telemetry.pb.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "RTC.h"
|
||||
#include "Router.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include <OLEDDisplay.h>
|
||||
#include <OLEDDisplayUi.h>
|
||||
|
||||
// Sensors
|
||||
#include "Sensor/BME280Sensor.h"
|
||||
#include "Sensor/BME680Sensor.h"
|
||||
#include "Sensor/DHTSensor.h"
|
||||
#include "Sensor/DallasSensor.h"
|
||||
#include "Sensor/MCP9808Sensor.h"
|
||||
|
||||
BME280Sensor bme280Sensor;
|
||||
BME680Sensor bme680Sensor;
|
||||
DHTSensor dhtSensor;
|
||||
DallasSensor dallasSensor;
|
||||
MCP9808Sensor mcp9808Sensor;
|
||||
|
||||
#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10
|
||||
#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true
|
||||
|
||||
#ifdef HAS_EINK
|
||||
// The screen is bigger so use bigger fonts
|
||||
#define FONT_SMALL ArialMT_Plain_16
|
||||
#define FONT_MEDIUM ArialMT_Plain_24
|
||||
#define FONT_LARGE ArialMT_Plain_24
|
||||
#else
|
||||
#define FONT_SMALL ArialMT_Plain_10
|
||||
#define FONT_MEDIUM ArialMT_Plain_16
|
||||
#define FONT_LARGE ArialMT_Plain_24
|
||||
#endif
|
||||
|
||||
#define fontHeight(font) ((font)[1] + 1) // height is position 1
|
||||
|
||||
#define FONT_HEIGHT_SMALL fontHeight(FONT_SMALL)
|
||||
#define FONT_HEIGHT_MEDIUM fontHeight(FONT_MEDIUM)
|
||||
|
||||
int32_t TelemetryModule::runOnce()
|
||||
{
|
||||
#ifndef PORTDUINO
|
||||
/*
|
||||
Uncomment the preferences below if you want to use the module
|
||||
without having to configure it from the PythonAPI or WebUI.
|
||||
*/
|
||||
/*
|
||||
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_sensor_pin = 13; // If one-wire
|
||||
radioConfig.preferences.telemetry_module_sensor_type = RadioConfig_UserPreferences_TelemetrySensorType::RadioConfig_UserPreferences_TelemetrySensorType_BME280;
|
||||
*/
|
||||
|
||||
if (firstTime) {
|
||||
// This is the first time the OSThread library has called this function, so do some setup
|
||||
firstTime = 0;
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
// 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 (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,
|
||||
getPref_telemetry_module_update_interval());
|
||||
sensor_read_error_count = 0;
|
||||
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",
|
||||
radioConfig.preferences.telemetry_module_read_error_count_threshold);
|
||||
return (INT32_MAX);
|
||||
|
||||
} else if (sensor_read_error_count > 0) {
|
||||
DEBUG_MSG("Telemetry: There have been %d sensor read failures. Will retry %d more times\n",
|
||||
sensor_read_error_count, sensor_read_error_count, sensor_read_error_count,
|
||||
radioConfig.preferences.telemetry_module_read_error_count_threshold -
|
||||
sensor_read_error_count);
|
||||
}
|
||||
sendOurTelemetry();
|
||||
}
|
||||
// OSThread library. Multiply the preference value by 1000 to convert seconds to miliseconds
|
||||
return (getPref_telemetry_module_update_interval() * 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool TelemetryModule::wantUIFrame()
|
||||
{
|
||||
return radioConfig.preferences.telemetry_module_screen_enabled;
|
||||
}
|
||||
|
||||
String GetSenderName(const MeshPacket &mp)
|
||||
{
|
||||
String sender;
|
||||
|
||||
auto node = nodeDB.getNode(getFrom(&mp));
|
||||
if (node) {
|
||||
sender = node->user.short_name;
|
||||
} else {
|
||||
sender = "UNK";
|
||||
}
|
||||
return sender;
|
||||
}
|
||||
|
||||
uint32_t GetTimeSinceMeshPacket(const MeshPacket *mp)
|
||||
{
|
||||
uint32_t now = getTime();
|
||||
|
||||
uint32_t last_seen = mp->rx_time;
|
||||
int delta = (int)(now - last_seen);
|
||||
if (delta < 0) // our clock must be slightly off still - not set from GPS yet
|
||||
delta = 0;
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
float TelemetryModule::CelsiusToFahrenheit(float c)
|
||||
{
|
||||
return (c * 9) / 5 + 32;
|
||||
}
|
||||
|
||||
void TelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||
{
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display->setFont(FONT_MEDIUM);
|
||||
display->drawString(x, y, "Environment");
|
||||
if (lastMeasurementPacket == nullptr) {
|
||||
display->setFont(FONT_SMALL);
|
||||
display->drawString(x, y += fontHeight(FONT_MEDIUM), "No measurement");
|
||||
return;
|
||||
}
|
||||
|
||||
Telemetry lastMeasurement;
|
||||
|
||||
uint32_t agoSecs = GetTimeSinceMeshPacket(lastMeasurementPacket);
|
||||
String lastSender = GetSenderName(*lastMeasurementPacket);
|
||||
|
||||
auto &p = lastMeasurementPacket->decoded;
|
||||
if (!pb_decode_from_bytes(p.payload.bytes, p.payload.size, Telemetry_fields, &lastMeasurement)) {
|
||||
display->setFont(FONT_SMALL);
|
||||
display->drawString(x, y += fontHeight(FONT_MEDIUM), "Measurement Error");
|
||||
DEBUG_MSG("Telemetry: unable to decode last packet");
|
||||
return;
|
||||
}
|
||||
|
||||
display->setFont(FONT_SMALL);
|
||||
String last_temp = String(lastMeasurement.temperature, 0) + "°C";
|
||||
if (radioConfig.preferences.telemetry_module_display_fahrenheit) {
|
||||
last_temp = String(CelsiusToFahrenheit(lastMeasurement.temperature), 0) + "°F";
|
||||
}
|
||||
display->drawString(x, y += fontHeight(FONT_MEDIUM) - 2, "From: " + lastSender + "(" + String(agoSecs) + "s)");
|
||||
display->drawString(x, y += fontHeight(FONT_SMALL) - 2,"Temp/Hum: " + last_temp + " / " + String(lastMeasurement.relative_humidity, 0) + "%");
|
||||
if (lastMeasurement.barometric_pressure != 0)
|
||||
display->drawString(x, y += fontHeight(FONT_SMALL),"Press: " + String(lastMeasurement.barometric_pressure, 0) + "hPA");
|
||||
}
|
||||
|
||||
bool TelemetryModule::handleReceivedProtobuf(const MeshPacket &mp, Telemetry *t)
|
||||
{
|
||||
String sender = GetSenderName(mp);
|
||||
|
||||
DEBUG_MSG("-----------------------------------------\n");
|
||||
DEBUG_MSG("Telemetry: Received data from %s\n", sender);
|
||||
DEBUG_MSG("Telemetry->time: %i\n", t->time);
|
||||
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.time = getTime();
|
||||
|
||||
m.air_util_tx = myNodeInfo.air_util_tx;
|
||||
m.barometric_pressure = 0;
|
||||
m.battery_level = powerStatus->getBatteryChargePercent();
|
||||
m.channel_utilization = myNodeInfo.channel_utilization;
|
||||
m.current = 0;
|
||||
m.gas_resistance = 0;
|
||||
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) {
|
||||
case RadioConfig_UserPreferences_TelemetrySensorType_DS18B20:
|
||||
if (!dallasSensor.getMeasurement(&m))
|
||||
sensor_read_error_count++;
|
||||
break;
|
||||
case RadioConfig_UserPreferences_TelemetrySensorType_DHT11:
|
||||
case RadioConfig_UserPreferences_TelemetrySensorType_DHT12:
|
||||
case RadioConfig_UserPreferences_TelemetrySensorType_DHT21:
|
||||
case RadioConfig_UserPreferences_TelemetrySensorType_DHT22:
|
||||
if (!dhtSensor.getMeasurement(&m))
|
||||
sensor_read_error_count++;
|
||||
break;
|
||||
case RadioConfig_UserPreferences_TelemetrySensorType_BME280:
|
||||
bme280Sensor.getMeasurement(&m);
|
||||
break;
|
||||
case RadioConfig_UserPreferences_TelemetrySensorType_BME680:
|
||||
bme680Sensor.getMeasurement(&m);
|
||||
break;
|
||||
case RadioConfig_UserPreferences_TelemetrySensorType_MCP9808:
|
||||
mcp9808Sensor.getMeasurement(&m);
|
||||
break;
|
||||
default:
|
||||
DEBUG_MSG("Telemetry: No external sensor type selected; Only sending internal metrics\n");
|
||||
}
|
||||
|
||||
DEBUG_MSG("Telemetry->time: %i\n", m.time);
|
||||
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;
|
||||
|
||||
MeshPacket *p = allocDataProtobuf(m);
|
||||
p->to = dest;
|
||||
p->decoded.want_response = wantReplies;
|
||||
|
||||
lastMeasurementPacket = packetPool.allocCopy(*p);
|
||||
DEBUG_MSG("Telemetry: Sending packet to mesh");
|
||||
service.sendToMesh(p);
|
||||
return true;
|
||||
}
|
@ -290,15 +290,17 @@ String MQTT::downstreamPacketToJson(MeshPacket *mp)
|
||||
memset(&scratch, 0, sizeof(scratch));
|
||||
if (pb_decode_from_bytes(mp->decoded.payload.bytes, mp->decoded.payload.size, &Telemetry_msg,
|
||||
&scratch)) {
|
||||
decoded = &scratch;
|
||||
msgPayload = Json::object{
|
||||
{"temperature", decoded->temperature},
|
||||
{"relative_humidity", decoded->relative_humidity},
|
||||
{"barometric_pressure", decoded->barometric_pressure},
|
||||
{"gas_resistance", decoded->gas_resistance},
|
||||
{"voltage", decoded->voltage},
|
||||
{"current", decoded->current},
|
||||
};
|
||||
if (decoded->which_variant == Telemetry_environment_metrics_tag) {
|
||||
decoded = &scratch;
|
||||
msgPayload = Json::object{
|
||||
{"temperature", decoded->variant.environment_metrics.temperature},
|
||||
{"relative_humidity", decoded->variant.environment_metrics.relative_humidity},
|
||||
{"barometric_pressure", decoded->variant.environment_metrics.barometric_pressure},
|
||||
{"gas_resistance", decoded->variant.environment_metrics.gas_resistance},
|
||||
{"voltage", decoded->variant.environment_metrics.voltage},
|
||||
{"current", decoded->variant.environment_metrics.current},
|
||||
};
|
||||
}
|
||||
} else
|
||||
DEBUG_MSG("Error decoding protobuf for telemetry message!\n");
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user