Merge branch 'meshtastic:master' into master

pull/1273/head
joshpirihi 2022-03-06 05:46:32 +13:00 zatwierdzone przez GitHub
commit 0a14f5d168
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
103 zmienionych plików z 1882 dodań i 1809 usunięć

Wyświetl plik

@ -1,8 +1,11 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide",
"xaver.clang-format"
]
}
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide",
"xaver.clang-format"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

Wyświetl plik

@ -11,7 +11,7 @@ env.Replace( MKSPIFFSTOOL=env.get("PROJECT_DIR") + '/bin/mklittlefs.py' )
try:
import littlefs
except ImportError:
env.Execute("$PYTHONEXE -m pip install --user littlefs-python")
env.Execute("$PYTHONEXE -m pip install littlefs-python")
Import("projenv")

Wyświetl plik

@ -63,7 +63,7 @@ You probably don't care about this section - skip to the next one.
## Multichannel support
* DONE cleanup the external notification and serial plugins
* DONE cleanup the external notification and serial modules
* non ack version of stress test fails sometimes!
* tx fault test has a bug #734 - * turn off fault 8: https://github.com/meshtastic/Meshtastic-device/issues/734
* DONE move device types into an enum in nodeinfo
@ -71,7 +71,7 @@ You probably don't care about this section - skip to the next one.
* nrf52 should preserve local time across reset
* cdcacm bug on nrf52: emittx thinks it emitted but client sees nothing. works again later
* nrf52: segger logs have errors in formatting that should be impossible (because not going through serial, try stalling on segger)
* DONE call RouterPlugin for *all* packets - not just Router packets
* DONE call RouterModule for *all* packets - not just Router packets
* DONE generate channel hash from the name of the channel+the psk (not just one or the other)
* DONE send a hint that can be used to select which channel to try and hash against with each message
* DONE remove deprecated
@ -79,13 +79,13 @@ You probably don't care about this section - skip to the next one.
* DONE set mynodeinfo.max_channels
* DONE set mynodeinfo.num_bands (formerly num_channels)
* DONE fix sniffing of non Routing packets
* DONE enable remote setttings access by moving settings operations into a regular plugin (move settings ops out of PhoneAPI)
* DONE enable remote setttings access by moving settings operations into a regular module (move settings ops out of PhoneAPI)
* DONE move portnum up?
* DONE remove region specific builds from the firmware
* DONE test single channel without python
* DONE Use "default" for name if name is empty
* DONE fix python data packet receiving (nothing showing in log?)
* DONE implement 'get channels' Admin plugin operation
* DONE implement 'get channels' Admin module operation
* DONE use get-channels from python
* DONE use get channels & get settings from android
* DONE use set-channel from python
@ -98,7 +98,7 @@ You probably don't care about this section - skip to the next one.
* DONE fix setch-fast in python tool
* age out pendingrequests in the python API
* DONE stress test channel download from python, sometimes it seems like we don't get all replies, bug was due to simultaneous android connection
* DONE combine acks and responses in a single message if possible (do routing plugin LAST and drop ACK if someone else has already replied)
* DONE combine acks and responses in a single message if possible (do routing module LAST and drop ACK if someone else has already replied)
* DONE don't send packets we received from the phone BACK TOWARDS THE PHONE (possibly use fromnode 0 for packets the phone sends?)
* DONE fix 1.1.50 android debug panel display
* DONE test android channel setting
@ -118,7 +118,7 @@ You probably don't care about this section - skip to the next one.
* use single byte 'well known' channel names for admin, gpio, etc...
* use presence of gpio channel to enable gpio ops, same for serial etc...
* DONE restrict gpio & serial & settings operations to the admin channel (unless local to the current node)
* DONE add channel restrictions for plugins (and restrict routing plugin to the "control" channel)
* DONE add channel restrictions for modules (and restrict routing module to the "control" channel)
* stress test multi channel
* DONE investigate @mc-hamster report of heap corruption
* DONE use set-user from android
@ -134,7 +134,7 @@ You probably don't care about this section - skip to the next one.
* allow chaning packets in single transmission - to increase airtime efficiency and amortize packet overhead
* DONE move most parts of meshpacket into the Data packet, so that we can chain multiple Data for sending when they all have a common destination and key.
* when selecting a MeshPacket for transmit, scan the TX queue for any Data packets we can merge together as a WirePayload. In the low level send/rx code expand that into multiple MeshPackets as needed (thus 'hiding' from MeshPacket that over the wire we send multiple datapackets
* DONE confirm we are still calling the plugins for messages inbound from the phone (or generated locally)
* DONE confirm we are still calling the modules for messages inbound from the phone (or generated locally)
* DONE confirm we are still multi hop routing flood broadcasts
* DONE confirm we are still doing resends on unicast reliable packets
* add history to routed packets: https://meshtastic.discourse.group/t/packet-source-tracking/2764/2
@ -142,7 +142,7 @@ You probably don't care about this section - skip to the next one.
* DONE move acks into routing
* DONE make all subpackets different versions of data
* DONE move routing control into a data packet
* have phoneapi done via plugin (will allow multiple simultaneous API clients - stop disabling BLE while using phone API)
* have phoneapi done via module (will allow multiple simultaneous API clients - stop disabling BLE while using phone API)
* use reference counting and dynamic sizing for meshpackets. - use https://docs.microsoft.com/en-us/cpp/cpp/how-to-create-and-use-shared-ptr-instances?view=msvc-160 (already used in arduino)
* let multiple PhoneAPI endpoints work at once
* allow multiple simultaneous bluetooth connections (create the bluetooth phoneapi instance dynamically based on client id)
@ -182,13 +182,13 @@ For app cleanup:
* DONE require a recent python api to talk to these new device loads
* DONE require a recent android app to talk to these new device loads
* DONE fix handleIncomingPosition
* DONE move want_replies handling into plugins
* DONE move want_replies handling into modules
* DONE on android for received positions handle either old or new positions / user messages
* DONE on android side send old or new positions as needed / user messages
* DONE test python side handle new position/user messages
* DONE make a gpio example. --gpiowrb 4 1, --gpiord 0x444, --gpiowatch 0x3ff
* DONE fix position sending to use new plugin
* DONE Add SinglePortNumPlugin - as the new most useful baseclass
* DONE fix position sending to use new module
* DONE Add SinglePortNumModule - as the new most useful baseclass
* DONE move positions into regular data packets (use new app framework)
* DONE move user info into regular data packets (use new app framework)
* DONE test that positions, text messages and user info still work

Wyświetl plik

@ -197,7 +197,7 @@ build_flags =
-Isdk-nrfxlib/crypto/nrf_oberon/include -Lsdk-nrfxlib/crypto/nrf_oberon/lib/cortex-m4/hard-float/ -lliboberon_3.0.7
;-DCFG_DEBUG=3
src_filter =
${arduino_base.src_filter} -<esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<plugins/esp32> -<mqtt/>
${arduino_base.src_filter} -<esp32/> -<nimble/> -<mesh/wifi/> -<mesh/http/> -<modules/esp32> -<mqtt/>
lib_ignore =
BluetoothOTA
; monitor_port = /dev/ttyACM1

2
proto

@ -1 +1 @@
Subproject commit 30e147a55ce27199cb638a1d82e0b88adc8f5385
Subproject commit f6ba3722be8a51c3c0c1446bb08e730a0be568e0

220
src/ButtonThread.h 100644
Wyświetl plik

@ -0,0 +1,220 @@
#include "configuration.h"
#include "concurrency/OSThread.h"
#include "PowerFSM.h"
#include "RadioLibInterface.h"
#include "graphics/Screen.h"
#include "power.h"
#include "buzz.h"
#include <OneButton.h>
#ifndef NO_ESP32
#include "nimble/BluetoothUtil.h"
#endif
namespace concurrency
{
/**
* Watch a GPIO and if we get an IRQ, wake the main thread.
* Use to add wake on button press
*/
void wakeOnIrq(int irq, int mode)
{
attachInterrupt(
irq,
[] {
BaseType_t higherWake = 0;
mainDelay.interruptFromISR(&higherWake);
},
FALLING);
}
class ButtonThread : public concurrency::OSThread
{
// Prepare for button presses
#ifdef BUTTON_PIN
OneButton userButton;
#endif
#ifdef BUTTON_PIN_ALT
OneButton userButtonAlt;
#endif
#ifdef BUTTON_PIN_TOUCH
OneButton userButtonTouch;
#endif
static bool shutdown_on_long_stop;
public:
static uint32_t longPressTime;
// callback returns the period for the next callback invocation (or 0 if we should no longer be called)
ButtonThread() : OSThread("Button")
{
#ifdef BUTTON_PIN
userButton = OneButton(BUTTON_PIN, true, true);
#ifdef INPUT_PULLUP_SENSE
// Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did
pinMode(BUTTON_PIN, INPUT_PULLUP_SENSE);
#endif
userButton.attachClick(userButtonPressed);
userButton.attachDuringLongPress(userButtonPressedLong);
userButton.attachDoubleClick(userButtonDoublePressed);
userButton.attachMultiClick(userButtonMultiPressed);
userButton.attachLongPressStart(userButtonPressedLongStart);
userButton.attachLongPressStop(userButtonPressedLongStop);
wakeOnIrq(BUTTON_PIN, FALLING);
#endif
#ifdef BUTTON_PIN_ALT
userButtonAlt = OneButton(BUTTON_PIN_ALT, true, true);
#ifdef INPUT_PULLUP_SENSE
// Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did
pinMode(BUTTON_PIN_ALT, INPUT_PULLUP_SENSE);
#endif
userButtonAlt.attachClick(userButtonPressed);
userButtonAlt.attachDuringLongPress(userButtonPressedLong);
userButtonAlt.attachDoubleClick(userButtonDoublePressed);
userButtonAlt.attachLongPressStart(userButtonPressedLongStart);
userButtonAlt.attachLongPressStop(userButtonPressedLongStop);
wakeOnIrq(BUTTON_PIN_ALT, FALLING);
#endif
#ifdef BUTTON_PIN_TOUCH
userButtonTouch = OneButton(BUTTON_PIN_TOUCH, true, true);
#ifdef INPUT_PULLUP_SENSE
// Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did
pinMode(BUTTON_PIN_TOUCH, INPUT_PULLUP_SENSE);
#endif
userButtonTouch.attachClick(touchPressed);
userButtonTouch.attachDuringLongPress(touchPressedLong);
userButtonTouch.attachDoubleClick(touchDoublePressed);
userButtonTouch.attachLongPressStart(touchPressedLongStart);
userButtonTouch.attachLongPressStop(touchPressedLongStop);
wakeOnIrq(BUTTON_PIN_TOUCH, FALLING);
#endif
}
protected:
/// If the button is pressed we suppress CPU sleep until release
int32_t runOnce() override
{
canSleep = true; // Assume we should not keep the board awake
#ifdef BUTTON_PIN
userButton.tick();
canSleep &= userButton.isIdle();
#endif
#ifdef BUTTON_PIN_ALT
userButtonAlt.tick();
canSleep &= userButtonAlt.isIdle();
#endif
#ifdef BUTTON_PIN_TOUCH
userButtonTouch.tick();
canSleep &= userButtonTouch.isIdle();
#endif
// if (!canSleep) DEBUG_MSG("Supressing sleep!\n");
// else DEBUG_MSG("sleep ok\n");
return 5;
}
private:
static void touchPressed()
{
screen->forceDisplay();
DEBUG_MSG("touch press!\n");
}
static void touchDoublePressed()
{
DEBUG_MSG("touch double press!\n");
}
static void touchPressedLong()
{
DEBUG_MSG("touch press long!\n");
}
static void touchDoublePressedLong()
{
DEBUG_MSG("touch double pressed!\n");
}
static void touchPressedLongStart()
{
DEBUG_MSG("touch long press start!\n");
}
static void touchPressedLongStop()
{
DEBUG_MSG("touch long press stop!\n");
}
static void userButtonPressed()
{
// DEBUG_MSG("press!\n");
powerFSM.trigger(EVENT_PRESS);
}
static void userButtonPressedLong()
{
// DEBUG_MSG("Long press!\n");
#ifndef NRF52_SERIES
screen->adjustBrightness();
#endif
// If user button is held down for 5 seconds, shutdown the device.
if (millis() - longPressTime > 5 * 1000) {
#ifdef TBEAM_V10
if (axp192_found == true) {
setLed(false);
power->shutdown();
}
#elif NRF52_SERIES
// Do actual shutdown when button released, otherwise the button release
// may wake the board immediatedly.
if (!shutdown_on_long_stop) {
screen->startShutdownScreen();
DEBUG_MSG("Shutdown from long press");
playBeep();
ledOff(PIN_LED1);
ledOff(PIN_LED2);
shutdown_on_long_stop = true;
}
#endif
} else {
// DEBUG_MSG("Long press %u\n", (millis() - longPressTime));
}
}
static void userButtonDoublePressed()
{
#ifndef NO_ESP32
disablePin();
#elif defined(HAS_EINK)
digitalWrite(PIN_EINK_EN,digitalRead(PIN_EINK_EN) == LOW);
#endif
}
static void userButtonMultiPressed()
{
#ifndef NO_ESP32
clearNVS();
#endif
#ifdef NRF52_SERIES
clearBonds();
#endif
}
static void userButtonPressedLongStart()
{
DEBUG_MSG("Long press start!\n");
longPressTime = millis();
}
static void userButtonPressedLongStop()
{
DEBUG_MSG("Long press stop!\n");
longPressTime = 0;
if (shutdown_on_long_stop) {
playShutdownMelody();
delay(3000);
power->shutdown();
}
}
};
}

Wyświetl plik

@ -0,0 +1,38 @@
#include "configuration.h"
#include "concurrency/OSThread.h"
#include "main.h"
#include "PowerFSM.h"
#include "power.h"
#include "NodeDB.h"
namespace concurrency
{
/// Wrapper to convert our powerFSM stuff into a 'thread'
class PowerFSMThread : public OSThread
{
public:
// callback returns the period for the next callback invocation (or 0 if we should no longer be called)
PowerFSMThread() : OSThread("PowerFSM") {}
protected:
int32_t runOnce() override
{
powerFSM.run_machine();
/// If we are in power state we force the CPU to wake every 10ms to check for serial characters (we don't yet wake
/// cpu for serial rx - FIXME)
auto state = powerFSM.getState();
canSleep = (state != &statePOWER) && (state != &stateSERIAL);
if (powerStatus->getHasUSB()) {
timeLastPowered = millis();
} else if (radioConfig.preferences.on_battery_shutdown_after_secs > 0 &&
millis() > timeLastPowered + (1000 * radioConfig.preferences.on_battery_shutdown_after_secs)) { //shutdown after 30 minutes unpowered
powerFSM.trigger(EVENT_SHUTDOWN);
}
return 10;
}
};
}

Wyświetl plik

@ -140,7 +140,7 @@ int32_t AirTime::runOnce()
}
// Init airtime windows to all 0
for (int i = 0; i < PERIODS_TO_LOG; i++) {
for (int i = 0; i < myNodeInfo.air_period_rx_count; i++) {
this->airtimes.periodTX[i] = 0;
this->airtimes.periodRX[i] = 0;
this->airtimes.periodRX_ALL[i] = 0;

Wyświetl plik

@ -26,7 +26,7 @@
#define CHANNEL_UTILIZATION_PERIODS 6
#define SECONDS_PER_PERIOD 3600
#define PERIODS_TO_LOG 24
#define PERIODS_TO_LOG 8
#define MINUTES_IN_HOUR 60
#define SECONDS_IN_MINUTE 60
#define MS_IN_HOUR (MINUTES_IN_HOUR * SECONDS_IN_MINUTE * 1000)

Wyświetl plik

@ -0,0 +1,19 @@
#if 0
// Turn off for now
uint32_t axpDebugRead()
{
axp.debugCharging();
DEBUG_MSG("vbus current %f\n", axp.getVbusCurrent());
DEBUG_MSG("charge current %f\n", axp.getBattChargeCurrent());
DEBUG_MSG("bat voltage %f\n", axp.getBattVoltage());
DEBUG_MSG("batt pct %d\n", axp.getBattPercentage());
DEBUG_MSG("is battery connected %d\n", axp.isBatteryConnect());
DEBUG_MSG("is USB connected %d\n", axp.isVBUSPlug());
DEBUG_MSG("is charging %d\n", axp.isChargeing());
return 30 * 1000;
}
Periodic axpDebugOutput(axpDebugRead);
axpDebugOutput.setup();
#endif

Wyświetl plik

@ -0,0 +1,44 @@
#include "../configuration.h"
#include "../main.h"
#include <Wire.h>
#ifndef NO_WIRE
void scanI2Cdevice(void)
{
byte err, addr;
int nDevices = 0;
for (addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr);
err = Wire.endTransmission();
if (err == 0) {
DEBUG_MSG("I2C device found at address 0x%x\n", addr);
nDevices++;
if (addr == SSD1306_ADDRESS) {
screen_found = addr;
DEBUG_MSG("ssd1306 display found\n");
}
if (addr == ST7567_ADDRESS) {
screen_found = addr;
DEBUG_MSG("st7567 display found\n");
}
#ifdef AXP192_SLAVE_ADDRESS
if (addr == AXP192_SLAVE_ADDRESS) {
axp192_found = true;
DEBUG_MSG("axp192 PMU found\n");
}
#endif
} else if (err == 4) {
DEBUG_MSG("Unknow error at address 0x%x\n", addr);
}
}
if (nDevices == 0)
DEBUG_MSG("No I2C devices found\n");
else
DEBUG_MSG("done\n");
}
#else
void scanI2Cdevice(void) {}
#endif

Wyświetl plik

@ -32,7 +32,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "main.h"
#include "mesh-pb-constants.h"
#include "mesh/Channels.h"
#include "plugins/TextMessagePlugin.h"
#include "modules/TextMessageModule.h"
#include "sleep.h"
#include "target_specific.h"
#include "utils.h"
@ -67,9 +67,9 @@ 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<MeshPlugin *> pluginFrames;
// At some point, we're going to ask all of the modules if they would like to display a screen frame
// we'll need to hold onto pointers for the modules that can draw a frame.
std::vector<MeshPlugin *> moduleFrames;
// Stores the last 4 of our hardware ID, to make finding the device for pairing easier
static char ourId[5];
@ -176,9 +176,9 @@ static void drawSleepScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int
}
#endif
static void drawPluginFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
static void drawModuleFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
uint8_t plugin_frame;
uint8_t module_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,
@ -187,14 +187,14 @@ static void drawPluginFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int
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;
module_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);
// otherwise, just display the module frame that's aligned with the current frame
module_frame = state->currentFrame;
// DEBUG_MSG("Screen is not in transition. Frame: %d\n\n", module_frame);
}
// DEBUG_MSG("Drawing Plugin Frame %d\n\n", plugin_frame);
MeshPlugin &pi = *pluginFrames.at(plugin_frame);
// DEBUG_MSG("Drawing Module Frame %d\n\n", module_frame);
MeshPlugin &pi = *moduleFrames.at(module_frame);
pi.drawFrame(display, state, x, y);
}
@ -259,11 +259,11 @@ static void drawCriticalFaultFrame(OLEDDisplay *display, OLEDDisplayUiState *sta
display->drawString(0 + x, FONT_HEIGHT_MEDIUM + y, "For help, please post on\nmeshtastic.discourse.group");
}
// Ignore messages orginating from phone (from the current node 0x0) unless range test or store and forward plugin are enabled
// Ignore messages orginating from phone (from the current node 0x0) unless range test or store and forward module are enabled
static bool shouldDrawMessage(const MeshPacket *packet)
{
return packet->from != 0 && !radioConfig.preferences.range_test_plugin_enabled &&
!radioConfig.preferences.store_forward_plugin_enabled;
return packet->from != 0 && !radioConfig.preferences.range_test_module_enabled &&
!radioConfig.preferences.store_forward_module_enabled;
}
/// Draw the last text message we received
@ -824,10 +824,10 @@ void Screen::setup()
powerStatusObserver.observe(&powerStatus->onNewStatus);
gpsStatusObserver.observe(&gpsStatus->onNewStatus);
nodeStatusObserver.observe(&nodeStatus->onNewStatus);
if (textMessagePlugin)
textMessageObserver.observe(textMessagePlugin);
if (textMessageModule)
textMessageObserver.observe(textMessageModule);
// Plugins can notify screen about refresh
// Modules can notify screen about refresh
MeshPlugin::observeUIEvents(&uiFrameEventObserver);
}
@ -976,9 +976,9 @@ 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();
moduleFrames = MeshPlugin::GetMeshModulesWithUIFrames();
DEBUG_MSG("Showing %d module frames\n", moduleFrames.size());
int totalFrameCount = MAX_NUM_NODES + NUM_EXTRA_FRAMES + moduleFrames.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)
@ -988,23 +988,23 @@ void Screen::setFrames()
size_t numframes = 0;
// put all of the plugin frames first.
// put all of the module 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
// the same drawModuleFrame handler here for all of these module 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;
// is the same offset into the moduleFrames vector
// so that we can invoke the module's callback
for (auto i = moduleFrames.begin(); i != moduleFrames.end(); ++i) {
normalFrames[numframes++] = drawModuleFrame;
}
DEBUG_MSG("Added plugins. numframes: %d\n", numframes);
DEBUG_MSG("Added modules. numframes: %d\n", numframes);
// If we have a critical fault, show it first
if (myNodeInfo.error_code)
normalFrames[numframes++] = drawCriticalFaultFrame;
// If we have a text message - show it next, unless it's a phone message and we aren't using any special plugins
// If we have a text message - show it next, unless it's a phone message and we aren't using any special modules
if (devicestate.has_rx_text_message && shouldDrawMessage(&devicestate.rx_text_message)) {
normalFrames[numframes++] = drawTextMessageFrame;
}

Wyświetl plik

