@@ -28,11 +28,11 @@ | |||||
#define SLEEP_DEFAULT_INCREASE_THRESHOLD 3 | #define SLEEP_DEFAULT_INCREASE_THRESHOLD 3 | ||||
#define GPS_DEFAULT_INTERMEDIATE_TIMEOUT_MS 10000 | #define GPS_DEFAULT_INTERMEDIATE_TIMEOUT_MS 10000 | ||||
#define GPS_DEFAULT_TOTAL_TIMEOUT_MS 180000 | |||||
#define GPS_DEFAULT_TOTAL_TIMEOUT_MS 80000 | |||||
#define NETWORK_DEFAULT_INTERMEDIATE_TIMEOUT_MS 6000 | #define NETWORK_DEFAULT_INTERMEDIATE_TIMEOUT_MS 6000 | ||||
#define NETWORK_DEFAULT_TOTAL_TIMEOUT_MS 180000 | |||||
#define NETWORK_DEFAULT_NO_NETWORK_QUALIRY_THRESHOLD 8 | |||||
#define NETWORK_DEFAULT_TOTAL_TIMEOUT_MS 80000 | |||||
#define NETWORK_DEFAULT_NO_NETWORK_QUALITY_THRESHOLD 8 | |||||
#define NETWORK_DEFAULT_NO_NETWORK_TRIES 5 | #define NETWORK_DEFAULT_NO_NETWORK_TRIES 5 | ||||
#pragma endregion | #pragma endregion | ||||
@@ -12,6 +12,7 @@ namespace core { | |||||
void main() { | void main() { | ||||
positions::prepareBackup(); | |||||
PositionEntryMetadata metadata; | PositionEntryMetadata metadata; | ||||
if (positions::acquire(metadata)) { | if (positions::acquire(metadata)) { | ||||
positions::appendLast(metadata); | positions::appendLast(metadata); | ||||
@@ -25,7 +25,7 @@ namespace gps { | |||||
char lastPosition[GPS_POSITION_SIZE]; | char lastPosition[GPS_POSITION_SIZE]; | ||||
SIM808_GPS_STATUS lastStatus; | SIM808_GPS_STATUS lastStatus; | ||||
SIM808_GPS_STATUS acquireCurrentPosition(uint32_t timeout) { | |||||
SIM808_GPS_STATUS acquireCurrentPosition(int32_t timeout) { | |||||
SIM808_GPS_STATUS currentStatus = SIM808_GPS_STATUS::OFF; | SIM808_GPS_STATUS currentStatus = SIM808_GPS_STATUS::OFF; | ||||
do { | do { | ||||
@@ -15,7 +15,7 @@ namespace gps { | |||||
inline void powerOn() { hardware::sim808::gpsPowerOn(); } | inline void powerOn() { hardware::sim808::gpsPowerOn(); } | ||||
inline void powerOff() { hardware::sim808::gpsPowerOff(); } | inline void powerOff() { hardware::sim808::gpsPowerOff(); } | ||||
SIM808_GPS_STATUS acquireCurrentPosition(uint32_t timeout); | |||||
SIM808_GPS_STATUS acquireCurrentPosition(int32_t timeout); | |||||
uint8_t getVelocity(); | uint8_t getVelocity(); | ||||
void getTime(tmElements_t &time); | void getTime(tmElements_t &time); |
@@ -55,7 +55,7 @@ namespace hardware { | |||||
} | } | ||||
void gpsPowerOff() { | void gpsPowerOff() { | ||||
NOTICE("gpsPowerOff"); | |||||
VERBOSE("gpsPowerOff"); | |||||
device.disableGps(); | device.disableGps(); | ||||
powerOffIfUnused(); | powerOffIfUnused(); | ||||
} | } | ||||
@@ -10,20 +10,21 @@ | |||||
namespace network { | namespace network { | ||||
SIM808RegistrationStatus waitForRegistered(uint32_t timeout) { | |||||
VERBOSE("waitForRegistered"); | |||||
SIM808RegistrationStatus waitForRegistered(int32_t timeout) { | |||||
NOTICE_FORMAT("waitForRegistered", "Timeout : %d", timeout); | |||||
SIM808RegistrationStatus currentStatus; | SIM808RegistrationStatus currentStatus; | ||||
SIM808SignalQualityReport report; | |||||
uint8_t noReliableNetwork = 0; | uint8_t noReliableNetwork = 0; | ||||
do { | do { | ||||
currentStatus = hardware::sim808::device.getNetworkRegistrationStatus(); | currentStatus = hardware::sim808::device.getNetworkRegistrationStatus(); | ||||
if (isAvailable(currentStatus.stat)) break; | if (isAvailable(currentStatus.stat)) break; | ||||
SIM808SignalQualityReport report = hardware::sim808::device.getSignalQuality(); | |||||
report = hardware::sim808::device.getSignalQuality(); | |||||
NOTICE_FORMAT("waitForRegistered", "%d, [%d %ddBm]", currentStatus.stat, report.ssri, report.attenuation); | NOTICE_FORMAT("waitForRegistered", "%d, [%d %ddBm]", currentStatus.stat, report.ssri, report.attenuation); | ||||
if (report.ssri < NETWORK_DEFAULT_NO_NETWORK_QUALIRY_THRESHOLD) noReliableNetwork++; | |||||
if (report.ssri < NETWORK_DEFAULT_NO_NETWORK_QUALITY_THRESHOLD) noReliableNetwork++; | |||||
else noReliableNetwork = 0; | else noReliableNetwork = 0; | ||||
if (noReliableNetwork > NETWORK_DEFAULT_NO_NETWORK_TRIES) { | if (noReliableNetwork > NETWORK_DEFAULT_NO_NETWORK_TRIES) { | ||||
NOTICE_MSG("waitForRegistered", "No reliable signal"); | NOTICE_MSG("waitForRegistered", "No reliable signal"); | ||||
@@ -34,6 +35,7 @@ namespace network { | |||||
timeout -= NETWORK_DEFAULT_INTERMEDIATE_TIMEOUT_MS; | timeout -= NETWORK_DEFAULT_INTERMEDIATE_TIMEOUT_MS; | ||||
} while (timeout > 1); | } while (timeout > 1); | ||||
report = hardware::sim808::device.getSignalQuality(); | |||||
NOTICE_FORMAT("waitForRegistered", "%d, [%d %ddBm]", currentStatus.stat, report.ssri, report.attenuation); | NOTICE_FORMAT("waitForRegistered", "%d, [%d %ddBm]", currentStatus.stat, report.ssri, report.attenuation); | ||||
return currentStatus; | return currentStatus; | ||||
} | } | ||||
@@ -7,7 +7,7 @@ namespace network { | |||||
inline void powerOn() { hardware::sim808::networkPowerOn(); } | inline void powerOn() { hardware::sim808::networkPowerOn(); } | ||||
inline void powerOff() { hardware::sim808::networkPowerOff(); } | inline void powerOff() { hardware::sim808::networkPowerOff(); } | ||||
SIM808RegistrationStatus waitForRegistered(uint32_t timeout); | |||||
SIM808RegistrationStatus waitForRegistered(int32_t timeout); | |||||
bool isAvailable(SIM808_NETWORK_REGISTRATION_STATE state); | bool isAvailable(SIM808_NETWORK_REGISTRATION_STATE state); | ||||
bool enableGprs(); | bool enableGprs(); | ||||
} | } |
@@ -5,7 +5,6 @@ | |||||
#if BACKUP_ENABLE_NETWORK | #if BACKUP_ENABLE_NETWORK | ||||
#include "NetworkPositionsBackup.h" | #include "NetworkPositionsBackup.h" | ||||
#include "Debug.h" | #include "Debug.h" | ||||
#include "Positions.h" | |||||
#include "Hardware.h" | #include "Hardware.h" | ||||
#include "Network.h" | #include "Network.h" | ||||
@@ -16,76 +15,90 @@ namespace positions { | |||||
namespace backup { | namespace backup { | ||||
namespace net { | namespace net { | ||||
namespace details { | |||||
bool NetworkPositionsBackup::isBackupNeeded(bool forPrepare) { | |||||
config_t *config = &config::main::value; | |||||
return (config->network.lastSavedEntry == 0xFFFF && config->lastEntry != 0xFFFF) || | |||||
positions::count(config->network.lastSavedEntry) > config->network.saveThreshold - (forPrepare ? 1 : 0); | |||||
} | |||||
bool isBackupNeeded() { | |||||
config_t *config = &config::main::value; | |||||
return (config->network.lastSavedEntry == 0xFFFF && config ->lastEntry != 0xFFFF) || | |||||
positions::count(config->network.lastSavedEntry) > config->network.saveThreshold; | |||||
} | |||||
bool NetworkPositionsBackup::appendPosition(PositionEntry &entry) { | |||||
char buffer[BUFFER_SIZE]; | |||||
snprintf(buffer, BUFFER_SIZE, "%d,%d,%d,%d,%d,%d,", | |||||
debug::freeRam(), | |||||
hardware::sim808::device.getSignalQuality().attenuation, | |||||
entry.metadata.batteryLevel, | |||||
entry.metadata.batteryVoltage, | |||||
static_cast<uint16_t>(entry.metadata.temperature * 100), | |||||
static_cast<uint8_t>(entry.metadata.status)); | |||||
strcat(buffer, entry.position); | |||||
NOTICE_FORMAT("appendPosition", "Sending : %s", buffer); | |||||
uint16_t responseCode = hardware::sim808::device.httpPost( | |||||
config::main::value.network.url, | |||||
F("text/csv"), | |||||
buffer, | |||||
buffer, | |||||
BUFFER_SIZE | |||||
) == POSITIONS_CONFIG_NET_DEFAULT_EXPECTED_RESPONSE; | |||||
NOTICE_FORMAT("appendPosition", "Response : %d", responseCode); | |||||
return responseCode; | |||||
} | |||||
bool appendPosition(PositionEntry &entry) { | |||||
char buffer[BUFFER_SIZE]; | |||||
snprintf(buffer, BUFFER_SIZE, "%d,%d,%d,%d,%d,%d,", | |||||
debug::freeRam(), | |||||
hardware::sim808::device.getSignalQuality().attenuation, | |||||
entry.metadata.batteryLevel, | |||||
entry.metadata.batteryVoltage, | |||||
static_cast<uint16_t>(entry.metadata.temperature * 100), | |||||
static_cast<uint8_t>(entry.metadata.status)); | |||||
strcat(buffer, entry.position); | |||||
NOTICE_FORMAT("appendPosition", "Sending : %s", buffer); | |||||
uint16_t responseCode = hardware::sim808::device.httpPost( | |||||
config::main::value.network.url, | |||||
F("text/csv"), | |||||
buffer, | |||||
buffer, | |||||
BUFFER_SIZE | |||||
) == POSITIONS_CONFIG_NET_DEFAULT_EXPECTED_RESPONSE; | |||||
NOTICE_FORMAT("appendPosition", "Response : %d", responseCode); | |||||
return responseCode; | |||||
__attribute__((__optimize__("O2"))) | |||||
void NetworkPositionsBackup::appendPositions() { | |||||
uint16_t currentEntryIndex = config::main::value.network.lastSavedEntry + 1; | |||||
int32_t networkTimeout = 0; | |||||
PositionEntry currentEntry; | |||||
SIM808RegistrationStatus networkStatus; | |||||
network::powerOn(); | |||||
networkTimeout = _prepareTime > 0 ? | |||||
NETWORK_DEFAULT_TOTAL_TIMEOUT_MS - (rtc::getTime() - _prepareTime) * 1000 : | |||||
NETWORK_DEFAULT_TOTAL_TIMEOUT_MS; | |||||
networkStatus = network::waitForRegistered(networkTimeout); | |||||
if (!network::isAvailable(networkStatus.stat)) NOTICE_MSG("appendPositions", "network unavailable"); | |||||
else if (!network::enableGprs()) NOTICE_MSG("appendPositions", "gprs unavailable"); | |||||
else { | |||||
hardware::i2c::powerOn(); | |||||
do { | |||||
if (!positions::get(currentEntryIndex, currentEntry)) break; | |||||
if (!appendPosition(currentEntry)) break; | |||||
config::main::value.network.lastSavedEntry = currentEntryIndex; | |||||
config::main::save(); | |||||
} while (positions::moveNext(currentEntryIndex)); | |||||
hardware::i2c::powerOff(); | |||||
} | } | ||||
void appendPositions() { | |||||
uint16_t currentEntryIndex = config::main::value.network.lastSavedEntry + 1; | |||||
PositionEntry currentEntry; | |||||
SIM808RegistrationStatus networkStatus; | |||||
network::powerOn(); | |||||
networkStatus = network::waitForRegistered(NETWORK_DEFAULT_TOTAL_TIMEOUT_MS); | |||||
if (!network::isAvailable(networkStatus.stat)) NOTICE_MSG("appendPositions", "network unavailable"); | |||||
else if (!network::enableGprs()) NOTICE_MSG("appendPositions", "gprs unavailable"); | |||||
else { | |||||
hardware::i2c::powerOn(); | |||||
do { | |||||
if (!positions::get(currentEntryIndex, currentEntry)) break; | |||||
if (!appendPosition(currentEntry)) break; | |||||
network::powerOff(); | |||||
} | |||||
config::main::value.network.lastSavedEntry = currentEntryIndex; | |||||
config::main::save(); | |||||
void NetworkPositionsBackup::setup() { | |||||
NOTICE("setup"); | |||||
} | |||||
} while (positions::moveNext(currentEntryIndex)); | |||||
hardware::i2c::powerOff(); | |||||
} | |||||
void NetworkPositionsBackup::prepare() { | |||||
NOTICE("prepare"); | |||||
network::powerOff(); | |||||
if (!isBackupNeeded(true)) { | |||||
_prepareTime = 0; | |||||
return; | |||||
} | } | ||||
} | |||||
void NetworkPositionsBackup::setup() { | |||||
NOTICE("setup"); | |||||
network::powerOn(); | |||||
_prepareTime = rtc::getTime(); | |||||
} | } | ||||
void NetworkPositionsBackup::backup() { | void NetworkPositionsBackup::backup() { | ||||
NOTICE("backup"); | NOTICE("backup"); | ||||
if (!details::isBackupNeeded()) return; | |||||
details::appendPositions(); | |||||
if (!isBackupNeeded(false)) return; | |||||
appendPositions(); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -1,6 +1,8 @@ | |||||
#pragma once | #pragma once | ||||
#include "PositionsBackup.h" | #include "PositionsBackup.h" | ||||
#include "Time2.h" | |||||
#include "Positions.h" | |||||
namespace positions { | namespace positions { | ||||
namespace backup { | namespace backup { | ||||
@@ -8,8 +10,16 @@ namespace positions { | |||||
class NetworkPositionsBackup : public PositionsBackup { | class NetworkPositionsBackup : public PositionsBackup { | ||||
private: | private: | ||||
timestamp_t _prepareTime; | |||||
bool isBackupNeeded(bool forPrepare); | |||||
bool appendPosition(PositionEntry &entry); | |||||
void appendPositions(); | |||||
public: | public: | ||||
void setup(); | void setup(); | ||||
void prepare(); | |||||
void backup(); | void backup(); | ||||
}; | }; | ||||
@@ -144,6 +144,14 @@ namespace positions { | |||||
return config->lastEntry - fromIndex; | return config->lastEntry - fromIndex; | ||||
} | } | ||||
void prepareBackup() { | |||||
#ifdef BACKUPS_ENABLED | |||||
for (int i = 0; i < BACKUPS_ENABLED; i++) { | |||||
_backups[i]->prepare(); | |||||
} | |||||
#endif | |||||
} | |||||
void doBackup() { | void doBackup() { | ||||
#ifdef BACKUPS_ENABLED | #ifdef BACKUPS_ENABLED | ||||
for (int i = 0; i < BACKUPS_ENABLED; i++) { | for (int i = 0; i < BACKUPS_ENABLED; i++) { | ||||
@@ -27,5 +27,6 @@ namespace positions { | |||||
bool moveNext(uint16_t &index); | bool moveNext(uint16_t &index); | ||||
uint16_t count(uint16_t fromIndex); | uint16_t count(uint16_t fromIndex); | ||||
void prepareBackup(); | |||||
void doBackup(); | void doBackup(); | ||||
} | } |
@@ -6,8 +6,10 @@ namespace positions { | |||||
class PositionsBackup { | class PositionsBackup { | ||||
public: | public: | ||||
~PositionsBackup(); | ~PositionsBackup(); | ||||
virtual void setup()=0; | |||||
virtual void backup()=0; | |||||
virtual void setup() = 0; | |||||
virtual void prepare() = 0; | |||||
virtual void backup() = 0; | |||||
}; | }; | ||||
} | } |