Merge branch 'dev' into dev1.2

# Conflicts:
#	proto
#	src/mesh/generated/deviceonly.pb.h
#	src/mesh/generated/mesh.pb.h
#	src/plugins/esp32/EnvironmentalMeasurementPlugin.cpp
This commit is contained in:
Kevin Hester
2021-02-25 19:44:08 +08:00
7 changed files with 225 additions and 24 deletions

View File

@@ -7,6 +7,8 @@
#include "main.h"
#include "../mesh/generated/environmental_measurement.pb.h"
#include <DHT.h>
#include <OLEDDisplay.h>
#include <OLEDDisplayUi.h>
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,64 @@ 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::handleReceivedProtobuf(const MeshPacket &mp, const EnvironmentalMeasurement *p)
bool EnvironmentalMeasurementPluginRadio::wantUIFrame() {
return radioConfig.preferences.environmental_measurement_plugin_screen_enabled;
}
void EnvironmentalMeasurementPluginRadio::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
// This plugin doesn't really do anything with the messages it receives.
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 *pptr)
{
const EnvironmentalMeasurement &p = *pptr;
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 +189,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;
}