diff --git a/proto b/proto index 564292ee..d70f6f6f 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 564292ee83bbd085d0c51a7f882d3a2aa305d6d6 +Subproject commit d70f6f6f669df79c9423795caf34adbd28967e19 diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 40ea2523..8f974a4c 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -64,6 +64,10 @@ uint8_t imgBattery[16] = {0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, // Threshold values for the GPS lock accuracy bar display uint32_t dopThresholds[5] = {2000, 1000, 500, 200, 100}; +// At some point, we're going to ask all of the plugins if they would like to display a screen frame +// we'll need to hold onto pointers for the plugins that can draw a frame. +std::vector pluginFrames; + // Stores the last 4 of our hardware ID, to make finding the device for pairing easier static char ourId[5]; @@ -144,6 +148,30 @@ static void drawSleepScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int drawIconScreen("Sleeping...", display, state, x, y); } +static void drawPluginFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) +{ + uint8_t plugin_frame; + // there's a little but in the UI transition code + // where it invokes the function at the correct offset + // in the array of "drawScreen" functions; however, + // the passed-state doesn't quite reflect the "current" + // screen, so we have to detect it. + if (state->frameState == IN_TRANSITION && state->transitionFrameRelationship == INCOMING) { + // if we're transitioning from the end of the frame list back around to the first + // frame, then we want this to be `0` + plugin_frame = state->transitionFrameTarget; + } + else { + // otherwise, just display the plugin frame that's aligned with the current frame + plugin_frame = state->currentFrame; + //DEBUG_MSG("Screen is not in transition. Frame: %d\n\n", plugin_frame); + } + //DEBUG_MSG("Drawing Plugin Frame %d\n\n", plugin_frame); + MeshPlugin &pi = *pluginFrames.at(plugin_frame); + pi.drawFrame(display,state,x,y); + +} + static void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { display->setTextAlignment(TEXT_ALIGN_CENTER); @@ -887,6 +915,11 @@ void Screen::setFrames() DEBUG_MSG("showing standard frames\n"); showingNormalScreen = true; + pluginFrames = MeshPlugin::GetMeshPluginsWithUIFrames(); + DEBUG_MSG("Showing %d plugin frames\n", pluginFrames.size()); + int totalFrameCount = MAX_NUM_NODES + NUM_EXTRA_FRAMES + pluginFrames.size(); + DEBUG_MSG("Total frame count: %d\n", totalFrameCount); + // We don't show the node info our our node (if we have it yet - we should) size_t numnodes = nodeStatus->getNumTotal(); if (numnodes > 0) @@ -894,6 +927,18 @@ void Screen::setFrames() size_t numframes = 0; + // put all of the plugin frames first. + // this is a little bit of a dirty hack; since we're going to call + // the same drawPluginFrame handler here for all of these plugin frames + // and then we'll just assume that the state->currentFrame value + // is the same offset into the pluginFrames vector + // so that we can invoke the plugin's callback + for (auto i = pluginFrames.begin(); i != pluginFrames.end(); ++i) { + normalFrames[numframes++] = drawPluginFrame; + } + + DEBUG_MSG("Added plugins. numframes: %d\n", numframes); + // If we have a critical fault, show it first if (myNodeInfo.error_code) normalFrames[numframes++] = drawCriticalFaultFrame; @@ -922,6 +967,8 @@ void Screen::setFrames() } #endif + DEBUG_MSG("Finished building frames. numframes: %d\n", numframes); + ui.setFrames(normalFrames, numframes); ui.enableAllIndicators(); diff --git a/src/mesh/MeshPlugin.cpp b/src/mesh/MeshPlugin.cpp index ebaee49a..006ce571 100644 --- a/src/mesh/MeshPlugin.cpp +++ b/src/mesh/MeshPlugin.cpp @@ -75,4 +75,18 @@ void MeshPlugin::sendResponse(const MeshPacket &req) { void setReplyTo(MeshPacket *p, const MeshPacket &to) { p->to = to.from; p->want_ack = to.want_ack; -} \ No newline at end of file +} + +std::vector MeshPlugin::GetMeshPluginsWithUIFrames() { + + std::vector pluginsWithUIFrames; + for (auto i = plugins->begin(); i != plugins->end(); ++i) { + auto &pi = **i; + if ( pi.wantUIFrame()) { + DEBUG_MSG("Plugin wants a UI Frame\n"); + pluginsWithUIFrames.push_back(&pi); + } + } + return pluginsWithUIFrames; + +} diff --git a/src/mesh/MeshPlugin.h b/src/mesh/MeshPlugin.h index 01af5811..a5fa4844 100644 --- a/src/mesh/MeshPlugin.h +++ b/src/mesh/MeshPlugin.h @@ -2,6 +2,8 @@ #include "mesh/MeshTypes.h" #include +#include +#include /** A baseclass for any mesh "plugin". * * A plugin allows you to add new features to meshtastic device code, without needing to know messaging details. @@ -14,7 +16,7 @@ */ class MeshPlugin { - static std::vector *plugins; + static std::vector *plugins; public: /** Constructor @@ -28,6 +30,10 @@ class MeshPlugin */ static void callPlugins(const MeshPacket &mp); + static std::vector GetMeshPluginsWithUIFrames(); + + virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { return; } + protected: const char *name; @@ -61,6 +67,13 @@ class MeshPlugin * so that subclasses can (optionally) send a response back to the original sender. */ virtual MeshPacket *allocReply() { return NULL; } + /*** + * @return true if you want to be alloced a UI screen frame + */ + virtual bool wantUIFrame() { return false; } + + + private: /** Messages can be received that have the want_response bit set. If set, this callback will be invoked diff --git a/src/mesh/generated/deviceonly.pb.h b/src/mesh/generated/deviceonly.pb.h index 99d838d3..0e933b96 100644 --- a/src/mesh/generated/deviceonly.pb.h +++ b/src/mesh/generated/deviceonly.pb.h @@ -80,10 +80,10 @@ extern const pb_msgdesc_t DeviceState_msg; #define DeviceState_fields &DeviceState_msg /* Maximum encoded size of messages (where known) */ -#define DeviceState_size 6266 +#define DeviceState_size 6293 #ifdef __cplusplus } /* extern "C" */ #endif -#endif \ No newline at end of file +#endif diff --git a/src/mesh/generated/mesh.pb.h b/src/mesh/generated/mesh.pb.h index 397a313e..edc74a90 100644 --- a/src/mesh/generated/mesh.pb.h +++ b/src/mesh/generated/mesh.pb.h @@ -208,6 +208,11 @@ typedef struct _RadioConfig_UserPreferences { bool range_test_plugin_save; bool store_forward_plugin_enabled; uint32_t store_forward_plugin_records; + bool environmental_measurement_plugin_measurement_enabled; + bool environmental_measurement_plugin_screen_enabled; + uint32_t environmental_measurement_plugin_read_error_count_threshold; + uint32_t environmental_measurement_plugin_update_interval; + uint32_t environmental_measurement_plugin_recovery_interval; } RadioConfig_UserPreferences; typedef struct _RouteDiscovery { @@ -360,7 +365,7 @@ extern "C" { #define MeshPacket_init_default {0, 0, 0, {SubPacket_init_default}, 0, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN} #define ChannelSettings_init_default {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0, 0, 0, 0} #define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default, false, ChannelSettings_init_default} -#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, _LocationSharing_MIN, _GpsOperation_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 RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, _LocationSharing_MIN, _GpsOperation_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, 0, 0, 0, 0, 0} #define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0} #define MyNodeInfo_init_default {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0} #define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN} @@ -374,7 +379,7 @@ extern "C" { #define MeshPacket_init_zero {0, 0, 0, {SubPacket_init_zero}, 0, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN} #define ChannelSettings_init_zero {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0, 0, 0, 0} #define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero, false, ChannelSettings_init_zero} -#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, _LocationSharing_MIN, _GpsOperation_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 RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, _LocationSharing_MIN, _GpsOperation_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, 0, 0, 0, 0, 0} #define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0} #define MyNodeInfo_init_zero {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0} #define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN} @@ -460,6 +465,11 @@ extern "C" { #define RadioConfig_UserPreferences_range_test_plugin_save_tag 134 #define RadioConfig_UserPreferences_store_forward_plugin_enabled_tag 136 #define RadioConfig_UserPreferences_store_forward_plugin_records_tag 137 +#define RadioConfig_UserPreferences_environmental_measurement_plugin_measurement_enabled_tag 140 +#define RadioConfig_UserPreferences_environmental_measurement_plugin_screen_enabled_tag 141 +#define RadioConfig_UserPreferences_environmental_measurement_plugin_read_error_count_threshold_tag 142 +#define RadioConfig_UserPreferences_environmental_measurement_plugin_update_interval_tag 143 +#define RadioConfig_UserPreferences_environmental_measurement_plugin_recovery_interval_tag 144 #define RouteDiscovery_route_tag 2 #define User_id_tag 1 #define User_long_name_tag 2 @@ -641,7 +651,12 @@ X(a, STATIC, SINGULAR, BOOL, range_test_plugin_enabled, 132) \ X(a, STATIC, SINGULAR, UINT32, range_test_plugin_sender, 133) \ X(a, STATIC, SINGULAR, BOOL, range_test_plugin_save, 134) \ X(a, STATIC, SINGULAR, BOOL, store_forward_plugin_enabled, 136) \ -X(a, STATIC, SINGULAR, UINT32, store_forward_plugin_records, 137) +X(a, STATIC, SINGULAR, UINT32, store_forward_plugin_records, 137) \ +X(a, STATIC, SINGULAR, BOOL, environmental_measurement_plugin_measurement_enabled, 140) \ +X(a, STATIC, SINGULAR, BOOL, environmental_measurement_plugin_screen_enabled, 141) \ +X(a, STATIC, SINGULAR, UINT32, environmental_measurement_plugin_read_error_count_threshold, 142) \ +X(a, STATIC, SINGULAR, UINT32, environmental_measurement_plugin_update_interval, 143) \ +X(a, STATIC, SINGULAR, UINT32, environmental_measurement_plugin_recovery_interval, 144) #define RadioConfig_UserPreferences_CALLBACK NULL #define RadioConfig_UserPreferences_DEFAULT NULL @@ -753,13 +768,13 @@ extern const pb_msgdesc_t ToRadio_msg; #define SubPacket_size 275 #define MeshPacket_size 322 #define ChannelSettings_size 95 -#define RadioConfig_size 405 -#define RadioConfig_UserPreferences_size 305 +#define RadioConfig_size 432 +#define RadioConfig_UserPreferences_size 332 #define NodeInfo_size 132 #define MyNodeInfo_size 106 #define LogRecord_size 81 -#define FromRadio_size 414 -#define ToRadio_size 409 +#define FromRadio_size 441 +#define ToRadio_size 436 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/generated/portnums.pb.h b/src/mesh/generated/portnums.pb.h index 8d262c47..496324a8 100644 --- a/src/mesh/generated/portnums.pb.h +++ b/src/mesh/generated/portnums.pb.h @@ -18,10 +18,10 @@ typedef enum _PortNum { PortNum_NODEINFO_APP = 4, PortNum_REPLY_APP = 32, PortNum_IP_TUNNEL_APP = 33, - PortNum_ENVIRONMENTAL_MEASUREMENT_APP = 34, PortNum_SERIAL_APP = 64, PortNum_STORE_FORWARD_APP = 65, PortNum_RANGE_TEST_APP = 66, + PortNum_ENVIRONMENTAL_MEASUREMENT_APP = 67, PortNum_PRIVATE_APP = 256, PortNum_ATAK_FORWARDER = 257 } PortNum; diff --git a/src/plugins/esp32/EnvironmentalMeasurementPlugin.cpp b/src/plugins/esp32/EnvironmentalMeasurementPlugin.cpp index 76eda3d2..2d706150 100644 --- a/src/plugins/esp32/EnvironmentalMeasurementPlugin.cpp +++ b/src/plugins/esp32/EnvironmentalMeasurementPlugin.cpp @@ -7,6 +7,8 @@ #include "main.h" #include "../mesh/generated/environmental_measurement.pb.h" #include +#include +#include EnvironmentalMeasurementPlugin *environmentalMeasurementPlugin; EnvironmentalMeasurementPluginRadio *environmentalMeasurementPluginRadio; @@ -16,19 +18,51 @@ EnvironmentalMeasurementPlugin::EnvironmentalMeasurementPlugin() : concurrency:: uint32_t sensor_read_error_count = 0; #define DHT_11_GPIO_PIN 13 -//TODO: Make a related radioconfig preference to allow less-frequent reads -#define DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000 -#define SENSOR_READ_ERROR_COUNT_THRESHOLD 5 -#define SENSOR_READ_MULTIPLIER 3 - +#define DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000 // Some sensors (the DHT11) have a minimum required duration between read attempts +#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10 +#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true DHT dht(DHT_11_GPIO_PIN,DHT11); + +#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 EnvironmentalMeasurementPlugin::runOnce() { -#ifndef NO_ESP32 +#ifndef NO_ESP32 // this only works on ESP32 devices + + /* + Uncomment the preferences below if you want to use the plugin + without having to configure it from the PythonAPI or WebUI. + */ + /*radioConfig.preferences.environmental_measurement_plugin_measurement_enabled = 1; + radioConfig.preferences.environmental_measurement_plugin_screen_enabled = 1; + radioConfig.preferences.environmental_measurement_plugin_read_error_count_threshold = 5; + radioConfig.preferences.environmental_measurement_plugin_update_interval = 30; + radioConfig.preferences.environmental_measurement_plugin_recovery_interval = 600;*/ + + if (! (radioConfig.preferences.environmental_measurement_plugin_measurement_enabled || radioConfig.preferences.environmental_measurement_plugin_screen_enabled)){ + // If this plugin 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 - DEBUG_MSG("Initializing Environmental Measurement Plugin -- Sender\n"); + DEBUG_MSG("EnvironmentalMeasurement: Initializing\n"); environmentalMeasurementPluginRadio = new EnvironmentalMeasurementPluginRadio(); firstTime = 0; // begin reading measurements from the sensor @@ -37,19 +71,44 @@ int32_t EnvironmentalMeasurementPlugin::runOnce() { // returning the interval here means that the next time OSThread // calls our plugin, we'll run the other branch of this if statement // and actually do a "sendOurEnvironmentalMeasurement()" - dht.begin(); - return(DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + if (radioConfig.preferences.environmental_measurement_plugin_measurement_enabled) + { + // it's possible to have this plugin enabled, only for displaying values on the screen. + // therefore, we should only enable the sensor loop if measurement is also enabled + dht.begin(); + return(DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + } + return (INT32_MAX); } else { + if (!radioConfig.preferences.environmental_measurement_plugin_measurement_enabled) + { + // if we somehow got to a second run of this plugin with measurement disabled, then just wait forever + // I can't imagine we'd ever get here though. + 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 > SENSOR_READ_ERROR_COUNT_THRESHOLD) + if(sensor_read_error_count > radioConfig.preferences.environmental_measurement_plugin_read_error_count_threshold) { - DEBUG_MSG("Environmental Measurement Plugin: DISABLED; The SENSOR_READ_ERROR_COUNT_THRESHOLD has been exceed: %d\n",SENSOR_READ_ERROR_COUNT_THRESHOLD); - return(DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + if (radioConfig.preferences.environmental_measurement_plugin_recovery_interval > 0 ) { + DEBUG_MSG( + "EnvironmentalMeasurement: TEMPORARILY DISABLED; The environmental_measurement_plugin_read_error_count_threshold has been exceed: %d. Will retry reads in %d seconds\n", + radioConfig.preferences.environmental_measurement_plugin_read_error_count_threshold, + radioConfig.preferences.environmental_measurement_plugin_recovery_interval); + return(radioConfig.preferences.environmental_measurement_plugin_recovery_interval*1000); + } + DEBUG_MSG( + "EnvironmentalMeasurement: DISABLED; The environmental_measurement_plugin_read_error_count_threshold has been exceed: %d. Reads will not be retried until after device reset\n", + radioConfig.preferences.environmental_measurement_plugin_read_error_count_threshold); + return(INT32_MAX); + + } else if (sensor_read_error_count > 0){ - DEBUG_MSG("Environmental Measurement Plugin: There have been %d sensor read failures.\n",sensor_read_error_count); + DEBUG_MSG("EnvironmentalMeasurement: There have been %d sensor read failures. Will retry %d more times\n", + sensor_read_error_count, + radioConfig.preferences.environmental_measurement_plugin_read_error_count_threshold-sensor_read_error_count); } if (! environmentalMeasurementPluginRadio->sendOurEnvironmentalMeasurement() ){ // if we failed to read the sensor, then try again @@ -59,14 +118,62 @@ int32_t EnvironmentalMeasurementPlugin::runOnce() { } // The return of runOnce is an int32 representing the desired number of // miliseconds until the function should be called again by the - // OSThread library. - return(SENSOR_READ_MULTIPLIER * DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS); + // OSThread library. Multiply the preference value by 1000 to convert seconds to miliseconds + return(radioConfig.preferences.environmental_measurement_plugin_update_interval * 1000); #endif } +bool EnvironmentalMeasurementPluginRadio::wantUIFrame() { + return radioConfig.preferences.environmental_measurement_plugin_screen_enabled; +} + +void EnvironmentalMeasurementPluginRadio::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"); + display->setFont(FONT_SMALL); + display->drawString(x, y += fontHeight(FONT_MEDIUM), lastSender+": T:"+ String(lastMeasurement.temperature,2) + " H:" + String(lastMeasurement.relative_humidity,2)); + +} + +String GetSenderName(const MeshPacket &mp) { + String sender; + + if (nodeDB.getNode(mp.from)){ + sender = nodeDB.getNode(mp.from)->user.short_name; + } + else { + sender = "UNK"; + } + return sender; +} + bool EnvironmentalMeasurementPluginRadio::handleReceivedProtobuf(const MeshPacket &mp, const EnvironmentalMeasurement &p) { - // This plugin doesn't really do anything with the messages it receives. + if (!(radioConfig.preferences.environmental_measurement_plugin_measurement_enabled || radioConfig.preferences.environmental_measurement_plugin_screen_enabled)){ + // If this plugin is not enabled in any capacity, don't handle the packet, and allow other plugins to consume + return false; + } + bool wasBroadcast = mp.to == NODENUM_BROADCAST; + + String sender = GetSenderName(mp); + + // Show new nodes on LCD screen + if (DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN && wasBroadcast) { + String lcd = String("Env Measured: ") +sender + "\n" + + "T: " + p.temperature + "\n" + + "H: " + p.relative_humidity + "\n"; + screen->print(lcd.c_str()); + } + DEBUG_MSG("-----------------------------------------\n"); + + DEBUG_MSG("EnvironmentalMeasurement: Received data from %s\n", sender); + DEBUG_MSG("EnvironmentalMeasurement->relative_humidity: %f\n", p.relative_humidity); + DEBUG_MSG("EnvironmentalMeasurement->temperature: %f\n", p.temperature); + + lastMeasurement = p; + lastSender = sender; return false; // Let others look at this message also if they want } @@ -80,13 +187,13 @@ bool EnvironmentalMeasurementPluginRadio::sendOurEnvironmentalMeasurement(NodeNu DEBUG_MSG("-----------------------------------------\n"); - DEBUG_MSG("Environmental Measurement Plugin: Read data\n"); + DEBUG_MSG("EnvironmentalMeasurement: Read data\n"); DEBUG_MSG("EnvironmentalMeasurement->relative_humidity: %f\n", m.relative_humidity); DEBUG_MSG("EnvironmentalMeasurement->temperature: %f\n", m.temperature); if (isnan(m.relative_humidity) || isnan(m.temperature) ){ sensor_read_error_count++; - DEBUG_MSG("Environmental Measurement Plugin: FAILED TO READ DATA\n"); + DEBUG_MSG("EnvironmentalMeasurement: FAILED TO READ DATA\n"); return false; } diff --git a/src/plugins/esp32/EnvironmentalMeasurementPlugin.h b/src/plugins/esp32/EnvironmentalMeasurementPlugin.h index 31581b31..19d73914 100644 --- a/src/plugins/esp32/EnvironmentalMeasurementPlugin.h +++ b/src/plugins/esp32/EnvironmentalMeasurementPlugin.h @@ -1,6 +1,8 @@ #pragma once #include "ProtobufPlugin.h" #include "../mesh/generated/environmental_measurement.pb.h" +#include +#include class EnvironmentalMeasurementPlugin : private concurrency::OSThread @@ -25,12 +27,19 @@ class EnvironmentalMeasurementPluginRadio : public ProtobufPlugin