Compare commits

..

15 Commits

Author SHA1 Message Date
Tavis
092e6f2424 add rssi and snr to json output (#2894)
* add rssi and snr to json output

* explicitly cast to int and float
2023-10-17 06:50:36 -05:00
Andre K
e6b20bff77 refactor: simplify MQTT defaults (#2893)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-10-15 18:56:47 -05:00
Andre K
2c625f6ba1 fix: channel routing for decoded MQTT packets (#2892)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-10-15 06:41:40 -05:00
Manuel
142d56c663 allow sensors connected to second I2C port (#2891) 2023-10-14 19:33:45 -05:00
Ben Meadors
f4b40562d3 Start of TAK role (#2890)
* Start of TAK role

* Position flags change for CoT friendly altitudes

* Trunk
2023-10-14 06:49:38 -05:00
github-actions[bot]
9e203532d0 [create-pull-request] automated change (#2889) 2023-10-13 20:02:59 -05:00
code8buster
8bd7b5e779 Merge pull request #2887 from yupyvovarov/fix-hwids-address
Fix typo in tbeam-s3-core hwids address
2023-10-13 10:24:49 +00:00
Yurii Pyvovarov
1af970765f Fix typo in tbeam-s3-core hwids address 2023-10-13 11:31:10 +03:00
Ben Meadors
def55ec063 Remove specific upload ports from pio 2023-10-11 10:21:58 -05:00
Ben Meadors
092c6cac66 Convert from inline to static class methods (#2883) 2023-10-11 06:17:05 -05:00
Ben Meadors
e39f129bd6 More comprehensively clear current position info (#2881) 2023-10-10 19:33:58 -05:00
S5NC
9d1fe8c245 Update architecture.h (#2880) 2023-10-10 15:35:07 -05:00
Aciid
786248a6b1 Dragino TrackerD wip (#2324)
* Dragino TrackerD initial variant

* fmt

---------

Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2023-10-10 06:20:46 -05:00
github-actions[bot]
d1ac2dc6ea [create-pull-request] automated change (#2879)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2023-10-09 20:43:42 -05:00
Ben Meadors
87396d9105 Refactor away some code duplication in screen frames and display formatter for modem presets (#2872)
* Refactor away some duplication

* Refactor preset names to display formatter method

* Remove unused screen brightness adjustment and extract wifi disconnect reason name to display formatter method

* Tronk

* Let's be more clear with this naming

* Effed

* DisplayFormatters static class and use native wifi disconnect reason names method

* git mv file so casing should match now

* Include titlecase

* Trunk
2023-10-09 20:43:16 -05:00
54 changed files with 319 additions and 347 deletions

View File

@@ -1,6 +1,6 @@
version: 0.1 version: 0.1
cli: cli:
version: 1.16.2 version: 1.17.0
plugins: plugins:
sources: sources:
- id: trunk - id: trunk

View File

@@ -15,7 +15,7 @@
"f_cpu": "240000000L", "f_cpu": "240000000L",
"f_flash": "80000000L", "f_flash": "80000000L",
"flash_mode": "dio", "flash_mode": "dio",
"hwids": [["0X303A", "0x1001"]], "hwids": [["0x303A", "0x1001"]],
"mcu": "esp32s3", "mcu": "esp32s3",
"variant": "tbeam-s3-core" "variant": "tbeam-s3-core"
}, },

34
src/DisplayFormatters.cpp Normal file
View File

@@ -0,0 +1,34 @@
#include "DisplayFormatters.h"
const char *DisplayFormatters::getModemPresetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset, bool useShortName)
{
switch (preset) {
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
return useShortName ? "ShortS" : "ShortSlow";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
return useShortName ? "ShortF" : "ShortFast";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
return useShortName ? "MedS" : "MediumSlow";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
return useShortName ? "MedF" : "MediumFast";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW:
return useShortName ? "LongS" : "LongSlow";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
return useShortName ? "LongF" : "LongFast";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
return useShortName ? "LongM" : "LongMod";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
return useShortName ? "VeryL" : "VLongSlow";
break;
default:
return useShortName ? "Custom" : "Invalid";
break;
}
}

8
src/DisplayFormatters.h Normal file
View File

@@ -0,0 +1,8 @@
#pragma once
#include "NodeDB.h"
class DisplayFormatters
{
public:
static const char *getModemPresetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset, bool useShortName);
};

View File

@@ -281,9 +281,10 @@ class AnalogBatteryLevel : public HasBatteryLevel
#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO) #if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO)
uint16_t getINAVoltage() uint16_t getINAVoltage()
{ {
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219] == config.power.device_battery_ina_address) { if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
return ina219Sensor.getBusVoltageMv(); return ina219Sensor.getBusVoltageMv();
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260] == config.power.device_battery_ina_address) { } else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260].first ==
config.power.device_battery_ina_address) {
return ina260Sensor.getBusVoltageMv(); return ina260Sensor.getBusVoltageMv();
} }
return 0; return 0;
@@ -294,11 +295,12 @@ class AnalogBatteryLevel : public HasBatteryLevel
if (!config.power.device_battery_ina_address) { if (!config.power.device_battery_ina_address) {
return false; return false;
} }
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219] == config.power.device_battery_ina_address) { if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
if (!ina219Sensor.isInitialized()) if (!ina219Sensor.isInitialized())
return ina219Sensor.runOnce() > 0; return ina219Sensor.runOnce() > 0;
return ina219Sensor.isRunning(); return ina219Sensor.isRunning();
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260] == config.power.device_battery_ina_address) { } else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260].first ==
config.power.device_battery_ina_address) {
if (!ina260Sensor.isInitialized()) if (!ina260Sensor.isInitialized())
return ina260Sensor.runOnce() > 0; return ina260Sensor.runOnce() > 0;
return ina260Sensor.isRunning(); return ina260Sensor.isRunning();

View File

@@ -18,6 +18,8 @@ class ScanI2CTwoWire : public ScanI2C
ScanI2C::FoundDevice find(ScanI2C::DeviceType) const override; ScanI2C::FoundDevice find(ScanI2C::DeviceType) const override;
TwoWire *fetchI2CBus(ScanI2C::DeviceAddress) const;
bool exists(ScanI2C::DeviceType) const override; bool exists(ScanI2C::DeviceType) const override;
size_t countDevices() const override; size_t countDevices() const override;
@@ -51,6 +53,4 @@ class ScanI2CTwoWire : public ScanI2C
uint16_t getRegisterValue(const RegisterLocation &, ResponseWidth) const; uint16_t getRegisterValue(const RegisterLocation &, ResponseWidth) const;
DeviceType probeOLED(ScanI2C::DeviceAddress) const; DeviceType probeOLED(ScanI2C::DeviceAddress) const;
TwoWire *fetchI2CBus(ScanI2C::DeviceAddress) const;
}; };

View File

