Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

144 linhas
4.0 KiB

  1. #include "Core.h"
  2. #include "Config.h"
  3. #include "Flash.h"
  4. #include "Alerts.h"
  5. #include "Buffer.h"
  6. #define LOGGER_NAME "Core"
  7. #define SMS_MAX_SIZE 140
  8. #define NO_ALERTS_NOTIFIED 0
  9. using namespace utils;
  10. namespace core {
  11. uint16_t sleepTime = SLEEP_DEFAULT_TIME_SECONDS;
  12. uint8_t stoppedInARow = SLEEP_DEFAULT_STOPPED_THRESHOLD - 1;
  13. namespace details {
  14. void appendToSmsBuffer(const char * fmt, ...) {
  15. va_list args;
  16. va_start(args, fmt);
  17. size_t bufferLeft = SMS_MAX_SIZE - strlen(buffer::value);
  18. char * p = buffer::value + strlen(buffer::value);
  19. vsnprintf_P(p, bufferLeft, fmt, args);
  20. va_end(args);
  21. }
  22. }
  23. void main() {
  24. bool forceBackup = false;
  25. bool acquired = false;
  26. PositionEntryMetadata metadata;
  27. positions::prepareBackup();
  28. acquired = positions::acquire(metadata);
  29. if (acquired) {
  30. positions::appendLast(metadata);
  31. forceBackup = updateSleepTime();
  32. gps::preserveCurrentCoordinates();
  33. }
  34. alerts::add(notifyFailures(metadata));
  35. alerts::clear(metadata);
  36. positions::doBackup(forceBackup);
  37. if (acquired) updateRtcTime();
  38. mainunit::deepSleep(sleepTime);
  39. }
  40. uint8_t notifyFailures(PositionEntryMetadata &metadata) {
  41. SIM808RegistrationStatus networkStatus;
  42. const __FlashStringHelper * backupFailureString = F(" Backup battery failure ?\n");
  43. uint8_t triggered = alerts::getTriggered(metadata);
  44. if (!triggered) return NO_ALERTS_NOTIFIED;
  45. network::powerOn();
  46. networkStatus = network::waitForRegistered(NETWORK_DEFAULT_TOTAL_TIMEOUT_MS);
  47. if (!network::isAvailable(networkStatus.stat)) return NO_ALERTS_NOTIFIED;
  48. buffer::clear();
  49. strcpy_P(buffer::value, PSTR("Alerts !\n"));
  50. if (bitRead(triggered, ALERT_BATTERY_LEVEL_1) || bitRead(triggered, ALERT_BATTERY_LEVEL_2)) {
  51. details::appendToSmsBuffer(PSTR("- Battery at %d%%.\n"), metadata.batteryLevel);
  52. }
  53. if (bitRead(triggered, ALERT_RTC_CLOCK_FAILURE)) {
  54. details::appendToSmsBuffer(PSTR("-RTC was stopped. %S"), backupFailureString);
  55. }
  56. if (bitRead(triggered, ALERT_RTC_TEMPERATURE_FAILURE)) {
  57. details::appendToSmsBuffer(PSTR("- Temperature is %dC. %S"), static_cast<uint16_t>(metadata.temperature * 100), backupFailureString);
  58. }
  59. bool notified = network::sendSms(buffer::value);
  60. if (!notified) NOTICE_MSG("notifyFailure", "SMS not sent !");
  61. network::powerOff();
  62. return notified ? triggered : NO_ALERTS_NOTIFIED; //If not notified, the alerts state should not be persisted (so we can retry to notify them)
  63. }
  64. void updateRtcTime() {
  65. tmElements_t time;
  66. gps::getTime(time);
  67. rtc::setTime(time);
  68. }
  69. bool updateSleepTime() {
  70. uint8_t velocity = gps::getVelocity();
  71. uint16_t result = mapSleepTime(velocity);
  72. bool goingLongSleep = false;
  73. if (velocity < SLEEP_TIMING_MIN_MOVING_VELOCITY) {
  74. float distance = gps::getDistanceFromPrevious(); //did we missed positions because we were sleeping ?
  75. if (distance > GPS_DEFAULT_MISSED_POSITION_GAP_KM) stoppedInARow = 0;
  76. else stoppedInARow = min(stoppedInARow + 1, SLEEP_DEFAULT_STOPPED_THRESHOLD + 1); //avoid overflow on REALLY long stops
  77. if (stoppedInARow < SLEEP_DEFAULT_STOPPED_THRESHOLD) {
  78. result = SLEEP_DEFAULT_PAUSING_TIME_SECONDS;
  79. }
  80. else if (stoppedInARow == SLEEP_DEFAULT_STOPPED_THRESHOLD) goingLongSleep = true;
  81. }
  82. else stoppedInARow = 0;
  83. sleepTime = result;
  84. NOTICE_FORMAT("updateSleepTime", "%dkmh => %d seconds", velocity, sleepTime);
  85. return goingLongSleep;
  86. }
  87. uint16_t mapSleepTime(uint8_t velocity) {
  88. uint16_t result;
  89. uint16_t currentTime = 0xFFFF;
  90. if (rtc::isAccurate()) {
  91. tmElements_t time;
  92. rtc::getTime(time);
  93. currentTime = SLEEP_TIMING_TIME(time.Hour, time.Minute);
  94. }
  95. for (uint8_t i = flash::getArraySize(config::defaultSleepTimings); i--;) {
  96. sleepTimings_t timing;
  97. flash::read(&config::defaultSleepTimings[i], timing);
  98. if (velocity < timing.speed) continue;
  99. if (currentTime != 0xFFFF && (currentTime < timing.timeMin || currentTime > timing.timeMax)) continue;
  100. result = timing.seconds;
  101. break;
  102. }
  103. VERBOSE_FORMAT("computeSleepTime", "%d,%d", velocity, result);
  104. return result;
  105. }
  106. }