Compare commits

...

6 Commits

Author SHA1 Message Date
Ben Meadors
7f7c5cbd62 Triple GPS state (#3157)
* Triple state GPS refactoring

* Skip probe

* Move GPS toggle into the GPSThread

* Consolidate

* make all happy (including me)

* corrected screen texts

* NOT_PRESENT guard in main.cpp

---------

Co-authored-by: mverch67 <manuel.verch@gmx.de>
2024-02-01 15:24:39 -06:00
GUVWAF
0c0a3c4b55 Fix: mark packet sent to MQTT as ACKed only after we sent it out via LoRa (#3155)
* Fix: mark packet via MQTT as ACKed only after we sent it out via LoRa

* Don't need to check for broadcast, DMs also get implicit ACKs

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2024-01-31 14:04:52 -06:00
github-actions[bot]
bf762bc58d [create-pull-request] automated change (#3156)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2024-01-31 13:47:17 -06:00
Ben Meadors
84e578323e Update version.properties 2024-01-31 13:46:48 -06:00
Ben Meadors
bdbe42dfd0 Update version.properties 2024-01-31 12:58:04 -06:00
github-actions[bot]
4f64c4f7b9 [create-pull-request] automated change (#3154)
Co-authored-by: thebentern <thebentern@users.noreply.github.com>
2024-01-30 20:01:00 -06:00
14 changed files with 100 additions and 50 deletions

View File

@@ -193,15 +193,7 @@ class ButtonThread : public concurrency::OSThread
static void userButtonMultiPressed()
{
if (!config.device.disable_triple_click && (gps != nullptr)) {
config.position.gps_enabled = !(config.position.gps_enabled);
if (config.position.gps_enabled) {
LOG_DEBUG("Flag set to true to restore power\n");
gps->enable();
} else {
LOG_DEBUG("Flag set to false for gps power\n");
gps->disable();
}
gps->toggleGpsMode();
}
}

View File

@@ -604,7 +604,7 @@ uint32_t GPS::getSleepTime() const
uint32_t t = config.position.gps_update_interval;
// We'll not need the GPS thread to wake up again after first acq. with fixed position.
if (!config.position.gps_enabled || config.position.fixed_position)
if (config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_ENABLED || config.position.fixed_position)
t = UINT32_MAX; // Sleep forever now
if (t == UINT32_MAX)
@@ -625,21 +625,24 @@ void GPS::publishUpdate()
// Notify any status instances that are observing us
const meshtastic::GPSStatus status = meshtastic::GPSStatus(hasValidLocation, isConnected(), isPowerSaving(), p);
newStatus.notifyObservers(&status);
if (config.position.gps_enabled)
if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) {
positionModule->handleNewPosition();
}
}
}
int32_t GPS::runOnce()
{
if (!GPSInitFinished) {
if (!_serial_gps)
if (!_serial_gps || config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT) {
LOG_INFO("GPS set to not-present. Skipping probe.\n");
return disable();
}
if (!setup())
return 2000; // Setup failed, re-run in two seconds
// We have now loaded our saved preferences from flash
if (config.position.gps_enabled == false) {
if (config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_ENABLED) {
return disable();
}
// ONCE we will factory reset the GPS for bug #327
@@ -662,7 +665,7 @@ int32_t GPS::runOnce()
// if we have received valid NMEA claim we are connected
setConnected();
} else {
if ((config.position.gps_enabled == 1) && (gnssModel == GNSS_MODEL_UBLOX)) {
if ((config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) && (gnssModel == GNSS_MODEL_UBLOX)) {
// reset the GPS on next bootup
if (devicestate.did_gps_reset && (millis() - lastWakeStartMsec > 60000) && !hasFlow()) {
LOG_DEBUG("GPS is not communicating, trying factory reset on next bootup.\n");
@@ -902,7 +905,7 @@ GPS *GPS::createGps()
int8_t _rx_gpio = config.position.rx_gpio;
int8_t _tx_gpio = config.position.tx_gpio;
int8_t _en_gpio = config.position.gps_en_gpio;
#if defined(HAS_GPS) && !defined(ARCH_ESP32)
#if HAS_GPS && !defined(ARCH_ESP32)
_rx_gpio = 1; // We only specify GPS serial ports on ESP32. Otherwise, these are just flags.
_tx_gpio = 1;
#endif
@@ -1098,7 +1101,7 @@ bool GPS::lookForLocation()
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
fixType = atoi(gsafixtype.value()); // will set to zero if no data
// LOG_DEBUG("FIX QUAL=%d, TYPE=%d\n", fixQual, fixType);
// LOG_DEBUG("FIX QUAL=%d, TYPE=%d\n", fixQual, fixType);
#endif
// check if GPS has an acceptable lock
@@ -1280,4 +1283,17 @@ int32_t GPS::disable()
setAwake(false);
return INT32_MAX;
}
void GPS::toggleGpsMode()
{
if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) {
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_DISABLED;
LOG_DEBUG("Flag set to false for gps power. GpsMode: DISABLED\n");
disable();
} else if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_DISABLED) {
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED;
LOG_DEBUG("Flag set to true to restore power. GpsMode: ENABLED\n");
enable();
}
}

View File

@@ -133,6 +133,9 @@ class GPS : private concurrency::OSThread
// Disable the thread
int32_t disable() override;
// toggle between enabled/disabled
void toggleGpsMode();
void setGPSPower(bool on, bool standbyOnly, uint32_t sleepTime);
/// Returns true if we have acquired GPS lock.
@@ -144,7 +147,7 @@ class GPS : private concurrency::OSThread
/// Return true if we are connected to a GPS
bool isConnected() const { return hasGPS; }
bool isPowerSaving() const { return !config.position.gps_enabled; }
bool isPowerSaving() const { return config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_ENABLED; }
// Empty the input buffer as quickly as possible
void clearBuffer();

View File

@@ -558,15 +558,20 @@ static void drawGPS(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus
}
}
// Draw status when gps is disabled by PMU
// Draw status when GPS is disabled or not present
static void drawGPSpowerstat(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps)
{
String displayLine = "GPS disabled";
int16_t xPos = display->getStringWidth(displayLine);
if (!config.position.gps_enabled) {
display->drawString(x + xPos, y, displayLine);
String displayLine;
int pos;
if (y < FONT_HEIGHT_SMALL) { // Line 1: use short string
displayLine = config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT ? "No GPS" : "GPS off";
pos = SCREEN_WIDTH - display->getStringWidth(displayLine);
} else {
displayLine = config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT ? "GPS not present"
: "GPS is disabled";
pos = (SCREEN_WIDTH - display->getStringWidth(displayLine)) / 2;
}
display->drawString(x + pos, y, displayLine);
}
static void drawGPSAltitude(OLEDDisplay *display, int16_t x, int16_t y, const GPSStatus *gps)
@@ -594,7 +599,7 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const
String displayLine = "";
if (!gps->getIsConnected() && !config.position.fixed_position) {
displayLine = "No GPS Module";
displayLine = "No GPS present";
display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine);
} else if (!gps->getHasLock() && !config.position.fixed_position) {
displayLine = "No GPS Lock";
@@ -1549,7 +1554,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 3, nodeStatus);
}
// Display GPS status
if (!config.position.gps_enabled) {
if (config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_ENABLED) {
drawGPSpowerstat(display, x, y + 2, gpsStatus);
} else {
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
@@ -1777,7 +1782,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
char chUtil[13];
snprintf(chUtil, sizeof(chUtil), "ChUtil %2.0f%%", airTime->channelUtilizationPercent());
display->drawString(x + SCREEN_WIDTH - display->getStringWidth(chUtil), y + FONT_HEIGHT_SMALL * 1, chUtil);
if (config.position.gps_enabled) {
if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) {
// Line 3
if (config.display.gps_format !=
meshtastic_Config_DisplayConfig_GpsCoordinateFormat_DMS) // if DMS then don't draw altitude
@@ -1786,10 +1791,7 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
// Line 4
drawGPScoordinates(display, x, y + FONT_HEIGHT_SMALL * 3, gpsStatus);
} else {
drawGPSpowerstat(display, x - (SCREEN_WIDTH / 4), y + FONT_HEIGHT_SMALL * 2, gpsStatus);
#ifdef GPS_POWER_TOGGLE
display->drawString(x + 30, (y + FONT_HEIGHT_SMALL * 3), " by button");
#endif
drawGPSpowerstat(display, x, y + FONT_HEIGHT_SMALL * 2, gpsStatus);
}
/* Display a heartbeat pixel that blinks every time the frame is redrawn */
#ifdef SHOW_REDRAWS

View File

@@ -685,7 +685,8 @@ void setup()
readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time)
// If we're taking on the repeater role, ignore GPS
if (config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER) {
if (config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER &&
config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT) {
gps = GPS::createGps();
}
if (gps) {

View File

@@ -182,7 +182,16 @@ void NodeDB::installDefaultConfig()
#else
config.device.disable_triple_click = true;
#endif
config.position.gps_enabled = true;
#if !HAS_GPS || defined(T_DECK)
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT;
#elif !defined(GPS_RX_PIN)
if (config.position.rx_gpio == 0)
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT;
else
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_DISABLED;
#else
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED;
#endif
config.position.position_broadcast_smart_enabled = true;
config.position.broadcast_smart_minimum_distance = 100;
config.position.broadcast_smart_minimum_interval_secs = 30;
@@ -454,6 +463,11 @@ void NodeDB::init()
memcpy(devicestate.node_remote_hardware_pins, empty, sizeof(empty));
}
if (config.position.gps_enabled) {
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED;
config.position.gps_enabled = 0;
}
saveToDisk(saveWhat);
}

View File

@@ -45,3 +45,4 @@ PB_BIND(meshtastic_Config_BluetoothConfig, meshtastic_Config_BluetoothConfig, AU

View File

@@ -108,6 +108,15 @@ typedef enum _meshtastic_Config_PositionConfig_PositionFlags {
meshtastic_Config_PositionConfig_PositionFlags_SPEED = 512
} meshtastic_Config_PositionConfig_PositionFlags;
typedef enum _meshtastic_Config_PositionConfig_GpsMode {
/* GPS is present but disabled */
meshtastic_Config_PositionConfig_GpsMode_DISABLED = 0,
/* GPS is present and enabled */
meshtastic_Config_PositionConfig_GpsMode_ENABLED = 1,
/* GPS is not present on the device */
meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT = 2
} meshtastic_Config_PositionConfig_GpsMode;
typedef enum _meshtastic_Config_NetworkConfig_AddressMode {
/* obtain ip address via DHCP */
meshtastic_Config_NetworkConfig_AddressMode_DHCP = 0,
@@ -300,6 +309,8 @@ typedef struct _meshtastic_Config_PositionConfig {
uint32_t broadcast_smart_minimum_interval_secs;
/* (Re)define PIN_GPS_EN for your board. */
uint32_t gps_en_gpio;
/* Set where GPS is enabled, disabled, or not present */
meshtastic_Config_PositionConfig_GpsMode gps_mode;
} meshtastic_Config_PositionConfig;
/* Power Config\
@@ -507,6 +518,10 @@ extern "C" {
#define _meshtastic_Config_PositionConfig_PositionFlags_MAX meshtastic_Config_PositionConfig_PositionFlags_SPEED
#define _meshtastic_Config_PositionConfig_PositionFlags_ARRAYSIZE ((meshtastic_Config_PositionConfig_PositionFlags)(meshtastic_Config_PositionConfig_PositionFlags_SPEED+1))
#define _meshtastic_Config_PositionConfig_GpsMode_MIN meshtastic_Config_PositionConfig_GpsMode_DISABLED
#define _meshtastic_Config_PositionConfig_GpsMode_MAX meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT
#define _meshtastic_Config_PositionConfig_GpsMode_ARRAYSIZE ((meshtastic_Config_PositionConfig_GpsMode)(meshtastic_Config_PositionConfig_GpsMode_NOT_PRESENT+1))
#define _meshtastic_Config_NetworkConfig_AddressMode_MIN meshtastic_Config_NetworkConfig_AddressMode_DHCP
#define _meshtastic_Config_NetworkConfig_AddressMode_MAX meshtastic_Config_NetworkConfig_AddressMode_STATIC
#define _meshtastic_Config_NetworkConfig_AddressMode_ARRAYSIZE ((meshtastic_Config_NetworkConfig_AddressMode)(meshtastic_Config_NetworkConfig_AddressMode_STATIC+1))
@@ -543,6 +558,7 @@ extern "C" {
#define meshtastic_Config_DeviceConfig_role_ENUMTYPE meshtastic_Config_DeviceConfig_Role
#define meshtastic_Config_DeviceConfig_rebroadcast_mode_ENUMTYPE meshtastic_Config_DeviceConfig_RebroadcastMode
#define meshtastic_Config_PositionConfig_gps_mode_ENUMTYPE meshtastic_Config_PositionConfig_GpsMode
#define meshtastic_Config_NetworkConfig_address_mode_ENUMTYPE meshtastic_Config_NetworkConfig_AddressMode
@@ -562,7 +578,7 @@ extern "C" {
/* Initializer values for message structs */
#define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}}
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0}
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""}
#define meshtastic_Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0}
@@ -571,7 +587,7 @@ extern "C" {
#define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0}
#define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}}
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0}
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""}
#define meshtastic_Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0}
@@ -602,6 +618,7 @@ extern "C" {
#define meshtastic_Config_PositionConfig_broadcast_smart_minimum_distance_tag 10
#define meshtastic_Config_PositionConfig_broadcast_smart_minimum_interval_secs_tag 11
#define meshtastic_Config_PositionConfig_gps_en_gpio_tag 12
#define meshtastic_Config_PositionConfig_gps_mode_tag 13
#define meshtastic_Config_PowerConfig_is_power_saving_tag 1
#define meshtastic_Config_PowerConfig_on_battery_shutdown_after_secs_tag 2
#define meshtastic_Config_PowerConfig_adc_multiplier_override_tag 3
@@ -704,7 +721,8 @@ X(a, STATIC, SINGULAR, UINT32, rx_gpio, 8) \
X(a, STATIC, SINGULAR, UINT32, tx_gpio, 9) \
X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_distance, 10) \
X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_interval_secs, 11) \
X(a, STATIC, SINGULAR, UINT32, gps_en_gpio, 12)
X(a, STATIC, SINGULAR, UINT32, gps_en_gpio, 12) \
X(a, STATIC, SINGULAR, UENUM, gps_mode, 13)
#define meshtastic_Config_PositionConfig_CALLBACK NULL
#define meshtastic_Config_PositionConfig_DEFAULT NULL
@@ -810,7 +828,7 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg;
#define meshtastic_Config_LoRaConfig_size 80
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
#define meshtastic_Config_NetworkConfig_size 196
#define meshtastic_Config_PositionConfig_size 60
#define meshtastic_Config_PositionConfig_size 62
#define meshtastic_Config_PowerConfig_size 40
#define meshtastic_Config_size 199
@@ -818,4 +836,4 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg;
} /* extern "C" */
#endif
#endif
#endif