@@ -24,6 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#if HAS_SCREEN #if HAS_SCREEN
#include <OLEDDisplay.h> #include <OLEDDisplay.h>
#include "DisplayFormatters.h"
#include "GPS.h" #include "GPS.h"
#include "MeshService.h" #include "MeshService.h"
#include "NodeDB.h" #include "NodeDB.h"
@@ -160,34 +161,9 @@ static void drawIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDispl
xstr(APP_VERSION_SHORT)); // Note: we don't bother printing region or now, it makes the string too long xstr(APP_VERSION_SHORT)); // Note: we don't bother printing region or now, it makes the string too long
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(buf), y + 0, buf); display->drawString(x + SCREEN_WIDTH - display->getStringWidth(buf), y + 0, buf);
screen->forceDisplay(); screen->forceDisplay();
// FIXME - draw serial # somewhere? // FIXME - draw serial # somewhere?
} }
#ifdef ARCH_ESP32
static void drawFrameResume(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
uint16_t x_offset = display->width() / 2;
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_MEDIUM);
display->drawString(x_offset + x, 26 + y, "Resuming...");
}
#endif
static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
#ifdef ARCH_ESP32
if (wakeCause == ESP_SLEEP_WAKEUP_TIMER || wakeCause == ESP_SLEEP_WAKEUP_EXT1) {
drawFrameResume(display, state, x, y);
} else
#endif
{
// Draw region in upper left
const char *region = myRegion ? myRegion->name : NULL;
drawIconScreen(region, display, state, x, y);
}
}
static void drawOEMIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) static void drawOEMIconScreen(const char *upperMsg, OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{ {
// draw an xbm image. // draw an xbm image.
@@ -237,6 +213,28 @@ static void drawOEMBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, i
drawOEMIconScreen(region, display, state, x, y); drawOEMIconScreen(region, display, state, x, y);
} }
static void drawFrameText(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y, const char *message)
{
uint16_t x_offset = display->width() / 2;
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_MEDIUM);
display->drawString(x_offset + x, 26 + y, message);
}
static void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
#ifdef ARCH_ESP32
if (wakeCause == ESP_SLEEP_WAKEUP_TIMER || wakeCause == ESP_SLEEP_WAKEUP_EXT1) {
drawFrameText(display, state, x, y, "Resuming...");
} else
#endif
{
// Draw region in upper left
const char *region = myRegion ? myRegion->name : NULL;
drawIconScreen(region, display, state, x, y);
}
}
// Used on boot when a certificate is being created // Used on boot when a certificate is being created
static void drawSSLScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) static void drawSSLScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{ {
@@ -337,22 +335,6 @@ static void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state,
display->drawString(x_offset + x, y_offset + y, deviceName); display->drawString(x_offset + x, y_offset + y, deviceName);
} }
static void drawFrameShutdown(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
uint16_t x_offset = display->width() / 2;
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_MEDIUM);
display->drawString(x_offset + x, 26 + y, "Shutting down...");
}
static void drawFrameReboot(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
uint16_t x_offset = display->width() / 2;
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->setFont(FONT_MEDIUM);
display->drawString(x_offset + x, 26 + y, "Rebooting...");
}
static void drawFrameFirmware(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) static void drawFrameFirmware(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{ {
display->setTextAlignment(TEXT_ALIGN_CENTER); display->setTextAlignment(TEXT_ALIGN_CENTER);
@@ -923,20 +905,6 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
drawColumns(display, x, y, fields); drawColumns(display, x, y, fields);
} }
// #ifdef RAK4630
// Screen::Screen(uint8_t address, int sda, int scl) : OSThread("Screen"), cmdQueue(32), dispdev(address, sda, scl),
// dispdev_oled(address, sda, scl), ui(&dispdev)
// {
// address_found = address;
// cmdQueue.setReader(this);
// if (screen_found) {
// (void)dispdev;
// AutoOLEDWire dispdev = dispdev_oled;
// (void)ui;
// OLEDDisplayUi ui(&dispdev);
// }
// }
// #else
Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_OledType screenType, OLEDDISPLAY_GEOMETRY geometry) Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_OledType screenType, OLEDDISPLAY_GEOMETRY geometry)
: concurrency::OSThread("Screen"), address_found(address), model(screenType), geometry(geometry), cmdQueue(32), : concurrency::OSThread("Screen"), address_found(address), model(screenType), geometry(geometry), cmdQueue(32),
dispdev(address.address, -1, -1, geometry, (address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE), dispdev(address.address, -1, -1, geometry, (address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE),
@@ -944,7 +912,7 @@ Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_O
{ {
cmdQueue.setReader(this); cmdQueue.setReader(this);
} }
// #endif
/** /**
* Prepare the display for the unit going to the lowest power mode possible. Most screens will just * Prepare the display for the unit going to the lowest power mode possible. Most screens will just
* poweroff, but eink screens will show a "I'm sleeping" graphic, possibly with a QR code * poweroff, but eink screens will show a "I'm sleeping" graphic, possibly with a QR code
@@ -1261,11 +1229,8 @@ void Screen::setWelcomeFrames()
{ {
if (address_found.address) { if (address_found.address) {
// LOG_DEBUG("showing Welcome frames\n"); // LOG_DEBUG("showing Welcome frames\n");
ui.disableAllIndicators(); static FrameCallback frames[] = {drawWelcomeScreen};
setFrameImmediateDraw(frames);
static FrameCallback welcomeFrames[] = {drawWelcomeScreen};
ui.setFrames(welcomeFrames, 1);
ui.update();
} }
} }
@@ -1352,12 +1317,15 @@ void Screen::handleStartBluetoothPinScreen(uint32_t pin)
LOG_DEBUG("showing bluetooth screen\n"); LOG_DEBUG("showing bluetooth screen\n");
showingNormalScreen = false; showingNormalScreen = false;
static FrameCallback btFrames[] = {drawFrameBluetooth}; static FrameCallback frames[] = {drawFrameBluetooth};
snprintf(btPIN, sizeof(btPIN), "%06u", pin); snprintf(btPIN, sizeof(btPIN), "%06u", pin);
setFrameImmediateDraw(frames);
}
void Screen::setFrameImmediateDraw(FrameCallback *drawFrames)
{
ui.disableAllIndicators(); ui.disableAllIndicators();
ui.setFrames(btFrames, 1); ui.setFrames(drawFrames, 1);
setFastFramerate(); setFastFramerate();
} }
@@ -1366,11 +1334,12 @@ void Screen::handleShutdownScreen()
LOG_DEBUG("showing shutdown screen\n"); LOG_DEBUG("showing shutdown screen\n");
showingNormalScreen = false; showingNormalScreen = false;
static FrameCallback shutdownFrames[] = {drawFrameShutdown}; auto frame = [](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
drawFrameText(display, state, x, y, "Shutting down...");
};
static FrameCallback frames[] = {frame};
ui.disableAllIndicators(); setFrameImmediateDraw(frames);
ui.setFrames(shutdownFrames, 1);
setFastFramerate();
} }
void Screen::handleRebootScreen() void Screen::handleRebootScreen()
@@ -1378,11 +1347,11 @@ void Screen::handleRebootScreen()
LOG_DEBUG("showing reboot screen\n"); LOG_DEBUG("showing reboot screen\n");
showingNormalScreen = false; showingNormalScreen = false;
static FrameCallback rebootFrames[] = {drawFrameReboot}; auto frame = [](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
drawFrameText(display, state, x, y, "Rebooting...");
ui.disableAllIndicators(); };
ui.setFrames(rebootFrames, 1); static FrameCallback frames[] = {frame};
setFastFramerate(); setFrameImmediateDraw(frames);
} }
void Screen::handleStartFirmwareUpdateScreen() void Screen::handleStartFirmwareUpdateScreen()
@@ -1390,11 +1359,8 @@ void Screen::handleStartFirmwareUpdateScreen()
LOG_DEBUG("showing firmware screen\n"); LOG_DEBUG("showing firmware screen\n");
showingNormalScreen = false; showingNormalScreen = false;
static FrameCallback btFrames[] = {drawFrameFirmware}; static FrameCallback frames[] = {drawFrameFirmware};
setFrameImmediateDraw(frames);
ui.disableAllIndicators();
ui.setFrames(btFrames, 1);
setFastFramerate();
} }
void Screen::blink() void Screen::blink()
@@ -1655,65 +1621,8 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
} else { } else {
// Codes: // Codes:
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-reason-code // https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#wi-fi-reason-code
if (getWifiDisconnectReason() == 2) { display->drawString(x, y + FONT_HEIGHT_SMALL * 1,
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Authentication Invalid"); WiFi.disconnectReasonName(static_cast<wifi_err_reason_t>(getWifiDisconnectReason())));
} else if (getWifiDisconnectReason() == 3) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "De-authenticated");
} else if (getWifiDisconnectReason() == 4) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Disassociated Expired");
} else if (getWifiDisconnectReason() == 5) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AP - Too Many Clients");
} else if (getWifiDisconnectReason() == 6) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "NOT_AUTHED");
} else if (getWifiDisconnectReason() == 7) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "NOT_ASSOCED");
} else if (getWifiDisconnectReason() == 8) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Disassociated");
} else if (getWifiDisconnectReason() == 9) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "ASSOC_NOT_AUTHED");
} else if (getWifiDisconnectReason() == 10) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "DISASSOC_PWRCAP_BAD");
} else if (getWifiDisconnectReason() == 11) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "DISASSOC_SUPCHAN_BAD");
} else if (getWifiDisconnectReason() == 13) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IE_INVALID");
} else if (getWifiDisconnectReason() == 14) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "MIC_FAILURE");
} else if (getWifiDisconnectReason() == 15) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AP Handshake Timeout");
} else if (getWifiDisconnectReason() == 16) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "GROUP_KEY_UPDATE_TIMEOUT");
} else if (getWifiDisconnectReason() == 17) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IE_IN_4WAY_DIFFERS");
} else if (getWifiDisconnectReason() == 18) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Invalid Group Cipher");
} else if (getWifiDisconnectReason() == 19) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Invalid Pairwise Cipher");
} else if (getWifiDisconnectReason() == 20) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AKMP_INVALID");
} else if (getWifiDisconnectReason() == 21) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "UNSUPP_RSN_IE_VERSION");
} else if (getWifiDisconnectReason() == 22) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "INVALID_RSN_IE_CAP");
} else if (getWifiDisconnectReason() == 23) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "802_1X_AUTH_FAILED");
} else if (getWifiDisconnectReason() == 24) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "CIPHER_SUITE_REJECTED");
} else if (getWifiDisconnectReason() == 200) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "BEACON_TIMEOUT");
} else if (getWifiDisconnectReason() == 201) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AP Not Found");
} else if (getWifiDisconnectReason() == 202) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "AUTH_FAIL");
} else if (getWifiDisconnectReason() == 203) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "ASSOC_FAIL");
} else if (getWifiDisconnectReason() == 204) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "HANDSHAKE_TIMEOUT");
} else if (getWifiDisconnectReason() == 205) {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Connection Failed");
} else {
display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "Unknown Status");
}
} }
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName)); display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
@@ -1760,37 +1669,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
display->drawString(x + 1, y, String("USB")); display->drawString(x + 1, y, String("USB"));
} }
auto mode = ""; auto mode = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, true);
switch (config.lora.modem_preset) {
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
mode = "ShortS";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
mode = "ShortF";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
mode = "MedS";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
mode = "MedF";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW:
mode = "LongS";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
mode = "LongF";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
mode = "LongM";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
mode = "VeryL";
break;
default:
mode = "Custom";
break;
}
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode), y, mode); display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode), y, mode);
if (config.display.heading_bold) if (config.display.heading_bold)
@@ -1857,23 +1736,6 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
heartbeat = !heartbeat; heartbeat = !heartbeat;
#endif #endif
} }
// adjust Brightness cycle through 1 to 254 as long as attachDuringLongPress is true
void Screen::adjustBrightness()
{
if (!useDisplay)
return;
if (brightness == 254) {
brightness = 0;
} else {
brightness++;
}
int width = brightness / (254.00 / SCREEN_WIDTH);
dispdev.drawRect(0, 30, SCREEN_WIDTH, 4);
dispdev.fillRect(0, 31, width, 2);
dispdev.display();
dispdev.setBrightness(brightness);
}
int Screen::handleStatusUpdate(const meshtastic::Status *arg) int Screen::handleStatusUpdate(const meshtastic::Status *arg)
{ {

View File

@@ -19,7 +19,6 @@ class Screen
void setup() {} void setup() {}
void setOn(bool) {} void setOn(bool) {}
void print(const char *) {} void print(const char *) {}
void adjustBrightness() {}
void doDeepSleep() {} void doDeepSleep() {}
void forceDisplay() {} void forceDisplay() {}
void startBluetoothPinScreen(uint32_t pin) {} void startBluetoothPinScreen(uint32_t pin) {}
@@ -161,7 +160,6 @@ class Screen : public concurrency::OSThread
void showNextFrame() { enqueueCmd(ScreenCmd{.cmd = Cmd::SHOW_NEXT_FRAME}); } void showNextFrame() { enqueueCmd(ScreenCmd{.cmd = Cmd::SHOW_NEXT_FRAME}); }
// Implementation to Adjust Brightness // Implementation to Adjust Brightness
void adjustBrightness();
uint8_t brightness = BRIGHTNESS_DEFAULT; uint8_t brightness = BRIGHTNESS_DEFAULT;
/// Starts showing the Bluetooth PIN screen. /// Starts showing the Bluetooth PIN screen.
@@ -363,6 +361,9 @@ class Screen : public concurrency::OSThread
/// Try to start drawing ASAP /// Try to start drawing ASAP
void setFastFramerate(); void setFastFramerate();
// Sets frame up for immediate drawing
void setFrameImmediateDraw(FrameCallback *drawFrames);
/// Called when debug screen is to be drawn, calls through to debugInfo.drawFrame. /// Called when debug screen is to be drawn, calls through to debugInfo.drawFrame.
static void drawDebugInfoTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y); static void drawDebugInfoTrampoline(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);

View File

@@ -29,6 +29,7 @@
#include "target_specific.h" #include "target_specific.h"
#include <Wire.h> #include <Wire.h>
#include <memory> #include <memory>
#include <utility>
// #include <driver/rtc_io.h> // #include <driver/rtc_io.h>
#include "mesh/eth/ethClient.h" #include "mesh/eth/ethClient.h"
@@ -122,9 +123,8 @@ uint32_t serialSinceMsec;
bool pmu_found; bool pmu_found;
// Array map of sensor types (as array index) and i2c address as value we'll find in the i2c scan // Array map of sensor types with i2c address and wire as we'll find in the i2c scan
uint8_t nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1] = { std::pair<uint8_t, TwoWire *> nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1] = {};
0}; // one is enough, missing elements will be initialized to 0 anyway.
Router *router = NULL; // Users of router don't care what sort of subclass implements that API Router *router = NULL; // Users of router don't care what sort of subclass implements that API
@@ -491,7 +491,8 @@ void setup()
{ \ { \
auto found = i2cScanner->find(SCANNER_T); \ auto found = i2cScanner->find(SCANNER_T); \
if (found.type != ScanI2C::DeviceType::NONE) { \ if (found.type != ScanI2C::DeviceType::NONE) { \
nodeTelemetrySensorsMap[PB_T] = found.address.address; \ nodeTelemetrySensorsMap[PB_T].first = found.address.address; \
nodeTelemetrySensorsMap[PB_T].second = i2cScanner->fetchI2CBus(found.address); \
LOG_DEBUG("found i2c sensor %s\n", STRING(PB_T)); \ LOG_DEBUG("found i2c sensor %s\n", STRING(PB_T)); \
} \ } \
} }

View File

@@ -1,5 +1,6 @@
#include "Channels.h" #include "Channels.h"
#include "CryptoEngine.h" #include "CryptoEngine.h"
#include "DisplayFormatters.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "configuration.h" #include "configuration.h"
@@ -239,38 +240,9 @@ const char *Channels::getName(size_t chIndex)
const char *channelName = channelSettings.name; const char *channelName = channelSettings.name;
if (!*channelName) { // emptystring if (!*channelName) { // emptystring
// Per mesh.proto spec, if bandwidth is specified we must ignore modemPreset enum, we assume that in that case // Per mesh.proto spec, if bandwidth is specified we must ignore modemPreset enum, we assume that in that case
// the app fucked up and forgot to set channelSettings.name // the app effed up and forgot to set channelSettings.name
if (config.lora.use_preset) { if (config.lora.use_preset) {
switch (config.lora.modem_preset) { channelName = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false);
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
channelName = "ShortSlow";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
channelName = "ShortFast";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
channelName = "MediumSlow";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
channelName = "MediumFast";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW:
channelName = "LongSlow";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST:
channelName = "LongFast";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
channelName = "LongMod";
break;
case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW:
channelName = "VLongSlow";
break;
default:
channelName = "Invalid";
break;
}
} else { } else {
channelName = "Custom"; channelName = "Custom";
} }

View File

@@ -335,7 +335,7 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *newStatus)
// Used fixed position if configured regalrdless of GPS lock // Used fixed position if configured regalrdless of GPS lock
if (config.position.fixed_position) { if (config.position.fixed_position) {
LOG_WARN("Using fixed position\n"); LOG_WARN("Using fixed position\n");
pos = ConvertToPosition(node->position); pos = TypeConversions::ConvertToPosition(node->position);
} }
// Add a fresh timestamp // Add a fresh timestamp

View File

@@ -254,6 +254,8 @@ void NodeDB::installDefaultModuleConfig()
strncpy(moduleConfig.mqtt.address, default_mqtt_address, sizeof(moduleConfig.mqtt.address)); strncpy(moduleConfig.mqtt.address, default_mqtt_address, sizeof(moduleConfig.mqtt.address));
strncpy(moduleConfig.mqtt.username, default_mqtt_username, sizeof(moduleConfig.mqtt.username)); strncpy(moduleConfig.mqtt.username, default_mqtt_username, sizeof(moduleConfig.mqtt.username));
strncpy(moduleConfig.mqtt.password, default_mqtt_password, sizeof(moduleConfig.mqtt.password)); strncpy(moduleConfig.mqtt.password, default_mqtt_password, sizeof(moduleConfig.mqtt.password));
strncpy(moduleConfig.mqtt.root, default_mqtt_root, sizeof(moduleConfig.mqtt.root));
moduleConfig.mqtt.encryption_enabled = true;
moduleConfig.has_neighbor_info = true; moduleConfig.has_neighbor_info = true;
moduleConfig.neighbor_info.enabled = false; moduleConfig.neighbor_info.enabled = false;
@@ -285,6 +287,15 @@ void NodeDB::installRoleDefaults(meshtastic_Config_DeviceConfig_Role role)
} else if (role == meshtastic_Config_DeviceConfig_Role_SENSOR) { } else if (role == meshtastic_Config_DeviceConfig_Role_SENSOR) {
moduleConfig.telemetry.environment_measurement_enabled = true; moduleConfig.telemetry.environment_measurement_enabled = true;
moduleConfig.telemetry.environment_update_interval = 300; moduleConfig.telemetry.environment_update_interval = 300;
} else if (role == meshtastic_Config_DeviceConfig_Role_TAK) {
config.device.node_info_broadcast_secs = ONE_DAY;
config.position.position_broadcast_smart_enabled = false;
config.position.position_broadcast_secs = ONE_DAY;
// Remove Altitude MSL from flags since CoTs use HAE (height above ellipsoid)
config.position.position_flags =
(meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_SPEED |
meshtastic_Config_PositionConfig_PositionFlags_HEADING | meshtastic_Config_PositionConfig_PositionFlags_DOP);
moduleConfig.telemetry.device_update_interval = ONE_DAY;
} }
} }
@@ -688,7 +699,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
p.longitude_i, p.altitude); p.longitude_i, p.altitude);
setLocalPosition(p); setLocalPosition(p);
info->position = ConvertToPositionLite(p); info->position = TypeConversions::ConvertToPositionLite(p);
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) { } else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) {
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO // FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
// (stop-gap fix for issue #900) // (stop-gap fix for issue #900)
@@ -706,7 +717,7 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
uint32_t tmp_time = info->position.time; uint32_t tmp_time = info->position.time;
// Next, update atomically // Next, update atomically
info->position = ConvertToPositionLite(p); info->position = TypeConversions::ConvertToPositionLite(p);
// Last, restore any fields that may have been overwritten // Last, restore any fields that may have been overwritten
if (!info->position.time) if (!info->position.time)

View File

@@ -204,6 +204,7 @@ extern NodeDB nodeDB;
#define default_mqtt_address "mqtt.meshtastic.org" #define default_mqtt_address "mqtt.meshtastic.org"
#define default_mqtt_username "meshdev" #define default_mqtt_username "meshdev"
#define default_mqtt_password "large4cats" #define default_mqtt_password "large4cats"
#define default_mqtt_root "msh"
inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval) inline uint32_t getConfiguredOrDefaultMs(uint32_t configuredInterval)
{ {

View File

@@ -405,7 +405,7 @@ bool PhoneAPI::available()
if (nodeInfoForPhone.num == 0) { if (nodeInfoForPhone.num == 0) {
auto nextNode = nodeDB.readNextMeshNode(readIndex); auto nextNode = nodeDB.readNextMeshNode(readIndex);
if (nextNode) { if (nextNode) {
nodeInfoForPhone = ConvertToNodeInfo(nextNode); nodeInfoForPhone = TypeConversions::ConvertToNodeInfo(nextNode);
} }
} }
return true; // Always say we have something, because we might need to advance our state machine return true; // Always say we have something, because we might need to advance our state machine

View File

@@ -249,29 +249,12 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) { if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
ChannelIndex chIndex = p->channel; // keep as a local because we are about to change it ChannelIndex chIndex = p->channel; // keep as a local because we are about to change it
bool shouldActuallyEncrypt = true;
if (moduleConfig.mqtt.enabled) { if (moduleConfig.mqtt.enabled) {
// check if we should send decrypted packets to mqtt
// truth table: LOG_INFO("Should encrypt MQTT?: %d\n", moduleConfig.mqtt.encryption_enabled);
/* mqtt_server mqtt_encryption_enabled should_encrypt
* not set 0 1
* not set 1 1
* set 0 0
* set 1 1
*
* => so we only decrypt mqtt if they have a custom mqtt server AND mqtt_encryption_enabled is FALSE
*/
if (*moduleConfig.mqtt.address && !moduleConfig.mqtt.encryption_enabled) {
shouldActuallyEncrypt = false;
}
LOG_INFO("Should encrypt MQTT?: %d\n", shouldActuallyEncrypt);
// the packet is currently in a decrypted state. send it now if they want decrypted packets // the packet is currently in a decrypted state. send it now if they want decrypted packets
if (mqtt && !shouldActuallyEncrypt) if (mqtt && !moduleConfig.mqtt.encryption_enabled)
mqtt->onSend(*p, chIndex); mqtt->onSend(*p, chIndex);
} }
@@ -284,7 +267,7 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
if (moduleConfig.mqtt.enabled) { if (moduleConfig.mqtt.enabled) {
// the packet is now encrypted. // the packet is now encrypted.
// check if we should send encrypted packets to mqtt // check if we should send encrypted packets to mqtt
if (mqtt && shouldActuallyEncrypt) if (mqtt && moduleConfig.mqtt.encryption_enabled)
mqtt->onSend(*p, chIndex); mqtt->onSend(*p, chIndex);
} }
} }

