diff --git a/src/GPSStatus.h b/src/GPSStatus.h index 25c7b10394c..2a384c8b5cb 100644 --- a/src/GPSStatus.h +++ b/src/GPSStatus.h @@ -17,6 +17,7 @@ class GPSStatus : public Status bool hasLock = false; // default to false, until we complete our first read bool isConnected = false; // Do we have a GPS we are talking to + bool hasTime = false; // GPS has decoded a valid time this acquisition, even without a position fix bool isPowerSaving = false; // Are we in power saving state @@ -29,11 +30,12 @@ class GPSStatus : public Status GPSStatus() { statusType = STATUS_TYPE_GPS; } // preferred method - GPSStatus(bool hasLock, bool isConnected, bool isPowerSaving, const meshtastic_Position &pos) : Status() + GPSStatus(bool hasLock, bool isConnected, bool isPowerSaving, const meshtastic_Position &pos, bool hasTime = false) : Status() { this->hasLock = hasLock; this->isConnected = isConnected; this->isPowerSaving = isPowerSaving; + this->hasTime = hasTime; // all-in-one struct copy this->p = pos; @@ -50,6 +52,8 @@ class GPSStatus : public Status bool getIsPowerSaving() const { return isPowerSaving; } + bool getHasTime() const { return hasTime; } + int32_t getLatitude() const { if (config.position.fixed_position) { @@ -91,7 +95,7 @@ class GPSStatus : public Status #ifdef GPS_DEBUG LOG_DEBUG("GPSStatus.match() new pos@%x to old pos@%x", newStatus->p.timestamp, p.timestamp); #endif - return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected || + return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected || newStatus->hasTime != hasTime || newStatus->isPowerSaving != isPowerSaving || newStatus->p.latitude_i != p.latitude_i || newStatus->p.longitude_i != p.longitude_i || newStatus->p.altitude != p.altitude || newStatus->p.altitude_hae != p.altitude_hae || newStatus->p.PDOP != p.PDOP || @@ -112,6 +116,7 @@ class GPSStatus : public Status initialized = true; hasLock = newStatus->hasLock; isConnected = newStatus->isConnected; + hasTime = newStatus->hasTime; p = newStatus->p; diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index dcd765c9e85..928e8261450 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -1446,7 +1446,7 @@ void GPS::publishUpdate() LOG_DEBUG("Publish pos@%x:2, hasVal=%d, Sats=%d, GPSlock=%d", p.timestamp, hasValidLocation, p.sats_in_view, hasLock()); // Notify any status instances that are observing us - const meshtastic::GPSStatus status = meshtastic::GPSStatus(hasValidLocation, isConnected(), isPowerSaving(), p); + const meshtastic::GPSStatus status = meshtastic::GPSStatus(hasValidLocation, isConnected(), isPowerSaving(), p, gotTime); newStatus.notifyObservers(&status); if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) { positionModule->handleNewPosition(); @@ -1502,7 +1502,7 @@ int32_t GPS::runOnce() // gps_update_interval is faster than the position broadcast interval so there's a // fresh position ready when the device wants to broadcast one on the mesh. // - // 1. Got a time for the first time --> set the time, don't publish. + // 1. Got a time for the first time --> set the time, publish so the UI can show the time-only state. // 2. Got a lock for the first time // --> If gps_update_interval is <= 10s --> publishUpdate // --> Otherwise, hold for MIN(gps_update_interval - GPS_UPDATE_ALWAYS_ON_THRESHOLD_MS, 20s) @@ -1536,6 +1536,11 @@ int32_t GPS::runOnce() // 1. Got a time for the first time this cycle if (!gotTime && lookForTime()) { // Note: we count on this && short-circuiting and not resetting the RTC time gotTime = true; + // Publish immediately (rather than via the block below, which would clear fixHoldEnds) so the + // time-only state reaches the UI without waiting for a location. Safe without a valid location: + // PositionModule::handleNewPosition ignores invalid positions. + shouldPublish = true; + publishUpdate(); } // 2. Got a lock for the first time, or 3. Got a lock after turning back on diff --git a/src/graphics/draw/UIRenderer.cpp b/src/graphics/draw/UIRenderer.cpp index b8ead27066e..b82b850f9de 100644 --- a/src/graphics/draw/UIRenderer.cpp +++ b/src/graphics/draw/UIRenderer.cpp @@ -582,7 +582,7 @@ void UIRenderer::drawGpsCoordinates(OLEDDisplay *display, int16_t x, int16_t y, } } else if (!gps->getHasLock() && !config.position.fixed_position) { if (strcmp(mode, "line1") == 0) { - strcpy(displayLine, "No GPS Lock"); + strcpy(displayLine, gps->getHasTime() ? "GPS Time Only" : "No GPS Lock"); display->drawString(x, y, displayLine); } } else {