@ -27,7 +27,7 @@ void RotaryEncoderInterruptImpl1::init()
char eventPressed =
static_cast<char>(radioConfig.preferences.rotary1_event_press);
//radioConfig.preferences.ext_notification_plugin_output
//radioConfig.preferences.ext_notification_module_output
RotaryEncoderInterruptBase::init(
pinA, pinB, pinPress,
eventCw, eventCcw, eventPressed,

Wyświetl plik

@ -18,10 +18,12 @@
#include "concurrency/Periodic.h"
#include "graphics/Screen.h"
#include "main.h"
#include "plugins/Plugins.h"
#include "modules/Modules.h"
#include "sleep.h"
#include "shutdown.h"
#include "target_specific.h"
#include <OneButton.h>
#include "debug/i2cScan.h"
#include "debug/axpDebug.h"
#include <Wire.h>
// #include <driver/rtc_io.h>
@ -48,6 +50,8 @@
#include "SX1268Interface.h"
#include "LLCC68Interface.h"
#include "ButtonThread.h"
#include "PowerFSMThread.h"
using namespace concurrency;
@ -70,50 +74,6 @@ bool axp192_found;
Router *router = NULL; // Users of router don't care what sort of subclass implements that API
// -----------------------------------------------------------------------------
// Application
// -----------------------------------------------------------------------------
#ifndef NO_WIRE
void scanI2Cdevice(void)
{
byte err, addr;
int nDevices = 0;
for (addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr);
err = Wire.endTransmission();
if (err == 0) {
DEBUG_MSG("I2C device found at address 0x%x\n", addr);
nDevices++;
if (addr == SSD1306_ADDRESS) {
screen_found = addr;
DEBUG_MSG("ssd1306 display found\n");
}
if (addr == ST7567_ADDRESS) {
screen_found = addr;
DEBUG_MSG("st7567 display found\n");
}
#ifdef AXP192_SLAVE_ADDRESS
if (addr == AXP192_SLAVE_ADDRESS) {
axp192_found = true;
DEBUG_MSG("axp192 PMU found\n");
}
#endif
} else if (err == 4) {
DEBUG_MSG("Unknow error at address 0x%x\n", addr);
}
}
if (nDevices == 0)
DEBUG_MSG("No I2C devices found\n");
else
DEBUG_MSG("done\n");
}
#else
void scanI2Cdevice(void) {}
#endif
const char *getDeviceName()
{
uint8_t dmac[6];
@ -139,238 +99,6 @@ static int32_t ledBlinker()
uint32_t timeLastPowered = 0;
/// Wrapper to convert our powerFSM stuff into a 'thread'
class PowerFSMThread : public OSThread
{
public:
// callback returns the period for the next callback invocation (or 0 if we should no longer be called)
PowerFSMThread() : OSThread("PowerFSM") {}
protected:
int32_t runOnce() override
{
powerFSM.run_machine();
/// If we are in power state we force the CPU to wake every 10ms to check for serial characters (we don't yet wake
/// cpu for serial rx - FIXME)
auto state = powerFSM.getState();
canSleep = (state != &statePOWER) && (state != &stateSERIAL);
if (powerStatus->getHasUSB()) {
timeLastPowered = millis();
} else if (radioConfig.preferences.on_battery_shutdown_after_secs > 0 &&
millis() > timeLastPowered + (1000 * radioConfig.preferences.on_battery_shutdown_after_secs)) { //shutdown after 30 minutes unpowered
powerFSM.trigger(EVENT_SHUTDOWN);
}
return 10;
}
};
/**
* Watch a GPIO and if we get an IRQ, wake the main thread.
* Use to add wake on button press
*/
void wakeOnIrq(int irq, int mode)
{
attachInterrupt(
irq,
[] {
BaseType_t higherWake = 0;
mainDelay.interruptFromISR(&higherWake);
},
FALLING);
}
class ButtonThread : public OSThread
{
// Prepare for button presses
#ifdef BUTTON_PIN
OneButton userButton;
#endif
#ifdef BUTTON_PIN_ALT
OneButton userButtonAlt;
#endif
#ifdef BUTTON_PIN_TOUCH
OneButton userButtonTouch;
#endif
static bool shutdown_on_long_stop;
public:
static uint32_t longPressTime;
// callback returns the period for the next callback invocation (or 0 if we should no longer be called)
ButtonThread() : OSThread("Button")
{
#ifdef BUTTON_PIN
userButton = OneButton(BUTTON_PIN, true, true);
#ifdef INPUT_PULLUP_SENSE
// Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did
pinMode(BUTTON_PIN, INPUT_PULLUP_SENSE);
#endif
userButton.attachClick(userButtonPressed);
userButton.attachDuringLongPress(userButtonPressedLong);
userButton.attachDoubleClick(userButtonDoublePressed);
userButton.attachMultiClick(userButtonMultiPressed);
userButton.attachLongPressStart(userButtonPressedLongStart);
userButton.attachLongPressStop(userButtonPressedLongStop);
wakeOnIrq(BUTTON_PIN, FALLING);
#endif
#ifdef BUTTON_PIN_ALT
userButtonAlt = OneButton(BUTTON_PIN_ALT, true, true);
#ifdef INPUT_PULLUP_SENSE
// Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did
pinMode(BUTTON_PIN_ALT, INPUT_PULLUP_SENSE);
#endif
userButtonAlt.attachClick(userButtonPressed);
userButtonAlt.attachDuringLongPress(userButtonPressedLong);
userButtonAlt.attachDoubleClick(userButtonDoublePressed);
userButtonAlt.attachLongPressStart(userButtonPressedLongStart);
userButtonAlt.attachLongPressStop(userButtonPressedLongStop);
wakeOnIrq(BUTTON_PIN_ALT, FALLING);
#endif
#ifdef BUTTON_PIN_TOUCH
userButtonTouch = OneButton(BUTTON_PIN_TOUCH, true, true);
#ifdef INPUT_PULLUP_SENSE
// Some platforms (nrf52) have a SENSE variant which allows wake from sleep - override what OneButton did
pinMode(BUTTON_PIN_TOUCH, INPUT_PULLUP_SENSE);
#endif
userButtonTouch.attachClick(touchPressed);
userButtonTouch.attachDuringLongPress(touchPressedLong);
userButtonTouch.attachDoubleClick(touchDoublePressed);
userButtonTouch.attachLongPressStart(touchPressedLongStart);
userButtonTouch.attachLongPressStop(touchPressedLongStop);
wakeOnIrq(BUTTON_PIN_TOUCH, FALLING);
#endif
}
protected:
/// If the button is pressed we suppress CPU sleep until release
int32_t runOnce() override
{
canSleep = true; // Assume we should not keep the board awake
#ifdef BUTTON_PIN
userButton.tick();
canSleep &= userButton.isIdle();
#endif
#ifdef BUTTON_PIN_ALT
userButtonAlt.tick();
canSleep &= userButtonAlt.isIdle();
#endif
#ifdef BUTTON_PIN_TOUCH
userButtonTouch.tick();
canSleep &= userButtonTouch.isIdle();
#endif
// if (!canSleep) DEBUG_MSG("Supressing sleep!\n");
// else DEBUG_MSG("sleep ok\n");
return 5;
}
private:
static void touchPressed()
{
screen->forceDisplay();
DEBUG_MSG("touch press!\n");
}
static void touchDoublePressed()
{
DEBUG_MSG("touch double press!\n");
}
static void touchPressedLong()
{
DEBUG_MSG("touch press long!\n");
}
static void touchDoublePressedLong()
{
DEBUG_MSG("touch double pressed!\n");
}
static void touchPressedLongStart()
{
DEBUG_MSG("touch long press start!\n");
}
static void touchPressedLongStop()
{
DEBUG_MSG("touch long press stop!\n");
}
static void userButtonPressed()
{
// DEBUG_MSG("press!\n");
powerFSM.trigger(EVENT_PRESS);
}
static void userButtonPressedLong()
{
// DEBUG_MSG("Long press!\n");
#ifndef NRF52_SERIES
screen->adjustBrightness();
#endif
// If user button is held down for 5 seconds, shutdown the device.
if (millis() - longPressTime > 5 * 1000) {
#ifdef TBEAM_V10
if (axp192_found == true) {
setLed(false);
power->shutdown();
}
#elif NRF52_SERIES
// Do actual shutdown when button released, otherwise the button release
// may wake the board immediatedly.
if (!shutdown_on_long_stop) {
screen->startShutdownScreen();
DEBUG_MSG("Shutdown from long press");
playBeep();
ledOff(PIN_LED1);
ledOff(PIN_LED2);
shutdown_on_long_stop = true;
}
#endif
} else {
// DEBUG_MSG("Long press %u\n", (millis() - longPressTime));
}
}
static void userButtonDoublePressed()
{
#ifndef NO_ESP32
disablePin();
#elif defined(HAS_EINK)
digitalWrite(PIN_EINK_EN,digitalRead(PIN_EINK_EN) == LOW);
#endif
}
static void userButtonMultiPressed()
{
#ifndef NO_ESP32
clearNVS();
#endif
#ifdef NRF52_SERIES
clearBonds();
#endif
}
static void userButtonPressedLongStart()
{
DEBUG_MSG("Long press start!\n");
longPressTime = millis();
}
static void userButtonPressedLongStop()
{
DEBUG_MSG("Long press stop!\n");
longPressTime = 0;
if (shutdown_on_long_stop) {
playShutdownMelody();
delay(3000);
power->shutdown();
}
}
};
bool ButtonThread::shutdown_on_long_stop = false;
static Periodic *ledPeriodic;
@ -516,22 +244,6 @@ void setup()
readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time)
#ifdef GENIEBLOCKS
Im intentionally breaking your build so you see this note.Feel free to revert if not correct.I think you can
remove this GPS_RESET_N code by instead defining PIN_GPS_RESET and
use the shared code in GPS.cpp instead.- geeksville
// gps setup
pinMode(GPS_RESET_N, OUTPUT);
pinMode(GPS_EXTINT, OUTPUT);
digitalWrite(GPS_RESET_N, HIGH);
digitalWrite(GPS_EXTINT, LOW);
// battery setup
// If we want to read battery level, we need to set BATTERY_EN_PIN pin to low.
// ToDo: For low power consumption after read battery level, set that pin to high.
pinMode(BATTERY_EN_PIN, OUTPUT);
digitalWrite(BATTERY_EN_PIN, LOW);
#endif
gps = createGps();
if (gps)
@ -543,8 +255,8 @@ void setup()
service.init();
// Now that the mesh service is created, create any plugins
setupPlugins();
// Now that the mesh service is created, create any modules
setupModules();
// Do this after service.init (because that clears error_code)
#ifdef AXP192_SLAVE_ADDRESS
@ -686,66 +398,9 @@ void setup()
setCPUFast(false); // 80MHz is fine for our slow peripherals
}
#if 0
// Turn off for now
uint32_t axpDebugRead()
{
axp.debugCharging();
DEBUG_MSG("vbus current %f\n", axp.getVbusCurrent());
DEBUG_MSG("charge current %f\n", axp.getBattChargeCurrent());
DEBUG_MSG("bat voltage %f\n", axp.getBattVoltage());
DEBUG_MSG("batt pct %d\n", axp.getBattPercentage());
DEBUG_MSG("is battery connected %d\n", axp.isBatteryConnect());
DEBUG_MSG("is USB connected %d\n", axp.isVBUSPlug());
DEBUG_MSG("is charging %d\n", axp.isChargeing());
return 30 * 1000;
}
Periodic axpDebugOutput(axpDebugRead);
axpDebugOutput.setup();
#endif
uint32_t rebootAtMsec; // If not zero we will reboot at this time (used to reboot shortly after the update completes)
uint32_t shutdownAtMsec; // If not zero we will shutdown at this time (used to shutdown from python or mobile client)
void powerCommandsCheck()
{
if (rebootAtMsec && millis() > rebootAtMsec) {
#ifndef NO_ESP32
DEBUG_MSG("Rebooting for update\n");
ESP.restart();
#else
DEBUG_MSG("FIXME implement reboot for this platform");
#endif
}
#if NRF52_SERIES
if (shutdownAtMsec) {
screen->startShutdownScreen();
playBeep();
ledOff(PIN_LED1);
ledOff(PIN_LED2);
}
#endif
if (shutdownAtMsec && millis() > shutdownAtMsec) {
DEBUG_MSG("Shutting down from admin command\n");
#ifdef TBEAM_V10
if (axp192_found == true) {
setLed(false);
power->shutdown();
}
#elif NRF52_SERIES
playShutdownMelody();
power->shutdown();
#else
DEBUG_MSG("FIXME implement shutdown for this platform");
#endif
}
}
// If a thread does something that might need for it to be rescheduled ASAP it can set this flag
// This will supress the current delay and instead try to run ASAP.
bool runASAP;

Wyświetl plik

@ -5,6 +5,7 @@
#include "PowerStatus.h"
#include "graphics/Screen.h"
extern uint8_t screen_found;
extern bool axp192_found;
extern bool isCharging;
extern bool isUSBPowered;
@ -20,6 +21,8 @@ extern graphics::Screen *screen;
// Return a human readable string of the form "Meshtastic_ab13"
const char *getDeviceName();
extern uint32_t timeLastPowered;
extern uint32_t rebootAtMsec;
extern uint32_t shutdownAtMsec;

Wyświetl plik

@ -1,5 +1,5 @@
#include "configuration.h"
#include "FloodingRouter.h"
#include "configuration.h"
#include "mesh-pb-constants.h"
FloodingRouter::FloodingRouter() {}
@ -27,11 +27,41 @@ bool FloodingRouter::shouldFilterReceived(MeshPacket *p)
return Router::shouldFilterReceived(p);
}
bool FloodingRouter::inRangeOfRouter()
{
uint32_t maximum_router_sec = 300;
// FIXME : Scale minimum_snr to accomodate different modem configurations.
float minimum_snr = 2;
for (int i = 0; i < myNodeInfo.router_count; i++) {
// A router has been seen and the heartbeat was heard within the last 300 seconds
if (
((myNodeInfo.router_sec[i] > 0) && (myNodeInfo.router_sec[i] < maximum_router_sec)) &&
(myNodeInfo.router_snr[i] > minimum_snr)
) {
return true;
}
}
return false;
}
void FloodingRouter::sniffReceived(const MeshPacket *p, const Routing *c)
{
// If a broadcast, possibly _also_ send copies out into the mesh.
// (FIXME, do something smarter than naive flooding here)
if (p->to == NODENUM_BROADCAST && p->hop_limit > 0 && getFrom(p) != getNodeNum()) {
bool rebroadcastPacket = true;
if (radioConfig.preferences.role == Role_Repeater || radioConfig.preferences.role == Role_Router) {
rebroadcastPacket = true;
} else if ((radioConfig.preferences.role == Role_Default) && inRangeOfRouter()) {
DEBUG_MSG("Role_Default - rx_snr > 13\n");
rebroadcastPacket = false;
}
if ((p->to == NODENUM_BROADCAST) && (p->hop_limit > 0) && (getFrom(p) != getNodeNum() && rebroadcastPacket)) {
if (p->id != 0) {
MeshPacket *tosend = packetPool.allocCopy(*p); // keep a copy because we will be sending it

Wyświetl plik

@ -52,6 +52,14 @@ class FloodingRouter : public Router, protected PacketHistory
*/
virtual bool shouldFilterReceived(MeshPacket *p) override;
/**
* Are we in range of a router?
*
* "range" here may not be the right term.
* @return true if we're in range of a router
*/
virtual bool inRangeOfRouter();
/**
* Look for broadcasts we need to rebroadcast
*/

Wyświetl plik

@ -3,15 +3,15 @@
#include "Channels.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "plugins/RoutingPlugin.h"
#include "modules/RoutingModule.h"
#include <assert.h>
std::vector<MeshPlugin *> *MeshPlugin::plugins;
std::vector<MeshPlugin *> *MeshPlugin::modules;
const MeshPacket *MeshPlugin::currentRequest;
/**
* If any of the current chain of plugins has already sent a reply, it will be here. This is useful to allow
* If any of the current chain of modules has already sent a reply, it will be here. This is useful to allow
* the RoutingPlugin to avoid sending redundant acks
*/
MeshPacket *MeshPlugin::currentReply;
@ -19,17 +19,17 @@ MeshPacket *MeshPlugin::currentReply;
MeshPlugin::MeshPlugin(const char *_name) : name(_name)
{
// Can't trust static initalizer order, so we check each time
if (!plugins)
plugins = new std::vector<MeshPlugin *>();
if (!modules)
modules = new std::vector<MeshPlugin *>();
plugins->push_back(this);
modules->push_back(this);
}
void MeshPlugin::setup() {}
MeshPlugin::~MeshPlugin()
{
assert(0); // FIXME - remove from list of plugins once someone needs this feature
assert(0); // FIXME - remove from list of modules once someone needs this feature
}
MeshPacket *MeshPlugin::allocAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex)
@ -68,10 +68,10 @@ MeshPacket *MeshPlugin::allocErrorResponse(Routing_Error err, const MeshPacket *
void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src)
{
// DEBUG_MSG("In call plugins\n");
bool pluginFound = false;
// DEBUG_MSG("In call modules\n");
bool moduleFound = false;
// We now allow **encrypted** packets to pass through the plugins
// We now allow **encrypted** packets to pass through the modules
bool isDecoded = mp.which_payloadVariant == MeshPacket_decoded_tag;
currentReply = NULL; // No reply yet
@ -80,12 +80,12 @@ void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src)
auto ourNodeNum = nodeDB.getNodeNum();
bool toUs = mp.to == NODENUM_BROADCAST || mp.to == ourNodeNum;
for (auto i = plugins->begin(); i != plugins->end(); ++i) {
for (auto i = modules->begin(); i != modules->end(); ++i) {
auto &pi = **i;
pi.currentRequest = &mp;
/// We only call plugins that are interested in the packet (and the message is destined to us or we are promiscious)
/// We only call modules that are interested in the packet (and the message is destined to us or we are promiscious)
bool wantsPacket = (isDecoded || pi.encryptedOk) && (pi.isPromiscuous || toUs) && pi.wantPacket(&mp);
if ((src == RX_SRC_LOCAL) && !(pi.loopbackOk)) {
@ -96,15 +96,15 @@ void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src)
assert(!pi.myReply); // If it is !null it means we have a bug, because it should have been sent the previous time
if (wantsPacket) {
DEBUG_MSG("Plugin '%s' wantsPacket=%d\n", pi.name, wantsPacket);
DEBUG_MSG("Module '%s' wantsPacket=%d\n", pi.name, wantsPacket);
pluginFound = true;
moduleFound = true;
/// received channel (or NULL if not decoded)
Channel *ch = isDecoded ? &channels.getByIndex(mp.channel) : NULL;
/// Is the channel this packet arrived on acceptable? (security check)
/// Note: we can't know channel names for encrypted packets, so those are NEVER sent to boundChannel plugins
/// Note: we can't know channel names for encrypted packets, so those are NEVER sent to boundChannel modules
/// Also: if a packet comes in on the local PC interface, we don't check for bound channels, because it is TRUSTED and it needs to
/// to be able to fetch the initial admin packets without yet knowing any channels.
@ -128,7 +128,7 @@ void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src)
ProcessMessage handled = pi.handleReceived(mp);
// Possibly send replies (but only if the message was directed to us specifically, i.e. not for promiscious
// sniffing) also: we only let the one plugin send a reply, once that happens, remaining plugins are not
// sniffing) also: we only let the one module send a reply, once that happens, remaining modules are not
// considered
// NOTE: we send a reply *even if the (non broadcast) request was from us* which is unfortunate but necessary
@ -137,9 +137,9 @@ void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src)
// any other node.
if (mp.decoded.want_response && toUs && (getFrom(&mp) != ourNodeNum || mp.to == ourNodeNum) && !currentReply) {
pi.sendResponse(mp);
DEBUG_MSG("Plugin '%s' sent a response\n", pi.name);
DEBUG_MSG("Module '%s' sent a response\n", pi.name);
} else {
DEBUG_MSG("Plugin '%s' considered\n", pi.name);
DEBUG_MSG("Module '%s' considered\n", pi.name);
}
// If the requester didn't ask for a response we might need to discard unused replies to prevent memory leaks
@ -150,7 +150,7 @@ void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src)
}
if (handled == ProcessMessage::STOP) {
DEBUG_MSG("Plugin '%s' handled and skipped other processing\n", pi.name);
DEBUG_MSG("Module '%s' handled and skipped other processing\n", pi.name);
break;
}
}
@ -173,12 +173,12 @@ void MeshPlugin::callPlugins(const MeshPacket &mp, RxSource src)
// SECURITY NOTE! I considered sending back a different error code if we didn't find the psk (i.e. !isDecoded)
// but opted NOT TO. Because it is not a good idea to let remote nodes 'probe' to find out which PSKs were "good" vs
// bad.
routingPlugin->sendAckNak(Routing_Error_NO_RESPONSE, getFrom(&mp), mp.id, mp.channel);
routingModule->sendAckNak(Routing_Error_NO_RESPONSE, getFrom(&mp), mp.id, mp.channel);
}
}
if (!pluginFound)
DEBUG_MSG("No plugins interested in portnum=%d, src=%s\n",
if (!moduleFound)
DEBUG_MSG("No modules interested in portnum=%d, src=%s\n",
mp.decoded.portnum,
(src == RX_SRC_LOCAL) ? "LOCAL":"REMOTE");
}
@ -201,8 +201,8 @@ void MeshPlugin::sendResponse(const MeshPacket &req)
setReplyTo(r, req);
currentReply = r;
} else {
// Ignore - this is now expected behavior for routing plugin (because it ignores some replies)
// DEBUG_MSG("WARNING: Client requested response but this plugin did not provide\n");
// Ignore - this is now expected behavior for routing module (because it ignores some replies)
// DEBUG_MSG("WARNING: Client requested response but this module did not provide\n");
}
}
@ -222,32 +222,32 @@ void setReplyTo(MeshPacket *p, const MeshPacket &to)
p->decoded.request_id = to.id;
}
std::vector<MeshPlugin *> MeshPlugin::GetMeshPluginsWithUIFrames()
std::vector<MeshPlugin *> MeshPlugin::GetMeshModulesWithUIFrames()
{
std::vector<MeshPlugin *> pluginsWithUIFrames;
if (plugins) {
for (auto i = plugins->begin(); i != plugins->end(); ++i) {
std::vector<MeshPlugin *> modulesWithUIFrames;
if (modules) {
for (auto i = modules->begin(); i != modules->end(); ++i) {
auto &pi = **i;
if (pi.wantUIFrame()) {
DEBUG_MSG("Plugin wants a UI Frame\n");
pluginsWithUIFrames.push_back(&pi);
DEBUG_MSG("Module wants a UI Frame\n");
modulesWithUIFrames.push_back(&pi);
}
}
}
return pluginsWithUIFrames;
return modulesWithUIFrames;
}
void MeshPlugin::observeUIEvents(
Observer<const UIFrameEvent *> *observer)
{
if (plugins) {
for (auto i = plugins->begin(); i != plugins->end(); ++i) {
if (modules) {
for (auto i = modules->begin(); i != modules->end(); ++i) {
auto &pi = **i;
Observable<const UIFrameEvent *> *observable =
pi.getUIFrameObservable();
if (observable != NULL) {
DEBUG_MSG("Plugin wants a UI Frame\n");
DEBUG_MSG("Module wants a UI Frame\n");
observer->observe(observable);
}
}
@ -257,14 +257,14 @@ void MeshPlugin::observeUIEvents(
AdminMessageHandleResult MeshPlugin::handleAdminMessageForAllPlugins(const MeshPacket &mp, AdminMessage *request, AdminMessage *response)
{
AdminMessageHandleResult handled = AdminMessageHandleResult::NOT_HANDLED;
if (plugins) {
for (auto i = plugins->begin(); i != plugins->end(); ++i) {
if (modules) {
for (auto i = modules->begin(); i != modules->end(); ++i) {
auto &pi = **i;
AdminMessageHandleResult h = pi.handleAdminMessageForPlugin(mp, request, response);
AdminMessageHandleResult h = pi.handleAdminMessageForModule(mp, request, response);
if (h == AdminMessageHandleResult::HANDLED_WITH_RESPONSE)
{
// In case we have a response it always has priority.
DEBUG_MSG("Reply prepared by plugin '%s' of variant: %d\n",
DEBUG_MSG("Reply prepared by module '%s' of variant: %d\n",
pi.name,
response->which_variant);
handled = h;

Wyświetl plik

@ -22,8 +22,8 @@ enum class ProcessMessage
};
/**
* Used by plugins to return the result of the AdminMessage handling.
* If request is handled, then plugin should return HANDLED,
* Used by modules to return the result of the AdminMessage handling.
* If request is handled, then module should return HANDLED,
* If response is also prepared for the request, then HANDLED_WITH_RESPONSE
* should be returned.
*/
@ -42,19 +42,19 @@ typedef struct _UIFrameEvent {
bool needRedraw;
} UIFrameEvent;
/** A baseclass for any mesh "plugin".
/** A baseclass for any mesh "module".
*
* A plugin allows you to add new features to meshtastic device code, without needing to know messaging details.
* A module allows you to add new features to meshtastic device code, without needing to know messaging details.
*
* A key concept for this is that your plugin should use a particular "portnum" for each message type you want to receive
* A key concept for this is that your module should use a particular "portnum" for each message type you want to receive
* and handle.
*
* Interally we use plugins to implement the core meshtastic text messaging and gps position sharing features. You
* can use these classes as examples for how to write your own custom plugin. See here: (FIXME)
* Interally we use modules to implement the core meshtastic text messaging and gps position sharing features. You
* can use these classes as examples for how to write your own custom module. See here: (FIXME)
*/
class MeshPlugin
{
static std::vector<MeshPlugin *> *plugins;
static std::vector<MeshPlugin *> *modules;
public:
/** Constructor
@ -68,7 +68,7 @@ class MeshPlugin
*/
static void callPlugins(const MeshPacket &mp, RxSource src = RX_SRC_RADIO);
static std::vector<MeshPlugin *> GetMeshPluginsWithUIFrames();
static std::vector<MeshPlugin *> GetMeshModulesWithUIFrames();
static void observeUIEvents(Observer<const UIFrameEvent *> *observer);
static AdminMessageHandleResult handleAdminMessageForAllPlugins(
const MeshPacket &mp, AdminMessage *request, AdminMessage *response);
@ -78,17 +78,17 @@ class MeshPlugin
protected:
const char *name;
/** Most plugins only care about packets that are destined for their node (i.e. broadcasts or has their node as the specific
/** Most modules only care about packets that are destined for their node (i.e. broadcasts or has their node as the specific
recipient) But some plugs might want to 'sniff' packets that are merely being routed (passing through the current node). Those
plugins can set this to true and their handleReceived() will be called for every packet.
modules can set this to true and their handleReceived() will be called for every packet.
*/
bool isPromiscuous = false;
/** Also receive a copy of LOCALLY GENERATED messages - most plugins should leave
/** Also receive a copy of LOCALLY GENERATED messages - most modules should leave
* this setting disabled - see issue #877 */
bool loopbackOk = false;
/** Most plugins only understand decrypted packets. For plugins that also want to see encrypted packets, they should set this
/** Most modules only understand decrypted packets. For modules that also want to see encrypted packets, they should set this
* flag */
bool encryptedOk = false;
@ -101,11 +101,11 @@ class MeshPlugin
const char *boundChannel = NULL;
/**
* If this plugin is currently handling a request currentRequest will be preset
* If this module is currently handling a request currentRequest will be preset
* to the packet with the request. This is mostly useful for reply handlers.
*
* Note: this can be static because we are guaranteed to be processing only one
* plugin at a time.
* plumodulegin at a time.
*/
static const MeshPacket *currentRequest;
@ -115,7 +115,7 @@ class MeshPlugin
MeshPacket *myReply = NULL;
/**
* Initialize your plugin. This setup function is called once after all hardware and mesh protocol layers have
* Initialize your module. This setup function is called once after all hardware and mesh protocol layers have
* been initialized
*/
virtual void setup();
@ -151,7 +151,7 @@ class MeshPlugin
MeshPacket *allocErrorResponse(Routing_Error err, const MeshPacket *p);
/**
* @brief An admin message arrived to AdminPlugin. Plugin was asked whether it want to handle the request.
* @brief An admin message arrived to AdminModule. Module was asked whether it want to handle the request.
*
* @param mp The mesh packet arrived.
* @param request The AdminMessage request extracted from the packet.
@ -160,13 +160,13 @@ class MeshPlugin
* HANDLED if message was handled
* HANDLED_WITH_RESPONSE if a response is also prepared and to be sent.
*/
virtual AdminMessageHandleResult handleAdminMessageForPlugin(
virtual AdminMessageHandleResult handleAdminMessageForModule(
const MeshPacket &mp, AdminMessage *request, AdminMessage *response) { return AdminMessageHandleResult::NOT_HANDLED; };
private:
/**
* If any of the current chain of plugins has already sent a reply, it will be here. This is useful to allow
* the RoutingPlugin to avoid sending redundant acks
* If any of the current chain of modules has already sent a reply, it will be here. This is useful to allow
* the RoutingModule to avoid sending redundant acks
*/
static MeshPacket *currentReply;

Wyświetl plik

@ -12,8 +12,8 @@
#include "RTC.h"
#include "main.h"
#include "mesh-pb-constants.h"
#include "plugins/NodeInfoPlugin.h"
#include "plugins/PositionPlugin.h"
#include "modules/NodeInfoModule.h"
#include "modules/PositionModule.h"
#include "power.h"
/*
@ -115,10 +115,10 @@ void MeshService::reloadOwner()
// DEBUG_MSG("reloadOwner()\n");
// update our local data directly
nodeDB.updateUser(nodeDB.getNodeNum(), owner);
assert(nodeInfoPlugin);
assert(nodeInfoModule);
// update everyone else
if (nodeInfoPlugin)
nodeInfoPlugin->sendOurNodeInfo();
if (nodeInfoModule)
nodeInfoModule->sendOurNodeInfo();
nodeDB.saveToDisk();
}
@ -175,14 +175,14 @@ void MeshService::sendNetworkPing(NodeNum dest, bool wantReplies)
assert(node);
if (node->has_position) {
if (positionPlugin) {
if (positionModule) {
DEBUG_MSG("Sending position ping to 0x%x, wantReplies=%d\n", dest, wantReplies);
positionPlugin->sendOurPosition(dest, wantReplies);
positionModule->sendOurPosition(dest, wantReplies);
}
} else {
if (nodeInfoPlugin) {
if (nodeInfoModule) {
DEBUG_MSG("Sending nodeinfo ping to 0x%x, wantReplies=%d\n", dest, wantReplies);
nodeInfoPlugin->sendOurNodeInfo(dest, wantReplies);
nodeInfoModule->sendOurNodeInfo(dest, wantReplies);
}
}
}

Wyświetl plik

@ -91,7 +91,7 @@ class MeshService
/// Handle a packet that just arrived from the radio. This method does _ReliableRouternot_ free the provided packet. If it
/// needs to keep the packet around it makes a copy
int handleFromRadio(const MeshPacket *p);
friend class RoutingPlugin;
friend class RoutingModule;
};
extern MeshService service;

Wyświetl plik

@ -19,7 +19,7 @@
#ifndef NO_ESP32
#include "mesh/http/WiFiAPClient.h"
#include "plugins/esp32/StoreForwardPlugin.h"
#include "modules/esp32/StoreForwardModule.h"
#include <Preferences.h>
#include <nvs_flash.h>
#endif
@ -34,7 +34,6 @@ NodeDB nodeDB;
// we have plenty of ram so statically alloc this tempbuf (for now)
EXT_RAM_ATTR DeviceState devicestate;
MyNodeInfo &myNodeInfo = devicestate.my_node;
GroupInfo &ourGroupInfo = devicestate.group_info;
RadioConfig radioConfig;
ChannelFile channelFile;

Wyświetl plik

@ -11,7 +11,6 @@
extern DeviceState devicestate;
extern ChannelFile channelFile;
extern MyNodeInfo &myNodeInfo;
extern GroupInfo &ourGroupInfo;
extern RadioConfig radioConfig;
extern User &owner;

Wyświetl plik

@ -59,7 +59,7 @@ class PhoneAPI
// Call this when the client drops the connection, resets the state to STATE_SEND_NOTHING
// Unregisters our observer. A closed connection **can** be reopened by calling init again.
void close();
virtual void close();
/**
* Handle a ToRadio protobuf

Wyświetl plik

@ -2,10 +2,10 @@
#include "SinglePortPlugin.h"
/**
* A base class for mesh plugins that assume that they are sending/receiving one particular protobuf based
* A base class for mesh modules that assume that they are sending/receiving one particular protobuf based
* payload. Using one particular app ID.
*
* If you are using protobufs to encode your packets (recommended) you can use this as a baseclass for your plugin
* If you are using protobufs to encode your packets (recommended) you can use this as a baseclass for your module
* and avoid a bunch of boilerplate code.
*/
template <class T> class ProtobufPlugin : protected SinglePortPlugin
@ -67,7 +67,7 @@ template <class T> class ProtobufPlugin : protected SinglePortPlugin
if (pb_decode_from_bytes(p.payload.bytes, p.payload.size, fields, &scratch))
decoded = &scratch;
else
DEBUG_MSG("Error decoding protobuf plugin!\n");
DEBUG_MSG("Error decoding protobuf module!\n");
}
return handleReceivedProtobuf(mp, decoded) ? ProcessMessage::STOP : ProcessMessage::CONTINUE;

Wyświetl plik

@ -140,6 +140,8 @@ bool RF95Interface::reconfigure()
void RF95Interface::addReceiveMetadata(MeshPacket *mp)
{
mp->rx_snr = lora->getSNR();
mp->rx_rssi = lround(lora->getRSSI());
}
void RF95Interface::setStandby()

Wyświetl plik

@ -48,9 +48,10 @@ const RegionInfo regions[] = {
RDEF(JP, 920.8f, 927.8f, 100, 0, 16, true, false),
/*
???
https://www.iot.org.au/wp/wp-content/uploads/2016/12/IoTSpectrumFactSheet.pdf
https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf
*/
RDEF(ANZ, 915.0f, 928.0f, 100, 0, 0, true, false),
RDEF(ANZ, 915.0f, 928.0f, 100, 0, 30, true, false),
/*
https://digital.gov.ru/uploaded/files/prilozhenie-12-k-reshenyu-gkrch-18-46-03-1.pdf
@ -75,7 +76,13 @@ const RegionInfo regions[] = {
*/
RDEF(IN, 865.0f, 867.0f, 100, 0, 30, true, false),
/*
/*
https://rrf.rsm.govt.nz/smart-web/smart/page/-smart/domain/licence/LicenceSummary.wdk?id=219752
https://iotalliance.org.nz/wp-content/uploads/sites/4/2019/05/IoT-Spectrum-in-NZ-Briefing-Paper.pdf
*/
RDEF(NZ865, 864.0f, 868.0f, 100, 0, 0, true, false),
/*
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
*/
RDEF(TH, 920.0f, 925.0f, 100, 0, 16, true, false),
@ -212,6 +219,9 @@ void printPacket(const char *prefix, const MeshPacket *p)
if (p->rx_snr != 0.0) {
DEBUG_MSG(" rxSNR=%g", p->rx_snr);
}
if (p->rx_rssi != 0) {
DEBUG_MSG(" rxSNR=%g", p->rx_rssi);
}
if (p->priority != 0)
DEBUG_MSG(" priority=%d", p->priority);
@ -447,4 +457,4 @@ size_t RadioInterface::beginSending(MeshPacket *p)
sendingPacket = p;
return p->encrypted.size + sizeof(PacketHeader);
}
}

Wyświetl plik

@ -6,7 +6,7 @@
#include "RTC.h"
#include "main.h"
#include "mesh-pb-constants.h"
#include "plugins/RoutingPlugin.h"
#include "modules/RoutingModule.h"
#if defined(HAS_WIFI) || defined(PORTDUINO)
#include "mqtt/MQTT.h"
@ -132,7 +132,7 @@ MeshPacket *Router::allocForSending()
*/
void Router::sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex)
{
routingPlugin->sendAckNak(err, to, idFrom, chIndex);
routingModule->sendAckNak(err, to, idFrom, chIndex);
}
void Router::abortSendAndNak(Routing_Error err, MeshPacket *p)
@ -276,7 +276,7 @@ bool perhapsDecode(MeshPacket *p)
if (p->which_payloadVariant == MeshPacket_decoded_tag)
return true; // If packet was already decoded just return
assert(p->which_payloadVariant == MeshPacket_encrypted_tag);
//assert(p->which_payloadVariant == MeshPacket_encrypted_tag);
// Try to find a channel that works with this hash
for (ChannelIndex chIndex = 0; chIndex < channels.getNumChannels(); chIndex++) {
@ -376,7 +376,7 @@ void Router::handleReceived(MeshPacket *p, RxSource src)
printPacket("packet decoding failed (no PSK?)", p);
}
// call plugins here
// call modules here
MeshPlugin::callPlugins(*p, src);
}

Wyświetl plik

@ -71,7 +71,7 @@ class Router : protected concurrency::OSThread
void enqueueReceivedMessage(MeshPacket *p);
protected:
friend class RoutingPlugin;
friend class RoutingModule;
/**
* Send a packet on a suitable interface. This routine will
@ -85,7 +85,7 @@ class Router : protected concurrency::OSThread
/**
* Should this incoming filter be dropped?
*
* FIXME, move this into the new RoutingPlugin and do the filtering there using the regular plugin logic
* FIXME, move this into the new RoutingModule and do the filtering there using the regular module logic
*
* Called immedately on receiption, before any further processing.
* @return true to abandon the packet

Wyświetl plik

@ -3,7 +3,7 @@
#include "Router.h"
/**
* Most plugins are only interested in sending/receving one particular portnum. This baseclass simplifies that common
* Most modules are only interested in sending/receving one particular portnum. This baseclass simplifies that common
* case.
*/
class SinglePortPlugin : public MeshPlugin

Wyświetl plik

@ -29,18 +29,18 @@ typedef struct _AdminMessage {
bool confirm_set_radio;
bool exit_simulator;
int32_t reboot_seconds;
bool get_canned_message_plugin_part1_request;
char get_canned_message_plugin_part1_response[201];
bool get_canned_message_plugin_part2_request;
char get_canned_message_plugin_part2_response[201];
bool get_canned_message_plugin_part3_request;
char get_canned_message_plugin_part3_response[201];
bool get_canned_message_plugin_part4_request;
char get_canned_message_plugin_part4_response[201];
char set_canned_message_plugin_part1[201];
char set_canned_message_plugin_part2[201];
char set_canned_message_plugin_part3[201];
char set_canned_message_plugin_part4[201];
bool get_canned_message_module_part1_request;
char get_canned_message_module_part1_response[201];
bool get_canned_message_module_part2_request;
char get_canned_message_module_part2_response[201];
bool get_canned_message_module_part3_request;
char get_canned_message_module_part3_response[201];
bool get_canned_message_module_part4_request;
char get_canned_message_module_part4_response[201];
char set_canned_message_module_part1[201];
char set_canned_message_module_part2[201];
char set_canned_message_module_part3[201];
char set_canned_message_module_part4[201];
int32_t shutdown_seconds;
};
} AdminMessage;
@ -68,18 +68,18 @@ extern "C" {
#define AdminMessage_confirm_set_radio_tag 33
#define AdminMessage_exit_simulator_tag 34
#define AdminMessage_reboot_seconds_tag 35
#define AdminMessage_get_canned_message_plugin_part1_request_tag 36
#define AdminMessage_get_canned_message_plugin_part1_response_tag 37
#define AdminMessage_get_canned_message_plugin_part2_request_tag 38
#define AdminMessage_get_canned_message_plugin_part2_response_tag 39
#define AdminMessage_get_canned_message_plugin_part3_request_tag 40
#define AdminMessage_get_canned_message_plugin_part3_response_tag 41
#define AdminMessage_get_canned_message_plugin_part4_request_tag 42
#define AdminMessage_get_canned_message_plugin_part4_response_tag 43
#define AdminMessage_set_canned_message_plugin_part1_tag 44
#define AdminMessage_set_canned_message_plugin_part2_tag 45
#define AdminMessage_set_canned_message_plugin_part3_tag 46
#define AdminMessage_set_canned_message_plugin_part4_tag 47
#define AdminMessage_get_canned_message_module_part1_request_tag 36
#define AdminMessage_get_canned_message_module_part1_response_tag 37
#define AdminMessage_get_canned_message_module_part2_request_tag 38
#define AdminMessage_get_canned_message_module_part2_response_tag 39
#define AdminMessage_get_canned_message_module_part3_request_tag 40
#define AdminMessage_get_canned_message_module_part3_response_tag 41
#define AdminMessage_get_canned_message_module_part4_request_tag 42
#define AdminMessage_get_canned_message_module_part4_response_tag 43
#define AdminMessage_set_canned_message_module_part1_tag 44
#define AdminMessage_set_canned_message_module_part2_tag 45
#define AdminMessage_set_canned_message_module_part3_tag 46
#define AdminMessage_set_canned_message_module_part4_tag 47
#define AdminMessage_shutdown_seconds_tag 51
/* Struct field encoding specification for nanopb */
@ -97,18 +97,18 @@ X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_channel,confirm_set_chan
X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_radio,confirm_set_radio), 33) \
X(a, STATIC, ONEOF, BOOL, (variant,exit_simulator,exit_simulator), 34) \
X(a, STATIC, ONEOF, INT32, (variant,reboot_seconds,reboot_seconds), 35) \
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_plugin_part1_request,get_canned_message_plugin_part1_request), 36) \
X(a, STATIC, ONEOF, STRING, (variant,get_canned_message_plugin_part1_response,get_canned_message_plugin_part1_response), 37) \
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_plugin_part2_request,get_canned_message_plugin_part2_request), 38) \
X(a, STATIC, ONEOF, STRING, (variant,get_canned_message_plugin_part2_response,get_canned_message_plugin_part2_response), 39) \
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_plugin_part3_request,get_canned_message_plugin_part3_request), 40) \
X(a, STATIC, ONEOF, STRING, (variant,get_canned_message_plugin_part3_response,get_canned_message_plugin_part3_response), 41) \
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_plugin_part4_request,get_canned_message_plugin_part4_request), 42) \
X(a, STATIC, ONEOF, STRING, (variant,get_canned_message_plugin_part4_response,get_canned_message_plugin_part4_response), 43) \
X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_plugin_part1,set_canned_message_plugin_part1), 44) \
X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_plugin_part2,set_canned_message_plugin_part2), 45) \
X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_plugin_part3,set_canned_message_plugin_part3), 46) \
X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_plugin_part4,set_canned_message_plugin_part4), 47) \
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_module_part1_request,get_canned_message_module_part1_request), 36) \
X(a, STATIC, ONEOF, STRING, (variant,get_canned_message_module_part1_response,get_canned_message_module_part1_response), 37) \
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_module_part2_request,get_canned_message_module_part2_request), 38) \
X(a, STATIC, ONEOF, STRING, (variant,get_canned_message_module_part2_response,get_canned_message_module_part2_response), 39) \
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_module_part3_request,get_canned_message_module_part3_request), 40) \
X(a, STATIC, ONEOF, STRING, (variant,get_canned_message_module_part3_response,get_canned_message_module_part3_response), 41) \
X(a, STATIC, ONEOF, BOOL, (variant,get_canned_message_module_part4_request,get_canned_message_module_part4_request), 42) \
X(a, STATIC, ONEOF, STRING, (variant,get_canned_message_module_part4_response,get_canned_message_module_part4_response), 43) \
X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_module_part1,set_canned_message_module_part1), 44) \
X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_module_part2,set_canned_message_module_part2), 45) \
X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_module_part3,set_canned_message_module_part3), 46) \
X(a, STATIC, ONEOF, STRING, (variant,set_canned_message_module_part4,set_canned_message_module_part4), 47) \
X(a, STATIC, ONEOF, INT32, (variant,shutdown_seconds,shutdown_seconds), 51)
#define AdminMessage_CALLBACK NULL
#define AdminMessage_DEFAULT NULL
@ -125,7 +125,7 @@ extern const pb_msgdesc_t AdminMessage_msg;
#define AdminMessage_fields &AdminMessage_msg
/* Maximum encoded size of messages (where known) */
#define AdminMessage_size 601
#define AdminMessage_size 611
#ifdef __cplusplus
} /* extern "C" */