View File

@@ -0,0 +1,55 @@
#include "TypeConversions.h"
#include "mesh/generated/meshtastic/deviceonly.pb.h"
#include "mesh/generated/meshtastic/mesh.pb.h"
meshtastic_NodeInfo TypeConversions::ConvertToNodeInfo(const meshtastic_NodeInfoLite *lite)
{
meshtastic_NodeInfo info = meshtastic_NodeInfo_init_default;
info.num = lite->num;
info.snr = lite->snr;
info.last_heard = lite->last_heard;
info.channel = lite->channel;
if (lite->has_position) {
info.has_position = true;
info.position.latitude_i = lite->position.latitude_i;
info.position.longitude_i = lite->position.longitude_i;
info.position.altitude = lite->position.altitude;
info.position.location_source = lite->position.location_source;
info.position.time = lite->position.time;
}
if (lite->has_user) {
info.has_user = true;
info.user = lite->user;
}
if (lite->has_device_metrics) {
info.has_device_metrics = true;
info.device_metrics = lite->device_metrics;
}
return info;
}
meshtastic_PositionLite TypeConversions::ConvertToPositionLite(meshtastic_Position position)
{
meshtastic_PositionLite lite = meshtastic_PositionLite_init_default;
lite.latitude_i = position.latitude_i;
lite.longitude_i = position.longitude_i;
lite.altitude = position.altitude;
lite.location_source = position.location_source;
lite.time = position.time;
return lite;
}
meshtastic_Position TypeConversions::ConvertToPosition(meshtastic_PositionLite lite)
{
meshtastic_Position position = meshtastic_Position_init_default;
position.latitude_i = lite.latitude_i;
position.longitude_i = lite.longitude_i;
position.altitude = lite.altitude;
position.location_source = lite.location_source;
position.time = lite.time;
return position;
}

