Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

132 righe
4.0 KiB

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