You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

180 line
4.8 KiB

  1. #include "Config.h"
  2. #include "Debug.h"
  3. #include "Positions.h"
  4. #include "Gps.h"
  5. #if BACKUP_ENABLE_SDCARD || BACKUP_ENABLE_NETWORK
  6. #define BACKUPS_ENABLED (BACKUP_ENABLE_SDCARD + BACKUP_ENABLE_NETWORK)
  7. #endif
  8. #if BACKUP_ENABLE_SDCARD
  9. #include "SdPositionsBackup.h"
  10. #endif
  11. #if BACKUP_ENABLE_NETWORK
  12. #include "NetworkPositionsBackup.h"
  13. #endif
  14. #define LOGGER_NAME "Positions"
  15. #define ENTRY_RESERVED_SIZE 128
  16. #define ENTRIES_ADDR CONFIG_RESERVED_SIZE
  17. namespace positions {
  18. #if BACKUPS_ENABLED > 1
  19. backup::PositionsBackup **_backups;
  20. #elif BACKUPS_ENABLED == 1
  21. backup::PositionsBackup * _backup;
  22. #endif
  23. namespace details {
  24. uint16_t maxEntryIndex = 0;
  25. uint16_t getEntryAddress(uint16_t index) {
  26. if (index > maxEntryIndex) return -1;
  27. return ENTRIES_ADDR + (ENTRY_RESERVED_SIZE * index);
  28. }
  29. }
  30. void setup() {
  31. details::maxEntryIndex = (E24_MAX_ADDRESS(hardware::i2c::eeprom.getSize()) - ENTRIES_ADDR) / ENTRY_RESERVED_SIZE;
  32. #if BACKUPS_ENABLED > 0
  33. backup::PositionsBackup * backup = NULL;
  34. #if BACKUPS_ENABLED > 1
  35. uint8_t backupIdx = 0;
  36. _backups = new backup::PositionsBackup*[BACKUPS_ENABLED];
  37. #endif //BACKUPS_ENABLED > 1
  38. #if BACKUP_ENABLE_SDCARD
  39. backup = new backup::sd::SdPositionsBackup();
  40. backup->setup();
  41. #if BACKUPS_ENABLED > 1
  42. _backups[backupIdx] = backup;
  43. backupIdx++;
  44. #endif //BACKUPS_ENABLED > 1
  45. #endif //BACKUP_ENABLE_SDCARD
  46. #if BACKUP_ENABLE_NETWORK
  47. backup = new backup::net::NetworkPositionsBackup();
  48. backup->setup();
  49. #if BACKUPS_ENABLED > 1
  50. _backups[backupIdx] = backup;
  51. backupIdx++;
  52. #endif //BACKUPS_ENABLED > 1
  53. #endif //BACKUP_ENABLE_NETWORK
  54. #if BACKUPS_ENABLED == 1
  55. _backup = backup;
  56. #endif //BACKUPS_ENABLED == 1
  57. #endif //BACKUPS_ENABLED > 0
  58. }
  59. bool acquire(PositionEntryMetadata &metadata) {
  60. NOTICE("acquire");
  61. timestamp_t before;
  62. gps::powerOn();
  63. before = rtc::getTime();
  64. SIM808_GPS_STATUS gpsStatus = gps::acquireCurrentPosition(GPS_DEFAULT_TOTAL_TIMEOUT_MS);
  65. uint16_t timeToFix = rtc::getTime() - before;
  66. SIM808ChargingStatus battery = hardware::sim808::device.getChargingState();
  67. gps::powerOff();
  68. bool acquired = gpsStatus >= SIM808_GPS_STATUS::FIX; //prety useless wins 14 bytes on the hex size rather than return gpStatus >= ...
  69. NOTICE_FORMAT("acquire", "Status : %d", gpsStatus);
  70. metadata = {
  71. battery.level,
  72. battery.voltage,
  73. rtc::getTemperature(),
  74. timeToFix,
  75. gpsStatus
  76. };
  77. return acquired;
  78. }
  79. void appendLast(const PositionEntryMetadata &metadata) {
  80. VERBOSE("appendLast");
  81. uint16_t entryIndex;
  82. uint16_t entryAddress;
  83. PositionEntry entry = { metadata };
  84. strlcpy(entry.position, gps::lastPosition, POSITION_SIZE);
  85. config_t* config = &config::main::value;
  86. entryIndex = config->lastEntry + 1;
  87. entryAddress = details::getEntryAddress(entryIndex);
  88. hardware::i2c::powerOn();
  89. hardware::i2c::eeprom.writeBlock(entryAddress, entry);
  90. NOTICE_FORMAT("appendLast", "Saved @ %X : [%d%% @ %dmV] [%f�C] [TTF : %d, Status : %d, Position : %s]", entryAddress, entry.metadata.batteryLevel, entry.metadata.batteryVoltage, entry.metadata.temperature, entry.metadata.timeToFix, entry.metadata.status, entry.position);
  91. config->lastEntry++;
  92. if (config->lastEntry > details::maxEntryIndex) config->lastEntry = 0;
  93. if (config->lastEntry == config->firstEntry) config->firstEntry++;
  94. if (config->firstEntry > details::maxEntryIndex) config->firstEntry = 0;
  95. config::main::save();
  96. hardware::i2c::powerOff();
  97. }
  98. bool get(uint16_t index, PositionEntry &entry) {
  99. VERBOSE("get");
  100. uint16_t entryAddress = details::getEntryAddress(index);
  101. if (entryAddress == -1) return false;
  102. VERBOSE_FORMAT("get", "Reading entry n�%d @ %X", index, entryAddress);
  103. hardware::i2c::powerOn();
  104. hardware::i2c::eeprom.readBlock(entryAddress, entry);
  105. hardware::i2c::powerOff();
  106. NOTICE_FORMAT("get", "Read from EEPROM @ %X : [%d%% @ %dmV] [%f�C] [TTF : %d, Status : %d, Position : %s]", entryAddress, entry.metadata.batteryLevel, entry.metadata.batteryVoltage, entry.metadata.temperature, entry.metadata.timeToFix, entry.metadata.status, entry.position);
  107. return true;
  108. }
  109. bool moveNext(uint16_t &index) {
  110. if (index == config::main::value.lastEntry) return false;
  111. if (index == details::maxEntryIndex) index = 0; //could use a modulo but easier to understand that way
  112. else index++;
  113. return true;
  114. }
  115. uint16_t count(uint16_t fromIndex) {
  116. config_t *config = &config::main::value;
  117. uint16_t lastEntry = config->lastEntry;
  118. if (lastEntry < fromIndex) { lastEntry += details::maxEntryIndex; }
  119. return lastEntry - fromIndex;
  120. }
  121. void prepareBackup() {
  122. #if BACKUPS_ENABLED > 1
  123. for (int i = 0; i < BACKUPS_ENABLED; i++) {
  124. _backups[i]->prepare();
  125. }
  126. #elif BACKUPS_ENABLED == 1
  127. _backup->prepare();
  128. #endif
  129. }
  130. void doBackup(bool force) {
  131. #if BACKUPS_ENABLED > 1
  132. for (int i = 0; i < BACKUPS_ENABLED; i++) {
  133. _backups[i]->backup(force);
  134. }
  135. #elif BACKUPS_ENABLED == 1
  136. _backup->backup(force);
  137. #endif
  138. }
  139. }