View File

@@ -1,54 +1,13 @@
#include "mesh/generated/meshtastic/deviceonly.pb.h" #include "mesh/generated/meshtastic/deviceonly.pb.h"
#include "mesh/generated/meshtastic/mesh.pb.h" #include "mesh/generated/meshtastic/mesh.pb.h"
inline static meshtastic_NodeInfo ConvertToNodeInfo(const meshtastic_NodeInfoLite *lite) #pragma once
#include "NodeDB.h"
class TypeConversions
{ {
meshtastic_NodeInfo info = meshtastic_NodeInfo_init_default; public:
static meshtastic_NodeInfo ConvertToNodeInfo(const meshtastic_NodeInfoLite *lite);
info.num = lite->num; static meshtastic_PositionLite ConvertToPositionLite(meshtastic_Position position);
info.snr = lite->snr; static meshtastic_Position ConvertToPosition(meshtastic_PositionLite lite);
info.last_heard = lite->last_heard; };
info.channel = lite->channel;
if (lite->has_position) {
info.has_position = true;
info.position.latitude_i = lite->position.latitude_i;
info.position.longitude_i = lite->position.longitude_i;
info.position.altitude = lite->position.altitude;
info.position.location_source = lite->position.location_source;
info.position.time = lite->position.time;
}
if (lite->has_user) {
info.has_user = true;
info.user = lite->user;
}
if (lite->has_device_metrics) {
info.has_device_metrics = true;
info.device_metrics = lite->device_metrics;
}
return info;
}
inline static meshtastic_PositionLite ConvertToPositionLite(meshtastic_Position position)
{
meshtastic_PositionLite lite = meshtastic_PositionLite_init_default;
lite.latitude_i = position.latitude_i;
lite.longitude_i = position.longitude_i;
lite.altitude = position.altitude;
lite.location_source = position.location_source;
lite.time = position.time;
return lite;
}
inline static meshtastic_Position ConvertToPosition(meshtastic_PositionLite lite)
{
meshtastic_Position position = meshtastic_Position_init_default;
position.latitude_i = lite.latitude_i;
position.longitude_i = lite.longitude_i;
position.altitude = lite.altitude;
position.location_source = lite.location_source;
position.time = lite.time;
return position;
}

