Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

162 rader
4.3 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. #ifdef BACKUPS_ENABLED
  19. backup::PositionsBackup **_backups;
  20. #endif
  21. namespace details {
  22. uint16_t maxEntryIndex = 0;
  23. uint16_t getEntryAddress(uint16_t index) {
  24. if (index > maxEntryIndex) return -1;
  25. return ENTRIES_ADDR + (ENTRY_RESERVED_SIZE * index);
  26. }
  27. }
  28. void setup() {
  29. details::maxEntryIndex = (E24_MAX_ADDRESS(hardware::i2c::eeprom.getSize()) - ENTRIES_ADDR) / ENTRY_RESERVED_SIZE;
  30. #ifdef BACKUPS_ENABLED
  31. uint8_t backupIdx = 0;
  32. _backups = new backup::PositionsBackup*[BACKUPS_ENABLED];
  33. #if BACKUP_ENABLE_SDCARD
  34. _backups[backupIdx] = new backup::sd::SdPositionsBackup();
  35. _backups[backupIdx]->setup();
  36. backupIdx++;
  37. #endif
  38. #if BACKUP_ENABLE_NETWORK
  39. _backups[backupIdx] = new backup::net::NetworkPositionsBackup();
  40. _backups[backupIdx]->setup();
  41. backupIdx++;
  42. #endif
  43. #endif
  44. }
  45. bool acquire(PositionEntryMetadata &metadata) {
  46. NOTICE("acquire");
  47. timestamp_t before;
  48. gps::powerOn();
  49. before = rtc::getTime();
  50. SIM808_GPS_STATUS gpsStatus = gps::acquireCurrentPosition(GPS_DEFAULT_TOTAL_TIMEOUT_MS);
  51. SIM808ChargingStatus battery = hardware::sim808::device.getChargingState();
  52. gps::powerOff();
  53. NOTICE_FORMAT("acquire", "Status : %d", gpsStatus);
  54. if (gpsStatus < SIM808_GPS_STATUS::FIX) return false;
  55. uint16_t timeToFix = rtc::getTime() - before;
  56. tmElements_t time;
  57. gps::getTime(time);
  58. rtc::setTime(time);
  59. metadata = {
  60. battery.level,
  61. battery.voltage,
  62. rtc::getTemperature(),
  63. timeToFix,
  64. gpsStatus
  65. };
  66. return true;
  67. }
  68. void appendLast(const PositionEntryMetadata &metadata) {
  69. VERBOSE("appendLast");
  70. uint16_t entryIndex;
  71. uint16_t entryAddress;
  72. PositionEntry entry = { metadata };
  73. strlcpy(entry.position, gps::lastPosition, POSITION_SIZE);
  74. config_t* config = &config::main::value;
  75. entryIndex = config->lastEntry + 1;
  76. entryAddress = details::getEntryAddress(entryIndex);
  77. hardware::i2c::powerOn();
  78. hardware::i2c::eeprom.writeBlock(entryAddress, entry);
  79. 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);
  80. config->lastEntry++;
  81. if (config->lastEntry > details::maxEntryIndex) config->lastEntry = 0;
  82. if (config->lastEntry == config->firstEntry) config->firstEntry++;
  83. if (config->firstEntry > details::maxEntryIndex) config->firstEntry = 0;
  84. config::main::save();
  85. hardware::i2c::powerOff();
  86. }
  87. bool get(uint16_t index, PositionEntry &entry) {
  88. VERBOSE("get");
  89. uint16_t entryAddress = details::getEntryAddress(index);
  90. if (entryAddress == -1) return false;
  91. VERBOSE_FORMAT("get", "Reading entry n°%d @ %X", index, entryAddress);
  92. hardware::i2c::powerOn();
  93. hardware::i2c::eeprom.readBlock(entryAddress, entry);
  94. hardware::i2c::powerOff();
  95. 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);
  96. return true;
  97. }
  98. bool moveNext(uint16_t &index) {
  99. if (index == config::main::value.lastEntry) return false;
  100. if (index == details::maxEntryIndex) index = 0; //could use a modulo but easier to understand that way
  101. else index++;
  102. return true;
  103. }
  104. uint16_t count(uint16_t fromIndex) {
  105. config_t *config = &config::main::value;
  106. if (config->lastEntry < config->firstEntry) { config->lastEntry += details::maxEntryIndex; }
  107. return config->lastEntry - fromIndex;
  108. }
  109. void prepareBackup() {
  110. #ifdef BACKUPS_ENABLED
  111. for (int i = 0; i < BACKUPS_ENABLED; i++) {
  112. _backups[i]->prepare();
  113. }
  114. #endif
  115. }
  116. void doBackup() {
  117. #ifdef BACKUPS_ENABLED
  118. for (int i = 0; i < BACKUPS_ENABLED; i++) {
  119. _backups[i]->backup();
  120. }
  121. #endif
  122. }
  123. }