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.

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