View File

@@ -38,7 +38,12 @@ typedef enum _meshtastic_Config_DeviceConfig_Role {
Telemetry Mesh packets will be prioritized higher and sent more frequently by default. Telemetry Mesh packets will be prioritized higher and sent more frequently by default.
When used in conjunction with power.is_power_saving = true, nodes will wake up, When used in conjunction with power.is_power_saving = true, nodes will wake up,
send environment telemetry, and then sleep for telemetry.environment_update_interval seconds. */ send environment telemetry, and then sleep for telemetry.environment_update_interval seconds. */
meshtastic_Config_DeviceConfig_Role_SENSOR = 6 meshtastic_Config_DeviceConfig_Role_SENSOR = 6,
/* TAK device role
Used for nodes dedicated for connection to an ATAK EUD.
Turns off many of the routine broadcasts to favor CoT packet stream
from the Meshtastic ATAK plugin -> IMeshService -> Node */
meshtastic_Config_DeviceConfig_Role_TAK = 7
} meshtastic_Config_DeviceConfig_Role; } meshtastic_Config_DeviceConfig_Role;
/* Defines the device's behavior for how messages are rebroadcast */ /* Defines the device's behavior for how messages are rebroadcast */
@@ -474,8 +479,8 @@ extern "C" {
/* Helper constants for enums */ /* Helper constants for enums */
#define _meshtastic_Config_DeviceConfig_Role_MIN meshtastic_Config_DeviceConfig_Role_CLIENT #define _meshtastic_Config_DeviceConfig_Role_MIN meshtastic_Config_DeviceConfig_Role_CLIENT
#define _meshtastic_Config_DeviceConfig_Role_MAX meshtastic_Config_DeviceConfig_Role_SENSOR #define _meshtastic_Config_DeviceConfig_Role_MAX meshtastic_Config_DeviceConfig_Role_TAK
#define _meshtastic_Config_DeviceConfig_Role_ARRAYSIZE ((meshtastic_Config_DeviceConfig_Role)(meshtastic_Config_DeviceConfig_Role_SENSOR+1)) #define _meshtastic_Config_DeviceConfig_Role_ARRAYSIZE ((meshtastic_Config_DeviceConfig_Role)(meshtastic_Config_DeviceConfig_Role_TAK+1))
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN meshtastic_Config_DeviceConfig_RebroadcastMode_ALL #define _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN meshtastic_Config_DeviceConfig_RebroadcastMode_ALL
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_MAX meshtastic_Config_DeviceConfig_RebroadcastMode_LOCAL_ONLY #define _meshtastic_Config_DeviceConfig_RebroadcastMode_MAX meshtastic_Config_DeviceConfig_RebroadcastMode_LOCAL_ONLY

View File

@@ -113,8 +113,8 @@ typedef enum _meshtastic_HardwareModel {
meshtastic_HardwareModel_PICOMPUTER_S3 = 52, meshtastic_HardwareModel_PICOMPUTER_S3 = 52,
/* Heltec HT-CT62 with ESP32-C3 CPU and SX1262 LoRa */ /* Heltec HT-CT62 with ESP32-C3 CPU and SX1262 LoRa */
meshtastic_HardwareModel_HELTEC_HT62 = 53, meshtastic_HardwareModel_HELTEC_HT62 = 53,
/* E22-900M series modules with ESP32-S3 */ /* EBYTE SPI LoRa module and ESP32-S3 */
meshtastic_HardwareModel_E22_900M_S3 = 54, meshtastic_HardwareModel_EBYTE_ESP32_S3 = 54,
/* ------------------------------------------------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------------------------------------------------
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
------------------------------------------------------------------------------------------------------------------------------------------ */ ------------------------------------------------------------------------------------------------------------------------------------------ */

View File

@@ -88,7 +88,7 @@ void setupModules()
#endif #endif
#if HAS_SENSOR #if HAS_SENSOR
new EnvironmentTelemetryModule(); new EnvironmentTelemetryModule();
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I] > 0) { if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I].first > 0) {
new AirQualityTelemetryModule(); new AirQualityTelemetryModule();
} }
#endif #endif

