kopia lustrzana https://github.com/meshtastic/firmware
Merge branch 'meshtastic:master' into master
commit
0a14f5d168
|
@ -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"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
2
proto
|
@ -1 +1 @@
|
|||
Subproject commit 30e147a55ce27199cb638a1d82e0b88adc8f5385
|
||||
Subproject commit f6ba3722be8a51c3c0c1446bb08e730a0be568e0
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
361
src/main.cpp
361
src/main.cpp
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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 = ∓
|
||||
|
||||
/// 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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
extern DeviceState devicestate;
|
||||
extern ChannelFile channelFile;
|
||||
extern MyNodeInfo &myNodeInfo;
|
||||
extern GroupInfo &ourGroupInfo;
|
||||
extern RadioConfig radioConfig;
|
||||
extern User &owner;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" */
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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" */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -21,3 +21,4 @@ PB_BIND(RadioConfig_UserPreferences, RadioConfig_UserPreferences, 2)
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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" */
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
@ -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" */
|
|
@ -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;
|
|
@ -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;
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -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
|
||||
}
|
|
@ -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();
|
|
@ -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;
|
|
@ -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();
|
||||
}
|
|
@ -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();
|
|
@ -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;
|
||||
|
|
@ -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;
|
|
@ -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());
|
||||
|
|
@ -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;
|
|
@ -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();
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
|
@ -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);
|
|
@ -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;
|
|
@ -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;
|
||||
|
|
@ -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;
|
|
@ -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
|
|
@ -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;
|
|
@ -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
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
};
|
|
@ -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
|
||||
}
|
|
@ -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;
|
|
@ -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();
|
||||
}
|
|
@ -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();
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -36,3 +36,7 @@ cstyleCast
|
|||
// ignore stuff that is not ours
|
||||
*:.pio/*
|
||||
*:*/libdeps/*
|
||||
|
||||
// these two caused issues
|
||||
missingOverride
|
||||
virtualCallInConstructor
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
Ładowanie…
Reference in New Issue