PowerSaving GPS version 1 for repeaters
This commit is contained in:
1 parent
46c729b2e9
commit
16fbf33582
6 files changed
+120
-15
No files matched your search
@@ -162,6 +162,13 @@ protected:
|
||||
|
||||
#if ENV_INCLUDE_GPS == 1
|
||||
void applyGpsPrefs() {
|
||||
// If powersaving on, apply powersaving to sensors
|
||||
if (_prefs.powersaving_enabled) {
|
||||
sensors.powersaving_enabled = true;
|
||||
} else {
|
||||
sensors.powersaving_enabled = false;
|
||||
}
|
||||
|
||||
sensors.setSettingValue("gps", _prefs.gps_enabled?"1":"0");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -368,7 +368,12 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re
|
||||
if (_sensors->setSettingValue("gps", "1")) {
|
||||
_prefs->gps_enabled = 1;
|
||||
savePrefs();
|
||||
strcpy(reply, "ok");
|
||||
|
||||
if (_prefs->powersaving_enabled) { // Power Saving
|
||||
strcpy(reply, "on (powersaving)");
|
||||
} else { // Normal mode
|
||||
strcpy(reply, "ok");
|
||||
}
|
||||
} else {
|
||||
strcpy(reply, "gps toggle not found");
|
||||
}
|
||||
@@ -384,7 +389,7 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re
|
||||
LocationProvider * l = _sensors->getLocationProvider();
|
||||
if (l != NULL) {
|
||||
l->syncTime();
|
||||
strcpy(reply, "ok");
|
||||
strcpy(reply, "scheduled");
|
||||
} else {
|
||||
strcpy(reply, "gps provider not found");
|
||||
}
|
||||
@@ -430,13 +435,35 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re
|
||||
bool fix = l->isValid(); // has fix ?
|
||||
int sats = l->satellitesCount();
|
||||
bool active = !strcmp(_sensors->getSettingByKey("gps"), "1");
|
||||
if (enabled) {
|
||||
sprintf(reply, "on, %s, %s, %d sats",
|
||||
active?"active":"deactivated",
|
||||
fix?"fix":"no fix",
|
||||
sats);
|
||||
} else {
|
||||
strcpy(reply, "off");
|
||||
|
||||
if (_prefs->powersaving_enabled && l->getGPSPowerSaving()) { // GPS Power Saving
|
||||
if (enabled) {
|
||||
sprintf(reply, "on (powersaving, sleep in %lum), %s, %s, %d sats",
|
||||
(l->getNextGPSOff() - millis()) / 60000UL,
|
||||
active?"active":"deactivated",
|
||||
fix?"fix":"no fix",
|
||||
sats);
|
||||
} else {
|
||||
sprintf(reply, "off (powersaving, wake in %lum)", (l->getNextGPSOn() - millis()) / 60000UL);
|
||||
}
|
||||
|
||||
// "last sync" from GPS
|
||||
DateTime dt = DateTime(l->getLastValidTimeSync());
|
||||
if (dt.unixtime() == 0) {
|
||||
sprintf(reply + strlen(reply), ", last sync: none");
|
||||
} else {
|
||||
sprintf(reply + strlen(reply), ", last sync: %02d:%02d - %d/%d/%d UTC", dt.hour(), dt.minute(),
|
||||
dt.day(), dt.month(), dt.year());
|
||||
}
|
||||
} else { // Normal mode
|
||||
if (enabled) {
|
||||
sprintf(reply, "on, %s, %s, %d sats",
|
||||
active?"active":"deactivated",
|
||||
fix?"fix":"no fix",
|
||||
sats);
|
||||
} else {
|
||||
strcpy(reply, "off");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
strcpy(reply, "Can't find GPS");
|
||||
|
||||
@@ -13,8 +13,9 @@ class SensorManager {
|
||||
public:
|
||||
double node_lat, node_lon; // modify these, if you want to affect Advert location
|
||||
double node_altitude; // altitude in meters
|
||||
bool powersaving_enabled; // powersaving mode
|
||||
|
||||
SensorManager() { node_lat = 0; node_lon = 0; node_altitude = 0; }
|
||||
SensorManager() { node_lat = 0; node_lon = 0; node_altitude = 0; powersaving_enabled = false; }
|
||||
virtual bool begin() { return false; }
|
||||
virtual bool querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) { return false; }
|
||||
virtual void loop() { }
|
||||
|
||||
@@ -621,6 +621,12 @@ static const SensorDef SENSOR_TABLE[] = {
|
||||
|
||||
static const size_t SENSOR_TABLE_SIZE = (sizeof(SENSOR_TABLE) / sizeof(SENSOR_TABLE[0])) - 1;
|
||||
|
||||
// ============================================================
|
||||
// Power Saving GPS
|
||||
// ============================================================
|
||||
static unsigned long GPS_ON_DURATION_SECS = 600; // 10 minutes
|
||||
static unsigned long GPS_OFF_DURATION_SECS = 86400; // 1 day
|
||||
|
||||
// ============================================================
|
||||
// begin() — scan the I2C bus, then initialize only what was
|
||||
// found. A sensor whose address does not ACK during the scan
|
||||
@@ -730,8 +736,16 @@ bool EnvironmentSensorManager::setSettingValue(const char* name, const char* val
|
||||
#if ENV_INCLUDE_GPS
|
||||
if (gps_detected && strcmp(name, "gps") == 0) {
|
||||
if (strcmp(value, "0") == 0) {
|
||||
if (powersaving_enabled) {
|
||||
_location->setGPSPowerSaving(false);
|
||||
}
|
||||
|
||||
stop_gps();
|
||||
} else {
|
||||
if (powersaving_enabled) {
|
||||
_location->setGPSPowerSaving(true);
|
||||
}
|
||||
|
||||
start_gps();
|
||||
}
|
||||
return true;
|
||||
@@ -883,11 +897,22 @@ void EnvironmentSensorManager::start_gps() {
|
||||
#ifndef PIN_GPS_EN
|
||||
MESH_DEBUG_PRINTLN("Start GPS is N/A on this board. Actual GPS state unchanged");
|
||||
#endif
|
||||
|
||||
if (powersaving_enabled && _location->getGPSPowerSaving()) {
|
||||
_location->syncTime(); // Clear GPS data and force sync time
|
||||
_location->setNextGPSOff(millis() + GPS_ON_DURATION_SECS * 1000UL); // Next time to off
|
||||
}
|
||||
}
|
||||
|
||||
void EnvironmentSensorManager::stop_gps() {
|
||||
gps_active = false;
|
||||
#ifdef RAK_WISBLOCK_GPS
|
||||
|
||||
if (powersaving_enabled && _location->getGPSPowerSaving()) {
|
||||
_location->stopTimeSync(); // Stop time sync
|
||||
_location->setNextGPSOn(millis() + GPS_OFF_DURATION_SECS * 1000UL); // Next time to on
|
||||
}
|
||||
|
||||
#ifdef RAK_WISBLOCK_GPS
|
||||
pinMode(gpsResetPin, OUTPUT);
|
||||
digitalWrite(gpsResetPin, LOW);
|
||||
return;
|
||||
@@ -906,11 +931,39 @@ void EnvironmentSensorManager::loop() {
|
||||
|
||||
#if ENV_INCLUDE_GPS
|
||||
static long next_gps_update = 0;
|
||||
|
||||
// PowerSaving
|
||||
if (powersaving_enabled) {
|
||||
if (gps_detected && _location->getGPSPowerSaving()) {
|
||||
if (gps_active && ((int32_t)(millis() - _location->getNextGPSOff()) >= 0 ||
|
||||
!_location->waitingTimeSync())) { // Time to off or GPS set
|
||||
// --- TO REMOVE
|
||||
if ((int32_t)(millis() - _location->getNextGPSOff()) >= 0) Serial.println("Timeout, off");
|
||||
else if (!_location->waitingTimeSync()) Serial.println("GPS set, off early");
|
||||
// --- TO REMOVE
|
||||
|
||||
stop_gps();
|
||||
} else if (!gps_active && ((int32_t)(millis() - _location->getNextGPSOn()) >= 0)) { // Time to on
|
||||
// --- TO REMOVE
|
||||
Serial.println("Timeout, on");
|
||||
// --- TO REMOVE
|
||||
|
||||
start_gps();
|
||||
} else if (!gps_active && _location->waitingTimeSync()) { // On for "gps sync"
|
||||
// --- TO REMOVE
|
||||
Serial.println("gps sync CLI, on");
|
||||
// --- TO REMOVE
|
||||
|
||||
start_gps();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gps_active) {
|
||||
_location->loop();
|
||||
}
|
||||
if (millis() > next_gps_update) {
|
||||
|
||||
if ((int32_t)(millis() - next_gps_update) >= 0) {
|
||||
if(gps_active){
|
||||
#ifdef RAK_WISBLOCK_GPS
|
||||
if ((i2cGPSFlag || serialGPSFlag) && _location->isValid()) {
|
||||
@@ -929,8 +982,12 @@ void EnvironmentSensorManager::loop() {
|
||||
MESH_DEBUG_PRINTLN("lat %f lon %f alt %f", node_lat, node_lon, node_altitude);
|
||||
}
|
||||
#endif
|
||||
|
||||
// In powersaving mode, GPS is on and off. Only update data when GPS is on
|
||||
if(powersaving_enabled) next_gps_update = millis() + (gps_update_interval_sec * 1000);
|
||||
}
|
||||
next_gps_update = millis() + (gps_update_interval_sec * 1000);
|
||||
|
||||
if(!powersaving_enabled) next_gps_update = millis() + (gps_update_interval_sec * 1000);
|
||||
}
|
||||
#endif
|
||||
#if ENV_INCLUDE_BME680_BSEC
|
||||
|
||||
@@ -6,10 +6,22 @@
|
||||
class LocationProvider {
|
||||
protected:
|
||||
bool _time_sync_needed = true;
|
||||
bool powersaving_enabled = false;
|
||||
unsigned long _next_gps_off = 0;
|
||||
unsigned long _next_gps_on = 0;
|
||||
unsigned long _last_valid_time_sync = 0;
|
||||
|
||||
public:
|
||||
virtual void syncTime() { _time_sync_needed = true; }
|
||||
virtual bool waitingTimeSync() { return _time_sync_needed; }
|
||||
virtual void stopTimeSync() { _time_sync_needed = false; }
|
||||
virtual void setGPSPowerSaving(bool enabled) { powersaving_enabled = enabled; _next_gps_off = 0; _next_gps_on = 0; }
|
||||
virtual bool getGPSPowerSaving() { return powersaving_enabled; }
|
||||
virtual unsigned long setNextGPSOff(unsigned long _millis) { _next_gps_off = _millis; }
|
||||
virtual unsigned long getNextGPSOff() { return _next_gps_off; }
|
||||
virtual unsigned long setNextGPSOn(unsigned long _millis) { _next_gps_on = _millis; }
|
||||
virtual unsigned long getNextGPSOn() { return _next_gps_on; }
|
||||
virtual unsigned long getLastValidTimeSync() { return _last_valid_time_sync; }
|
||||
virtual long getLatitude() = 0;
|
||||
virtual long getLongitude() = 0;
|
||||
virtual long getAltitude() = 0;
|
||||
|
||||
@@ -120,7 +120,7 @@ public :
|
||||
return alt;
|
||||
}
|
||||
long satellitesCount() override { return nmea.getNumSatellites(); }
|
||||
bool isValid() override { return nmea.isValid(); }
|
||||
bool isValid() override { return nmea.isValid() && nmea.getYear() < 2030; } // TODO: Pending better validation
|
||||
|
||||
long getTimestamp() override {
|
||||
DateTime dt(nmea.getYear(), nmea.getMonth(),nmea.getDay(),nmea.getHour(),nmea.getMinute(),nmea.getSecond());
|
||||
@@ -154,9 +154,10 @@ public :
|
||||
_clock->setCurrentTime(getTimestamp());
|
||||
_time_sync_needed = false;
|
||||
_last_time_sync = millis();
|
||||
_last_valid_time_sync = _clock->getCurrentTime();
|
||||
}
|
||||
}
|
||||
if (isValid()) {
|
||||
if (isValid() && satellitesCount() >= 5) {
|
||||
time_valid ++;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user