Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

174 строки
5.1 KiB

  1. #include "Core.h"
  2. #include "Config.h"
  3. #include "Flash.h"
  4. #include "MainUnit.h"
  5. #include "Gps.h"
  6. #include "Network.h"
  7. #include "Rtc.h"
  8. #include "Alerts.h"
  9. #include "Logging.h"
  10. #define SMS_BUFFER_SIZE 140
  11. #define NO_ALERTS_NOTIFIED 0
  12. using namespace utils;
  13. namespace core {
  14. #define CURRENT_LOGGER "core"
  15. uint16_t sleepTime = SLEEP_TIME_SECONDS;
  16. uint8_t stoppedInARow = SLEEP_STOPPED_THRESHOLD - 1;
  17. TRACKER_MOVING_STATE movingState = TRACKER_MOVING_STATE::MOVING;
  18. namespace details {
  19. void appendToSmsBuffer(char * buffer, const char * fmt, ...) {
  20. va_list args;
  21. va_start(args, fmt);
  22. size_t bufferLeft = SMS_BUFFER_SIZE - strlen(buffer);
  23. char * p = buffer + strlen(buffer);
  24. vsnprintf_P(p, bufferLeft, fmt, args);
  25. va_end(args);
  26. }
  27. }
  28. void main() {
  29. bool acquired = false;
  30. PositionEntryMetadata metadata;
  31. if(movingState >= TRACKER_MOVING_STATE::ABOUT_TO_STOP) {
  32. //forcing when the tracker is about to stop (which should result in STOPPED a few lines below)
  33. positions::prepareBackup(movingState == TRACKER_MOVING_STATE::ABOUT_TO_STOP);
  34. }
  35. acquired = positions::acquire(metadata);
  36. if (acquired) {
  37. positions::appendLast(metadata);
  38. movingState = updateSleepTime();
  39. gps::preserveCurrentCoordinates();
  40. }
  41. alerts::clear(metadata);
  42. alerts::add(notifyFailures(metadata));
  43. if(movingState >= TRACKER_MOVING_STATE::STOPPED) {
  44. positions::doBackup(movingState == TRACKER_MOVING_STATE::STOPPED); //forcing at the moment the tracker stop
  45. }
  46. if (acquired) updateRtcTime();
  47. hardware::sim808::powerOff(); //forcing power off, regardless of the counts and current use
  48. mainunit::deepSleep(sleepTime);
  49. }
  50. uint8_t notifyFailures(PositionEntryMetadata &metadata) {
  51. #define CURRENT_LOGGER_FUNCTION "notifyFailures"
  52. SIM808_NETWORK_REGISTRATION_STATE networkStatus;
  53. char buffer[SMS_BUFFER_SIZE];
  54. const __FlashStringHelper * backupFailureString = F(" Backup battery failure ?");
  55. bool notified = false;
  56. uint8_t triggered = alerts::getTriggered(metadata);
  57. NOTICE_FORMAT("triggered : %B", triggered);
  58. if (!triggered) return NO_ALERTS_NOTIFIED;
  59. network::powerOn();
  60. networkStatus = network::waitForRegistered(NETWORK_TOTAL_TIMEOUT_MS);
  61. if (network::isAvailable(networkStatus)) {
  62. strncpy_P(buffer, PSTR("Alerts !"), SMS_BUFFER_SIZE);
  63. if (bitRead(triggered, ALERT_BATTERY_LEVEL_1) || bitRead(triggered, ALERT_BATTERY_LEVEL_2)) {
  64. details::appendToSmsBuffer(buffer, PSTR("\n- Battery at %d%%."), metadata.batteryLevel);
  65. }
  66. if (bitRead(triggered, ALERT_RTC_TEMPERATURE_FAILURE)) {
  67. details::appendToSmsBuffer(buffer, PSTR("\n- Temperature is %dC.%S"), metadata.temperature, backupFailureString);
  68. }
  69. if (bitRead(triggered, ALERT_RTC_CLOCK_FAILURE)) {
  70. details::appendToSmsBuffer(buffer, PSTR("\n- RTC was stopped.%S"), backupFailureString);
  71. }
  72. #if ALERTS_ON_SERIAL
  73. NOTICE_FORMAT("%s", buffer);
  74. notified = true;
  75. #else
  76. notified = network::sendSms(buffer);
  77. #endif
  78. if (!notified) NOTICE_MSG("SMS not sent !");
  79. }
  80. network::powerOff();
  81. return notified ? triggered : NO_ALERTS_NOTIFIED; //If not notified, the alerts state should not be persisted (so we can retry to notify them)
  82. }
  83. void updateRtcTime() {
  84. tmElements_t time;
  85. gps::getTime(time);
  86. rtc::setTime(time);
  87. }
  88. TRACKER_MOVING_STATE updateSleepTime() {
  89. #define CURRENT_LOGGER_FUNCTION "updateSleepTime"
  90. TRACKER_MOVING_STATE state = TRACKER_MOVING_STATE::MOVING;
  91. uint8_t velocity = gps::getVelocity();
  92. sleepTime = mapSleepTime(velocity);
  93. if (velocity < SLEEP_TIMING_MIN_MOVING_VELOCITY) {
  94. float distance = gps::getDistanceFromPrevious(); //did we missed positions because we were sleeping ?
  95. if (distance > GPS_MISSED_POSITION_GAP_KM) stoppedInARow = 0;
  96. else stoppedInARow = min(stoppedInARow + 1, SLEEP_STOPPED_THRESHOLD + 1); //avoid overflow on REALLY long stops
  97. if (stoppedInARow < SLEEP_STOPPED_THRESHOLD) {
  98. sleepTime = SLEEP_PAUSING_TIME_SECONDS;
  99. state = stoppedInARow == SLEEP_STOPPED_THRESHOLD - 1 ?
  100. TRACKER_MOVING_STATE::ABOUT_TO_STOP :
  101. TRACKER_MOVING_STATE::PAUSED;
  102. }
  103. else if (stoppedInARow == SLEEP_STOPPED_THRESHOLD) state = TRACKER_MOVING_STATE::STOPPED;
  104. else state = TRACKER_MOVING_STATE::STATIC;
  105. }
  106. else stoppedInARow = 0;
  107. NOTICE_FORMAT("stop %d, state %d, %dkmh => %ds", stoppedInARow, state, velocity, sleepTime);
  108. return state;
  109. }
  110. uint16_t mapSleepTime(uint8_t velocity) {
  111. #define CURRENT_LOGGER_FUNCTION "mapSleepTime"
  112. uint16_t result;
  113. uint16_t currentTime = 0xFFFF;
  114. if (rtc::isAccurate()) {
  115. tmElements_t time;
  116. rtc::getTime(time);
  117. currentTime = SLEEP_TIMING_TIME(time.hour, time.minute);
  118. }
  119. for (uint8_t i = flash::getArraySize(config::defaultSleepTimings); i--;) {
  120. sleepTimings_t timing;
  121. flash::read(&config::defaultSleepTimings[i], timing);
  122. if (velocity < timing.speed) continue;
  123. if (currentTime != 0xFFFF && (currentTime < timing.timeMin || currentTime > timing.timeMax)) continue;
  124. result = timing.seconds;
  125. break;
  126. }
  127. VERBOSE_FORMAT("%d,%d", velocity, result);
  128. return result;
  129. }
  130. }