Wyświetl plik

@ -6,7 +6,7 @@
#error Regenerate this file with the current version of nanopb generator.
#endif
PB_BIND(CannedMessagePluginConfig, CannedMessagePluginConfig, 2)
PB_BIND(CannedMessageModuleConfig, CannedMessageModuleConfig, 2)

Wyświetl plik

@ -10,12 +10,12 @@
#endif
/* Struct definitions */
typedef struct _CannedMessagePluginConfig {
typedef struct _CannedMessageModuleConfig {
char messagesPart1[201];
char messagesPart2[201];
char messagesPart3[201];
char messagesPart4[201];
} CannedMessagePluginConfig;
} CannedMessageModuleConfig;
#ifdef __cplusplus
@ -23,31 +23,31 @@ extern "C" {
#endif
/* Initializer values for message structs */
#define CannedMessagePluginConfig_init_default {"", "", "", ""}
#define CannedMessagePluginConfig_init_zero {"", "", "", ""}
#define CannedMessageModuleConfig_init_default {"", "", "", ""}
#define CannedMessageModuleConfig_init_zero {"", "", "", ""}
/* Field tags (for use in manual encoding/decoding) */
#define CannedMessagePluginConfig_messagesPart1_tag 11
#define CannedMessagePluginConfig_messagesPart2_tag 12
#define CannedMessagePluginConfig_messagesPart3_tag 13
#define CannedMessagePluginConfig_messagesPart4_tag 14
#define CannedMessageModuleConfig_messagesPart1_tag 11
#define CannedMessageModuleConfig_messagesPart2_tag 12
#define CannedMessageModuleConfig_messagesPart3_tag 13
#define CannedMessageModuleConfig_messagesPart4_tag 14
/* Struct field encoding specification for nanopb */
#define CannedMessagePluginConfig_FIELDLIST(X, a) \
#define CannedMessageModuleConfig_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, STRING, messagesPart1, 11) \
X(a, STATIC, SINGULAR, STRING, messagesPart2, 12) \
X(a, STATIC, SINGULAR, STRING, messagesPart3, 13) \
X(a, STATIC, SINGULAR, STRING, messagesPart4, 14)
#define CannedMessagePluginConfig_CALLBACK NULL
#define CannedMessagePluginConfig_DEFAULT NULL
#define CannedMessageModuleConfig_CALLBACK NULL
#define CannedMessageModuleConfig_DEFAULT NULL
extern const pb_msgdesc_t CannedMessagePluginConfig_msg;
extern const pb_msgdesc_t CannedMessageModuleConfig_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define CannedMessagePluginConfig_fields &CannedMessagePluginConfig_msg
#define CannedMessageModuleConfig_fields &CannedMessageModuleConfig_msg
/* Maximum encoded size of messages (where known) */
#define CannedMessagePluginConfig_size 812
#define CannedMessageModuleConfig_size 812
#ifdef __cplusplus
} /* extern "C" */

Wyświetl plik

@ -6,7 +6,6 @@
#include <pb.h>
#include "channel.pb.h"
#include "mesh.pb.h"
#include "radioconfig.pb.h"
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
@ -27,8 +26,6 @@ typedef struct _DeviceState {
NodeInfo node_db[32];
pb_size_t receive_queue_count;
MeshPacket receive_queue[1];
bool has_group_info;
GroupInfo group_info;
bool has_rx_text_message;
MeshPacket rx_text_message;
uint32_t version;
@ -42,9 +39,9 @@ extern "C" {
#endif
/* Initializer values for message structs */
#define DeviceState_init_default {false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, GroupInfo_init_default, false, MeshPacket_init_default, 0, 0, 0}
#define DeviceState_init_default {false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0}
#define ChannelFile_init_default {0, {Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default}}
#define DeviceState_init_zero {false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, GroupInfo_init_zero, false, MeshPacket_init_zero, 0, 0, 0}
#define DeviceState_init_zero {false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0}
#define ChannelFile_init_zero {0, {Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero}}
/* Field tags (for use in manual encoding/decoding) */
@ -53,7 +50,6 @@ extern "C" {
#define DeviceState_owner_tag 3
#define DeviceState_node_db_tag 4
#define DeviceState_receive_queue_tag 5
#define DeviceState_group_info_tag 6
#define DeviceState_rx_text_message_tag 7
#define DeviceState_version_tag 8
#define DeviceState_no_save_tag 9
@ -65,7 +61,6 @@ X(a, STATIC, OPTIONAL, MESSAGE, my_node, 2) \
X(a, STATIC, OPTIONAL, MESSAGE, owner, 3) \
X(a, STATIC, REPEATED, MESSAGE, node_db, 4) \
X(a, STATIC, REPEATED, MESSAGE, receive_queue, 5) \
X(a, STATIC, OPTIONAL, MESSAGE, group_info, 6) \
X(a, STATIC, OPTIONAL, MESSAGE, rx_text_message, 7) \
X(a, STATIC, SINGULAR, UINT32, version, 8) \
X(a, STATIC, SINGULAR, BOOL, no_save, 9) \
@ -76,7 +71,6 @@ X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11)
#define DeviceState_owner_MSGTYPE User
#define DeviceState_node_db_MSGTYPE NodeInfo
#define DeviceState_receive_queue_MSGTYPE MeshPacket
#define DeviceState_group_info_MSGTYPE GroupInfo
#define DeviceState_rx_text_message_MSGTYPE MeshPacket
#define ChannelFile_FIELDLIST(X, a) \
@ -93,7 +87,7 @@ extern const pb_msgdesc_t ChannelFile_msg;
#define ChannelFile_fields &ChannelFile_msg
/* Maximum encoded size of messages (where known) */
#define DeviceState_size 10162
#define DeviceState_size 9885
#define ChannelFile_size 832
#ifdef __cplusplus

Wyświetl plik

@ -27,10 +27,7 @@ PB_BIND(MeshPacket, MeshPacket, 2)
PB_BIND(NodeInfo, NodeInfo, AUTO)
PB_BIND(GroupInfo, GroupInfo, AUTO)
PB_BIND(MyNodeInfo, MyNodeInfo, 2)
PB_BIND(MyNodeInfo, MyNodeInfo, AUTO)
PB_BIND(LogRecord, LogRecord, AUTO)

Wyświetl plik

@ -140,14 +140,8 @@ typedef struct _Data {
uint32_t request_id;
uint32_t reply_id;
bool is_tapback;
uint8_t group_id;
} Data;
typedef struct _GroupInfo {
pb_size_t group_count;
char group[10][17];
} GroupInfo;
typedef struct _LogRecord {
char message[64];
uint32_t time;
@ -169,12 +163,18 @@ typedef struct _MyNodeInfo {
uint32_t min_app_version;
uint32_t max_channels;
pb_size_t air_period_tx_count;
uint32_t air_period_tx[24];
uint32_t air_period_tx[8];
pb_size_t air_period_rx_count;
uint32_t air_period_rx[24];
uint32_t air_period_rx[8];
bool has_wifi;
float channel_utilization;
float air_util_tx;
pb_size_t router_count;
uint32_t router[4];
pb_size_t router_snr_count;
float router_snr[4];
pb_size_t router_sec_count;
uint16_t router_sec[4];
} MyNodeInfo;
typedef struct _Position {
@ -182,6 +182,7 @@ typedef struct _Position {
int32_t longitude_i;
int32_t altitude;
int32_t battery_level;
bool router_heartbeat;
uint32_t time;
Position_LocSource location_source;
Position_AltSource altitude_source;
@ -275,7 +276,6 @@ typedef struct _FromRadio {
uint32_t config_complete_id;
bool rebooted;
MeshPacket packet;
GroupInfo groups;
};
} FromRadio;
@ -337,28 +337,26 @@ 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, 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, 0}
#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 GroupInfo_init_default {0, {"", "", "", "", "", "", "", "", "", ""}}
#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, 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 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, 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, 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, 0}
#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 GroupInfo_init_zero {0, {"", "", "", "", "", "", "", "", "", ""}}
#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, 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 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, 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}}
#define ToRadio_init_zero {0, {MeshPacket_init_zero}}
@ -373,8 +371,6 @@ extern "C" {
#define Data_request_id_tag 6
#define Data_reply_id_tag 7
#define Data_is_tapback_tag 8
#define Data_group_id_tag 9
#define GroupInfo_group_tag 1
#define LogRecord_message_tag 1
#define LogRecord_time_tag 2
#define LogRecord_source_tag 3
@ -396,10 +392,14 @@ extern "C" {
#define MyNodeInfo_has_wifi_tag 18
#define MyNodeInfo_channel_utilization_tag 19
#define MyNodeInfo_air_util_tx_tag 20
#define MyNodeInfo_router_tag 21
#define MyNodeInfo_router_snr_tag 22
#define MyNodeInfo_router_sec_tag 23
#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_router_heartbeat_tag 5
#define Position_time_tag 9
#define Position_location_source_tag 10
#define Position_altitude_source_tag 11
@ -460,7 +460,6 @@ extern "C" {
#define FromRadio_config_complete_id_tag 8
#define FromRadio_rebooted_tag 9
#define FromRadio_packet_tag 11
#define FromRadio_groups_tag 12
#define ToRadio_packet_tag 2
#define ToRadio_peer_info_tag 3
#define ToRadio_want_config_id_tag 100
@ -472,6 +471,7 @@ 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, BOOL, router_heartbeat, 5) \
X(a, STATIC, SINGULAR, FIXED32, time, 9) \
X(a, STATIC, SINGULAR, UENUM, location_source, 10) \
X(a, STATIC, SINGULAR, UENUM, altitude_source, 11) \
@ -530,8 +530,7 @@ X(a, STATIC, SINGULAR, FIXED32, dest, 4) \
X(a, STATIC, SINGULAR, FIXED32, source, 5) \
X(a, STATIC, SINGULAR, FIXED32, request_id, 6) \
X(a, STATIC, SINGULAR, FIXED32, reply_id, 7) \
X(a, STATIC, SINGULAR, BOOL, is_tapback, 8) \
X(a, STATIC, SINGULAR, UINT32, group_id, 9)
X(a, STATIC, SINGULAR, BOOL, is_tapback, 8)
#define Data_CALLBACK NULL
#define Data_DEFAULT NULL
@ -564,11 +563,6 @@ X(a, STATIC, SINGULAR, FLOAT, snr, 7)
#define NodeInfo_user_MSGTYPE User
#define NodeInfo_position_MSGTYPE Position
#define GroupInfo_FIELDLIST(X, a) \
X(a, STATIC, REPEATED, STRING, group, 1)
#define GroupInfo_CALLBACK NULL
#define GroupInfo_DEFAULT NULL
#define MyNodeInfo_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, my_node_num, 1) \
X(a, STATIC, SINGULAR, BOOL, has_gps, 2) \
@ -586,7 +580,10 @@ X(a, STATIC, REPEATED, UINT32, air_period_tx, 16) \
X(a, STATIC, REPEATED, UINT32, air_period_rx, 17) \
X(a, STATIC, SINGULAR, BOOL, has_wifi, 18) \
X(a, STATIC, SINGULAR, FLOAT, channel_utilization, 19) \
X(a, STATIC, SINGULAR, FLOAT, air_util_tx, 20)
X(a, STATIC, SINGULAR, FLOAT, air_util_tx, 20) \
X(a, STATIC, REPEATED, UINT32, router, 21) \
X(a, STATIC, REPEATED, FLOAT, router_snr, 22) \
X(a, STATIC, REPEATED, UINT32, router_sec, 23)
#define MyNodeInfo_CALLBACK NULL
#define MyNodeInfo_DEFAULT NULL
@ -605,15 +602,13 @@ X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,node_info,node_info), 4) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,log_record,log_record), 7) \
X(a, STATIC, ONEOF, UINT32, (payloadVariant,config_complete_id,config_complete_id), 8) \
X(a, STATIC, ONEOF, BOOL, (payloadVariant,rebooted,rebooted), 9) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,packet,packet), 11) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,groups,groups), 12)
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,packet,packet), 11)
#define FromRadio_CALLBACK NULL
#define FromRadio_DEFAULT NULL
#define FromRadio_payloadVariant_my_info_MSGTYPE MyNodeInfo
#define FromRadio_payloadVariant_node_info_MSGTYPE NodeInfo
#define FromRadio_payloadVariant_log_record_MSGTYPE LogRecord
#define FromRadio_payloadVariant_packet_MSGTYPE MeshPacket
#define FromRadio_payloadVariant_groups_MSGTYPE GroupInfo
#define ToRadio_FIELDLIST(X, a) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,packet,packet), 2) \
@ -638,7 +633,6 @@ extern const pb_msgdesc_t Routing_msg;
extern const pb_msgdesc_t Data_msg;
extern const pb_msgdesc_t MeshPacket_msg;
extern const pb_msgdesc_t NodeInfo_msg;
extern const pb_msgdesc_t GroupInfo_msg;
extern const pb_msgdesc_t MyNodeInfo_msg;
extern const pb_msgdesc_t LogRecord_msg;
extern const pb_msgdesc_t FromRadio_msg;
@ -653,7 +647,6 @@ extern const pb_msgdesc_t ToRadio_PeerInfo_msg;
#define Data_fields &Data_msg
#define MeshPacket_fields &MeshPacket_msg
#define NodeInfo_fields &NodeInfo_msg
#define GroupInfo_fields &GroupInfo_msg
#define MyNodeInfo_fields &MyNodeInfo_msg
#define LogRecord_fields &LogRecord_msg
#define FromRadio_fields &FromRadio_msg
@ -661,18 +654,17 @@ 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 155
#define User_size 97
#define RouteDiscovery_size 40
#define Routing_size 42
#define Data_size 270
#define MeshPacket_size 321
#define NodeInfo_size 271
#define GroupInfo_size 180
#define MyNodeInfo_size 434
#define Data_size 267
#define MeshPacket_size 318
#define NodeInfo_size 273
#define MyNodeInfo_size 282
#define LogRecord_size 81
#define FromRadio_size 443
#define ToRadio_size 324
#define FromRadio_size 327
#define ToRadio_size 321
#define ToRadio_PeerInfo_size 8
#ifdef __cplusplus

Wyświetl plik