View File

@@ -33,6 +33,9 @@ void PositionModule::clearPosition()
meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum()); meshtastic_NodeInfoLite *node = nodeDB.getMeshNode(nodeDB.getNodeNum());
node->position.latitude_i = 0; node->position.latitude_i = 0;
node->position.longitude_i = 0; node->position.longitude_i = 0;
node->position.altitude = 0;
node->position.time = 0;
nodeDB.setLocalPosition(meshtastic_Position_init_default);
} }
bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Position *pptr) bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Position *pptr)
@@ -98,7 +101,7 @@ meshtastic_MeshPacket *PositionModule::allocReply()
meshtastic_Position p = meshtastic_Position_init_default; // Start with an empty structure meshtastic_Position p = meshtastic_Position_init_default; // Start with an empty structure
// if localPosition is totally empty, put our last saved position (lite) in there // if localPosition is totally empty, put our last saved position (lite) in there
if (localPosition.latitude_i == 0 && localPosition.longitude_i == 0) { if (localPosition.latitude_i == 0 && localPosition.longitude_i == 0) {
nodeDB.setLocalPosition(ConvertToPosition(node->position)); nodeDB.setLocalPosition(TypeConversions::ConvertToPosition(node->position));
} }
localPosition.seq_number++; localPosition.seq_number++;

View File