View File

@@ -316,7 +316,7 @@ extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePin_msg;
#define meshtastic_DeviceState_size 17062
#define meshtastic_NodeInfoLite_size 153
#define meshtastic_NodeRemoteHardwarePin_size 29
#define meshtastic_OEMStore_size 3244
#define meshtastic_OEMStore_size 3246
#define meshtastic_PositionLite_size 28
#ifdef __cplusplus

View File

@@ -180,7 +180,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
#define meshtastic_LocalModuleConfig_fields &meshtastic_LocalModuleConfig_msg
/* Maximum encoded size of messages (where known) */
#define meshtastic_LocalConfig_size 467
#define meshtastic_LocalConfig_size 469
#define meshtastic_LocalModuleConfig_size 631
#ifdef __cplusplus

View File

@@ -71,6 +71,8 @@ typedef enum _meshtastic_HardwareModel {
meshtastic_HardwareModel_SENSELORA_RP2040 = 27,
/* Makerfabs SenseLoRA Industrial Monitor (ESP32-S3 + RFM96) */
meshtastic_HardwareModel_SENSELORA_S3 = 28,
/* Canary Radio Company - CanaryOne: https://canaryradio.io/products/canaryone */
meshtastic_HardwareModel_CANARYONE = 29,
/* ---------------------------------------------------------------------------
Less common/prototype boards listed here (needs one more byte over the air)
--------------------------------------------------------------------------- */

View File

@@ -127,11 +127,17 @@ void MQTT::onReceive(char *topic, byte *payload, size_t length)
LOG_ERROR("Invalid MQTT service envelope, topic %s, len %u!\n", topic, length);
return;
} else {
if (strcmp(e.gateway_id, owner.id) == 0)
LOG_INFO("Ignoring downlink message we originally sent.\n");
else {
meshtastic_Channel ch = channels.getByName(e.channel_id);
if (strcmp(e.gateway_id, owner.id) == 0) {
// Generate an implicit ACK towards ourselves (handled and processed only locally!) for this message.
// We do this because packets are not rebroadcasted back into MQTT anymore and we assume that at least one node
// receives it when we get our own packet back. Then we'll stop our retransmissions.
if (e.packet && getFrom(e.packet) == nodeDB.getNodeNum())
routingModule->sendAckNak(meshtastic_Routing_Error_NONE, getFrom(e.packet), e.packet->id, ch.index);
else
LOG_INFO("Ignoring downlink message we originally sent.\n");
} else {
// 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);
meshtastic_MeshPacket *p = packetPool.allocCopy(*e.packet);
@@ -505,11 +511,6 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp, const meshtastic_MeshPacket &
}
}
// Generate an implicit ACK towards ourselves (handled and processed only locally!) for this message.
// We do this because packets are not rebroadcasted back into MQTT anymore and we assume that at least one node
// receives it when we're connected to the broker. Then we'll stop our retransmissions.
if (getFrom(&mp) == nodeDB.getNodeNum())
routingModule->sendAckNak(meshtastic_Routing_Error_NONE, getFrom(&mp), mp.id, chIndex);
} else {
LOG_INFO("MQTT not connected, queueing packet\n");
if (mqttQueue.numFree() == 0) {

View File

@@ -1,4 +1,4 @@
[VERSION]
major = 2
minor = 2
build = 20
build = 21