@ -20,11 +20,10 @@ typedef enum _PortNum {
PortNum_ADMIN_APP = 6,
PortNum_REPLY_APP = 32,
PortNum_IP_TUNNEL_APP = 33,
PortNum_GROUP_APP = 34,
PortNum_SERIAL_APP = 64,
PortNum_STORE_FORWARD_APP = 65,
PortNum_RANGE_TEST_APP = 66,
PortNum_ENVIRONMENTAL_MEASUREMENT_APP = 67,
PortNum_TELEMETRY_APP = 67,
PortNum_ZPS_APP = 68,
PortNum_PRIVATE_APP = 256,
PortNum_ATAK_FORWARDER = 257,

Wyświetl plik

@ -21,3 +21,4 @@ PB_BIND(RadioConfig_UserPreferences, RadioConfig_UserPreferences, 2)

Wyświetl plik

@ -22,9 +22,16 @@ typedef enum _RegionCode {
RegionCode_TW = 8,
RegionCode_RU = 9,
RegionCode_IN = 10,
RegionCode_TH = 11
RegionCode_NZ865 = 11,
RegionCode_TH = 12
} RegionCode;
typedef enum _Role {
Role_Default = 0,
Role_Router = 1,
Role_Repeater = 2
} Role;
typedef enum _ChargeCurrent {
ChargeCurrent_MAUnset = 0,
ChargeCurrent_MA100 = 1,
@ -92,17 +99,17 @@ typedef enum _InputEventChar {
InputEventChar_KEY_CANCEL = 24
} InputEventChar;
typedef enum _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType {
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11 = 0,
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20 = 1,
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT12 = 2,
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT21 = 3,
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT22 = 4,
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME280 = 5,
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME680 = 6,
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MCP9808 = 7,
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_SHTC3 = 8
} RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType;
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;
/* Struct definitions */
typedef struct _RadioConfig_UserPreferences {
@ -122,6 +129,7 @@ typedef struct _RadioConfig_UserPreferences {
RegionCode region;
ChargeCurrent charge_current;
bool position_broadcast_smart;
Role role;
LocationSharing location_share;
GpsOperation gps_operation;
uint32_t gps_update_interval;
@ -140,34 +148,34 @@ typedef struct _RadioConfig_UserPreferences {
bool debug_log_enabled;
pb_size_t ignore_incoming_count;
uint32_t ignore_incoming[3];
bool serialplugin_enabled;
bool serialplugin_echo;
uint32_t serialplugin_rxd;
uint32_t serialplugin_txd;
uint32_t serialplugin_timeout;
uint32_t serialplugin_mode;
bool ext_notification_plugin_enabled;
uint32_t ext_notification_plugin_output_ms;
uint32_t ext_notification_plugin_output;
bool ext_notification_plugin_active;
bool ext_notification_plugin_alert_message;
bool ext_notification_plugin_alert_bell;
bool range_test_plugin_enabled;
uint32_t range_test_plugin_sender;
bool range_test_plugin_save;
uint32_t store_forward_plugin_records;
uint32_t store_forward_plugin_history_return_max;
uint32_t store_forward_plugin_history_return_window;
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;
bool environmental_measurement_plugin_display_farenheit;
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType environmental_measurement_plugin_sensor_type;
uint32_t environmental_measurement_plugin_sensor_pin;
bool store_forward_plugin_enabled;
bool store_forward_plugin_heartbeat;
bool serialmodule_enabled;
bool serialmodule_echo;
uint32_t serialmodule_rxd;
uint32_t serialmodule_txd;
uint32_t serialmodule_timeout;
uint32_t serialmodule_mode;
bool ext_notification_module_enabled;
uint32_t ext_notification_module_output_ms;
uint32_t ext_notification_module_output;
bool ext_notification_module_active;
bool ext_notification_module_alert_message;
bool ext_notification_module_alert_bell;
bool range_test_module_enabled;
uint32_t range_test_module_sender;
bool range_test_module_save;
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_farenheit;
RadioConfig_UserPreferences_TelemetrySensorType telemetry_module_sensor_type;
uint32_t telemetry_module_sensor_pin;
bool store_forward_module_enabled;
bool store_forward_module_heartbeat;
uint32_t position_flags;
bool is_always_powered;
uint32_t auto_screen_carousel_secs;
@ -184,11 +192,12 @@ typedef struct _RadioConfig_UserPreferences {
InputEventChar rotary1_event_cw;
InputEventChar rotary1_event_ccw;
InputEventChar rotary1_event_press;
bool canned_message_plugin_enabled;
char canned_message_plugin_allow_input_source[16];
bool canned_message_plugin_send_bell;
bool canned_message_module_enabled;
char canned_message_module_allow_input_source[16];
bool canned_message_module_send_bell;
bool mqtt_encryption_enabled;
float adc_multiplier_override;
uint32_t serialmodule_baud;
} RadioConfig_UserPreferences;
typedef struct _RadioConfig {
@ -202,6 +211,10 @@ typedef struct _RadioConfig {
#define _RegionCode_MAX RegionCode_TH
#define _RegionCode_ARRAYSIZE ((RegionCode)(RegionCode_TH+1))
#define _Role_MIN Role_Default
#define _Role_MAX Role_Repeater
#define _Role_ARRAYSIZE ((Role)(Role_Repeater+1))
#define _ChargeCurrent_MIN ChargeCurrent_MAUnset
#define _ChargeCurrent_MAX ChargeCurrent_MA1320
#define _ChargeCurrent_ARRAYSIZE ((ChargeCurrent)(ChargeCurrent_MA1320+1))
@ -226,9 +239,9 @@ typedef struct _RadioConfig {
#define _InputEventChar_MAX InputEventChar_KEY_BACK
#define _InputEventChar_ARRAYSIZE ((InputEventChar)(InputEventChar_KEY_BACK+1))
#define _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11
#define _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MAX RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_SHTC3
#define _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_ARRAYSIZE ((RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType)(RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_SHTC3+1))
#define _RadioConfig_UserPreferences_TelemetrySensorType_MIN RadioConfig_UserPreferences_TelemetrySensorType_DHT11
#define _RadioConfig_UserPreferences_TelemetrySensorType_MAX RadioConfig_UserPreferences_TelemetrySensorType_SHTC3
#define _RadioConfig_UserPreferences_TelemetrySensorType_ARRAYSIZE ((RadioConfig_UserPreferences_TelemetrySensorType)(RadioConfig_UserPreferences_TelemetrySensorType_SHTC3+1))
#ifdef __cplusplus
@ -237,9 +250,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, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_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, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_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}
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _Role_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_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, _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}
#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, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_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, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_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}
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _Role_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_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, _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}
/* Field tags (for use in manual encoding/decoding) */
#define RadioConfig_UserPreferences_position_broadcast_secs_tag 1
@ -258,6 +271,7 @@ extern "C" {
#define RadioConfig_UserPreferences_region_tag 15
#define RadioConfig_UserPreferences_charge_current_tag 16
#define RadioConfig_UserPreferences_position_broadcast_smart_tag 17
#define RadioConfig_UserPreferences_role_tag 18
#define RadioConfig_UserPreferences_location_share_tag 32
#define RadioConfig_UserPreferences_gps_operation_tag 33
#define RadioConfig_UserPreferences_gps_update_interval_tag 34
@ -275,34 +289,34 @@ extern "C" {
#define RadioConfig_UserPreferences_factory_reset_tag 100
#define RadioConfig_UserPreferences_debug_log_enabled_tag 101
#define RadioConfig_UserPreferences_ignore_incoming_tag 103
#define RadioConfig_UserPreferences_serialplugin_enabled_tag 120
#define RadioConfig_UserPreferences_serialplugin_echo_tag 121
#define RadioConfig_UserPreferences_serialplugin_rxd_tag 122
#define RadioConfig_UserPreferences_serialplugin_txd_tag 123
#define RadioConfig_UserPreferences_serialplugin_timeout_tag 124
#define RadioConfig_UserPreferences_serialplugin_mode_tag 125
#define RadioConfig_UserPreferences_ext_notification_plugin_enabled_tag 126
#define RadioConfig_UserPreferences_ext_notification_plugin_output_ms_tag 127
#define RadioConfig_UserPreferences_ext_notification_plugin_output_tag 128
#define RadioConfig_UserPreferences_ext_notification_plugin_active_tag 129
#define RadioConfig_UserPreferences_ext_notification_plugin_alert_message_tag 130
#define RadioConfig_UserPreferences_ext_notification_plugin_alert_bell_tag 131
#define RadioConfig_UserPreferences_range_test_plugin_enabled_tag 132
#define RadioConfig_UserPreferences_range_test_plugin_sender_tag 133
#define RadioConfig_UserPreferences_range_test_plugin_save_tag 134
#define RadioConfig_UserPreferences_store_forward_plugin_records_tag 137
#define RadioConfig_UserPreferences_store_forward_plugin_history_return_max_tag 138
#define RadioConfig_UserPreferences_store_forward_plugin_history_return_window_tag 139
#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 RadioConfig_UserPreferences_environmental_measurement_plugin_display_farenheit_tag 145
#define RadioConfig_UserPreferences_environmental_measurement_plugin_sensor_type_tag 146
#define RadioConfig_UserPreferences_environmental_measurement_plugin_sensor_pin_tag 147
#define RadioConfig_UserPreferences_store_forward_plugin_enabled_tag 148
#define RadioConfig_UserPreferences_store_forward_plugin_heartbeat_tag 149
#define RadioConfig_UserPreferences_serialmodule_enabled_tag 120
#define RadioConfig_UserPreferences_serialmodule_echo_tag 121
#define RadioConfig_UserPreferences_serialmodule_rxd_tag 122
#define RadioConfig_UserPreferences_serialmodule_txd_tag 123
#define RadioConfig_UserPreferences_serialmodule_timeout_tag 124
#define RadioConfig_UserPreferences_serialmodule_mode_tag 125
#define RadioConfig_UserPreferences_ext_notification_module_enabled_tag 126
#define RadioConfig_UserPreferences_ext_notification_module_output_ms_tag 127
#define RadioConfig_UserPreferences_ext_notification_module_output_tag 128
#define RadioConfig_UserPreferences_ext_notification_module_active_tag 129
#define RadioConfig_UserPreferences_ext_notification_module_alert_message_tag 130
#define RadioConfig_UserPreferences_ext_notification_module_alert_bell_tag 131
#define RadioConfig_UserPreferences_range_test_module_enabled_tag 132
#define RadioConfig_UserPreferences_range_test_module_sender_tag 133
#define RadioConfig_UserPreferences_range_test_module_save_tag 134
#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_farenheit_tag 145
#define RadioConfig_UserPreferences_telemetry_module_sensor_type_tag 146
#define RadioConfig_UserPreferences_telemetry_module_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
#define RadioConfig_UserPreferences_is_always_powered_tag 151
#define RadioConfig_UserPreferences_auto_screen_carousel_secs_tag 152
@ -319,11 +333,12 @@ extern "C" {
#define RadioConfig_UserPreferences_rotary1_event_cw_tag 164
#define RadioConfig_UserPreferences_rotary1_event_ccw_tag 165
#define RadioConfig_UserPreferences_rotary1_event_press_tag 166
#define RadioConfig_UserPreferences_canned_message_plugin_enabled_tag 170
#define RadioConfig_UserPreferences_canned_message_plugin_allow_input_source_tag 171
#define RadioConfig_UserPreferences_canned_message_plugin_send_bell_tag 173
#define RadioConfig_UserPreferences_canned_message_module_enabled_tag 170
#define RadioConfig_UserPreferences_canned_message_module_allow_input_source_tag 171
#define RadioConfig_UserPreferences_canned_message_module_send_bell_tag 173
#define RadioConfig_UserPreferences_mqtt_encryption_enabled_tag 174
#define RadioConfig_UserPreferences_adc_multiplier_override_tag 175
#define RadioConfig_UserPreferences_serialmodule_baud_tag 176
#define RadioConfig_preferences_tag 1
/* Struct field encoding specification for nanopb */
@ -350,6 +365,7 @@ X(a, STATIC, SINGULAR, BOOL, wifi_ap_mode, 14) \
X(a, STATIC, SINGULAR, UENUM, region, 15) \
X(a, STATIC, SINGULAR, UENUM, charge_current, 16) \
X(a, STATIC, SINGULAR, BOOL, position_broadcast_smart, 17) \
X(a, STATIC, SINGULAR, UENUM, role, 18) \
X(a, STATIC, SINGULAR, UENUM, location_share, 32) \
X(a, STATIC, SINGULAR, UENUM, gps_operation, 33) \
X(a, STATIC, SINGULAR, UINT32, gps_update_interval, 34) \
@ -367,34 +383,34 @@ X(a, STATIC, SINGULAR, UINT32, gps_max_dop, 46) \
X(a, STATIC, SINGULAR, BOOL, factory_reset, 100) \
X(a, STATIC, SINGULAR, BOOL, debug_log_enabled, 101) \
X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103) \
X(a, STATIC, SINGULAR, BOOL, serialplugin_enabled, 120) \
X(a, STATIC, SINGULAR, BOOL, serialplugin_echo, 121) \
X(a, STATIC, SINGULAR, UINT32, serialplugin_rxd, 122) \
X(a, STATIC, SINGULAR, UINT32, serialplugin_txd, 123) \
X(a, STATIC, SINGULAR, UINT32, serialplugin_timeout, 124) \
X(a, STATIC, SINGULAR, UINT32, serialplugin_mode, 125) \
X(a, STATIC, SINGULAR, BOOL, ext_notification_plugin_enabled, 126) \
X(a, STATIC, SINGULAR, UINT32, ext_notification_plugin_output_ms, 127) \
X(a, STATIC, SINGULAR, UINT32, ext_notification_plugin_output, 128) \
X(a, STATIC, SINGULAR, BOOL, ext_notification_plugin_active, 129) \
X(a, STATIC, SINGULAR, BOOL, ext_notification_plugin_alert_message, 130) \
X(a, STATIC, SINGULAR, BOOL, ext_notification_plugin_alert_bell, 131) \
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, UINT32, store_forward_plugin_records, 137) \
X(a, STATIC, SINGULAR, UINT32, store_forward_plugin_history_return_max, 138) \
X(a, STATIC, SINGULAR, UINT32, store_forward_plugin_history_return_window, 139) \
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) \
X(a, STATIC, SINGULAR, BOOL, environmental_measurement_plugin_display_farenheit, 145) \
X(a, STATIC, SINGULAR, UENUM, environmental_measurement_plugin_sensor_type, 146) \
X(a, STATIC, SINGULAR, UINT32, environmental_measurement_plugin_sensor_pin, 147) \
X(a, STATIC, SINGULAR, BOOL, store_forward_plugin_enabled, 148) \
X(a, STATIC, SINGULAR, BOOL, store_forward_plugin_heartbeat, 149) \
X(a, STATIC, SINGULAR, BOOL, serialmodule_enabled, 120) \
X(a, STATIC, SINGULAR, BOOL, serialmodule_echo, 121) \
X(a, STATIC, SINGULAR, UINT32, serialmodule_rxd, 122) \
X(a, STATIC, SINGULAR, UINT32, serialmodule_txd, 123) \
X(a, STATIC, SINGULAR, UINT32, serialmodule_timeout, 124) \
X(a, STATIC, SINGULAR, UINT32, serialmodule_mode, 125) \
X(a, STATIC, SINGULAR, BOOL, ext_notification_module_enabled, 126) \
X(a, STATIC, SINGULAR, UINT32, ext_notification_module_output_ms, 127) \
X(a, STATIC, SINGULAR, UINT32, ext_notification_module_output, 128) \
X(a, STATIC, SINGULAR, BOOL, ext_notification_module_active, 129) \
X(a, STATIC, SINGULAR, BOOL, ext_notification_module_alert_message, 130) \
X(a, STATIC, SINGULAR, BOOL, ext_notification_module_alert_bell, 131) \
X(a, STATIC, SINGULAR, BOOL, range_test_module_enabled, 132) \
X(a, STATIC, SINGULAR, UINT32, range_test_module_sender, 133) \
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_farenheit, 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, store_forward_module_enabled, 148) \
X(a, STATIC, SINGULAR, BOOL, store_forward_module_heartbeat, 149) \
X(a, STATIC, SINGULAR, UINT32, position_flags, 150) \
X(a, STATIC, SINGULAR, BOOL, is_always_powered, 151) \
X(a, STATIC, SINGULAR, UINT32, auto_screen_carousel_secs, 152) \
@ -411,11 +427,12 @@ X(a, STATIC, SINGULAR, UINT32, rotary1_pin_press, 163) \
X(a, STATIC, SINGULAR, UENUM, rotary1_event_cw, 164) \
X(a, STATIC, SINGULAR, UENUM, rotary1_event_ccw, 165) \
X(a, STATIC, SINGULAR, UENUM, rotary1_event_press, 166) \
X(a, STATIC, SINGULAR, BOOL, canned_message_plugin_enabled, 170) \
X(a, STATIC, SINGULAR, STRING, canned_message_plugin_allow_input_source, 171) \
X(a, STATIC, SINGULAR, BOOL, canned_message_plugin_send_bell, 173) \
X(a, STATIC, SINGULAR, BOOL, canned_message_module_enabled, 170) \
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, FLOAT, adc_multiplier_override, 175) \
X(a, STATIC, SINGULAR, UINT32, serialmodule_baud, 176)
#define RadioConfig_UserPreferences_CALLBACK NULL
#define RadioConfig_UserPreferences_DEFAULT NULL
@ -427,8 +444,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_size 598
#define RadioConfig_UserPreferences_size 595
#define RadioConfig_size 608
#define RadioConfig_UserPreferences_size 605
#ifdef __cplusplus
} /* extern "C" */

Wyświetl plik

@ -1,12 +1,12 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.4 */
#include "environmental_measurement.pb.h"
#include "telemetry.pb.h"
#if PB_PROTO_HEADER_VERSION != 40
#error Regenerate this file with the current version of nanopb generator.
#endif
PB_BIND(EnvironmentalMeasurement, EnvironmentalMeasurement, AUTO)
PB_BIND(Telemetry, Telemetry, AUTO)

Wyświetl plik

@ -1,8 +1,8 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.4 */
#ifndef PB_ENVIRONMENTAL_MEASUREMENT_PB_H_INCLUDED
#define PB_ENVIRONMENTAL_MEASUREMENT_PB_H_INCLUDED
#ifndef PB_TELEMETRY_PB_H_INCLUDED
#define PB_TELEMETRY_PB_H_INCLUDED
#include <pb.h>
#if PB_PROTO_HEADER_VERSION != 40
@ -10,14 +10,14 @@
#endif
/* Struct definitions */
typedef struct _EnvironmentalMeasurement {
typedef struct _Telemetry {
float temperature;
float relative_humidity;
float barometric_pressure;
float gas_resistance;
float voltage;
float current;
} EnvironmentalMeasurement;
} Telemetry;
#ifdef __cplusplus
@ -25,35 +25,35 @@ extern "C" {
#endif
/* Initializer values for message structs */
#define EnvironmentalMeasurement_init_default {0, 0, 0, 0, 0, 0}
#define EnvironmentalMeasurement_init_zero {0, 0, 0, 0, 0, 0}
#define Telemetry_init_default {0, 0, 0, 0, 0, 0}
#define Telemetry_init_zero {0, 0, 0, 0, 0, 0}
/* Field tags (for use in manual encoding/decoding) */
#define EnvironmentalMeasurement_temperature_tag 1
#define EnvironmentalMeasurement_relative_humidity_tag 2
#define EnvironmentalMeasurement_barometric_pressure_tag 3
#define EnvironmentalMeasurement_gas_resistance_tag 4
#define EnvironmentalMeasurement_voltage_tag 5
#define EnvironmentalMeasurement_current_tag 6
#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
/* Struct field encoding specification for nanopb */
#define EnvironmentalMeasurement_FIELDLIST(X, a) \
#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)
#define EnvironmentalMeasurement_CALLBACK NULL
#define EnvironmentalMeasurement_DEFAULT NULL
#define Telemetry_CALLBACK NULL
#define Telemetry_DEFAULT NULL
extern const pb_msgdesc_t EnvironmentalMeasurement_msg;
extern const pb_msgdesc_t Telemetry_msg;
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
#define EnvironmentalMeasurement_fields &EnvironmentalMeasurement_msg
#define Telemetry_fields &Telemetry_msg
/* Maximum encoded size of messages (where known) */
#define EnvironmentalMeasurement_size 30
#define Telemetry_size 30
#ifdef __cplusplus
} /* extern "C" */

Wyświetl plik

@ -1,5 +1,5 @@
#include "configuration.h"
#include "AdminPlugin.h"
#include "AdminModule.h"
#include "Channels.h"
#include "MeshService.h"
#include "NodeDB.h"
@ -10,7 +10,7 @@
#include "unistd.h"
#endif
AdminPlugin *adminPlugin;
AdminModule *adminModule;
/// A special reserved string to indicate strings we can not share with external nodes. We will use this 'reserved' word instead.
/// Also, to make setting work correctly, if someone tries to set a string to this reserved value we assume they don't really want a change.
@ -30,7 +30,7 @@ static void writeSecret(char *buf, const char *currentVal) {
}
}
void AdminPlugin::handleGetChannel(const MeshPacket &req, uint32_t channelIndex)
void AdminModule::handleGetChannel(const MeshPacket &req, uint32_t channelIndex)
{
if (req.decoded.want_response) {
// We create the reply here
@ -41,7 +41,7 @@ void AdminPlugin::handleGetChannel(const MeshPacket &req, uint32_t channelIndex)
}
}
void AdminPlugin::handleGetRadio(const MeshPacket &req)
void AdminModule::handleGetRadio(const MeshPacket &req)
{
if (req.decoded.want_response) {
// We create the reply here
@ -61,7 +61,7 @@ void AdminPlugin::handleGetRadio(const MeshPacket &req)
}
}
bool AdminPlugin::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
bool AdminModule::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
{
// if handled == false, then let others look at this message also if they want
bool handled = false;
@ -143,7 +143,7 @@ bool AdminPlugin::handleReceivedProtobuf(const MeshPacket &mp, AdminMessage *r)
return handled;
}
void AdminPlugin::handleSetOwner(const User &o)
void AdminModule::handleSetOwner(const User &o)
{
int changed = 0;
@ -173,7 +173,7 @@ void AdminPlugin::handleSetOwner(const User &o)
service.reloadOwner();
}
void AdminPlugin::handleSetChannel(const Channel &cc)
void AdminModule::handleSetChannel(const Channel &cc)
{
channels.setChannel(cc);
@ -187,7 +187,7 @@ void AdminPlugin::handleSetChannel(const Channel &cc)
}
}
void AdminPlugin::handleSetRadio(RadioConfig &r)
void AdminModule::handleSetRadio(RadioConfig &r)
{
writeSecret(r.preferences.wifi_password, radioConfig.preferences.wifi_password);
radioConfig = r;
@ -195,7 +195,7 @@ void AdminPlugin::handleSetRadio(RadioConfig &r)
service.reloadConfig();
}
AdminPlugin::AdminPlugin() : ProtobufPlugin("Admin", PortNum_ADMIN_APP, AdminMessage_fields)
AdminModule::AdminModule() : ProtobufPlugin("Admin", PortNum_ADMIN_APP, AdminMessage_fields)
{
// restrict to the admin channel for rx
boundChannel = Channels::adminChannel;

Wyświetl plik

@ -2,15 +2,15 @@
#include "ProtobufPlugin.h"
/**
* Routing plugin for router control messages
* Routing module for router control messages
*/
class AdminPlugin : public ProtobufPlugin<AdminMessage>
class AdminModule : public ProtobufPlugin<AdminMessage>
{
public:
/** Constructor
* name is for debugging output
*/
AdminPlugin();
AdminModule();
protected:
/** Called to handle a particular incoming message
@ -28,4 +28,4 @@ class AdminPlugin : public ProtobufPlugin<AdminMessage>
void handleGetRadio(const MeshPacket &req);
};
extern AdminPlugin *adminPlugin;
extern AdminModule *adminModule;

Wyświetl plik

@ -1,5 +1,5 @@
#include "configuration.h"
#include "CannedMessagePlugin.h"
#include "CannedMessageModule.h"
#include "MeshService.h"
#include "FSCommon.h"
#include "mesh/generated/cannedmessages.pb.h"
@ -14,29 +14,29 @@
static const char *cannedMessagesConfigFile = "/prefs/cannedConf.proto";
CannedMessagePluginConfig cannedMessagePluginConfig;
CannedMessageModuleConfig cannedMessageModuleConfig;
CannedMessagePlugin *cannedMessagePlugin;
CannedMessageModule *cannedMessageModule;
// TODO: move it into NodeDB.h!
extern bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct);
extern bool saveProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, const void *dest_struct);
CannedMessagePlugin::CannedMessagePlugin()
CannedMessageModule::CannedMessageModule()
: SinglePortPlugin("canned", PortNum_TEXT_MESSAGE_APP),
concurrency::OSThread("CannedMessagePlugin")
concurrency::OSThread("CannedMessageModule")
{
if (radioConfig.preferences.canned_message_plugin_enabled)
if (radioConfig.preferences.canned_message_module_enabled)
{
this->loadProtoForPlugin();
this->loadProtoForModule();
if(this->splitConfiguredMessages() <= 0)
{
DEBUG_MSG("CannedMessagePlugin: No messages are configured. Plugin is disabled\n");
DEBUG_MSG("CannedMessageModule: No messages are configured. Module is disabled\n");
this->runState = CANNED_MESSAGE_RUN_STATE_DISABLED;
}
else
{
DEBUG_MSG("CannedMessagePlugin is enabled\n");
DEBUG_MSG("CannedMessageModule is enabled\n");
this->inputObserver.observe(inputBroker);
}
}
@ -48,7 +48,7 @@ CannedMessagePlugin::CannedMessagePlugin()
*
* @return int Returns the number of messages found.
*/
int CannedMessagePlugin::splitConfiguredMessages()
int CannedMessageModule::splitConfiguredMessages()
{
int messageIndex = 0;
int i = 0;
@ -56,16 +56,16 @@ int CannedMessagePlugin::splitConfiguredMessages()
// collect all the message parts
strcpy(
this->messageStore,
cannedMessagePluginConfig.messagesPart1);
cannedMessageModuleConfig.messagesPart1);
strcat(
this->messageStore,
cannedMessagePluginConfig.messagesPart2);
cannedMessageModuleConfig.messagesPart2);
strcat(
this->messageStore,
cannedMessagePluginConfig.messagesPart3);
cannedMessageModuleConfig.messagesPart3);
strcat(
this->messageStore,
cannedMessagePluginConfig.messagesPart4);
cannedMessageModuleConfig.messagesPart4);
// The first message points to the beginning of the store.
this->messages[messageIndex++] =
@ -83,7 +83,7 @@ int CannedMessagePlugin::splitConfiguredMessages()
messageIndex-1, this->messages[messageIndex-1]);
// hit our max messages, bail
if (messageIndex >= CANNED_MESSAGE_PLUGIN_MESSAGE_MAX_COUNT)
if (messageIndex >= CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT)
{
this->messagesCount = messageIndex;
return this->messagesCount;
@ -110,12 +110,12 @@ int CannedMessagePlugin::splitConfiguredMessages()
return this->messagesCount;
}
int CannedMessagePlugin::handleInputEvent(const InputEvent *event)
int CannedMessageModule::handleInputEvent(const InputEvent *event)
{
if (
(strlen(radioConfig.preferences.canned_message_plugin_allow_input_source) > 0) &&
(strcmp(radioConfig.preferences.canned_message_plugin_allow_input_source, event->source) != 0) &&
(strcmp(radioConfig.preferences.canned_message_plugin_allow_input_source, "_any") != 0))
(strlen(radioConfig.preferences.canned_message_module_allow_input_source) > 0) &&
(strcmp(radioConfig.preferences.canned_message_module_allow_input_source, event->source) != 0) &&
(strcmp(radioConfig.preferences.canned_message_module_allow_input_source, "_any") != 0))
{
// Event source is not accepted.
// Event only accepted if source matches the configured one, or
@ -153,7 +153,7 @@ int CannedMessagePlugin::handleInputEvent(const InputEvent *event)
return 0;
}
void CannedMessagePlugin::sendText(NodeNum dest,
void CannedMessageModule::sendText(NodeNum dest,
const char* message,
bool wantReplies)
{
@ -162,7 +162,7 @@ void CannedMessagePlugin::sendText(NodeNum dest,
p->want_ack = true;
p->decoded.payload.size = strlen(message);
memcpy(p->decoded.payload.bytes, message, p->decoded.payload.size);
if (radioConfig.preferences.canned_message_plugin_send_bell)
if (radioConfig.preferences.canned_message_module_send_bell)
{
p->decoded.payload.bytes[p->decoded.payload.size-1] = 7; // Bell character
p->decoded.payload.bytes[p->decoded.payload.size] = '\0'; // Bell character
@ -175,9 +175,9 @@ void CannedMessagePlugin::sendText(NodeNum dest,
service.sendToMesh(p);
}
int32_t CannedMessagePlugin::runOnce()
int32_t CannedMessageModule::runOnce()
{
if ((!radioConfig.preferences.canned_message_plugin_enabled)
if ((!radioConfig.preferences.canned_message_module_enabled)
|| (this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED)
|| (this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE))
{
@ -197,7 +197,7 @@ int32_t CannedMessagePlugin::runOnce()
(this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE)
&& (millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS)
{
// Reset plugin
// Reset module
DEBUG_MSG("Reset due the lack of activity.\n");
e.frameChanged = true;
this->currentMessageIndex = -1;
@ -245,28 +245,28 @@ int32_t CannedMessagePlugin::runOnce()
return 30000; // TODO: should return MAX_VAL
}
const char* CannedMessagePlugin::getCurrentMessage()
const char* CannedMessageModule::getCurrentMessage()
{
return this->messages[this->currentMessageIndex];
}
const char* CannedMessagePlugin::getPrevMessage()
const char* CannedMessageModule::getPrevMessage()
{
return this->messages[this->getPrevIndex()];
}
const char* CannedMessagePlugin::getNextMessage()
const char* CannedMessageModule::getNextMessage()
{
return this->messages[this->getNextIndex()];
}
bool CannedMessagePlugin::shouldDraw()
bool CannedMessageModule::shouldDraw()
{
if (!radioConfig.preferences.canned_message_plugin_enabled)
if (!radioConfig.preferences.canned_message_module_enabled)
{
return false;
}
return (currentMessageIndex != -1) || (this->runState != CANNED_MESSAGE_RUN_STATE_INACTIVE);
}
int CannedMessagePlugin::getNextIndex()
int CannedMessageModule::getNextIndex()
{
if (this->currentMessageIndex >= (this->messagesCount -1))
{
@ -278,7 +278,7 @@ int CannedMessagePlugin::getNextIndex()
}
}
int CannedMessagePlugin::getPrevIndex()
int CannedMessageModule::getPrevIndex()
{
if (this->currentMessageIndex <= 0)
{
@ -290,12 +290,12 @@ int CannedMessagePlugin::getPrevIndex()
}
}
void CannedMessagePlugin::drawFrame(
void CannedMessageModule::drawFrame(
OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
displayedNodeNum = 0; // Not currently showing a node pane
if (cannedMessagePlugin->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE)
if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE)
{
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_MEDIUM);
@ -305,28 +305,28 @@ void CannedMessagePlugin::drawFrame(
{
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL);
display->drawString(0 + x, 0 + y, cannedMessagePlugin->getPrevMessage());
display->drawString(0 + x, 0 + y, cannedMessageModule->getPrevMessage());
display->setFont(FONT_MEDIUM);
display->drawString(0 + x, 0 + y + 8, cannedMessagePlugin->getCurrentMessage());
display->drawString(0 + x, 0 + y + 8, cannedMessageModule->getCurrentMessage());
display->setFont(FONT_SMALL);
display->drawString(0 + x, 0 + y + 24, cannedMessagePlugin->getNextMessage());
display->drawString(0 + x, 0 + y + 24, cannedMessageModule->getNextMessage());
}
}
void CannedMessagePlugin::loadProtoForPlugin()
void CannedMessageModule::loadProtoForModule()
{
if (!loadProto(cannedMessagesConfigFile, CannedMessagePluginConfig_size, sizeof(cannedMessagesConfigFile), CannedMessagePluginConfig_fields, &cannedMessagePluginConfig)) {
installDefaultCannedMessagePluginConfig();
if (!loadProto(cannedMessagesConfigFile, CannedMessageModuleConfig_size, sizeof(cannedMessagesConfigFile), CannedMessageModuleConfig_fields, &cannedMessageModuleConfig)) {
installDefaultCannedMessageModuleConfig();
}
}
/**
* @brief Save the plugin config to file.
* @brief Save the module config to file.
*
* @return true On success.
* @return false On error.
*/
bool CannedMessagePlugin::saveProtoForPlugin()
bool CannedMessageModule::saveProtoForModule()
{
bool okay = true;
@ -334,7 +334,7 @@ bool CannedMessagePlugin::saveProtoForPlugin()
FS.mkdir("/prefs");
#endif
okay &= saveProto(cannedMessagesConfigFile, CannedMessagePluginConfig_size, sizeof(CannedMessagePluginConfig), CannedMessagePluginConfig_fields, &cannedMessagePluginConfig);
okay &= saveProto(cannedMessagesConfigFile, CannedMessageModuleConfig_size, sizeof(CannedMessageModuleConfig), CannedMessageModuleConfig_fields, &cannedMessageModuleConfig);
return okay;
}
@ -342,16 +342,16 @@ bool CannedMessagePlugin::saveProtoForPlugin()
/**
* @brief Fill configuration with default values.
*/
void CannedMessagePlugin::installDefaultCannedMessagePluginConfig()
void CannedMessageModule::installDefaultCannedMessageModuleConfig()
{
memset(cannedMessagePluginConfig.messagesPart1, 0, sizeof(cannedMessagePluginConfig.messagesPart1));
memset(cannedMessagePluginConfig.messagesPart2, 0, sizeof(cannedMessagePluginConfig.messagesPart2));
memset(cannedMessagePluginConfig.messagesPart3, 0, sizeof(cannedMessagePluginConfig.messagesPart3));
memset(cannedMessagePluginConfig.messagesPart4, 0, sizeof(cannedMessagePluginConfig.messagesPart4));
memset(cannedMessageModuleConfig.messagesPart1, 0, sizeof(cannedMessageModuleConfig.messagesPart1));
memset(cannedMessageModuleConfig.messagesPart2, 0, sizeof(cannedMessageModuleConfig.messagesPart2));
memset(cannedMessageModuleConfig.messagesPart3, 0, sizeof(cannedMessageModuleConfig.messagesPart3));
memset(cannedMessageModuleConfig.messagesPart4, 0, sizeof(cannedMessageModuleConfig.messagesPart4));
}
/**
* @brief An admin message arrived to AdminPlugin. We are asked whether we want to handle that.
* @brief An admin message arrived to AdminModule. We are asked whether we want to handle that.
*
* @param mp The mesh packet arrived.
* @param request The AdminMessage request extracted from the packet.
@ -359,61 +359,61 @@ void CannedMessagePlugin::installDefaultCannedMessagePluginConfig()
* @return AdminMessageHandleResult HANDLED if message was handled
* HANDLED_WITH_RESULT if a result is also prepared.
*/
AdminMessageHandleResult CannedMessagePlugin::handleAdminMessageForPlugin(
AdminMessageHandleResult CannedMessageModule::handleAdminMessageForModule(
const MeshPacket &mp, AdminMessage *request, AdminMessage *response)
{
AdminMessageHandleResult result;
switch (request->which_variant) {
case AdminMessage_get_canned_message_plugin_part1_request_tag:
case AdminMessage_get_canned_message_module_part1_request_tag:
DEBUG_MSG("Client is getting radio canned message part1\n");
this->handleGetCannedMessagePluginPart1(mp, response);
this->handleGetCannedMessageModulePart1(mp, response);
result = AdminMessageHandleResult::HANDLED_WITH_RESPONSE;
break;
case AdminMessage_get_canned_message_plugin_part2_request_tag:
case AdminMessage_get_canned_message_module_part2_request_tag:
DEBUG_MSG("Client is getting radio canned message part2\n");
this->handleGetCannedMessagePluginPart2(mp, response);
this->handleGetCannedMessageModulePart2(mp, response);
result = AdminMessageHandleResult::HANDLED_WITH_RESPONSE;
break;
case AdminMessage_get_canned_message_plugin_part3_request_tag:
case AdminMessage_get_canned_message_module_part3_request_tag:
DEBUG_MSG("Client is getting radio canned message part3\n");
this->handleGetCannedMessagePluginPart3(mp, response);
this->handleGetCannedMessageModulePart3(mp, response);
result = AdminMessageHandleResult::HANDLED_WITH_RESPONSE;
break;
case AdminMessage_get_canned_message_plugin_part4_request_tag:
case AdminMessage_get_canned_message_module_part4_request_tag:
DEBUG_MSG("Client is getting radio canned message part4\n");
this->handleGetCannedMessagePluginPart4(mp, response);
this->handleGetCannedMessageModulePart4(mp, response);
result = AdminMessageHandleResult::HANDLED_WITH_RESPONSE;
break;
case AdminMessage_set_canned_message_plugin_part1_tag:
case AdminMessage_set_canned_message_module_part1_tag:
DEBUG_MSG("Client is setting radio canned message part 1\n");
this->handleSetCannedMessagePluginPart1(
request->set_canned_message_plugin_part1);
this->handleSetCannedMessageModulePart1(
request->set_canned_message_module_part1);
result = AdminMessageHandleResult::HANDLED;
break;
case AdminMessage_set_canned_message_plugin_part2_tag:
case AdminMessage_set_canned_message_module_part2_tag:
DEBUG_MSG("Client is setting radio canned message part 2\n");
this->handleSetCannedMessagePluginPart2(
request->set_canned_message_plugin_part2);
this->handleSetCannedMessageModulePart2(
request->set_canned_message_module_part2);
result = AdminMessageHandleResult::HANDLED;
break;
case AdminMessage_set_canned_message_plugin_part3_tag:
case AdminMessage_set_canned_message_module_part3_tag:
DEBUG_MSG("Client is setting radio canned message part 3\n");
this->handleSetCannedMessagePluginPart3(
request->set_canned_message_plugin_part3);
this->handleSetCannedMessageModulePart3(
request->set_canned_message_module_part3);
result = AdminMessageHandleResult::HANDLED;
break;
case AdminMessage_set_canned_message_plugin_part4_tag:
case AdminMessage_set_canned_message_module_part4_tag:
DEBUG_MSG("Client is setting radio canned message part 4\n");
this->handleSetCannedMessagePluginPart4(
request->set_canned_message_plugin_part4);
this->handleSetCannedMessageModulePart4(
request->set_canned_message_module_part4);
result = AdminMessageHandleResult::HANDLED;
break;
@ -424,115 +424,115 @@ AdminMessageHandleResult CannedMessagePlugin::handleAdminMessageForPlugin(
return result;
}
void CannedMessagePlugin::handleGetCannedMessagePluginPart1(
void CannedMessageModule::handleGetCannedMessageModulePart1(
const MeshPacket &req, AdminMessage *response)
{
DEBUG_MSG("*** handleGetCannedMessagePluginPart1\n");
DEBUG_MSG("*** handleGetCannedMessageModulePart1\n");
assert(req.decoded.want_response);
response->which_variant = AdminMessage_get_canned_message_plugin_part1_response_tag;
response->which_variant = AdminMessage_get_canned_message_module_part1_response_tag;
strcpy(
response->get_canned_message_plugin_part1_response,
cannedMessagePluginConfig.messagesPart1);
response->get_canned_message_module_part1_response,
cannedMessageModuleConfig.messagesPart1);
}
void CannedMessagePlugin::handleGetCannedMessagePluginPart2(
void CannedMessageModule::handleGetCannedMessageModulePart2(
const MeshPacket &req, AdminMessage *response)
{
DEBUG_MSG("*** handleGetCannedMessagePluginPart2\n");
DEBUG_MSG("*** handleGetCannedMessageModulePart2\n");
assert(req.decoded.want_response);
response->which_variant = AdminMessage_get_canned_message_plugin_part2_response_tag;
response->which_variant = AdminMessage_get_canned_message_module_part2_response_tag;
strcpy(
response->get_canned_message_plugin_part2_response,
cannedMessagePluginConfig.messagesPart2);
response->get_canned_message_module_part2_response,
cannedMessageModuleConfig.messagesPart2);
}
void CannedMessagePlugin::handleGetCannedMessagePluginPart3(
void CannedMessageModule::handleGetCannedMessageModulePart3(
const MeshPacket &req, AdminMessage *response)
{
DEBUG_MSG("*** handleGetCannedMessagePluginPart3\n");
DEBUG_MSG("*** handleGetCannedMessageModulePart3\n");
assert(req.decoded.want_response);
response->which_variant = AdminMessage_get_canned_message_plugin_part3_response_tag;
response->which_variant = AdminMessage_get_canned_message_module_part3_response_tag;
strcpy(
response->get_canned_message_plugin_part3_response,
cannedMessagePluginConfig.messagesPart3);
response->get_canned_message_module_part3_response,
cannedMessageModuleConfig.messagesPart3);
}
void CannedMessagePlugin::handleGetCannedMessagePluginPart4(
void CannedMessageModule::handleGetCannedMessageModulePart4(
const MeshPacket &req, AdminMessage *response)
{
DEBUG_MSG("*** handleGetCannedMessagePluginPart4\n");
DEBUG_MSG("*** handleGetCannedMessageModulePart4\n");
assert(req.decoded.want_response);
response->which_variant = AdminMessage_get_canned_message_plugin_part4_response_tag;
response->which_variant = AdminMessage_get_canned_message_module_part4_response_tag;
strcpy(
response->get_canned_message_plugin_part4_response,
cannedMessagePluginConfig.messagesPart4);
response->get_canned_message_module_part4_response,
cannedMessageModuleConfig.messagesPart4);
}
void CannedMessagePlugin::handleSetCannedMessagePluginPart1(const char *from_msg)
void CannedMessageModule::handleSetCannedMessageModulePart1(const char *from_msg)
{
int changed = 0;
if (*from_msg)
{
changed |= strcmp(cannedMessagePluginConfig.messagesPart1, from_msg);
strcpy(cannedMessagePluginConfig.messagesPart1, from_msg);
changed |= strcmp(cannedMessageModuleConfig.messagesPart1, from_msg);
strcpy(cannedMessageModuleConfig.messagesPart1, from_msg);
DEBUG_MSG("*** from_msg.text:%s\n", from_msg);
}
if (changed)
{
this->saveProtoForPlugin();
this->saveProtoForModule();
}
}
void CannedMessagePlugin::handleSetCannedMessagePluginPart2(const char *from_msg)
void CannedMessageModule::handleSetCannedMessageModulePart2(const char *from_msg)
{
int changed = 0;
if (*from_msg)
{
changed |= strcmp(cannedMessagePluginConfig.messagesPart2, from_msg);
strcpy(cannedMessagePluginConfig.messagesPart2, from_msg);
changed |= strcmp(cannedMessageModuleConfig.messagesPart2, from_msg);
strcpy(cannedMessageModuleConfig.messagesPart2, from_msg);
}
if (changed)
{
this->saveProtoForPlugin();
this->saveProtoForModule();
}
}
void CannedMessagePlugin::handleSetCannedMessagePluginPart3(const char *from_msg)
void CannedMessageModule::handleSetCannedMessageModulePart3(const char *from_msg)
{
int changed = 0;
if (*from_msg)
{
changed |= strcmp(cannedMessagePluginConfig.messagesPart3, from_msg);
strcpy(cannedMessagePluginConfig.messagesPart3, from_msg);
changed |= strcmp(cannedMessageModuleConfig.messagesPart3, from_msg);
strcpy(cannedMessageModuleConfig.messagesPart3, from_msg);
}
if (changed)
{
this->saveProtoForPlugin();
this->saveProtoForModule();
}
}
void CannedMessagePlugin::handleSetCannedMessagePluginPart4(const char *from_msg)
void CannedMessageModule::handleSetCannedMessageModulePart4(const char *from_msg)
{
int changed = 0;
if (*from_msg)
{
changed |= strcmp(cannedMessagePluginConfig.messagesPart4, from_msg);
strcpy(cannedMessagePluginConfig.messagesPart4, from_msg);
changed |= strcmp(cannedMessageModuleConfig.messagesPart4, from_msg);
strcpy(cannedMessageModuleConfig.messagesPart4, from_msg);
}
if (changed)
{
this->saveProtoForPlugin();
this->saveProtoForModule();
}
}

Wyświetl plik

@ -2,7 +2,7 @@
#include "ProtobufPlugin.h"
#include "input/InputBroker.h"
enum cannedMessagePluginRunState
enum cannedMessageModuleRunState
{
CANNED_MESSAGE_RUN_STATE_DISABLED,
CANNED_MESSAGE_RUN_STATE_INACTIVE,
@ -14,22 +14,22 @@ enum cannedMessagePluginRunState
};
#define CANNED_MESSAGE_PLUGIN_MESSAGE_MAX_COUNT 50
#define CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT 50
/**
* Sum of CannedMessagePluginConfig part sizes.
* Sum of CannedMessageModuleConfig part sizes.
*/
#define CANNED_MESSAGE_PLUGIN_MESSAGES_SIZE 800
#define CANNED_MESSAGE_MODULE_MESSAGES_SIZE 800
class CannedMessagePlugin :
class CannedMessageModule :
public SinglePortPlugin,
public Observable<const UIFrameEvent *>,
private concurrency::OSThread
{
CallbackObserver<CannedMessagePlugin, const InputEvent *> inputObserver =
CallbackObserver<CannedMessagePlugin, const InputEvent *>(
this, &CannedMessagePlugin::handleInputEvent);
CallbackObserver<CannedMessageModule, const InputEvent *> inputObserver =
CallbackObserver<CannedMessageModule, const InputEvent *>(
this, &CannedMessageModule::handleInputEvent);
public:
CannedMessagePlugin();
CannedMessageModule();
const char* getCurrentMessage();
const char* getPrevMessage();
const char* getNextMessage();
@ -38,15 +38,15 @@ class CannedMessagePlugin :
void eventDown();
void eventSelect();
void handleGetCannedMessagePluginPart1(const MeshPacket &req, AdminMessage *response);
void handleGetCannedMessagePluginPart2(const MeshPacket &req, AdminMessage *response);
void handleGetCannedMessagePluginPart3(const MeshPacket &req, AdminMessage *response);
void handleGetCannedMessagePluginPart4(const MeshPacket &req, AdminMessage *response);
void handleGetCannedMessageModulePart1(const MeshPacket &req, AdminMessage *response);
void handleGetCannedMessageModulePart2(const MeshPacket &req, AdminMessage *response);
void handleGetCannedMessageModulePart3(const MeshPacket &req, AdminMessage *response);
void handleGetCannedMessageModulePart4(const MeshPacket &req, AdminMessage *response);
void handleSetCannedMessagePluginPart1(const char *from_msg);
void handleSetCannedMessagePluginPart2(const char *from_msg);
void handleSetCannedMessagePluginPart3(const char *from_msg);
void handleSetCannedMessagePluginPart4(const char *from_msg);
void handleSetCannedMessageModulePart1(const char *from_msg);
void handleSetCannedMessageModulePart2(const char *from_msg);
void handleSetCannedMessageModulePart3(const char *from_msg);
void handleSetCannedMessageModulePart4(const char *from_msg);
protected:
@ -66,21 +66,21 @@ class CannedMessagePlugin :
virtual Observable<const UIFrameEvent *>* getUIFrameObservable() override { return this; }
virtual void drawFrame(
OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) override;
virtual AdminMessageHandleResult handleAdminMessageForPlugin(
virtual AdminMessageHandleResult handleAdminMessageForModule(
const MeshPacket &mp, AdminMessage *request, AdminMessage *response) override;
void loadProtoForPlugin();
bool saveProtoForPlugin();
void loadProtoForModule();
bool saveProtoForModule();
void installDefaultCannedMessagePluginConfig();
void installDefaultCannedMessageModuleConfig();
int currentMessageIndex = -1;
cannedMessagePluginRunState runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
cannedMessageModuleRunState runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
char messageStore[CANNED_MESSAGE_PLUGIN_MESSAGES_SIZE+1];
char *messages[CANNED_MESSAGE_PLUGIN_MESSAGE_MAX_COUNT];
char messageStore[CANNED_MESSAGE_MODULE_MESSAGES_SIZE+1];
char *messages[CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT];
int messagesCount = 0;
unsigned long lastTouchMillis = 0;
};
extern CannedMessagePlugin *cannedMessagePlugin;
extern CannedMessageModule *cannedMessageModule;

Wyświetl plik

@ -0,0 +1,187 @@
#include "configuration.h"
#include "ExternalNotificationModule.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "RTC.h"
#include "Router.h"
#include <Arduino.h>
//#include <assert.h>
/*
Documentation:
https://github.com/meshtastic/Meshtastic-device/blob/master/docs/software/modules/ExternalNotificationModule.md
This module supports:
https://github.com/meshtastic/Meshtastic-device/issues/654
Quick reference:
radioConfig.preferences.ext_notification_module_enabled
0 = Disabled (Default)
1 = Enabled
radioConfig.preferences.ext_notification_module_active
0 = Active Low (Default)
1 = Active High
radioConfig.preferences.ext_notification_module_alert_message
0 = Disabled (Default)
1 = Alert when a text message comes
radioConfig.preferences.ext_notification_module_alert_bell
0 = Disabled (Default)
1 = Alert when the bell character is received
radioConfig.preferences.ext_notification_module_output
GPIO of the output. (Default = 13)
radioConfig.preferences.ext_notification_module_output_ms
Amount of time in ms for the alert. Default is 1000.
*/
// Default configurations
#define EXT_NOTIFICATION_MODULE_OUTPUT EXT_NOTIFY_OUT
#define EXT_NOTIFICATION_MODULE_OUTPUT_MS 1000
#define ASCII_BELL 0x07
bool externalCurrentState = 0;
uint32_t externalTurnedOn = 0;
int32_t ExternalNotificationModule::runOnce()
{
/*
Uncomment the preferences below if you want to use the module
without having to configure it from the PythonAPI or WebUI.
*/
// radioConfig.preferences.ext_notification_module_enabled = 1;
// radioConfig.preferences.ext_notification_module_alert_message = 1;
// radioConfig.preferences.ext_notification_module_active = 1;
// radioConfig.preferences.ext_notification_module_alert_bell = 1;
// radioConfig.preferences.ext_notification_module_output_ms = 1000;
// radioConfig.preferences.ext_notification_module_output = 13;
if (externalCurrentState) {
// If the output is turned on, turn it back off after the given period of time.
if (externalTurnedOn + (radioConfig.preferences.ext_notification_module_output_ms
? radioConfig.preferences.ext_notification_module_output_ms
: EXT_NOTIFICATION_MODULE_OUTPUT_MS) <
millis()) {
DEBUG_MSG("Turning off external notification\n");
setExternalOff();
}
}
return (25);
}
void ExternalNotificationModule::setExternalOn()
{
#ifdef EXT_NOTIFY_OUT
externalCurrentState = 1;
externalTurnedOn = millis();
digitalWrite((radioConfig.preferences.ext_notification_module_output ? radioConfig.preferences.ext_notification_module_output
: EXT_NOTIFICATION_MODULE_OUTPUT),
(radioConfig.preferences.ext_notification_module_active ? true : false));
#endif
}
void ExternalNotificationModule::setExternalOff()
{
#ifdef EXT_NOTIFY_OUT
externalCurrentState = 0;
digitalWrite((radioConfig.preferences.ext_notification_module_output ? radioConfig.preferences.ext_notification_module_output
: EXT_NOTIFICATION_MODULE_OUTPUT),
(radioConfig.preferences.ext_notification_module_active ? false : true));
#endif
}
// --------
ExternalNotificationModule::ExternalNotificationModule()
: SinglePortPlugin("ExternalNotificationModule", PortNum_TEXT_MESSAGE_APP), concurrency::OSThread(
"ExternalNotificationModule")
{
// restrict to the admin channel for rx
boundChannel = Channels::gpioChannel;
#ifndef NO_ESP32
#ifdef EXT_NOTIFY_OUT
/*
Uncomment the preferences below if you want to use the module
without having to configure it from the PythonAPI or WebUI.
*/
// radioConfig.preferences.ext_notification_module_enabled = 1;
// radioConfig.preferences.ext_notification_module_alert_message = 1;
// radioConfig.preferences.ext_notification_module_active = 1;
// radioConfig.preferences.ext_notification_module_alert_bell = 1;
// radioConfig.preferences.ext_notification_module_output_ms = 1000;
// radioConfig.preferences.ext_notification_module_output = 13;
if (radioConfig.preferences.ext_notification_module_enabled) {
DEBUG_MSG("Initializing External Notification Module\n");
// Set the direction of a pin
pinMode((radioConfig.preferences.ext_notification_module_output ? radioConfig.preferences.ext_notification_module_output
: EXT_NOTIFICATION_MODULE_OUTPUT),
OUTPUT);
// Turn off the pin
setExternalOff();
} else {
DEBUG_MSG("External Notification Module Disabled\n");
enabled = false;
}
#endif
#endif
}
ProcessMessage ExternalNotificationModule::handleReceived(const MeshPacket &mp)
{
#ifndef NO_ESP32
#ifdef EXT_NOTIFY_OUT
if (radioConfig.preferences.ext_notification_module_enabled) {
if (getFrom(&mp) != nodeDB.getNodeNum()) {
// TODO: This may be a problem if messages are sent in unicide, but I'm not sure if it will.
// Need to know if and how this could be a problem.
if (radioConfig.preferences.ext_notification_module_alert_bell) {
auto &p = mp.decoded;
DEBUG_MSG("externalNotificationModule - Notification Bell\n");
for (int i = 0; i < p.payload.size; i++) {
if (p.payload.bytes[i] == ASCII_BELL) {
setExternalOn();
}
}
}
if (radioConfig.preferences.ext_notification_module_alert_message) {
DEBUG_MSG("externalNotificationModule - Notification Module\n");
setExternalOn();
}
}
} else {
DEBUG_MSG("External Notification Module Disabled\n");
}
#endif
#endif
return ProcessMessage::CONTINUE; // Let others look at this message also if they want
}

Wyświetl plik

@ -7,13 +7,13 @@
#include <functional>
/*
* Radio interface for ExternalNotificationPlugin
* Radio interface for ExternalNotificationModule
*
*/
class ExternalNotificationPlugin : public SinglePortPlugin, private concurrency::OSThread
class ExternalNotificationModule : public SinglePortPlugin, private concurrency::OSThread
{
public:
ExternalNotificationPlugin();
ExternalNotificationModule();
void setExternalOn();
void setExternalOff();

Wyświetl plik

@ -0,0 +1,10 @@
#pragma once
/*
* To developers:
* Use this to enable / disable features in your module that you don't want to risk checking into GitHub.
*
*/
// Enable development more for StoreForwardModule
bool StoreForward_Dev = false;

Wyświetl plik

@ -0,0 +1,60 @@
#include "configuration.h"
#include "input/InputBroker.h"
#include "input/RotaryEncoderInterruptImpl1.h"
#include "modules/AdminModule.h"
#include "modules/CannedMessageModule.h"
#include "modules/ExternalNotificationModule.h"
#include "modules/NodeInfoModule.h"
#include "modules/PositionModule.h"
#include "modules/RemoteHardwareModule.h"
#include "modules/ReplyModule.h"
#include "modules/RoutingModule.h"
#include "modules/TextMessageModule.h"
#ifndef PORTDUINO
#include "modules/Telemetry/Telemetry.h"
#endif
#ifndef NO_ESP32
#include "modules/esp32/RangeTestModule.h"
#include "modules/esp32/SerialModule.h"
#include "modules/esp32/StoreForwardModule.h"
#endif
/**
* Create module instances here. If you are adding a new module, you must 'new' it here (or somewhere else)
*/
void setupModules()
{
inputBroker = new InputBroker();
adminModule = new AdminModule();
nodeInfoModule = new NodeInfoModule();
positionModule = new PositionModule();
textMessageModule = new TextMessageModule();
// Note: if the rest of meshtastic doesn't need to explicitly use your module, you do not need to assign the instance
// to a global variable.
new RemoteHardwareModule();
new ReplyModule();
rotaryEncoderInterruptImpl1 = new RotaryEncoderInterruptImpl1();
rotaryEncoderInterruptImpl1->init();
cannedMessageModule = new CannedMessageModule();
#ifndef PORTDUINO
new TelemetryModule();
#endif
#ifndef NO_ESP32
// Only run on an esp32 based device.
/*
Maintained by MC Hamster (Jm Casler) jm@casler.org
*/
new SerialModule();
new ExternalNotificationModule();
storeForwardModule = new StoreForwardModule();
new RangeTestModule();
#endif
// NOTE! This module must be added LAST because it likes to check for replies from other modules and avoid sending extra acks
routingModule = new RoutingModule();
}

Wyświetl plik

@ -0,0 +1,6 @@
#pragma once
/**
* Create module instances here. If you are adding a new module, you must 'new' it here (or somewhere else)
*/
void setupModules();

Wyświetl plik

@ -1,14 +1,14 @@
#include "configuration.h"
#include "NodeInfoPlugin.h"
#include "NodeInfoModule.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "RTC.h"
#include "Router.h"
#include "main.h"
NodeInfoPlugin *nodeInfoPlugin;
NodeInfoModule *nodeInfoModule;
bool NodeInfoPlugin::handleReceivedProtobuf(const MeshPacket &mp, User *pptr)
bool NodeInfoModule::handleReceivedProtobuf(const MeshPacket &mp, User *pptr)
{
auto p = *pptr;
@ -27,7 +27,7 @@ bool NodeInfoPlugin::handleReceivedProtobuf(const MeshPacket &mp, User *pptr)
return false; // Let others look at this message also if they want
}
void NodeInfoPlugin::sendOurNodeInfo(NodeNum dest, bool wantReplies)
void NodeInfoModule::sendOurNodeInfo(NodeNum dest, bool wantReplies)
{
// cancel any not yet sent (now stale) position packets
if (prevPacketId) // if we wrap around to zero, we'll simply fail to cancel in that rare case (no big deal)
@ -42,7 +42,7 @@ void NodeInfoPlugin::sendOurNodeInfo(NodeNum dest, bool wantReplies)
service.sendToMesh(p);
}
MeshPacket *NodeInfoPlugin::allocReply()
MeshPacket *NodeInfoModule::allocReply()
{
User &u = owner;
@ -50,15 +50,15 @@ MeshPacket *NodeInfoPlugin::allocReply()
return allocDataProtobuf(u);
}
NodeInfoPlugin::NodeInfoPlugin()
: ProtobufPlugin("nodeinfo", PortNum_NODEINFO_APP, User_fields), concurrency::OSThread("NodeInfoPlugin")
NodeInfoModule::NodeInfoModule()
: ProtobufPlugin("nodeinfo", PortNum_NODEINFO_APP, User_fields), concurrency::OSThread("NodeInfoModule")
{
isPromiscuous = true; // We always want to update our nodedb, even if we are sniffing on others
setIntervalFromNow(30 *
1000); // Send our initial owner announcement 30 seconds after we start (to give network time to setup)
}
int32_t NodeInfoPlugin::runOnce()
int32_t NodeInfoModule::runOnce()
{
static uint32_t currentGeneration;

Wyświetl plik

@ -2,9 +2,9 @@
#include "ProtobufPlugin.h"
/**
* NodeInfo plugin for sending/receiving NodeInfos into the mesh
* NodeInfo module for sending/receiving NodeInfos into the mesh
*/
class NodeInfoPlugin : public ProtobufPlugin<User>, private concurrency::OSThread
class NodeInfoModule : public ProtobufPlugin<User>, private concurrency::OSThread
{
/// The id of the last packet we sent, to allow us to cancel it if we make something fresher
PacketId prevPacketId = 0;
@ -14,7 +14,7 @@ class NodeInfoPlugin : public ProtobufPlugin<User>, private concurrency::OSThrea
/** Constructor
* name is for debugging output
*/
NodeInfoPlugin();
NodeInfoModule();
/**
* Send our NodeInfo into the mesh
@ -36,4 +36,4 @@ class NodeInfoPlugin : public ProtobufPlugin<User>, private concurrency::OSThrea
virtual int32_t runOnce() override;
};
extern NodeInfoPlugin *nodeInfoPlugin;
extern NodeInfoModule *nodeInfoModule;

Wyświetl plik

@ -1,4 +1,4 @@
#include "PositionPlugin.h"
#include "PositionModule.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "RTC.h"
@ -7,16 +7,16 @@
#include "configuration.h"
#include "gps/GeoCoord.h"
PositionPlugin *positionPlugin;
PositionModule *positionModule;
PositionPlugin::PositionPlugin()
: ProtobufPlugin("position", PortNum_POSITION_APP, Position_fields), concurrency::OSThread("PositionPlugin")
PositionModule::PositionModule()
: ProtobufPlugin("position", PortNum_POSITION_APP, Position_fields), concurrency::OSThread("PositionModule")
{
isPromiscuous = true; // We always want to update our nodedb, even if we are sniffing on others
setIntervalFromNow(60 * 1000); // Send our initial position 60 seconds after we start (to give GPS time to setup)
}
bool PositionPlugin::handleReceivedProtobuf(const MeshPacket &mp, Position *pptr)
bool PositionModule::handleReceivedProtobuf(const MeshPacket &mp, Position *pptr)
{
auto p = *pptr;
@ -53,7 +53,7 @@ bool PositionPlugin::handleReceivedProtobuf(const MeshPacket &mp, Position *pptr
return false; // Let others look at this message also if they want
}
MeshPacket *PositionPlugin::allocReply()
MeshPacket *PositionModule::allocReply()
{
NodeInfo *node = service.refreshMyNodeInfo(); // should guarantee there is now a position
assert(node->has_position);
@ -109,7 +109,7 @@ MeshPacket *PositionPlugin::allocReply()
return allocDataProtobuf(p);
}
void PositionPlugin::sendOurPosition(NodeNum dest, bool wantReplies)
void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies)
{
// cancel any not yet sent (now stale) position packets
if (prevPacketId) // if we wrap around to zero, we'll simply fail to cancel in that rare case (no big deal)
@ -124,7 +124,7 @@ void PositionPlugin::sendOurPosition(NodeNum dest, bool wantReplies)
service.sendToMesh(p);
}
int32_t PositionPlugin::runOnce()
int32_t PositionModule::runOnce()
{
NodeInfo *node = nodeDB.getNode(nodeDB.getNodeNum());

Wyświetl plik

@ -3,9 +3,9 @@
#include "concurrency/OSThread.h"
/**
* Position plugin for sending/receiving positions into the mesh
* Position module for sending/receiving positions into the mesh
*/
class PositionPlugin : public ProtobufPlugin<Position>, private concurrency::OSThread
class PositionModule : public ProtobufPlugin<Position>, private concurrency::OSThread
{
/// The id of the last packet we sent, to allow us to cancel it if we make something fresher
PacketId prevPacketId = 0;
@ -24,7 +24,7 @@ class PositionPlugin : public ProtobufPlugin<Position>, private concurrency::OST
/** Constructor
* name is for debugging output
*/
PositionPlugin();
PositionModule();
/**
* Send our position into the mesh
@ -47,4 +47,4 @@ class PositionPlugin : public ProtobufPlugin<Position>, private concurrency::OST
virtual int32_t runOnce() override;
};
extern PositionPlugin *positionPlugin;
extern PositionModule *positionModule;

Wyświetl plik

@ -1,5 +1,5 @@
#include "configuration.h"
#include "RemoteHardwarePlugin.h"
#include "RemoteHardwareModule.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "RTC.h"
@ -46,13 +46,13 @@ static uint64_t digitalReads(uint64_t mask)
return res;
}
RemoteHardwarePlugin::RemoteHardwarePlugin()
RemoteHardwareModule::RemoteHardwareModule()
: ProtobufPlugin("remotehardware", PortNum_REMOTE_HARDWARE_APP, HardwareMessage_fields), concurrency::OSThread(
"remotehardware")
{
}
bool RemoteHardwarePlugin::handleReceivedProtobuf(const MeshPacket &req, HardwareMessage *pptr)
bool RemoteHardwareModule::handleReceivedProtobuf(const MeshPacket &req, HardwareMessage *pptr)
{
auto p = *pptr;
DEBUG_MSG("Received RemoteHardware typ=%d\n", p.typ);
@ -111,7 +111,7 @@ bool RemoteHardwarePlugin::handleReceivedProtobuf(const MeshPacket &req, Hardwar
return false;
}
int32_t RemoteHardwarePlugin::runOnce()
int32_t RemoteHardwareModule::runOnce()
{
if (watchGpios) {
uint32_t now = millis();

Wyświetl plik

@ -4,9 +4,9 @@
#include "concurrency/OSThread.h"
/**
* A plugin that provides easy low-level remote access to device hardware.
* A module that provides easy low-level remote access to device hardware.
*/
class RemoteHardwarePlugin : public ProtobufPlugin<HardwareMessage>, private concurrency::OSThread
class RemoteHardwareModule : public ProtobufPlugin<HardwareMessage>, private concurrency::OSThread
{
/// The current set of GPIOs we've been asked to watch for changes
uint64_t watchGpios = 0;
@ -20,7 +20,7 @@ class RemoteHardwarePlugin : public ProtobufPlugin<HardwareMessage>, private con
/** Constructor
* name is for debugging output
*/
RemoteHardwarePlugin();
RemoteHardwareModule();
protected:
/** Called to handle a particular incoming message
@ -40,4 +40,4 @@ class RemoteHardwarePlugin : public ProtobufPlugin<HardwareMessage>, private con
virtual int32_t runOnce() override;
};
extern RemoteHardwarePlugin remoteHardwarePlugin;
extern RemoteHardwareModule remoteHardwareModule;

Wyświetl plik

@ -1,11 +1,11 @@
#include "configuration.h"
#include "ReplyPlugin.h"
#include "ReplyModule.h"
#include "MeshService.h"
#include "main.h"
#include <assert.h>
MeshPacket *ReplyPlugin::allocReply()
MeshPacket *ReplyModule::allocReply()
{
assert(currentRequest); // should always be !NULL
auto req = *currentRequest;

Wyświetl plik

@ -3,19 +3,19 @@
/**
* A simple example plugin that just replies with "Message received" to any message it receives.
* A simple example module that just replies with "Message received" to any message it receives.
*/
class ReplyPlugin : public SinglePortPlugin
class ReplyModule : public SinglePortPlugin
{
public:
/** Constructor
* name is for debugging output
*/
ReplyPlugin() : SinglePortPlugin("reply", PortNum_REPLY_APP) {}
ReplyModule() : SinglePortPlugin("reply", PortNum_REPLY_APP) {}
protected:
/** For reply plugin we do all of our processing in the (normally optional)
/** For reply module we do all of our processing in the (normally optional)
* want_replies handling
*/
virtual MeshPacket *allocReply() override;

Wyświetl plik

@ -1,18 +1,18 @@
#include "configuration.h"
#include "RoutingPlugin.h"
#include "RoutingModule.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "Router.h"
#include "main.h"
RoutingPlugin *routingPlugin;
RoutingModule *routingModule;
bool RoutingPlugin::handleReceivedProtobuf(const MeshPacket &mp, Routing *r)
bool RoutingModule::handleReceivedProtobuf(const MeshPacket &mp, Routing *r)
{
printPacket("Routing sniffing", &mp);
router->sniffReceived(&mp, r);
// FIXME - move this to a non promsicious PhoneAPI plugin?
// FIXME - move this to a non promsicious PhoneAPI module?
// Note: we are careful not to send back packets that started with the phone back to the phone
if ((mp.to == NODENUM_BROADCAST || mp.to == nodeDB.getNodeNum()) && (mp.from != 0)) {
printPacket("Delivering rx packet", &mp);
@ -22,7 +22,7 @@ bool RoutingPlugin::handleReceivedProtobuf(const MeshPacket &mp, Routing *r)
return false; // Let others look at this message also if they want
}
MeshPacket *RoutingPlugin::allocReply()
MeshPacket *RoutingModule::allocReply()
{
assert(currentRequest);
@ -34,14 +34,14 @@ MeshPacket *RoutingPlugin::allocReply()
return NULL;
}
void RoutingPlugin::sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex)
void RoutingModule::sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex)
{
auto p = allocAckNak(err, to, idFrom, chIndex);
router->sendLocal(p); // we sometimes send directly to the local node
}
RoutingPlugin::RoutingPlugin() : ProtobufPlugin("routing", PortNum_ROUTING_APP, Routing_fields)
RoutingModule::RoutingModule() : ProtobufPlugin("routing", PortNum_ROUTING_APP, Routing_fields)
{
isPromiscuous = true;
}

Wyświetl plik

@ -3,15 +3,15 @@
#include "Channels.h"
/**
* Routing plugin for router control messages
* Routing module for router control messages
*/
class RoutingPlugin : public ProtobufPlugin<Routing>
class RoutingModule : public ProtobufPlugin<Routing>
{
public:
/** Constructor
* name is for debugging output
*/
RoutingPlugin();
RoutingModule();
void sendAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex);
@ -32,4 +32,4 @@ class RoutingPlugin : public ProtobufPlugin<Routing>
virtual bool wantPacket(const MeshPacket *p) override { return true; }
};
extern RoutingPlugin *routingPlugin;
extern RoutingModule *routingModule;

Wyświetl plik

@ -1,10 +1,10 @@
#include "../mesh/generated/environmental_measurement.pb.h"
#include "../mesh/generated/telemetry.pb.h"
#include "configuration.h"
#include "EnvironmentalMeasurementSensor.h"
#include "TelemetrySensor.h"
#include "BME280Sensor.h"
#include <Adafruit_BME280.h>
BME280Sensor::BME280Sensor() : EnvironmentalMeasurementSensor {} {
BME280Sensor::BME280Sensor() : TelemetrySensor {} {
}
int32_t BME280Sensor::runOnce() {
@ -15,12 +15,12 @@ int32_t BME280Sensor::runOnce() {
DEBUG_MSG("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
// TODO more verbose diagnostics
} else {
DEBUG_MSG("EnvironmentalMeasurement: Opened BME280 on default i2c bus");
DEBUG_MSG("Telemetry: Opened BME280 on default i2c bus");
}
return BME_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
bool BME280Sensor::getMeasurement(EnvironmentalMeasurement *measurement) {
bool BME280Sensor::getMeasurement(Telemetry *measurement) {
measurement->temperature = bme280.readTemperature();
measurement->relative_humidity = bme280.readHumidity();
measurement->barometric_pressure = bme280.readPressure() / 100.0F;

Wyświetl plik

@ -0,0 +1,15 @@
#include "../mesh/generated/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <Adafruit_BME280.h>
#define BME_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class BME280Sensor : virtual public TelemetrySensor {
private:
Adafruit_BME280 bme280;
public:
BME280Sensor();
virtual int32_t runOnce() override;
virtual bool getMeasurement(Telemetry *measurement) override;
};

Wyświetl plik

@ -1,10 +1,10 @@
#include "../mesh/generated/environmental_measurement.pb.h"
#include "../mesh/generated/telemetry.pb.h"
#include "configuration.h"
#include "EnvironmentalMeasurementSensor.h"
#include "TelemetrySensor.h"
#include "BME680Sensor.h"
#include <Adafruit_BME680.h>
BME680Sensor::BME680Sensor() : EnvironmentalMeasurementSensor {} {
BME680Sensor::BME680Sensor() : TelemetrySensor {} {
}
int32_t BME680Sensor::runOnce() {
@ -13,9 +13,9 @@ int32_t BME680Sensor::runOnce() {
bme680Status = bme680.begin(0x76);
if (!bme680Status) {
DEBUG_MSG("Could not find a valid BME680 sensor, check wiring, address, sensor ID!");
// TODO more verbose diagnosticsEnvironmentalMeasurementSensor
// TODO more verbose TelemetrySensor
} else {
DEBUG_MSG("EnvironmentalMeasurement: Opened BME680 on default i2c bus");
DEBUG_MSG("Telemetry: Opened BME680 on default i2c bus");
// Set up oversampling and filter initialization
bme680.setTemperatureOversampling(BME680_OS_8X);
bme680.setHumidityOversampling(BME680_OS_2X);
@ -26,7 +26,7 @@ int32_t BME680Sensor::runOnce() {
return (BME_680_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
}
bool BME680Sensor::getMeasurement(EnvironmentalMeasurement *measurement) {
bool BME680Sensor::getMeasurement(Telemetry *measurement) {
measurement->temperature = bme680.readTemperature();
measurement->relative_humidity = bme680.readHumidity();
measurement->barometric_pressure = bme680.readPressure() / 100.0F;

Wyświetl plik

@ -0,0 +1,15 @@
#include "../mesh/generated/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <Adafruit_BME680.h>
#define BME_680_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class BME680Sensor : virtual public TelemetrySensor {
private:
Adafruit_BME680 bme680;
public:
BME680Sensor();
virtual int32_t runOnce() override;
virtual bool getMeasurement(Telemetry *measurement) override;
};

Wyświetl plik

@ -0,0 +1,36 @@
#include "../mesh/generated/telemetry.pb.h"
#include "configuration.h"
#include "MeshService.h"
#include "TelemetrySensor.h"
#include "DHTSensor.h"
#include <DHT.h>
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);
}
else {
dht = new DHT(radioConfig.preferences.telemetry_module_sensor_pin, DHT22);
}
dht->begin();
dht->read();
DEBUG_MSG("Telemetry: Opened DHT11/DHT12 on pin: %d\n",
radioConfig.preferences.telemetry_module_sensor_pin);
return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
}
bool DHTSensor::getMeasurement(Telemetry *measurement) {
if (!dht->read(true)) {
DEBUG_MSG("Telemetry: FAILED TO READ DATA\n");
return false;
}
measurement->relative_humidity = dht->readHumidity();
measurement->temperature = dht->readTemperature();
return true;
}

Wyświetl plik

@ -0,0 +1,15 @@
#include "../mesh/generated/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <DHT.h>
#define DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class DHTSensor : virtual public TelemetrySensor {
private:
DHT *dht = NULL;
public:
DHTSensor();
virtual int32_t runOnce() override;
virtual bool getMeasurement(Telemetry *measurement) override;
};

Wyświetl plik

@ -1,26 +1,26 @@
#include "../mesh/generated/environmental_measurement.pb.h"
#include "../mesh/generated/telemetry.pb.h"
#include "configuration.h"
#include "MeshService.h"
#include "EnvironmentalMeasurementSensor.h"
#include "TelemetrySensor.h"
#include "DallasSensor.h"
#include <DS18B20.h>
#include <OneWire.h>
DallasSensor::DallasSensor() : EnvironmentalMeasurementSensor {} {
DallasSensor::DallasSensor() : TelemetrySensor {} {
}
int32_t DallasSensor::runOnce() {
oneWire = new OneWire(radioConfig.preferences.environmental_measurement_plugin_sensor_pin);
oneWire = new OneWire(radioConfig.preferences.telemetry_module_sensor_pin);
ds18b20 = new DS18B20(oneWire);
ds18b20->begin();
ds18b20->setResolution(12);
ds18b20->requestTemperatures();
DEBUG_MSG("EnvironmentalMeasurement: Opened DS18B20 on pin: %d\n",
radioConfig.preferences.environmental_measurement_plugin_sensor_pin);
DEBUG_MSG("Telemetry: Opened DS18B20 on pin: %d\n",
radioConfig.preferences.telemetry_module_sensor_pin);
return (DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
}
bool DallasSensor::getMeasurement(EnvironmentalMeasurement *measurement) {
bool DallasSensor::getMeasurement(Telemetry *measurement) {
if (ds18b20->isConversionComplete()) {
measurement->temperature = ds18b20->getTempC();
measurement->relative_humidity = 0;

Wyświetl plik

@ -0,0 +1,17 @@
#include "../mesh/generated/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <DS18B20.h>
#include <OneWire.h>
#define DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class DallasSensor : virtual public TelemetrySensor {
private:
OneWire *oneWire = NULL;
DS18B20 *ds18b20 = NULL;
public:
DallasSensor();
virtual int32_t runOnce() override;
virtual bool getMeasurement(Telemetry *measurement) override;
};

Wyświetl plik

@ -1,10 +1,10 @@
#include "../mesh/generated/environmental_measurement.pb.h"
#include "../mesh/generated/telemetry.pb.h"
#include "configuration.h"
#include "EnvironmentalMeasurementSensor.h"
#include "TelemetrySensor.h"
#include "MCP9808Sensor.h"
#include <Adafruit_MCP9808.h>
MCP9808Sensor::MCP9808Sensor() : EnvironmentalMeasurementSensor {} {
MCP9808Sensor::MCP9808Sensor() : TelemetrySensor {} {
}
int32_t MCP9808Sensor::runOnce() {
@ -14,14 +14,14 @@ int32_t MCP9808Sensor::runOnce() {
if (!mcp9808Status) {
DEBUG_MSG("Could not find a valid MCP9808 sensor, check wiring, address, sensor ID!");
} else {
DEBUG_MSG("EnvironmentalMeasurement: Opened MCP9808 on default i2c bus");
DEBUG_MSG("TelemetrySensor: Opened MCP9808 on default i2c bus");
// Reduce resolution from 0.0625 degrees (precision) to 0.125 degrees (high).
mcp9808.setResolution(2);
}
return (MCP_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
}
bool MCP9808Sensor::getMeasurement(EnvironmentalMeasurement *measurement) {
bool MCP9808Sensor::getMeasurement(Telemetry *measurement) {
measurement->temperature = mcp9808.readTempC();
return true;

Wyświetl plik

@ -0,0 +1,15 @@
#include "../mesh/generated/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <Adafruit_MCP9808.h>
#define MCP_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class MCP9808Sensor : virtual public TelemetrySensor {
private:
Adafruit_MCP9808 mcp9808;
public:
MCP9808Sensor();
virtual int32_t runOnce() override;
virtual bool getMeasurement(Telemetry *measurement) override;
};

Wyświetl plik

@ -0,0 +1,12 @@
#pragma once
#include "../mesh/generated/telemetry.pb.h"
#define DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class TelemetrySensor {
protected:
TelemetrySensor() { }
public:
virtual int32_t runOnce() = 0;
virtual bool getMeasurement(Telemetry *measurement) = 0;
};

Wyświetl plik

@ -0,0 +1,299 @@
#include "Telemetry.h"
#include "../mesh/generated/telemetry.pb.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_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_farenheit = false;
radioConfig.preferences.telemetry_module_sensor_pin = 13;
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;
}
}
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) {
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);
sensor_read_error_count = 0;
return (radioConfig.preferences.telemetry_module_recovery_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);
}
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);
}
}
}
// 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);
#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::CelsiusToFarenheit(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_farenheit) {
last_temp = String(CelsiusToFarenheit(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 *p)
{
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("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);
lastMeasurementPacket = packetPool.allocCopy(mp);
return false; // Let others look at this message also if they want
}
bool TelemetryModule::sendOurTelemetry(NodeNum dest, bool wantReplies)
{
Telemetry m;
m.barometric_pressure = 0;
m.gas_resistance = 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: Invalid sensor type selected; Disabling module");
return false;
}
DEBUG_MSG("Telemetry->relative_humidity: %f\n", m.relative_humidity);
DEBUG_MSG("Telemetry->temperature: %f\n", m.temperature);
DEBUG_MSG("Telemetry->barometric_pressure: %f\n", m.barometric_pressure);
DEBUG_MSG("Telemetry->gas_resistance: %f\n", m.gas_resistance);
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;
}

Wyświetl plik

@ -1,15 +1,15 @@
#pragma once
#include "../mesh/generated/environmental_measurement.pb.h"
#include "../mesh/generated/telemetry.pb.h"
#include "ProtobufPlugin.h"
#include <OLEDDisplay.h>
#include <OLEDDisplayUi.h>
class EnvironmentalMeasurementPlugin : private concurrency::OSThread, public ProtobufPlugin<EnvironmentalMeasurement>
class TelemetryModule : private concurrency::OSThread, public ProtobufPlugin<Telemetry>
{
public:
EnvironmentalMeasurementPlugin()
: concurrency::OSThread("EnvironmentalMeasurementPlugin"),
ProtobufPlugin("EnvironmentalMeasurement", PortNum_ENVIRONMENTAL_MEASUREMENT_APP, &EnvironmentalMeasurement_msg)
TelemetryModule()
: concurrency::OSThread("TelemetryModule"),
ProtobufPlugin("Telemetry", PortNum_TELEMETRY_APP, &Telemetry_msg)
{
lastMeasurementPacket = nullptr;
}
@ -20,12 +20,12 @@ class EnvironmentalMeasurementPlugin : private concurrency::OSThread, public Pro
/** 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, EnvironmentalMeasurement *p) override;
virtual bool handleReceivedProtobuf(const MeshPacket &mp, Telemetry *p) override;
virtual int32_t runOnce() override;
/**
* Send our EnvironmentalMeasurement into the mesh
* Send our Telemetry into the mesh
*/
bool sendOurEnvironmentalMeasurement(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false);
bool sendOurTelemetry(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false);
private:
float CelsiusToFarenheit(float c);

Wyświetl plik

@ -1,11 +1,11 @@
#include "configuration.h"
#include "TextMessagePlugin.h"
#include "TextMessageModule.h"
#include "NodeDB.h"
#include "PowerFSM.h"
TextMessagePlugin *textMessagePlugin;
TextMessageModule *textMessageModule;
ProcessMessage TextMessagePlugin::handleReceived(const MeshPacket &mp)
ProcessMessage TextMessageModule::handleReceived(const MeshPacket &mp)
{
auto &p = mp.decoded;
DEBUG_MSG("Received text msg from=0x%0x, id=0x%x, msg=%.*s\n", mp.from, mp.id, p.payload.size, p.payload.bytes);

Wyświetl plik

@ -5,13 +5,13 @@
/**
* Text message handling for meshtastic - draws on the OLED display the most recent received message
*/
class TextMessagePlugin : public SinglePortPlugin, public Observable<const MeshPacket *>
class TextMessageModule : public SinglePortPlugin, public Observable<const MeshPacket *>
{
public:
/** Constructor
* name is for debugging output
*/
TextMessagePlugin() : SinglePortPlugin("text", PortNum_TEXT_MESSAGE_APP) {}
TextMessageModule() : SinglePortPlugin("text", PortNum_TEXT_MESSAGE_APP) {}
protected:
@ -22,4 +22,4 @@ class TextMessagePlugin : public SinglePortPlugin, public Observable<const MeshP
virtual ProcessMessage handleReceived(const MeshPacket &mp) override;
};
extern TextMessagePlugin *textMessagePlugin;
extern TextMessageModule *textMessageModule;

Wyświetl plik

@ -1,4 +1,4 @@
#include "RangeTestPlugin.h"
#include "RangeTestModule.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "PowerFSM.h"
@ -16,10 +16,10 @@
As a receiver, I can receive packets from multiple senders. These packets can be saved to the Filesystem.
*/
RangeTestPlugin *rangeTestPlugin;
RangeTestPluginRadio *rangeTestPluginRadio;
RangeTestModule *rangeTestModule;
RangeTestModuleRadio *rangeTestModuleRadio;
RangeTestPlugin::RangeTestPlugin() : concurrency::OSThread("RangeTestPlugin") {}
RangeTestModule::RangeTestModule() : concurrency::OSThread("RangeTestModule") {}
uint32_t packetSequence = 0;
@ -27,44 +27,44 @@ uint32_t packetSequence = 0;
#define SEC_PER_HOUR 3600
#define SEC_PER_MIN 60
int32_t RangeTestPlugin::runOnce()
int32_t RangeTestModule::runOnce()
{
#ifndef NO_ESP32
/*
Uncomment the preferences below if you want to use the plugin
Uncomment the preferences below if you want to use the module
without having to configure it from the PythonAPI or WebUI.
*/
// radioConfig.preferences.range_test_plugin_enabled = 1;
// radioConfig.preferences.range_test_plugin_sender = 45;
// radioConfig.preferences.range_test_plugin_save = 1;
// radioConfig.preferences.range_test_module_enabled = 1;
// radioConfig.preferences.range_test_module_sender = 45;
// radioConfig.preferences.range_test_module_save = 1;
// Fixed position is useful when testing indoors.
// radioConfig.preferences.fixed_position = 1;
uint32_t senderHeartbeat = radioConfig.preferences.range_test_plugin_sender * 1000;
uint32_t senderHeartbeat = radioConfig.preferences.range_test_module_sender * 1000;
if (radioConfig.preferences.range_test_plugin_enabled) {
if (radioConfig.preferences.range_test_module_enabled) {
if (firstTime) {
rangeTestPluginRadio = new RangeTestPluginRadio();
rangeTestModuleRadio = new RangeTestModuleRadio();
firstTime = 0;
if (radioConfig.preferences.range_test_plugin_sender) {
DEBUG_MSG("Initializing Range Test Plugin -- Sender\n");
if (radioConfig.preferences.range_test_module_sender) {
DEBUG_MSG("Initializing Range Test Module -- Sender\n");
return (5000); // Sending first message 5 seconds after initilization.
} else {
DEBUG_MSG("Initializing Range Test Plugin -- Receiver\n");
DEBUG_MSG("Initializing Range Test Module -- Receiver\n");
return (500);
}
} else {
if (radioConfig.preferences.range_test_plugin_sender) {
if (radioConfig.preferences.range_test_module_sender) {
// If sender
DEBUG_MSG("Range Test Plugin - Sending heartbeat every %d ms\n", (senderHeartbeat));
DEBUG_MSG("Range Test Module - Sending heartbeat every %d ms\n", (senderHeartbeat));
DEBUG_MSG("gpsStatus->getLatitude() %d\n", gpsStatus->getLatitude());
DEBUG_MSG("gpsStatus->getLongitude() %d\n", gpsStatus->getLongitude());
@ -75,7 +75,7 @@ int32_t RangeTestPlugin::runOnce()
// Only send packets if the channel is less than 25% utilized.
if (airTime->channelUtilizationPercent() < 25) {
rangeTestPluginRadio->sendPayload();
rangeTestModuleRadio->sendPayload();
} else {
DEBUG_MSG("rangeTest - Channel utilization is >25 percent. Skipping this opportunity to send.\n");
}
@ -90,14 +90,14 @@ int32_t RangeTestPlugin::runOnce()
}
} else {
DEBUG_MSG("Range Test Plugin - Disabled\n");
DEBUG_MSG("Range Test Module - Disabled\n");
}
#endif
return (INT32_MAX);
}
MeshPacket *RangeTestPluginRadio::allocReply()
MeshPacket *RangeTestModuleRadio::allocReply()
{
auto reply = allocDataPacket(); // Allocate a packet for sending
@ -105,7 +105,7 @@ MeshPacket *RangeTestPluginRadio::allocReply()
return reply;
}
void RangeTestPluginRadio::sendPayload(NodeNum dest, bool wantReplies)
void RangeTestModuleRadio::sendPayload(NodeNum dest, bool wantReplies)
{
MeshPacket *p = allocReply();
p->to = dest;
@ -127,11 +127,11 @@ void RangeTestPluginRadio::sendPayload(NodeNum dest, bool wantReplies)
powerFSM.trigger(EVENT_CONTACT_FROM_PHONE);
}
ProcessMessage RangeTestPluginRadio::handleReceived(const MeshPacket &mp)
ProcessMessage RangeTestModuleRadio::handleReceived(const MeshPacket &mp)
{
#ifndef NO_ESP32
if (radioConfig.preferences.range_test_plugin_enabled) {
if (radioConfig.preferences.range_test_module_enabled) {
/*
auto &p = mp.decoded;
@ -141,7 +141,7 @@ ProcessMessage RangeTestPluginRadio::handleReceived(const MeshPacket &mp)
if (getFrom(&mp) != nodeDB.getNodeNum()) {
if (radioConfig.preferences.range_test_plugin_save) {
if (radioConfig.preferences.range_test_module_save) {
appendFile(mp);
}
@ -175,7 +175,7 @@ ProcessMessage RangeTestPluginRadio::handleReceived(const MeshPacket &mp)
}
} else {
DEBUG_MSG("Range Test Plugin Disabled\n");
DEBUG_MSG("Range Test Module Disabled\n");
}
#endif
@ -183,7 +183,7 @@ ProcessMessage RangeTestPluginRadio::handleReceived(const MeshPacket &mp)
return ProcessMessage::CONTINUE; // Let others look at this message also if they want
}
bool RangeTestPluginRadio::appendFile(const MeshPacket &mp)
bool RangeTestModuleRadio::appendFile(const MeshPacket &mp)
{
auto &p = mp.decoded;

Wyświetl plik

@ -6,29 +6,29 @@
#include <Arduino.h>
#include <functional>
class RangeTestPlugin : private concurrency::OSThread
class RangeTestModule : private concurrency::OSThread
{
bool firstTime = 1;
public:
RangeTestPlugin();
RangeTestModule();
protected:
virtual int32_t runOnce() override;
};
extern RangeTestPlugin *rangeTestPlugin;
extern RangeTestModule *rangeTestModule;
/*
* Radio interface for RangeTestPlugin
* Radio interface for RangeTestModule
*
*/
class RangeTestPluginRadio : public SinglePortPlugin
class RangeTestModuleRadio : public SinglePortPlugin
{
uint32_t lastRxID = 0;
public:
RangeTestPluginRadio() : SinglePortPlugin("RangeTestPluginRadio", PortNum_TEXT_MESSAGE_APP) {}
RangeTestModuleRadio() : SinglePortPlugin("RangeTestModuleRadio", PortNum_TEXT_MESSAGE_APP) {}
/**
* Send our payload into the mesh
@ -55,4 +55,4 @@ class RangeTestPluginRadio : public SinglePortPlugin
virtual ProcessMessage handleReceived(const MeshPacket &mp) override;
};
extern RangeTestPluginRadio *rangeTestPluginRadio;
extern RangeTestModuleRadio *rangeTestModuleRadio;

Wyświetl plik

@ -1,5 +1,5 @@
#include "configuration.h"
#include "SerialPlugin.h"
#include "SerialModule.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "RTC.h"
@ -9,29 +9,29 @@
#include <assert.h>
/*
SerialPlugin
SerialModule
A simple interface to send messages over the mesh network by sending strings
over a serial port.
Default is to use RX GPIO 16 and TX GPIO 17.
Need help with this plugin? Post your question on the Meshtastic Discourse:
Need help with this module? Post your question on the Meshtastic Discourse:
https://meshtastic.discourse.group
Basic Usage:
1) Enable the plugin by setting serialplugin_enabled to 1.
2) Set the pins (serialplugin_rxd / serialplugin_rxd) for your preferred RX and TX GPIO pins.
1) Enable the module by setting serialmodule_enabled to 1.
2) Set the pins (serialmodule_rxd / serialmodule_rxd) for your preferred RX and TX GPIO pins.
On tbeam, recommend to use:
RXD 35
TXD 15
3) Set serialplugin_timeout to the amount of time to wait before we consider
3) Set serialmodule_timeout to the amount of time to wait before we consider
your packet as "done".
4) (Optional) In SerialPlugin.h set the port to PortNum_TEXT_MESSAGE_APP if you want to
4) (Optional) In SerialModule.h set the port to PortNum_TEXT_MESSAGE_APP if you want to
send messages to/from the general text message channel.
5) Connect to your device over the serial interface at 38400 8N1.
6) Send a packet up to 240 bytes in length. This will get relayed over the mesh network.
7) (Optional) Set serialplugin_echo to 1 and any message you send out will be echoed back
7) (Optional) Set serialmodule_echo to 1 and any message you send out will be echoed back
to your device.
TODO (in this order):
@ -39,7 +39,7 @@
- This won't happen any time soon.
KNOWN PROBLEMS
* Until the plugin is initilized by the startup sequence, the TX pin is in a floating
* Until the module is initilized by the startup sequence, the TX pin is in a floating
state. Device connected to that pin may see this as "noise".
* Will not work on NRF and the Linux device targets.
@ -48,66 +48,66 @@
#define RXD2 16
#define TXD2 17
#define SERIALPLUGIN_RX_BUFFER 128
#define SERIALPLUGIN_STRING_MAX Constants_DATA_PAYLOAD_LEN
#define SERIALPLUGIN_TIMEOUT 250
#define SERIALPLUGIN_BAUD 38400
#define SERIALPLUGIN_ACK 1
#define SERIALMODULE_RX_BUFFER 128
#define SERIALMODULE_STRING_MAX Constants_DATA_PAYLOAD_LEN
#define SERIALMODULE_TIMEOUT 250
#define SERIALMODULE_BAUD 38400
#define SERIALMODULE_ACK 1
SerialPlugin *serialPlugin;
SerialPluginRadio *serialPluginRadio;
SerialModule *serialModule;
SerialModuleRadio *serialModuleRadio;
SerialPlugin::SerialPlugin() : concurrency::OSThread("SerialPlugin") {}
SerialModule::SerialModule() : concurrency::OSThread("SerialModule") {}
char serialStringChar[Constants_DATA_PAYLOAD_LEN];
SerialPluginRadio::SerialPluginRadio() : SinglePortPlugin("SerialPluginRadio", PortNum_SERIAL_APP)
SerialModuleRadio::SerialModuleRadio() : SinglePortPlugin("SerialModuleRadio", PortNum_SERIAL_APP)
{
// restrict to the admin channel for rx
boundChannel = Channels::serialChannel;
}
int32_t SerialPlugin::runOnce()
int32_t SerialModule::runOnce()
{
#ifndef NO_ESP32
/*
Uncomment the preferences below if you want to use the plugin
Uncomment the preferences below if you want to use the module
without having to configure it from the PythonAPI or WebUI.
*/
// radioConfig.preferences.serialplugin_enabled = 1;
// radioConfig.preferences.serialplugin_rxd = 35;
// radioConfig.preferences.serialplugin_txd = 15;
// radioConfig.preferences.serialplugin_timeout = 1000;
// radioConfig.preferences.serialplugin_echo = 1;
// radioConfig.preferences.serialmodule_enabled = 1;
// radioConfig.preferences.serialmodule_rxd = 35;
// radioConfig.preferences.serialmodule_txd = 15;
// radioConfig.preferences.serialmodule_timeout = 1000;
// radioConfig.preferences.serialmodule_echo = 1;
if (radioConfig.preferences.serialplugin_enabled) {
if (radioConfig.preferences.serialmodule_enabled) {
if (firstTime) {
// Interface with the serial peripheral from in here.
DEBUG_MSG("Initializing serial peripheral interface\n");
if (radioConfig.preferences.serialplugin_rxd && radioConfig.preferences.serialplugin_txd) {
Serial2.begin(SERIALPLUGIN_BAUD, SERIAL_8N1, radioConfig.preferences.serialplugin_rxd,
radioConfig.preferences.serialplugin_txd);
if (radioConfig.preferences.serialmodule_rxd && radioConfig.preferences.serialmodule_txd) {
Serial2.begin(SERIALMODULE_BAUD, SERIAL_8N1, radioConfig.preferences.serialmodule_rxd,
radioConfig.preferences.serialmodule_txd);
} else {
Serial2.begin(SERIALPLUGIN_BAUD, SERIAL_8N1, RXD2, TXD2);
Serial2.begin(SERIALMODULE_BAUD, SERIAL_8N1, RXD2, TXD2);
}
if (radioConfig.preferences.serialplugin_timeout) {
if (radioConfig.preferences.serialmodule_timeout) {
Serial2.setTimeout(
radioConfig.preferences.serialplugin_timeout); // Number of MS to wait to set the timeout for the string.
radioConfig.preferences.serialmodule_timeout); // Number of MS to wait to set the timeout for the string.
} else {
Serial2.setTimeout(SERIALPLUGIN_TIMEOUT); // Number of MS to wait to set the timeout for the string.
Serial2.setTimeout(SERIALMODULE_TIMEOUT); // Number of MS to wait to set the timeout for the string.
}
Serial2.setRxBufferSize(SERIALPLUGIN_RX_BUFFER);
Serial2.setRxBufferSize(SERIALMODULE_RX_BUFFER);
serialPluginRadio = new SerialPluginRadio();
serialModuleRadio = new SerialModuleRadio();
firstTime = 0;
@ -118,7 +118,7 @@ int32_t SerialPlugin::runOnce()
serialString = Serial2.readString();
serialString.toCharArray(serialStringChar, Constants_DATA_PAYLOAD_LEN);
serialPluginRadio->sendPayload();
serialModuleRadio->sendPayload();
DEBUG_MSG("Received: %s\n", serialStringChar);
}
@ -126,7 +126,7 @@ int32_t SerialPlugin::runOnce()
return (10);
} else {
DEBUG_MSG("Serial Plugin Disabled\n");
DEBUG_MSG("Serial Module Disabled\n");
return (INT32_MAX);
}
@ -135,7 +135,7 @@ int32_t SerialPlugin::runOnce()
#endif
}
MeshPacket *SerialPluginRadio::allocReply()
MeshPacket *SerialModuleRadio::allocReply()
{
auto reply = allocDataPacket(); // Allocate a packet for sending
@ -143,13 +143,13 @@ MeshPacket *SerialPluginRadio::allocReply()
return reply;
}
void SerialPluginRadio::sendPayload(NodeNum dest, bool wantReplies)
void SerialModuleRadio::sendPayload(NodeNum dest, bool wantReplies)
{
MeshPacket *p = allocReply();
p->to = dest;
p->decoded.want_response = wantReplies;
p->want_ack = SERIALPLUGIN_ACK;
p->want_ack = SERIALMODULE_ACK;
p->decoded.payload.size = strlen(serialStringChar); // You must specify how many bytes are in the reply
memcpy(p->decoded.payload.bytes, serialStringChar, p->decoded.payload.size);
@ -157,11 +157,11 @@ void SerialPluginRadio::sendPayload(NodeNum dest, bool wantReplies)
service.sendToMesh(p);
}
ProcessMessage SerialPluginRadio::handleReceived(const MeshPacket &mp)
ProcessMessage SerialModuleRadio::handleReceived(const MeshPacket &mp)
{
#ifndef NO_ESP32
if (radioConfig.preferences.serialplugin_enabled) {
if (radioConfig.preferences.serialmodule_enabled) {
auto &p = mp.decoded;
// DEBUG_MSG("Received text msg self=0x%0x, from=0x%0x, to=0x%0x, id=%d, msg=%.*s\n",
@ -170,10 +170,10 @@ ProcessMessage SerialPluginRadio::handleReceived(const MeshPacket &mp)
if (getFrom(&mp) == nodeDB.getNodeNum()) {
/*
* If radioConfig.preferences.serialplugin_echo is true, then echo the packets that are sent out back to the TX
* If radioConfig.preferences.serialmodule_echo is true, then echo the packets that are sent out back to the TX
* of the serial interface.
*/
if (radioConfig.preferences.serialplugin_echo) {
if (radioConfig.preferences.serialmodule_echo) {
// For some reason, we get the packet back twice when we send out of the radio.
// TODO: need to find out why.
@ -187,12 +187,12 @@ ProcessMessage SerialPluginRadio::handleReceived(const MeshPacket &mp)
} else {
if (radioConfig.preferences.serialplugin_mode == 0 || radioConfig.preferences.serialplugin_mode == 1) {
if (radioConfig.preferences.serialmodule_mode == 0 || radioConfig.preferences.serialmodule_mode == 1) {
// DEBUG_MSG("* * Message came from the mesh\n");
// Serial2.println("* * Message came from the mesh");
Serial2.printf("%s", p.payload.bytes);
} else if (radioConfig.preferences.serialplugin_mode == 10) {
} else if (radioConfig.preferences.serialmodule_mode == 10) {
/*
@jobionekabnoi
Add code here to handle what gets sent out to the serial interface.
@ -202,7 +202,7 @@ ProcessMessage SerialPluginRadio::handleReceived(const MeshPacket &mp)
}
} else {
DEBUG_MSG("Serial Plugin Disabled\n");
DEBUG_MSG("Serial Module Disabled\n");
}
#endif

Wyświetl plik

@ -6,24 +6,24 @@
#include <Arduino.h>
#include <functional>
class SerialPlugin : private concurrency::OSThread
class SerialModule : private concurrency::OSThread
{
bool firstTime = 1;
public:
SerialPlugin();
SerialModule();
protected:
virtual int32_t runOnce() override;
};
extern SerialPlugin *serialPlugin;
extern SerialModule *serialModule;
/*
* Radio interface for SerialPlugin
* Radio interface for SerialModule
*
*/
class SerialPluginRadio : public SinglePortPlugin
class SerialModuleRadio : public SinglePortPlugin
{
uint32_t lastRxID = 0;
@ -33,7 +33,7 @@ class SerialPluginRadio : public SinglePortPlugin
from the main code.
*/
SerialPluginRadio();
SerialModuleRadio();
/**
* Send our payload into the mesh
@ -50,4 +50,4 @@ class SerialPluginRadio : public SinglePortPlugin
virtual ProcessMessage handleReceived(const MeshPacket &mp) override;
};
extern SerialPluginRadio *serialPluginRadio;
extern SerialModuleRadio *serialModuleRadio;

Wyświetl plik

@ -1,4 +1,4 @@
#include "StoreForwardPlugin.h"
#include "StoreForwardModule.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "RTC.h"
@ -7,19 +7,19 @@
#include "configuration.h"
#include "mesh-pb-constants.h"
#include "mesh/generated/storeforward.pb.h"
#include "plugins/PluginDev.h"
#include "modules/ModuleDev.h"
#include <Arduino.h>
#include <iterator>
#include <map>
StoreForwardPlugin *storeForwardPlugin;
StoreForwardModule *storeForwardModule;
int32_t StoreForwardPlugin::runOnce()
int32_t StoreForwardModule::runOnce()
{
#ifndef NO_ESP32
if (radioConfig.preferences.store_forward_plugin_enabled) {
if (radioConfig.preferences.store_forward_module_enabled) {
if (radioConfig.preferences.is_router) {
@ -31,11 +31,11 @@ int32_t StoreForwardPlugin::runOnce()
if (airTime->channelUtilizationPercent() < 25) {
// DEBUG_MSG("--- --- --- In busy loop 1 %d\n", this->packetHistoryTXQueue_index);
storeForwardPlugin->sendPayload(this->busyTo, this->packetHistoryTXQueue_index);
storeForwardModule->sendPayload(this->busyTo, this->packetHistoryTXQueue_index);
if (this->packetHistoryTXQueue_index == packetHistoryTXQueue_size) {
strcpy(this->routerMessage, "** S&F - Done");
storeForwardPlugin->sendMessage(this->busyTo, this->routerMessage);
storeForwardModule->sendMessage(this->busyTo, this->routerMessage);
// DEBUG_MSG("--- --- --- In busy loop - Done \n");
this->packetHistoryTXQueue_index = 0;
@ -52,13 +52,13 @@ int32_t StoreForwardPlugin::runOnce()
return (this->packetTimeMax);
} else {
DEBUG_MSG("Store & Forward Plugin - Disabled (is_router = false)\n");
DEBUG_MSG("Store & Forward Module - Disabled (is_router = false)\n");
return (INT32_MAX);
}
} else {
DEBUG_MSG("Store & Forward Plugin - Disabled\n");
DEBUG_MSG("Store & Forward Module - Disabled\n");
return (INT32_MAX);
}
@ -70,7 +70,7 @@ int32_t StoreForwardPlugin::runOnce()
/*
Create our data structure in the PSRAM.
*/
void StoreForwardPlugin::populatePSRAM()
void StoreForwardModule::populatePSRAM()
{
/*
For PSRAM usage, see:
@ -104,7 +104,7 @@ void StoreForwardPlugin::populatePSRAM()
DEBUG_MSG(" numberOfPackets for packetHistory - %u\n", numberOfPackets);
}
void StoreForwardPlugin::historyReport()
void StoreForwardModule::historyReport()
{
DEBUG_MSG("Iterating through the message history...\n");
DEBUG_MSG("Message history contains %u records\n", this->packetHistoryCurrent);
@ -113,27 +113,27 @@ void StoreForwardPlugin::historyReport()
/*
*
*/
void StoreForwardPlugin::historySend(uint32_t msAgo, uint32_t to)
void StoreForwardModule::historySend(uint32_t msAgo, uint32_t to)
{
// uint32_t packetsSent = 0;
uint32_t queueSize = storeForwardPlugin->historyQueueCreate(msAgo, to);
uint32_t queueSize = storeForwardModule->historyQueueCreate(msAgo, to);
if (queueSize) {
snprintf(this->routerMessage, 80, "** S&F - Sending %u message(s)", queueSize);
storeForwardPlugin->sendMessage(to, this->routerMessage);
storeForwardModule->sendMessage(to, this->routerMessage);
this->busy = true; // runOnce() will pickup the next steps once busy = true.
this->busyTo = to;
} else {
strcpy(this->routerMessage, "** S&F - No history to send");
storeForwardPlugin->sendMessage(to, this->routerMessage);
storeForwardModule->sendMessage(to, this->routerMessage);
}
}
uint32_t StoreForwardPlugin::historyQueueCreate(uint32_t msAgo, uint32_t to)
uint32_t StoreForwardModule::historyQueueCreate(uint32_t msAgo, uint32_t to)
{
// uint32_t packetHistoryTXQueueIndex = 0;
@ -177,7 +177,7 @@ uint32_t StoreForwardPlugin::historyQueueCreate(uint32_t msAgo, uint32_t to)
return this->packetHistoryTXQueue_size;
}
void StoreForwardPlugin::historyAdd(const MeshPacket &mp)
void StoreForwardModule::historyAdd(const MeshPacket &mp)
{
const auto &p = mp.decoded;
@ -191,13 +191,13 @@ void StoreForwardPlugin::historyAdd(const MeshPacket &mp)
this->packetHistoryCurrent++;
}
MeshPacket *StoreForwardPlugin::allocReply()
MeshPacket *StoreForwardModule::allocReply()
{
auto reply = allocDataPacket(); // Allocate a packet for sending
return reply;
}
void StoreForwardPlugin::sendPayload(NodeNum dest, uint32_t packetHistory_index)
void StoreForwardModule::sendPayload(NodeNum dest, uint32_t packetHistory_index)
{
DEBUG_MSG("Sending S&F Payload\n");
MeshPacket *p = allocReply();
@ -218,7 +218,7 @@ void StoreForwardPlugin::sendPayload(NodeNum dest, uint32_t packetHistory_index)
service.sendToMesh(p);
}
void StoreForwardPlugin::sendMessage(NodeNum dest, char *str)
void StoreForwardModule::sendMessage(NodeNum dest, char *str)
{
MeshPacket *p = allocReply();
@ -240,10 +240,10 @@ void StoreForwardPlugin::sendMessage(NodeNum dest, char *str)
// HardwareMessage_init_default
}
ProcessMessage StoreForwardPlugin::handleReceived(const MeshPacket &mp)
ProcessMessage StoreForwardModule::handleReceived(const MeshPacket &mp)
{
#ifndef NO_ESP32
if (radioConfig.preferences.store_forward_plugin_enabled) {
if (radioConfig.preferences.store_forward_module_enabled) {
DEBUG_MSG("--- S&F Received something\n");
@ -261,9 +261,9 @@ ProcessMessage StoreForwardPlugin::handleReceived(const MeshPacket &mp)
// Send the last 60 minutes of messages.
if (this->busy) {
strcpy(this->routerMessage, "** S&F - Busy. Try again shortly.");
storeForwardPlugin->sendMessage(getFrom(&mp), this->routerMessage);
storeForwardModule->sendMessage(getFrom(&mp), this->routerMessage);
} else {
storeForwardPlugin->historySend(1000 * 60, getFrom(&mp));
storeForwardModule->historySend(1000 * 60, getFrom(&mp));
}
} else if ((p.payload.bytes[0] == 'S') && (p.payload.bytes[1] == 'F') && (p.payload.bytes[2] == 'm') &&
(p.payload.bytes[3] == 0x00)) {
@ -271,10 +271,10 @@ ProcessMessage StoreForwardPlugin::handleReceived(const MeshPacket &mp)
"01234567890123456789012345678901234567890123456789012345678901234567890123456789"
"01234567890123456789012345678901234567890123456789012345678901234567890123456",
sizeof(this->routerMessage));
storeForwardPlugin->sendMessage(getFrom(&mp), this->routerMessage);
storeForwardModule->sendMessage(getFrom(&mp), this->routerMessage);
} else {
storeForwardPlugin->historyAdd(mp);
storeForwardModule->historyAdd(mp);
}
} else if (mp.decoded.portnum == PortNum_STORE_FORWARD_APP) {
@ -285,7 +285,7 @@ ProcessMessage StoreForwardPlugin::handleReceived(const MeshPacket &mp)
}
} else {
DEBUG_MSG("Store & Forward Plugin - Disabled\n");
DEBUG_MSG("Store & Forward Module - Disabled\n");
}
#endif
@ -293,10 +293,10 @@ ProcessMessage StoreForwardPlugin::handleReceived(const MeshPacket &mp)
return ProcessMessage::CONTINUE; // Let others look at this message also if they want
}
ProcessMessage StoreForwardPlugin::handleReceivedProtobuf(const MeshPacket &mp, StoreAndForward *p)
ProcessMessage StoreForwardModule::handleReceivedProtobuf(const MeshPacket &mp, StoreAndForward *p)
{
if (!radioConfig.preferences.store_forward_plugin_enabled) {
// If this plugin is not enabled in any capacity, don't handle the packet, and allow other plugins to consume
if (!radioConfig.preferences.store_forward_module_enabled) {
// If this module is not enabled in any capacity, don't handle the packet, and allow other modules to consume
return ProcessMessage::CONTINUE;
}
@ -323,9 +323,9 @@ ProcessMessage StoreForwardPlugin::handleReceivedProtobuf(const MeshPacket &mp,
// Send the last 60 minutes of messages.
if (this->busy) {
strcpy(this->routerMessage, "** S&F - Busy. Try again shortly.");
storeForwardPlugin->sendMessage(getFrom(&mp), this->routerMessage);
storeForwardModule->sendMessage(getFrom(&mp), this->routerMessage);
} else {
storeForwardPlugin->historySend(1000 * 60, getFrom(&mp));
storeForwardModule->historySend(1000 * 60, getFrom(&mp));
}
break;
@ -377,8 +377,8 @@ ProcessMessage StoreForwardPlugin::handleReceivedProtobuf(const MeshPacket &mp,
return ProcessMessage::STOP; // There's no need for others to look at this message.
}
StoreForwardPlugin::StoreForwardPlugin()
: SinglePortPlugin("StoreForwardPlugin", PortNum_TEXT_MESSAGE_APP), concurrency::OSThread("StoreForwardPlugin")
StoreForwardModule::StoreForwardModule()
: SinglePortPlugin("StoreForwardModule", PortNum_TEXT_MESSAGE_APP), concurrency::OSThread("StoreForwardModule")
{
#ifndef NO_ESP32
@ -387,57 +387,57 @@ StoreForwardPlugin::StoreForwardPlugin()
if (StoreForward_Dev) {
/*
Uncomment the preferences below if you want to use the plugin
Uncomment the preferences below if you want to use the module
without having to configure it from the PythonAPI or WebUI.
*/
radioConfig.preferences.store_forward_plugin_enabled = 1;
radioConfig.preferences.store_forward_module_enabled = 1;
radioConfig.preferences.is_router = 1;
radioConfig.preferences.is_always_powered = 1;
}
if (radioConfig.preferences.store_forward_plugin_enabled) {
if (radioConfig.preferences.store_forward_module_enabled) {
// Router
if (radioConfig.preferences.is_router) {
DEBUG_MSG("Initializing Store & Forward Plugin - Enabled as Router\n");
DEBUG_MSG("Initializing Store & Forward Module - Enabled as Router\n");
if (ESP.getPsramSize()) {
if (ESP.getFreePsram() >= 1024 * 1024) {
// Do the startup here
// Maximum number of records to return.
if (radioConfig.preferences.store_forward_plugin_history_return_max)
this->historyReturnMax = radioConfig.preferences.store_forward_plugin_history_return_max;
if (radioConfig.preferences.store_forward_module_history_return_max)
this->historyReturnMax = radioConfig.preferences.store_forward_module_history_return_max;
// Maximum time window for records to return (in minutes)
if (radioConfig.preferences.store_forward_plugin_history_return_window)
this->historyReturnWindow = radioConfig.preferences.store_forward_plugin_history_return_window;
if (radioConfig.preferences.store_forward_module_history_return_window)
this->historyReturnWindow = radioConfig.preferences.store_forward_module_history_return_window;
// Maximum number of records to store in memory
if (radioConfig.preferences.store_forward_plugin_records)
this->records = radioConfig.preferences.store_forward_plugin_records;
if (radioConfig.preferences.store_forward_module_records)
this->records = radioConfig.preferences.store_forward_module_records;
// Maximum number of records to store in memory
if (radioConfig.preferences.store_forward_plugin_heartbeat)
this->heartbeat = radioConfig.preferences.store_forward_plugin_heartbeat;
if (radioConfig.preferences.store_forward_module_heartbeat)
this->heartbeat = radioConfig.preferences.store_forward_module_heartbeat;
// Popupate PSRAM with our data structures.
this->populatePSRAM();
} else {
DEBUG_MSG("Device has less than 1M of PSRAM free. Aborting startup.\n");
DEBUG_MSG("Store & Forward Plugin - Aborting Startup.\n");
DEBUG_MSG("Store & Forward Module - Aborting Startup.\n");
}
} else {
DEBUG_MSG("Device doesn't have PSRAM.\n");
DEBUG_MSG("Store & Forward Plugin - Aborting Startup.\n");
DEBUG_MSG("Store & Forward Module - Aborting Startup.\n");
}
// Client
} else {
DEBUG_MSG("Initializing Store & Forward Plugin - Enabled as Client\n");
DEBUG_MSG("Initializing Store & Forward Module - Enabled as Client\n");
}
}
#endif

Wyświetl plik

@ -18,7 +18,7 @@ struct PacketHistoryStruct {
pb_size_t payload_size;
};
class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThread
class StoreForwardModule : public SinglePortPlugin, private concurrency::OSThread
{
// bool firstTime = 1;
bool busy = 0;
@ -37,7 +37,7 @@ class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThrea
uint32_t packetTimeMax = 2000;
public:
StoreForwardPlugin();
StoreForwardModule();
/**
Update our local reference of when we last saw that node.
@ -82,4 +82,4 @@ class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThrea
};
extern StoreForwardPlugin *storeForwardPlugin;
extern StoreForwardModule *storeForwardModule;

Wyświetl plik

@ -1,299 +0,0 @@
#include "EnvironmentalMeasurementPlugin.h"
#include "../mesh/generated/environmental_measurement.pb.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 EnvironmentalMeasurementPlugin::runOnce()
{
#ifndef PORTDUINO
/*
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 = 600;
radioConfig.preferences.environmental_measurement_plugin_recovery_interval = 60;
radioConfig.preferences.environmental_measurement_plugin_display_farenheit = false;
radioConfig.preferences.environmental_measurement_plugin_sensor_pin = 13;
radioConfig.preferences.environmental_measurement_plugin_sensor_type =
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType::
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME280;
*/
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
firstTime = 0;
if (radioConfig.preferences.environmental_measurement_plugin_measurement_enabled) {
DEBUG_MSG("EnvironmentalMeasurement: Initializing\n");
// 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
switch (radioConfig.preferences.environmental_measurement_plugin_sensor_type) {
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11:
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT12:
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT21:
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT22:
return dhtSensor.runOnce();
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20:
return dallasSensor.runOnce();
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME280:
return bme280Sensor.runOnce();
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME680:
return bme680Sensor.runOnce();
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MCP9808:
return mcp9808Sensor.runOnce();
default:
DEBUG_MSG("EnvironmentalMeasurement: Invalid sensor type selected; Disabling plugin");
return (INT32_MAX);
break;
}
}
return (INT32_MAX);
} else {
// if we somehow got to a second run of this plugin with measurement disabled, then just wait forever
if (!radioConfig.preferences.environmental_measurement_plugin_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.environmental_measurement_plugin_read_error_count_threshold) {
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);
sensor_read_error_count = 0;
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("EnvironmentalMeasurement: 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.environmental_measurement_plugin_read_error_count_threshold -
sensor_read_error_count);
}
if (!sendOurEnvironmentalMeasurement()) {
// if we failed to read the sensor, then try again
// as soon as we can according to the maximum polling frequency
switch (radioConfig.preferences.environmental_measurement_plugin_sensor_type) {
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11:
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT12:
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT21:
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT22:
return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20:
return (DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME280:
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME680:
return (BME_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MCP9808:
return (MCP_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
default:
return (DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
}
}
}
// 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.environmental_measurement_plugin_update_interval * 1000);
#endif
}
bool EnvironmentalMeasurementPlugin::wantUIFrame()
{
return radioConfig.preferences.environmental_measurement_plugin_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 EnvironmentalMeasurementPlugin::CelsiusToFarenheit(float c)
{
return (c * 9) / 5 + 32;
}
void EnvironmentalMeasurementPlugin::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;
}
EnvironmentalMeasurement 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, EnvironmentalMeasurement_fields, &lastMeasurement)) {
display->setFont(FONT_SMALL);
display->drawString(x, y += fontHeight(FONT_MEDIUM), "Measurement Error");
DEBUG_MSG("EnvironmentalMeasurement: unable to decode last packet");
return;
}
display->setFont(FONT_SMALL);
String last_temp = String(lastMeasurement.temperature, 0) + "°C";
if (radioConfig.preferences.environmental_measurement_plugin_display_farenheit) {
last_temp = String(CelsiusToFarenheit(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 EnvironmentalMeasurementPlugin::handleReceivedProtobuf(const MeshPacket &mp, EnvironmentalMeasurement *p)
{
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;
}
String sender = GetSenderName(mp);
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);
DEBUG_MSG("EnvironmentalMeasurement->barometric_pressure: %f\n", p->barometric_pressure);
DEBUG_MSG("EnvironmentalMeasurement->gas_resistance: %f\n", p->gas_resistance);
lastMeasurementPacket = packetPool.allocCopy(mp);
return false; // Let others look at this message also if they want
}
bool EnvironmentalMeasurementPlugin::sendOurEnvironmentalMeasurement(NodeNum dest, bool wantReplies)
{
EnvironmentalMeasurement m;
m.barometric_pressure = 0;
m.gas_resistance = 0;
DEBUG_MSG("-----------------------------------------\n");
DEBUG_MSG("EnvironmentalMeasurement: Read data\n");
switch (radioConfig.preferences.environmental_measurement_plugin_sensor_type) {
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DS18B20:
if (!dallasSensor.getMeasurement(&m))
sensor_read_error_count++;
break;
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11:
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT12:
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT21:
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT22:
if (!dhtSensor.getMeasurement(&m))
sensor_read_error_count++;
break;
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME280:
bme280Sensor.getMeasurement(&m);
break;
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_BME680:
bme680Sensor.getMeasurement(&m);
break;
case RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MCP9808:
mcp9808Sensor.getMeasurement(&m);
break;
default:
DEBUG_MSG("EnvironmentalMeasurement: Invalid sensor type selected; Disabling plugin");
return false;
}
DEBUG_MSG("EnvironmentalMeasurement->relative_humidity: %f\n", m.relative_humidity);
DEBUG_MSG("EnvironmentalMeasurement->temperature: %f\n", m.temperature);
DEBUG_MSG("EnvironmentalMeasurement->barometric_pressure: %f\n", m.barometric_pressure);
DEBUG_MSG("EnvironmentalMeasurement->gas_resistance: %f\n", m.gas_resistance);
sensor_read_error_count = 0;
MeshPacket *p = allocDataProtobuf(m);
p->to = dest;
p->decoded.want_response = wantReplies;
lastMeasurementPacket = packetPool.allocCopy(*p);
DEBUG_MSG("EnvironmentalMeasurement: Sending packet to mesh");
service.sendToMesh(p);
return true;
}

Wyświetl plik

@ -1,15 +0,0 @@
#include "../mesh/generated/environmental_measurement.pb.h"
#include "EnvironmentalMeasurementSensor.h"
#include <Adafruit_BME280.h>
#define BME_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class BME280Sensor : virtual public EnvironmentalMeasurementSensor {
private:
Adafruit_BME280 bme280;
public:
BME280Sensor();
virtual int32_t runOnce() override;
virtual bool getMeasurement(EnvironmentalMeasurement *measurement) override;
};

Wyświetl plik

@ -1,15 +0,0 @@
#include "../mesh/generated/environmental_measurement.pb.h"
#include "EnvironmentalMeasurementSensor.h"
#include <Adafruit_BME680.h>
#define BME_680_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class BME680Sensor : virtual public EnvironmentalMeasurementSensor {
private:
Adafruit_BME680 bme680;
public:
BME680Sensor();
virtual int32_t runOnce() override;
virtual bool getMeasurement(EnvironmentalMeasurement *measurement) override;
};

Wyświetl plik

@ -1,36 +0,0 @@
#include "../mesh/generated/environmental_measurement.pb.h"
#include "configuration.h"
#include "MeshService.h"
#include "EnvironmentalMeasurementSensor.h"
#include "DHTSensor.h"
#include <DHT.h>
DHTSensor::DHTSensor() : EnvironmentalMeasurementSensor {} {
}
int32_t DHTSensor::runOnce() {
if (RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT11 ||
RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_DHT12) {
dht = new DHT(radioConfig.preferences.environmental_measurement_plugin_sensor_pin, DHT11);
}
else {
dht = new DHT(radioConfig.preferences.environmental_measurement_plugin_sensor_pin, DHT22);
}
dht->begin();
dht->read();
DEBUG_MSG("EnvironmentalMeasurement: Opened DHT11/DHT12 on pin: %d\n",
radioConfig.preferences.environmental_measurement_plugin_sensor_pin);
return (DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS);
}
bool DHTSensor::getMeasurement(EnvironmentalMeasurement *measurement) {
if (!dht->read(true)) {
DEBUG_MSG("EnvironmentalMeasurement: FAILED TO READ DATA\n");
return false;
}
measurement->relative_humidity = dht->readHumidity();
measurement->temperature = dht->readTemperature();
return true;
}

Wyświetl plik

@ -1,15 +0,0 @@
#include "../mesh/generated/environmental_measurement.pb.h"
#include "EnvironmentalMeasurementSensor.h"
#include <DHT.h>
#define DHT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class DHTSensor : virtual public EnvironmentalMeasurementSensor {
private:
DHT *dht = NULL;
public:
DHTSensor();
virtual int32_t runOnce() override;
virtual bool getMeasurement(EnvironmentalMeasurement *measurement) override;
};

Wyświetl plik

@ -1,17 +0,0 @@
#include "../mesh/generated/environmental_measurement.pb.h"
#include "EnvironmentalMeasurementSensor.h"
#include <DS18B20.h>
#include <OneWire.h>
#define DS18B20_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class DallasSensor : virtual public EnvironmentalMeasurementSensor {
private:
OneWire *oneWire = NULL;
DS18B20 *ds18b20 = NULL;
public:
DallasSensor();
virtual int32_t runOnce() override;
virtual bool getMeasurement(EnvironmentalMeasurement *measurement) override;
};

Wyświetl plik

@ -1,12 +0,0 @@
#pragma once
#include "../mesh/generated/environmental_measurement.pb.h"
#define DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class EnvironmentalMeasurementSensor {
protected:
EnvironmentalMeasurementSensor() { }
public:
virtual int32_t runOnce() = 0;
virtual bool getMeasurement(EnvironmentalMeasurement *measurement) = 0;
};

Wyświetl plik

@ -1,15 +0,0 @@
#include "../mesh/generated/environmental_measurement.pb.h"
#include "EnvironmentalMeasurementSensor.h"
#include <Adafruit_MCP9808.h>
#define MCP_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
class MCP9808Sensor : virtual public EnvironmentalMeasurementSensor {
private:
Adafruit_MCP9808 mcp9808;
public:
MCP9808Sensor();
virtual int32_t runOnce() override;
virtual bool getMeasurement(EnvironmentalMeasurement *measurement) override;
};

Wyświetl plik

@ -1,187 +0,0 @@
#include "configuration.h"
#include "ExternalNotificationPlugin.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "RTC.h"
#include "Router.h"
#include <Arduino.h>
//#include <assert.h>
/*
Documentation:
https://github.com/meshtastic/Meshtastic-device/blob/master/docs/software/plugins/ExternalNotificationPlugin.md
This plugin supports:
https://github.com/meshtastic/Meshtastic-device/issues/654
Quick reference:
radioConfig.preferences.ext_notification_plugin_enabled
0 = Disabled (Default)
1 = Enabled
radioConfig.preferences.ext_notification_plugin_active
0 = Active Low (Default)
1 = Active High
radioConfig.preferences.ext_notification_plugin_alert_message
0 = Disabled (Default)
1 = Alert when a text message comes
radioConfig.preferences.ext_notification_plugin_alert_bell
0 = Disabled (Default)
1 = Alert when the bell character is received
radioConfig.preferences.ext_notification_plugin_output
GPIO of the output. (Default = 13)
radioConfig.preferences.ext_notification_plugin_output_ms
Amount of time in ms for the alert. Default is 1000.
*/
// Default configurations
#define EXT_NOTIFICATION_PLUGIN_OUTPUT EXT_NOTIFY_OUT
#define EXT_NOTIFICATION_PLUGIN_OUTPUT_MS 1000
#define ASCII_BELL 0x07
bool externalCurrentState = 0;
uint32_t externalTurnedOn = 0;
int32_t ExternalNotificationPlugin::runOnce()
{
/*
Uncomment the preferences below if you want to use the plugin
without having to configure it from the PythonAPI or WebUI.
*/
// radioConfig.preferences.ext_notification_plugin_enabled = 1;
// radioConfig.preferences.ext_notification_plugin_alert_message = 1;
// radioConfig.preferences.ext_notification_plugin_active = 1;
// radioConfig.preferences.ext_notification_plugin_alert_bell = 1;
// radioConfig.preferences.ext_notification_plugin_output_ms = 1000;
// radioConfig.preferences.ext_notification_plugin_output = 13;
if (externalCurrentState) {
// If the output is turned on, turn it back off after the given period of time.
if (externalTurnedOn + (radioConfig.preferences.ext_notification_plugin_output_ms
? radioConfig.preferences.ext_notification_plugin_output_ms
: EXT_NOTIFICATION_PLUGIN_OUTPUT_MS) <
millis()) {
DEBUG_MSG("Turning off external notification\n");
setExternalOff();
}
}
return (25);
}
void ExternalNotificationPlugin::setExternalOn()
{
#ifdef EXT_NOTIFY_OUT
externalCurrentState = 1;
externalTurnedOn = millis();
digitalWrite((radioConfig.preferences.ext_notification_plugin_output ? radioConfig.preferences.ext_notification_plugin_output
: EXT_NOTIFICATION_PLUGIN_OUTPUT),
(radioConfig.preferences.ext_notification_plugin_active ? true : false));
#endif
}
void ExternalNotificationPlugin::setExternalOff()
{
#ifdef EXT_NOTIFY_OUT
externalCurrentState = 0;
digitalWrite((radioConfig.preferences.ext_notification_plugin_output ? radioConfig.preferences.ext_notification_plugin_output
: EXT_NOTIFICATION_PLUGIN_OUTPUT),
(radioConfig.preferences.ext_notification_plugin_active ? false : true));
#endif
}
// --------
ExternalNotificationPlugin::ExternalNotificationPlugin()
: SinglePortPlugin("ExternalNotificationPlugin", PortNum_TEXT_MESSAGE_APP), concurrency::OSThread(
"ExternalNotificationPlugin")
{
// restrict to the admin channel for rx
boundChannel = Channels::gpioChannel;
#ifndef NO_ESP32
#ifdef EXT_NOTIFY_OUT
/*
Uncomment the preferences below if you want to use the plugin
without having to configure it from the PythonAPI or WebUI.
*/
// radioConfig.preferences.ext_notification_plugin_enabled = 1;
// radioConfig.preferences.ext_notification_plugin_alert_message = 1;
// radioConfig.preferences.ext_notification_plugin_active = 1;
// radioConfig.preferences.ext_notification_plugin_alert_bell = 1;
// radioConfig.preferences.ext_notification_plugin_output_ms = 1000;
// radioConfig.preferences.ext_notification_plugin_output = 13;
if (radioConfig.preferences.ext_notification_plugin_enabled) {
DEBUG_MSG("Initializing External Notification Plugin\n");
// Set the direction of a pin
pinMode((radioConfig.preferences.ext_notification_plugin_output ? radioConfig.preferences.ext_notification_plugin_output
: EXT_NOTIFICATION_PLUGIN_OUTPUT),
OUTPUT);
// Turn off the pin
setExternalOff();
} else {
DEBUG_MSG("External Notification Plugin Disabled\n");
enabled = false;
}
#endif
#endif
}
ProcessMessage ExternalNotificationPlugin::handleReceived(const MeshPacket &mp)
{
#ifndef NO_ESP32
#ifdef EXT_NOTIFY_OUT
if (radioConfig.preferences.ext_notification_plugin_enabled) {
if (getFrom(&mp) != nodeDB.getNodeNum()) {
// TODO: This may be a problem if messages are sent in unicide, but I'm not sure if it will.
// Need to know if and how this could be a problem.
if (radioConfig.preferences.ext_notification_plugin_alert_bell) {
auto &p = mp.decoded;
DEBUG_MSG("externalNotificationPlugin - Notification Bell\n");
for (int i = 0; i < p.payload.size; i++) {
if (p.payload.bytes[i] == ASCII_BELL) {
setExternalOn();
}
}
}
if (radioConfig.preferences.ext_notification_plugin_alert_message) {
DEBUG_MSG("externalNotificationPlugin - Notification Plugin\n");
setExternalOn();
}
}
} else {
DEBUG_MSG("External Notification Plugin Disabled\n");
}
#endif
#endif
return ProcessMessage::CONTINUE; // Let others look at this message also if they want
}

Wyświetl plik

@ -1,10 +0,0 @@
#pragma once
/*
* To developers:
* Use this to enable / disable features in your plugin that you don't want to risk checking into GitHub.
*
*/
// Enable development more for StoreForwardPlugin
bool StoreForward_Dev = false;

Wyświetl plik

@ -1,62 +0,0 @@
#include "configuration.h"
#include "input/InputBroker.h"
#include "input/RotaryEncoderInterruptImpl1.h"
#include "plugins/AdminPlugin.h"
#include "plugins/CannedMessagePlugin.h"
#include "plugins/ExternalNotificationPlugin.h"
#include "plugins/NodeInfoPlugin.h"
#include "plugins/PositionPlugin.h"
#include "plugins/RemoteHardwarePlugin.h"
#include "plugins/ReplyPlugin.h"
#include "plugins/RoutingPlugin.h"
#include "plugins/TextMessagePlugin.h"
#ifndef PORTDUINO
#include "plugins/EnvironmentalMeasurement/EnvironmentalMeasurementPlugin.h"
#endif
#ifndef NO_ESP32
#include "plugins/esp32/RangeTestPlugin.h"
#include "plugins/esp32/SerialPlugin.h"
#include "plugins/esp32/StoreForwardPlugin.h"
#endif
/**
* Create plugin instances here. If you are adding a new plugin, you must 'new' it here (or somewhere else)
*/
void setupPlugins()
{
inputBroker = new InputBroker();
adminPlugin = new AdminPlugin();
nodeInfoPlugin = new NodeInfoPlugin();
positionPlugin = new PositionPlugin();
textMessagePlugin = new TextMessagePlugin();
// Note: if the rest of meshtastic doesn't need to explicitly use your plugin, you do not need to assign the instance
// to a global variable.
new RemoteHardwarePlugin();
new ReplyPlugin();
rotaryEncoderInterruptImpl1 = new RotaryEncoderInterruptImpl1();
rotaryEncoderInterruptImpl1->init();
cannedMessagePlugin = new CannedMessagePlugin();
#ifndef PORTDUINO
new EnvironmentalMeasurementPlugin();
#endif
#ifndef NO_ESP32
// Only run on an esp32 based device.
/*
Maintained by MC Hamster (Jm Casler) jm@casler.org
*/
new SerialPlugin();
new ExternalNotificationPlugin();
// rangeTestPlugin = new RangeTestPlugin();
storeForwardPlugin = new StoreForwardPlugin();
new RangeTestPlugin();
// new StoreForwardPlugin();
#endif
// NOTE! This plugin must be added LAST because it likes to check for replies from other plugins and avoid sending extra acks
routingPlugin = new RoutingPlugin();
}

Wyświetl plik

@ -1,6 +0,0 @@
#pragma once
/**
* Create plugin instances here. If you are adding a new plugin, you must 'new' it here (or somewhere else)
*/
void setupPlugins();

41
src/shutdown.h 100644
Wyświetl plik

@ -0,0 +1,41 @@
#include "configuration.h"
#include "graphics/Screen.h"
#include "power.h"
#include "buzz.h"
#include "main.h"
void powerCommandsCheck()
{
if (rebootAtMsec && millis() > rebootAtMsec) {
#ifndef NO_ESP32
DEBUG_MSG("Rebooting for update\n");
ESP.restart();
#else
DEBUG_MSG("FIXME implement reboot for this platform");
#endif
}
#if NRF52_SERIES
if (shutdownAtMsec) {
screen->startShutdownScreen();
playBeep();
ledOff(PIN_LED1);
ledOff(PIN_LED2);
}
#endif
if (shutdownAtMsec && millis() > shutdownAtMsec) {
DEBUG_MSG("Shutting down from admin command\n");
#ifdef TBEAM_V10
if (axp192_found == true) {
setLed(false);
power->shutdown();
}
#elif NRF52_SERIES
playShutdownMelody();
power->shutdown();
#else
DEBUG_MSG("FIXME implement shutdown for this platform");
#endif
}
}

Wyświetl plik

@ -36,3 +36,7 @@ cstyleCast
// ignore stuff that is not ours
*:.pio/*
*:*/libdeps/*
// these two caused issues
missingOverride
virtualCallInConstructor

Wyświetl plik

@ -9,7 +9,7 @@
//#define GPS_TX_PIN 12 // not connected
#define BUTTON_PIN 39 // The middle button GPIO on the T-Beam
#define EXT_NOTIFY_OUT 12 // Overridden default pin to use for Ext Notify Plugin (#975).
#define EXT_NOTIFY_OUT 12 // Overridden default pin to use for Ext Notify Module (#975).
#define LED_PIN 2 // add status LED (compatible with core-pcb and DIY targets)
#define LORA_DIO0 26 // a No connect on the SX1262/SX1268 module

Wyświetl plik

@ -8,7 +8,7 @@
#define BUTTON_PIN 2 // The middle button GPIO on the T-Beam
#define BUTTON_NEED_PULLUP
#define EXT_NOTIFY_OUT 12 // Overridden default pin to use for Ext Notify Plugin (#975).
#define EXT_NOTIFY_OUT 12 // Overridden default pin to use for Ext Notify Module (#975).
#define LORA_DIO0 26 // a No connect on the SX1262/SX1268 module
#define LORA_RESET 27 // RST for SX1276, and for SX1262/SX1268

Wyświetl plik

@ -27,4 +27,4 @@
#define ADC_MULTIPLIER 3.8
#define BATTERY_PIN 37 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Plugin.
#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module.

Wyświetl plik

@ -7,8 +7,8 @@ src_filter =
-<nimble/>
-<nrf52/>
-<mesh/http/>
-<plugins/esp32>
-<plugins/EnvironmentalMeasurement>
-<modules/esp32>
-<modules/Telemetry>
+<../variants/portduino>
build_flags = ${arduino_base.build_flags} -O0 -I variants/portduino
framework = arduino
@ -26,8 +26,8 @@ src_filter =
-<nimble/>
-<nrf52/>
-<mesh/http/>
-<plugins/esp32>
-<plugins/EnvironmentalMeasurement>
-<modules/esp32>
-<modules/Telemetry>
+<../variants/portduino>
build_flags = ${arduino_base.build_flags} -O0 -lgpiod -I variants/portduino
framework = arduino

Wyświetl plik

@ -5,7 +5,7 @@
#define BUTTON_PIN 38 // The middle button GPIO on the T-Beam
//#define BUTTON_PIN_ALT 13 // Alternate GPIO for an external button if needed. Does anyone use this? It is not documented anywhere.
#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Plugin.
#define EXT_NOTIFY_OUT 13 // Default pin to use for Ext Notify Module.
#define LED_INVERTED 1
#define LED_PIN 4 // Newer tbeams (1.1) have an extra led on GPIO4

Some files were not shown because too many files have changed in this diff Show More