@@ -13,7 +13,7 @@ int32_t BME280Sensor::runOnce()
if (!hasSensor()) { if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
} }
status = bme280.begin(nodeTelemetrySensorsMap[sensorType]); status = bme280.begin(nodeTelemetrySensorsMap[sensorType].first, nodeTelemetrySensorsMap[sensorType].second);
bme280.setSampling(Adafruit_BME280::MODE_FORCED, bme280.setSampling(Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, // Temp. oversampling Adafruit_BME280::SAMPLING_X1, // Temp. oversampling

View File

@@ -2,7 +2,7 @@
#include "TelemetrySensor.h" #include "TelemetrySensor.h"
#include <Adafruit_BME280.h> #include <Adafruit_BME280.h>
class BME280Sensor : virtual public TelemetrySensor class BME280Sensor : public TelemetrySensor
{ {
private: private:
Adafruit_BME280 bme280; Adafruit_BME280 bme280;

View File

@@ -20,7 +20,7 @@ int32_t BME680Sensor::runOnce()
if (!hasSensor()) { if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
} }
if (!bme680.begin(nodeTelemetrySensorsMap[sensorType], Wire)) if (!bme680.begin(nodeTelemetrySensorsMap[sensorType].first, *nodeTelemetrySensorsMap[sensorType].second))
checkStatus("begin"); checkStatus("begin");
if (bme680.status == BSEC_OK) { if (bme680.status == BSEC_OK) {

View File

@@ -6,7 +6,7 @@
#include "bme680_iaq_33v_3s_4d/bsec_iaq.h" #include "bme680_iaq_33v_3s_4d/bsec_iaq.h"
class BME680Sensor : virtual public TelemetrySensor class BME680Sensor : public TelemetrySensor
{ {
private: private:
Bsec2 bme680; Bsec2 bme680;

View File

@@ -13,7 +13,8 @@ int32_t BMP280Sensor::runOnce()
if (!hasSensor()) { if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
} }
status = bmp280.begin(nodeTelemetrySensorsMap[sensorType]); bmp280 = Adafruit_BMP280(nodeTelemetrySensorsMap[sensorType].second);
status = bmp280.begin(nodeTelemetrySensorsMap[sensorType].first);
bmp280.setSampling(Adafruit_BMP280::MODE_FORCED, bmp280.setSampling(Adafruit_BMP280::MODE_FORCED,
Adafruit_BMP280::SAMPLING_X1, // Temp. oversampling Adafruit_BMP280::SAMPLING_X1, // Temp. oversampling

View File

@@ -2,7 +2,7 @@
#include "TelemetrySensor.h" #include "TelemetrySensor.h"
#include <Adafruit_BMP280.h> #include <Adafruit_BMP280.h>
class BMP280Sensor : virtual public TelemetrySensor class BMP280Sensor : public TelemetrySensor
{ {
private: private:
Adafruit_BMP280 bmp280; Adafruit_BMP280 bmp280;

View File

@@ -13,8 +13,8 @@ int32_t INA219Sensor::runOnce()
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
} }
if (!ina219.success()) { if (!ina219.success()) {
ina219 = Adafruit_INA219(nodeTelemetrySensorsMap[sensorType]); ina219 = Adafruit_INA219(nodeTelemetrySensorsMap[sensorType].first);
status = ina219.begin(); status = ina219.begin(nodeTelemetrySensorsMap[sensorType].second);
} else { } else {
status = ina219.success(); status = ina219.success();
} }

View File

@@ -3,7 +3,7 @@
#include "VoltageSensor.h" #include "VoltageSensor.h"
#include <Adafruit_INA219.h> #include <Adafruit_INA219.h>
class INA219Sensor : virtual public TelemetrySensor, VoltageSensor class INA219Sensor : public TelemetrySensor, VoltageSensor
{ {
private: private:
Adafruit_INA219 ina219; Adafruit_INA219 ina219;

View File

@@ -14,7 +14,7 @@ int32_t INA260Sensor::runOnce()
} }
if (!status) { if (!status) {
status = ina260.begin(nodeTelemetrySensorsMap[sensorType]); status = ina260.begin(nodeTelemetrySensorsMap[sensorType].first, nodeTelemetrySensorsMap[sensorType].second);
} }
return initI2CSensor(); return initI2CSensor();
} }

View File

@@ -3,7 +3,7 @@
#include "VoltageSensor.h" #include "VoltageSensor.h"
#include <Adafruit_INA260.h> #include <Adafruit_INA260.h>
class INA260Sensor : virtual public TelemetrySensor, VoltageSensor class INA260Sensor : public TelemetrySensor, VoltageSensor
{ {
private: private:
Adafruit_INA260 ina260 = Adafruit_INA260(); Adafruit_INA260 ina260 = Adafruit_INA260();

View File

@@ -13,7 +13,7 @@ int32_t LPS22HBSensor::runOnce()
if (!hasSensor()) { if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
} }
status = lps22hb.begin_I2C(nodeTelemetrySensorsMap[sensorType]); status = lps22hb.begin_I2C(nodeTelemetrySensorsMap[sensorType].first, nodeTelemetrySensorsMap[sensorType].second);
return initI2CSensor(); return initI2CSensor();
} }

View File

@@ -3,7 +3,7 @@
#include <Adafruit_LPS2X.h> #include <Adafruit_LPS2X.h>
#include <Adafruit_Sensor.h> #include <Adafruit_Sensor.h>
class LPS22HBSensor : virtual public TelemetrySensor class LPS22HBSensor : public TelemetrySensor
{ {
private: private:
Adafruit_LPS22 lps22hb; Adafruit_LPS22 lps22hb;

View File

@@ -12,7 +12,7 @@ int32_t MCP9808Sensor::runOnce()
if (!hasSensor()) { if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
} }
status = mcp9808.begin(nodeTelemetrySensorsMap[sensorType]); status = mcp9808.begin(nodeTelemetrySensorsMap[sensorType].first, nodeTelemetrySensorsMap[sensorType].second);
return initI2CSensor(); return initI2CSensor();
} }

View File

@@ -2,7 +2,7 @@
#include "TelemetrySensor.h" #include "TelemetrySensor.h"
#include <Adafruit_MCP9808.h> #include <Adafruit_MCP9808.h>
class MCP9808Sensor : virtual public TelemetrySensor class MCP9808Sensor : public TelemetrySensor
{ {
private: private:
Adafruit_MCP9808 mcp9808; Adafruit_MCP9808 mcp9808;

View File

@@ -2,7 +2,7 @@
#include "TelemetrySensor.h" #include "TelemetrySensor.h"
#include <Adafruit_SHT31.h> #include <Adafruit_SHT31.h>
class SHT31Sensor : virtual public TelemetrySensor class SHT31Sensor : public TelemetrySensor
{ {
private: private:
Adafruit_SHT31 sht31 = Adafruit_SHT31(); Adafruit_SHT31 sht31 = Adafruit_SHT31();

View File

@@ -2,7 +2,7 @@
#include "TelemetrySensor.h" #include "TelemetrySensor.h"
#include <Adafruit_SHTC3.h> #include <Adafruit_SHTC3.h>
class SHTC3Sensor : virtual public TelemetrySensor class SHTC3Sensor : public TelemetrySensor
{ {
private: private:
Adafruit_SHTC3 shtc3 = Adafruit_SHTC3(); Adafruit_SHTC3 shtc3 = Adafruit_SHTC3();

View File

@@ -1,9 +1,12 @@
#pragma once #pragma once
#include "../mesh/generated/meshtastic/telemetry.pb.h" #include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "NodeDB.h" #include "NodeDB.h"
#include <utility>
class TwoWire;
#define DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000 #define DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
extern uint8_t nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1]; extern std::pair<uint8_t, TwoWire *> nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1];
class TelemetrySensor class TelemetrySensor
{ {
@@ -16,7 +19,7 @@ class TelemetrySensor
} }
const char *sensorName; const char *sensorName;
meshtastic_TelemetrySensorType sensorType; meshtastic_TelemetrySensorType sensorType = meshtastic_TelemetrySensorType_SENSOR_UNSET;
unsigned status; unsigned status;
bool initialized = false; bool initialized = false;
@@ -24,9 +27,9 @@ class TelemetrySensor
{ {
if (!status) { if (!status) {
LOG_WARN("Could not connect to detected %s sensor.\n Removing from nodeTelemetrySensorsMap.\n", sensorName); LOG_WARN("Could not connect to detected %s sensor.\n Removing from nodeTelemetrySensorsMap.\n", sensorName);
nodeTelemetrySensorsMap[sensorType] = 0; nodeTelemetrySensorsMap[sensorType].first = 0;
} else { } else {
LOG_INFO("Opened %s sensor on default i2c bus\n", sensorName); LOG_INFO("Opened %s sensor on i2c bus\n", sensorName);
setup(); setup();
} }
initialized = true; initialized = true;
@@ -35,7 +38,7 @@ class TelemetrySensor
virtual void setup(); virtual void setup();
public: public:
bool hasSensor() { return sensorType < sizeof(nodeTelemetrySensorsMap) && nodeTelemetrySensorsMap[sensorType] > 0; } bool hasSensor() { return nodeTelemetrySensorsMap[sensorType].first > 0; }
virtual int32_t runOnce() = 0; virtual int32_t runOnce() = 0;
virtual bool isInitialized() { return initialized; } virtual bool isInitialized() { return initialized; }

View File

@@ -133,10 +133,16 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
if (strcmp(e.gateway_id, owner.id) == 0) if (strcmp(e.gateway_id, owner.id) == 0)
LOG_INFO("Ignoring downlink message we originally sent.\n"); LOG_INFO("Ignoring downlink message we originally sent.\n");
else { else {
if (e.packet) { // Find channel by channel_id and check downlink_enabled
meshtastic_Channel ch = channels.getByName(e.channel_id);
if (strcmp(e.channel_id, channels.getGlobalId(ch.index)) == 0 && e.packet && ch.settings.downlink_enabled) {
LOG_INFO("Received MQTT topic %s, len=%u\n", topic, length); LOG_INFO("Received MQTT topic %s, len=%u\n", topic, length);
meshtastic_MeshPacket *p = packetPool.allocCopy(*e.packet); meshtastic_MeshPacket *p = packetPool.allocCopy(*e.packet);
if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
p->channel = ch.index;
}
// ignore messages sent by us or if we don't have the channel key // ignore messages sent by us or if we don't have the channel key
if (router && p->from != nodeDB.getNodeNum() && perhapsDecode(p)) if (router && p->from != nodeDB.getNodeNum() && perhapsDecode(p))
router->enqueueReceivedMessage(p); router->enqueueReceivedMessage(p);
@@ -686,6 +692,10 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp)
jsonObj["channel"] = new JSONValue((uint)mp->channel); jsonObj["channel"] = new JSONValue((uint)mp->channel);
jsonObj["type"] = new JSONValue(msgType.c_str()); jsonObj["type"] = new JSONValue(msgType.c_str());
jsonObj["sender"] = new JSONValue(owner.id); jsonObj["sender"] = new JSONValue(owner.id);
if (mp->rx_rssi != 0)
jsonObj["rssi"] = new JSONValue((int)mp->rx_rssi);
if (mp->rx_snr != 0)
jsonObj["snr"] = new JSONValue((float)mp->rx_snr);
// serialize and write it to the stream // serialize and write it to the stream
JSONValue *value = new JSONValue(jsonObj); JSONValue *value = new JSONValue(jsonObj);

View File

@@ -46,6 +46,8 @@
#define HW_VENDOR meshtastic_HardwareModel_RAK4631 #define HW_VENDOR meshtastic_HardwareModel_RAK4631
#elif defined(TTGO_T_ECHO) #elif defined(TTGO_T_ECHO)
#define HW_VENDOR meshtastic_HardwareModel_T_ECHO #define HW_VENDOR meshtastic_HardwareModel_T_ECHO
#elif defined(NANO_G2_ULTRA)
#define HW_VENDOR meshtastic_HardwareModel_NANO_G2_ULTRA
#elif defined(NORDIC_PCA10059) #elif defined(NORDIC_PCA10059)
#define HW_VENDOR meshtastic_HardwareModel_NRF52840_PCA10059 #define HW_VENDOR meshtastic_HardwareModel_NRF52840_PCA10059
#elif defined(PRIVATE_HW) || defined(FEATHER_DIY) #elif defined(PRIVATE_HW) || defined(FEATHER_DIY)

View File

@@ -11,4 +11,4 @@ lib_deps =
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
zinggjm/GxEPD2@^1.4.9 zinggjm/GxEPD2@^1.4.9
debug_tool = jlink debug_tool = jlink
upload_port = /dev/ttyACM4 ;upload_port = /dev/ttyACM4

View File

@@ -11,7 +11,7 @@ build_flags =
-I variants/betafpv_2400_tx_micro -I variants/betafpv_2400_tx_micro
board_build.f_cpu = 240000000L board_build.f_cpu = 240000000L
upload_protocol = esptool upload_protocol = esptool
upload_port = /dev/ttyUSB0 ;upload_port = /dev/ttyUSB0
upload_speed = 460800 upload_speed = 460800
lib_deps = lib_deps =
${esp32_base.lib_deps} ${esp32_base.lib_deps}

View File

@@ -10,7 +10,7 @@ build_flags =
-I variants/betafpv_900_tx_nano -I variants/betafpv_900_tx_nano
board_build.f_cpu = 240000000L board_build.f_cpu = 240000000L
upload_protocol = esptool upload_protocol = esptool
upload_port = /dev/ttyUSB0 ;upload_port = /dev/ttyUSB0
upload_speed = 460800 upload_speed = 460800
lib_deps = lib_deps =
${esp32_base.lib_deps} ${esp32_base.lib_deps}

View File

@@ -6,7 +6,7 @@ board_level = extra
;upload_protocol = esp-builtin ;upload_protocol = esp-builtin
;Normal method ;Normal method
upload_protocol = esptool upload_protocol = esptool
upload_port = /dev/ttyACM2 ;upload_port = /dev/ttyACM2
lib_deps = lib_deps =
${esp32_base.lib_deps} ${esp32_base.lib_deps}
caveman99/ESP32 Codec2@^1.0.1 caveman99/ESP32 Codec2@^1.0.1

View File

@@ -8,5 +8,5 @@ build_flags =
-I variants/heltec_esp32c3 -I variants/heltec_esp32c3
monitor_speed = 115200 monitor_speed = 115200
upload_protocol = esptool upload_protocol = esptool
upload_port = /dev/ttyUSB0 ;upload_port = /dev/ttyUSB0
upload_speed = 921600 upload_speed = 921600

View File

@@ -8,5 +8,5 @@ build_flags =
-I variants/m5stack-stamp-c3 -I variants/m5stack-stamp-c3
monitor_speed = 115200 monitor_speed = 115200
upload_protocol = esptool upload_protocol = esptool
upload_port = /dev/ttyACM2 ;upload_port = /dev/ttyACM2
upload_speed = 921600 upload_speed = 921600

View File

@@ -23,4 +23,4 @@ lib_ignore =
monitor_filters = esp32_exception_decoder monitor_filters = esp32_exception_decoder
board_build.f_cpu = 240000000L board_build.f_cpu = 240000000L
upload_protocol = esptool upload_protocol = esptool
upload_port = /dev/ttyACM0 ;upload_port = /dev/ttyACM0

View File

@@ -6,7 +6,7 @@ board_build.arduino.memory_type = dio_opi
board_build.mcu = esp32s3 board_build.mcu = esp32s3
board_build.f_cpu = 240000000L board_build.f_cpu = 240000000L
upload_protocol = esptool upload_protocol = esptool
upload_port = /dev/ttyACM1 ;upload_port = /dev/ttyACM1
upload_speed = 921600 upload_speed = 921600
platform_packages = platform_packages =
tool-esptoolpy@^1.40500.0 tool-esptoolpy@^1.40500.0

View File

@@ -6,7 +6,7 @@ board_build.arduino.memory_type = dio_opi
board_build.mcu = esp32s3 board_build.mcu = esp32s3
board_build.f_cpu = 240000000L board_build.f_cpu = 240000000L
upload_protocol = esptool upload_protocol = esptool
upload_port = /dev/ttyACM0 ;upload_port = /dev/ttyACM0
upload_speed = 921600 upload_speed = 921600
platform_packages = platform_packages =
tool-esptoolpy@^1.40500.0 tool-esptoolpy@^1.40500.0

View File

@@ -15,4 +15,4 @@ lib_deps =
debug_tool = jlink debug_tool = jlink
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
;upload_protocol = jlink ;upload_protocol = jlink
upload_port = /dev/ttyACM3 ;upload_port = /dev/ttyACM3

View File

@@ -0,0 +1,13 @@
[env:trackerd]
extends = esp32_base
;platform = https://github.com/platformio/platform-espressif32.git#feature/arduino-upstream
platform = espressif32
board = pico32
board_build.f_flash = 80000000L
board_level = extra
build_flags =
${esp32_base.build_flags} -D PRIVATE_HW -I variants/trackerd -D BSFILE=\"boards/dragino_lbt2.h\"
;board_build.partitions = no_ota.csv
;platform_packages =
; platformio/framework-arduinoespressif32@3
;platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.1-RC1

View File

@@ -0,0 +1,46 @@
// Initialize i2c bus on sd_dat and esp_led pins, respectively. We need a bus to not hang on boot
#define HAS_SCREEN 0
#define I2C_SDA 21
#define I2C_SCL 22
#undef GPS_RX_PIN
#undef GPS_TX_PIN
#define GPS_RX_PIN 9
#define GPS_TX_PIN 10
#define LED_PIN 13 // 13 red, 2 blue, 15 red
//#define HAS_BUTTON 0
#define BUTTON_PIN 0
#define BUTTON_NEED_PULLUP
#define USE_RF95
#define LORA_DIO0 26 // a No connect on the SX1262 module
#define LORA_RESET 23
#define LORA_DIO1 33
#define LORA_DIO2 32 // Not really used
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
// Battery
// The battery sense is hooked to pin A0 (4)
// it is defined in the anlaolgue pin section of this file
// and has 12 bit resolution
#define BATTERY_SENSE_RESOLUTION_BITS 12
#define BATTERY_SENSE_RESOLUTION 4096.0
// Definition of milliVolt per LSB => 3.0V ADC range and 12-bit ADC resolution = 3000mV/4096
#define VBAT_MV_PER_LSB (0.73242188F)
// Voltage divider value => 100K + 100K voltage divider on VBAT = (100K / (100K + 100K))
#define VBAT_DIVIDER (0.5F)
// Compensation factor for the VBAT divider
#define VBAT_DIVIDER_COMP (2.0)
// Fixed calculation of milliVolt from compensation value
#define REAL_VBAT_MV_PER_LSB (VBAT_DIVIDER_COMP * VBAT_MV_PER_LSB)
#undef AREF_VOLTAGE
#define AREF_VOLTAGE 3.0
#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
#define ADC_MULTIPLIER VBAT_DIVIDER_COMP
#define VBAT_RAW_TO_SCALED(x) (REAL_VBAT_MV_PER_LSB * x)
//#define BATTERY_SENSE_SAMPLES 15 // Set the number of samples, It has an effect of increasing sensitivity.
//#define ADC_MULTIPLIER 3.3

View File

@@ -1,4 +1,4 @@
[VERSION] [VERSION]
major = 2 major = 2
minor = 2 minor = 2
build = 11 build = 12