// // Created by cfif on 12.06.2024. // #ifdef UVEOS_ADD_TELEMATICA #include #include "EgtsTeledataPoint.h" #include "string.h" #include "EgtsOutputCommands.h" #include "EgtsTimestamp.h" #include "math.h" #include "Nmea0183Parser.h" #include "Rtc.h" #include "SystemDelayInterface.h" #define LOG_SIGN "EGTS TELE" #define LOGGER &env->slog->logger const tStringStatic textEgtsEventTetedata[] = { StringStaticInit("EVENT_TIMEOUT_ENGINE_ON (0) - Наступление таймера при включенном зажигании\0"), StringStaticInit("EVENT_DISTANCE (1 (Превышение заданного расстояния\0"), StringStaticInit("EVENT_ROTATE_ANGLE_LIMIT (2) - Превышение заданного курсового угла\0"), StringStaticInit("EVENT_RESPONSE (3 (Событие по запросу\0"), StringStaticInit("EVENT_INPUT_CHANGED (4) - Изменение по аналоговым/дискретным входам\0"), StringStaticInit("EVENT_TIMEOUT_ENGINE_OFF (5) - Наступление таймера при выключенном зажигании\0"), StringStaticInit("-\0"), StringStaticInit("EVENT_HI_SPEED_LIMIT (7) - Превышение одного из заданных порогов скорости\0"), StringStaticInit("EVENT_CPU_RESTART (8) - Событие при старте прибора после перезагрузки по запросу\0"), StringStaticInit("-\0"), StringStaticInit("EVENT_TAMPER (10) - Срабатывание датчика вскрытия корпуса\0"), StringStaticInit("EVENT_EXT_POWER_LOST (11) - Пропадание внешнего питания\0"), StringStaticInit("EVENT_INT_BATTERY_LOW (12) - Низкий заряд встроенного АКБ\0"), StringStaticInit("EVENT_ALARM_BUTTON (13) - Нажата кнопка тревоги\0"), StringStaticInit("EVENT_USER_CALL (14) - Совершен голосовой вызов с устройства\0"), StringStaticInit("EVENT_EMERGENCY_CALL (15) - Экстренный вызов\0"), StringStaticInit("EVENT_DATA_FROM_EXT_SERVICE (16) - Данные с внешнего сервиса (в SDM не используется)\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("EVENT_INT_BATTERY_FAIL (19) - Неисправность внутреннего источника питания\0"), StringStaticInit("EVENT_RAPID_ACCELERATION (20) - Резкий разгон\0"), StringStaticInit("EVENT_RAPID_DECELERATION (21) - Резкое торможение\0"), StringStaticInit("EVENT_NAVIGATION_FAIL (22) - Неисправность навигационного модуля\0"), StringStaticInit("EVENT_ACC_FAIL (23) - Неисправность акселерометра\0"), StringStaticInit("EVENT_GSM_ANTENNA_FAIL (24) - Неисправность антенны сотовой связи\0"), StringStaticInit("EVENT_NAV_ANTENNA_FAIL (25) - Неисправность антенны ГНСС\0"), StringStaticInit("-\0"), StringStaticInit("EVENT_LOW_SPEED_LIMIT (27) - Снижение ниже одного из заданных порогов скорости\0"), StringStaticInit("EVENT_MOVEMENT_WITH_ENGINE_OFF (28) - Передвижение при выключенном зажигании\0"), StringStaticInit("EVENT_EMERGENCY_TRACKING_TIMEOUT (29) - Таймер посылки точек при экстренном слежении\0"), StringStaticInit("EVENT_NAVIGATION_START_STOP (30) - Событие при начале/окончании навигационного решения\0"), StringStaticInit("EVENT_NAVIGATION_UNSTABLE (31) - Нестабильная навигация\0"), StringStaticInit("EVENT_TCP_CONNECTION_START (32) - Событие при установлении соединения с сервером\0"), StringStaticInit("EVENT_GSM_UNSTABLE (33) - Нестабильная сотовая связь\0"), StringStaticInit("EVENT_TCP_UNSTABLE (34) - Нестабильное соединение с сервером\0"), StringStaticInit("EVENT_STATE_CHANGED (35) - Изменение состояния устройства\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("-\0"), StringStaticInit("EVENT_FIRMWARE_UPDATE (62) - Событие при старте устройства после обновления ПО\0"), StringStaticInit("EVENT_CHANGE_POS (63) - Событие по изменению местоположения\0"), StringStaticInit( "VENT_START_SL_MODE_LOW_LVB (64) - Событие по переходу в режим глубокий сон по низкому напряжению АКБ\0"), StringStaticInit( "VENT_START_SL_MODE_ENGINE_OFF (65) - Событие по переходу в режим глубокий сон через заданное время после выключения двигателя\0"), StringStaticInit( "EVENT_START_SL_MODE_GSM_OFF (66) - Событие по переходу в глубокий сон при отсутствии связи\0"), StringStaticInit( "VENT_EXIT_FROM_SL_MODE_CAN_ON (67) - Событие при выходе из глубокого сна по появлению активности в CAN-шине\0"), StringStaticInit( "VENT_EXIT_FROM_SL_MODE_HIGH_POW (68) - Событие при выходе из глубокого сна по появлению высокого напряжения на внешнем АКБ\0"), StringStaticInit( "VENT_EXIT_FROM_SL_MODE_TIMEOUT (69) - Событие при выходе из глубокого сна по заданному таймеру\0"), StringStaticInit("EVENT_GSM_CERTS_UPLOAD (70) - Событие по факту загрузки набора сертификатов\0"), StringStaticInit("EVENT_EGTS_CONFIG_UPDATED (71) - Событие по факту загрузки файла конфигурации\0"), StringStaticInit( "VENT_EXIT_FROM_SL_MODE_ERS (72) - Событие при выходе из глубокого сна для запуска двигателя по расписанию\0"), StringStaticInit("EVENT_WATCHDOG_RESTART (73) - Событие при старте прибора после перезагрузки по вотчдогу\0"), StringStaticInit("EVENT_VEH_STATE_CHANGED (74) - Изменение статуса автомобиля\0"), StringStaticInit("EVENT_DOORS_LOCK_STATE_CHANGED (75) - Изменение статуса замков дверей\0"), StringStaticInit( "VENT_VAS_ALARM_STATE_CHANGED (76) - Изменения статуса тревоги системы контроля доступа (сигнализация)\0"), StringStaticInit("EVENT_LVB_STATE_CHANGED (77) - Изменения статуса внешнего АКБ\0"), StringStaticInit("EVENT_DOORS_STATE_CHANGED (78) - Изменение статуса дверей и капота\0"), StringStaticInit("EVENT_CCU_STATE_CHANGED (79) - Изменение статуса климат-контроля\0"), StringStaticInit("EVENT_TCU_STATE_CHANGED (80) - Изменение статуса КПП\0"), StringStaticInit("EVENT_REFUELING (81) - Событие заправки топливного бака\0"), StringStaticInit("EVENT_SEATS_STATE_CHANGED (82) - Событие изменения статуса кресел\0"), StringStaticInit("EVENT_EXT_POWER_ON (83) - Событие при старте прибора после появления внешнего питания\0"), StringStaticInit("EVENT_CAN_RECIVE_ON (84) - Событие при появлении активности CAN-шины\0"), StringStaticInit("EVENT_CAN_RECIVE_OFF (85) - Событие при пропадании активности CAN-шины\0"), StringStaticInit("EVENT_MOVEMENT_ON (86) - Событие при начале движения\0"), StringStaticInit("EVENT_MOVEMENT_OFF (87) - Событие при окончании движения\0") }; void addTeledataQueue(tEgtsProcessing *env, tEgtsTeledata *egtsTeledata) { if (!isAuth(env)) { if ((egtsTeledata->egtsPosDataArgs.SRC != EVENT_EMERGENCY_CALL) && (egtsTeledata->egtsPosDataArgs.SRC != EVENT_USER_CALL) && (egtsTeledata->egtsPosDataArgs.SRC != EVENT_VEH_STATE_CHANGED) && (egtsTeledata->egtsPosDataArgs.SRC != EVENT_ROTATE_ANGLE_LIMIT) && (egtsTeledata->egtsPosDataArgs.SRC != EVENT_NAVIGATION_START_STOP)) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Соединение с сервером не установлено. Точка не критичная. Сохранение в очередь отменено") return; } } osStatus_t status = osMessageQueuePut(env->egtsTeledataAdditionalData.queue, egtsTeledata, 0x0, 0U); if (status != osOK) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка добавления в очередь addTeledataQueue (1)") tEgtsTeledata egtsTeledataStore; for (uint8_t i = 0; i < 100; ++i) { if (extractTeledataQueue(env, &egtsTeledataStore, 1)) { // bool result = dumpPointStorage(env, &egtsTeledataStore, false); // if (!result) LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка при сохранении данных телематики в хранилище (1)") } else { break; } } status = osMessageQueuePut(env->egtsTeledataAdditionalData.queue, egtsTeledata, 0x0, 0U); if (status != osOK) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка добавления в очередь addTeledataQueue (2)") } } } void addTeledataQueueEvent(tEgtsProcessing *env, eEgtsEventTetedata egtsTeledataEvent) { osStatus_t status = osMessageQueuePut(env->egtsTeledataAdditionalData.queueEvent, &egtsTeledataEvent, 0x0, 0U); if (status != osOK) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка добавления в очередь addTeledataQueueEvent") } else { if (egtsTeledataEvent < 88) { LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", textEgtsEventTetedata[egtsTeledataEvent].data); } else { LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло неизвестное событие: %u", egtsTeledataEvent); } } } bool extractTeledataQueue(tEgtsProcessing *env, tEgtsTeledata *egtsTeledata, uint32_t timeout) { osStatus_t status = osMessageQueueGet(env->egtsTeledataAdditionalData.queue, egtsTeledata, 0, timeout); if ((status != osOK) && (status != osErrorTimeout)) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка извлечения из очереди extractTeledataQueue") } if (status == osOK) { return true; } return false; } bool extractTeledataQueueEvent(tEgtsProcessing *env, eEgtsEventTetedata *egtsTeledataEvent, uint32_t timeout) { osStatus_t status = osMessageQueueGet(env->egtsTeledataAdditionalData.queueEvent, egtsTeledataEvent, 0, timeout); if ((status != osOK) && (status != osErrorTimeout)) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка извлечения из очереди extractTeledataQueueEvent") } if (status == osOK) { return true; } return false; } static double nmeaLocationToDeg(double dec) { double _dec = dec; int deg = (int) (_dec / 100); int min = (int) (_dec) - (deg * 100); double sec = (double) (_dec - min - 100 * deg) * 60.0; return deg + min / 60.0 + sec / 3600.0; } /* void addEventFromUveos(tEgtsProcessing *env, const eEgtsEventTetedata *event) { time_t timestamp = 0; RtcGet(env->gsm->Rtc, ×tamp); tNmeaRmc nmeaRmc; Gnss_GetFullNavData(env->gsm, &nmeaRmc); env->egtsTeledataUveos.egtsPosDataArgs.NTM = Egts_EpochTimestampToEgtsTime(timestamp); env->egtsTeledataAdditionalData.LAT = nmeaLocationToDeg(nmeaRmc.location.latitude); env->egtsTeledataAdditionalData.LON = nmeaLocationToDeg(nmeaRmc.location.longitude); double lat = (fabs(env->egtsTeledataAdditionalData.LAT) / 90) * 0xFFFFFFFF; env->egtsTeledataUveos.egtsPosDataArgs.LAT = (uint32_t) lat; double lon = (fabs(env->egtsTeledataAdditionalData.LON) / 180) * 0xFFFFFFFF; env->egtsTeledataUveos.egtsPosDataArgs.LONG = (uint32_t) lon; env->egtsTeledataUveos.egtsPosDataArgs.FLG.VLD = (nmeaRmc.status == 'A') ? 1 : 0; // Битовый флаг, признак «валидности» координатных данных env->egtsTeledataUveos.egtsPosDataArgs.FLG.FIX = 0; // битовое поле, тип определения координат env->egtsTeledataUveos.egtsPosDataArgs.FLG.CS = 0; // битовое поле, тип используемой системы env->egtsTeledataUveos.egtsPosDataArgs.FLG.BB = 0; // битовый флаг, признак отправки данных из памяти («черный ящик») env->egtsTeledataUveos.egtsPosDataArgs.FLG.MV = env->carEventPosition.carPosition; // битовый флаг, признак движения env->egtsTeledataUveos.egtsPosDataArgs.FLG.LAHS = (nmeaRmc.location.nsIndicator == 'S') ? 1 : 0; // битовый флаг определяет полушарие широты env->egtsTeledataUveos.egtsPosDataArgs.FLG.LOHS = (nmeaRmc.location.ewIndicator == 'W') ? 1 : 0; // битовый флаг определяет полушарие долготы env->egtsTeledataUveos.egtsPosDataArgs.FLG.ALTE = 1; // битовый флаг определяет наличие поля ALT в подзаписи uint16_t speed = (uint16_t) (nmeaRmc.knotVelocity * 1.82 * 10); uint16_t dir = (uint16_t) nmeaRmc.headingAngle; env->egtsTeledataUveos.egtsPosDataArgs.SPD.SPD = speed & 0b0011111111111111; // скорость в км/ч с дискретностью 0,1 км/ч (используется 14 младших бит) int32_t alt = GnssGgaGetAlt(env->gsm); if (alt >= 0) { env->egtsTeledataUveos.egtsPosDataArgs.SPD.ALTS = 0; } else { env->egtsTeledataEdit.egtsPosDataArgs.SPD.ALTS = 1; } env->egtsTeledataUveos.egtsPosDataArgs.SPD.DIRH = dir >> 8; // направление движения env->egtsTeledataUveos.egtsPosDataArgs.DIR = dir; // направление движения env->egtsTeledataUveos.egtsPosDataArgs.ODM = 0; // пройденное расстояние (пробег) в км, с дискретностью 0,1 км env->egtsTeledataUveos.egtsPosDataArgs.DIN = 0; // битовые флаги, определяют состояние основных дискретных входов env->egtsTeledataEdit.egtsPosDataArgs.ALT = abs(alt); env->egtsTeledataUveos.egtsPosDataArgs.SRC = *event; // определяет источник (событие) // Обновление датчиков env->egtsTeledataUveos.egtsSensorsAnArgs = env->egtsTeledataEdit.egtsSensorsAnArgs; env->egtsTeledataUveos.egtsSensorsDigArgs = env->egtsTeledataEdit.egtsSensorsDigArgs; LoggerInfoStatic(LOGGER, LOG_SIGN, "Сохранение события от УВЭОС") bool result = dumpPointStorage(env, &env->egtsTeledataUveos, true); SystemDelayMs(1500); } */ _Noreturn void EgtsProcessing_TransmitterTaskTeledata(tEgtsProcessing *env) { bool oneOn = true; bool oneOff = true; env->pPointsStorageSent = 0; for (;;) { if (onOffTelematica(env, &oneOn, &oneOff, "Задача отправки")) continue; //начало ---------------------------------Отправка теледанных--------------------------------------------------- //начало ---------------------------------Отправка теледанных--------------------------------------------------- //начало ---------------------------------Отправка теледанных--------------------------------------------------- if (!isAuth(env)) { // LoggerInfoStatic(LOGGER, LOG_SIGN, "Ожидание аутентификации на сервере") SystemDelayMs(1000); continue; } /* uint32_t countPoints = 1; while (countPoints) { getPointStorageCount(env, &countPoints); if (loadPointStorage(env, &env->egtsTeledataSent)) { LoggerStrFormatInfo(LOGGER, LOG_SIGN, "В хранилище найдены точки: %d", countPoints) if (env->egtsTeledataSent.egtsPosDataArgs.SRC < 88) { LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Событие в хранилище: %s", textEgtsEventTetedata[env->egtsTeledataSent.egtsPosDataArgs.SRC].data); } else { LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Неизвестное событие в хранилище: %d", env->egtsTeledataSent.egtsPosDataArgs.SRC); } // Передача теледанных if (EgtsProcessing_SendSensors(env, true) == false) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Передача теледанных не удалась") } else { ++env->pPointsStorageSent; LoggerInfoStatic(LOGGER, LOG_SIGN, "Теледанные из хранилища отправлены"); } } else { env->pPointsStorageSent = 0; } if (!isAuth(env) || (EXT_ENV_TELE.store.runtime->EGTS_FLEET_ON == false)) { break; } } */ if (!isAuth(env) || (env->store->runtime.EGTS_FLEET_ON == false)) { continue; } if (extractTeledataQueue(env, &env->egtsTeledataSent, 1)) { /* // начало --- тест --- for (int j = 0; j < 10000; ++j) { for (int i = 0; i < 7000; ++i) { if (dumpPointStorage(env, &env->egtsTeledataSent, false) == false) { asm("nop"); break; } } LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Циклов: %d", j) deleteFilePointStorage(env); asm("nop"); } // конец --- тест --- */ if (env->egtsTeledataSent.egtsPosDataArgs.SRC < 88) { LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Отправка события: %s", textEgtsEventTetedata[env->egtsTeledataSent.egtsPosDataArgs.SRC].data); } else { LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Неизвестное событие: %u", env->egtsTeledataSent.egtsPosDataArgs.SRC); continue; } /* if (!isAuth(env)) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Нет регистрации в сети или аутентификации на сервере") bool result = dumpPointStorage(env, &env->egtsTeledataSent, false); if (!result) LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка при сохранении данных телематики в хранилище") continue; } */ // Передача теледанных if (EgtsProcessing_SendSensors(env, false) == false) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Передача теледанных не удалась") // bool result = dumpPointStorage(env, &env->egtsTeledataSent, false); // if (!result) // LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка при сохранении данных телематики в хранилище") } } //конец ---------------------------------Отправка теледанных--------------------------------------------------- //конец ---------------------------------Отправка теледанных--------------------------------------------------- //конец ---------------------------------Отправка теледанных--------------------------------------------------- } } uint16_t getTotalSpeed(tEgtsProcessing *env, tNmeaRmc *nmeaRmc) { uint16_t totalSpeed = 0; if (nmeaRmc->status == 'A') totalSpeed = (uint16_t) (nmeaRmc->knotVelocity * 1.82); if (env->egtsCanEnv.isEbuData) { totalSpeed = env->egtsCanEnv.speed; } return totalSpeed; } uint32_t getTotalDist(tEgtsProcessing *env) { return env->egtsCanEnv.dist; } void ProcessInfo(tEgtsProcessing *env); _Noreturn void EgtsProcessing_EventTaskTeledata(tEgtsProcessing *env) { bool isTimestamp = true; time_t timestamp = 0; uint32_t timeTeleOff = 0; env->egtsPointEnv.isUpdatePoints = true; env->egtsPointEnv.isOneNav = true; env->egtsPointEnv.oneOn = true; env->egtsPointEnv.oneOff = true; env->egtsPointEnv.isBeginEndNav = false; env->egtsPointEnv.beginAngle = 0; env->egtsPointEnv.beginDist = 0; uint32_t timeTimestamp = 0; eEgtsTsStatus egtsTsStatus = TS_STATUS_UNKNOWN; bool isOneFixMove = true; for (;;) { if (onOffTelematica(env, &env->egtsPointEnv.oneOn, &env->egtsPointEnv.oneOff, "Задача формирования точек")) { if (GpioPinGet(env->ignition)) { env->egtsPointEnv.timeOutCheckTeledata_IGN_TimeUpdate = SystemGetMs() + env->deviceTeledataStorageData->telematica.EGTS_FLEET_IGN_ON_PERIOD * 1000; } else { env->egtsPointEnv.timeOutCheckTeledata_IGN_TimeUpdate = SystemGetMs() + env->deviceTeledataStorageData->telematica.EGTS_FLEET_IGN_OFF_PERIOD * 1000; } continue; } RtcGet(env->gsm->Rtc, ×tamp); if (timestamp < 1718359909) { if (timeTimestamp < SystemGetMs()) { timeTimestamp = SystemGetMs() + 10000; LoggerInfoStatic(LOGGER, LOG_SIGN, "Ожидание получения временной метки") } SystemDelayMs(1000); continue; } else { if (isTimestamp) { isTimestamp = false; LoggerInfoStatic(LOGGER, LOG_SIGN, "Временная метка получена") } } if (!env->isEnableTelematicaSendPoints) { if (timeTeleOff < SystemGetMs()) { timeTeleOff = SystemGetMs() + 10000; LoggerInfoStatic(LOGGER, LOG_SIGN, "Ожидание разрешения телематики") } SystemDelayMs(1000); continue; } env->egtsPointEnv.isEVENT_NAVIGATION_START_STOP = false; env->egtsPointEnv.isEVENT_ROTATE_ANGLE_LIMIT = false; env->egtsPointEnv.isEVENT_DISTANCE = false; env->egtsPointEnv.isEVENT_TIMEOUT_ENGINE_OFF = false; env->egtsPointEnv.isEVENT_TIMEOUT_ENGINE_ON = false; env->egtsPointEnv.isEVENT_EMERGENCY_TRACKING_TIMEOUT = false; env->egtsPointEnv.isEVENT_VEH_STATE_CHANGED = false; env->egtsPointEnv.isEVENT_MOVEMENT_ON = false; env->egtsPointEnv.isEVENT_MOVEMENT_OFF = false; eEgtsEventTetedata egtsEventTetedata = EVENT_INVALID_STATE; if (extractTeledataQueueEvent(env, &egtsEventTetedata, 1)) { } tNmeaRmc nmeaRmc; Gnss_GetFullNavData(env->gsm, &nmeaRmc); // начало --------------------- ДАТЧИКИ ------------------ env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_Uptime].value = SystemGetMs() / 60000; // Uptime // По умолчанию в SLEEP, до этого было в TS_STATUS_STANDBY eEgtsTsStatus SENSORS_AN_VehicleStatus_loc = TS_STATUS_SLEEP; // Поднят пин зажигания if (GpioPinGet(env->ignition)) { SENSORS_AN_VehicleStatus_loc = TS_STATUS_IGNITION; } else { } // Установка значения сенсора состояния env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_VehicleStatus].value = SENSORS_AN_VehicleStatus_loc; env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NumberOfSatellites].value = (uint8_t)nmeaRmc.magnetic.nsat; // конец --------------------- ДАТЧИКИ ------------------ //начало-----------------------------Отслеживание угла поворота и начала и окончания навигации------------------ //начало-----------------------------Отслеживание угла поворота и начала и окончания навигации------------------ //начало-----------------------------Отслеживание угла поворота и начала и окончания навигации------------------ uint16_t totalSpeed = getTotalSpeed(env, &nmeaRmc); bool isBeginNav = false; if ((env->egtsPointEnv.isBeginEndNav == false) && (nmeaRmc.status == 'A')) { env->egtsPointEnv.isBeginEndNav = true; isBeginNav = true; } bool isEndNav = false; if ((env->egtsPointEnv.isBeginEndNav == true) && (nmeaRmc.status != 'A')) { env->egtsPointEnv.isBeginEndNav = false; isEndNav = true; } if ((isBeginNav) || (isEndNav)) { env->egtsPointEnv.isEVENT_NAVIGATION_START_STOP = true; LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", textEgtsEventTetedata[EVENT_NAVIGATION_START_STOP].data); } uint16_t moveAngle = (uint16_t) nmeaRmc.headingAngle; uint16_t angle = abs(moveAngle - env->egtsPointEnv.beginAngle); if (angle > env->deviceTeledataStorageData->telematica.EGTS_FLEET_COURSE_THRESHOLD) { env->egtsPointEnv.beginAngle = moveAngle; if ((env->carEventPosition.carPosition == CAR_POSITION_MOVE) && (totalSpeed > env->deviceTeledataStorageData->telematica.EGTS_GNSS_COURSE_SPEED)) { LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Скорость транспортного средства: %d", totalSpeed); env->egtsPointEnv.isEVENT_ROTATE_ANGLE_LIMIT = true; LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", textEgtsEventTetedata[EVENT_ROTATE_ANGLE_LIMIT].data); } } uint16_t moveDist = getTotalDist(env); uint16_t dist = abs(moveDist - env->egtsPointEnv.beginDist); if (dist > env->deviceTeledataStorageData->telematica.EGTS_FLEET_DIST_THRESHOLD) { env->egtsPointEnv.beginDist = moveDist; env->egtsPointEnv.isEVENT_DISTANCE = true; LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", textEgtsEventTetedata[EVENT_DISTANCE].data); } //конец-----------------------------Отслеживание угла поворота и начала и окончания навигации------------------- //конец-----------------------------Отслеживание угла поворота и начала и окончания навигации------------------- //конец-----------------------------Отслеживание угла поворота и начала и окончания навигации------------------- // Отслеживание изменение состояния if (egtsTsStatus != env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_VehicleStatus].value) { egtsTsStatus = env->egtsTeledataEdit.egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_VehicleStatus].value; env->egtsPointEnv.isEVENT_VEH_STATE_CHANGED = true; LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", textEgtsEventTetedata[EVENT_VEH_STATE_CHANGED].data); } // Сброс события таймера, если было другое событие if (((egtsEventTetedata != EVENT_INVALID_STATE) && (egtsEventTetedata != EVENT_EMERGENCY_TRACKING_TIMEOUT)) || (env->egtsPointEnv.isEVENT_NAVIGATION_START_STOP) || (env->egtsPointEnv.isEVENT_ROTATE_ANGLE_LIMIT) || (env->egtsPointEnv.isEVENT_DISTANCE)) { if (GpioPinGet(env->ignition)) { env->egtsPointEnv.timeOutCheckTeledata_IGN_TimeUpdate = SystemGetMs() + env->deviceTeledataStorageData->telematica.EGTS_FLEET_IGN_ON_PERIOD * 1000; } else { env->egtsPointEnv.timeOutCheckTeledata_IGN_TimeUpdate = SystemGetMs() + env->deviceTeledataStorageData->telematica.EGTS_FLEET_IGN_OFF_PERIOD * 1000; } } // Отслеживание таймеров зажигания if (GpioPinGet(env->ignition)) { if (env->egtsPointEnv.timeOutCheckTeledata_IGN_TimeUpdate < SystemGetMs()) { env->egtsPointEnv.timeOutCheckTeledata_IGN_TimeUpdate = SystemGetMs() + env->deviceTeledataStorageData->telematica.EGTS_FLEET_IGN_ON_PERIOD * 1000; env->egtsPointEnv.isEVENT_TIMEOUT_ENGINE_ON = true; LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", textEgtsEventTetedata[EVENT_TIMEOUT_ENGINE_ON].data); } } else { if (env->egtsPointEnv.timeOutCheckTeledata_IGN_TimeUpdate < SystemGetMs()) { env->egtsPointEnv.timeOutCheckTeledata_IGN_TimeUpdate = SystemGetMs() + env->deviceTeledataStorageData->telematica.EGTS_FLEET_IGN_OFF_PERIOD * 1000; env->egtsPointEnv.isEVENT_TIMEOUT_ENGINE_OFF = true; LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", textEgtsEventTetedata[EVENT_TIMEOUT_ENGINE_OFF].data); } } // Отслеживание движения // CarEventPosition(env, &nmeaRmc, totalSpeed); env->egtsPointEnv.isUpdatePoints = false; // Если транспортное средство в движении if (env->carEventPosition.carPosition == CAR_POSITION_MOVE) { if (isOneFixMove) { isOneFixMove = false; env->egtsPointEnv.isEVENT_MOVEMENT_ON = true; LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", textEgtsEventTetedata[EVENT_MOVEMENT_ON].data); } env->egtsPointEnv.isUpdatePoints = true; } // Отслеживание таймера экстренного слежения if ((env->carEventPosition.carPosition == CAR_POSITION_MOVE) && (env->deviceTeledataStorageData->telematica.EGTS_FLEET_EM_MON_PERIOD != 0) && (env->egtsPointEnv.timeOutCheckTeledata_EM_TimeUpdate < SystemGetMs())) { env->egtsPointEnv.timeOutCheckTeledata_EM_TimeUpdate = SystemGetMs() + env->deviceTeledataStorageData->telematica.EGTS_FLEET_EM_MON_PERIOD * 1000; env->egtsPointEnv.isEVENT_EMERGENCY_TRACKING_TIMEOUT = true; LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", textEgtsEventTetedata[EVENT_EMERGENCY_TRACKING_TIMEOUT].data); } // Если транспортное средство не в движении if (env->carEventPosition.carPosition == CAR_POSITION_FIX) { isOneFixMove = true; env->egtsPointEnv.isEVENT_MOVEMENT_OFF = true; env->carEventPosition.carPosition = CAR_POSITION_UNDEFINED; LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Возникло событие: %s", textEgtsEventTetedata[EVENT_MOVEMENT_OFF].data); } if ((egtsEventTetedata != EVENT_INVALID_STATE) || (env->egtsPointEnv.isEVENT_NAVIGATION_START_STOP) || (env->egtsPointEnv.isEVENT_ROTATE_ANGLE_LIMIT) || (env->egtsPointEnv.isEVENT_DISTANCE) || (env->egtsPointEnv.isEVENT_TIMEOUT_ENGINE_OFF) || (env->egtsPointEnv.isEVENT_TIMEOUT_ENGINE_ON) || (env->egtsPointEnv.isEVENT_EMERGENCY_TRACKING_TIMEOUT) || (env->egtsPointEnv.isEVENT_VEH_STATE_CHANGED) || (env->egtsPointEnv.isEVENT_MOVEMENT_ON) || (env->egtsPointEnv.isEVENT_MOVEMENT_OFF) ) { // Первое получение навигации if (env->egtsPointEnv.isEVENT_NAVIGATION_START_STOP) { env->egtsPointEnv.isUpdatePoints = true; } if (env->egtsPointEnv.isUpdatePoints) { env->egtsTeledataEdit.egtsPosDataArgs.NTM = Egts_EpochTimestampToEgtsTime(timestamp); env->egtsTeledataAdditionalData.LAT = nmeaLocationToDeg(nmeaRmc.location.latitude); env->egtsTeledataAdditionalData.LON = nmeaLocationToDeg(nmeaRmc.location.longitude); double lat = (fabs(env->egtsTeledataAdditionalData.LAT) / 90) * 0xFFFFFFFF; env->egtsTeledataEdit.egtsPosDataArgs.LAT = (uint32_t) lat; double lon = (fabs(env->egtsTeledataAdditionalData.LON) / 180) * 0xFFFFFFFF; env->egtsTeledataEdit.egtsPosDataArgs.LONG = (uint32_t) lon; env->egtsTeledataEdit.egtsPosDataArgs.FLG.VLD = (nmeaRmc.status == 'A') ? 1 : 0; // Битовый флаг, признак «валидности» координатных данных env->egtsTeledataEdit.egtsPosDataArgs.FLG.FIX = 0; // битовое поле, тип определения координат env->egtsTeledataEdit.egtsPosDataArgs.FLG.CS = 0; // битовое поле, тип используемой системы env->egtsTeledataEdit.egtsPosDataArgs.FLG.BB = 0; // битовый флаг, признак отправки данных из памяти («черный ящик») if (env->carEventPosition.carPosition == CAR_POSITION_MOVE) { env->egtsTeledataUveos.egtsPosDataArgs.FLG.MV = 1; // битовый флаг, признак движения } else { env->egtsTeledataUveos.egtsPosDataArgs.FLG.MV = 0; // битовый флаг, признак движения } env->egtsTeledataEdit.egtsPosDataArgs.FLG.LAHS = (nmeaRmc.location.nsIndicator == 'S') ? 1 : 0; // битовый флаг определяет полушарие широты env->egtsTeledataEdit.egtsPosDataArgs.FLG.LOHS = (nmeaRmc.location.ewIndicator == 'W') ? 1 : 0; // битовый флаг определяет полушарие долготы env->egtsTeledataEdit.egtsPosDataArgs.FLG.ALTE = 1; // битовый флаг определяет наличие поля ALT в подзаписи uint16_t speed = (uint16_t) (nmeaRmc.knotVelocity * 1.82 * 10); uint16_t dir = (uint16_t) nmeaRmc.headingAngle; env->egtsTeledataEdit.egtsPosDataArgs.SPD.SPD = speed & 0b0011111111111111; // скорость в км/ч с дискретностью 0,1 км/ч (используется 14 младших бит) // int32_t alt = GnssGgaGetAlt(env->gsm); int32_t alt = (int32_t)nmeaRmc.location.altitude; if (alt >= 0) { env->egtsTeledataEdit.egtsPosDataArgs.SPD.ALTS = 0; } else { env->egtsTeledataEdit.egtsPosDataArgs.SPD.ALTS = 1; } env->egtsTeledataEdit.egtsPosDataArgs.SPD.DIRH = dir >> 8; // направление движения env->egtsTeledataEdit.egtsPosDataArgs.DIR = dir; // направление движения env->egtsTeledataEdit.egtsPosDataArgs.ODM = 0; // пройденное расстояние (пробег) в км, с дискретностью 0,1 км env->egtsTeledataEdit.egtsPosDataArgs.DIN = 0; // битовые флаги, определяют состояние основных дискретных входов env->egtsTeledataEdit.egtsPosDataArgs.ALT = abs(alt); // Обновление фиксированное позиции LoggerInfoStatic(LOGGER, LOG_SIGN, "Обновление фиксированной позиции") env->egtsTeledataFix = env->egtsTeledataEdit; } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Фиксированные координаты. Движение не зафиксировано") env->egtsTeledataEdit.egtsPosDataArgs = env->egtsTeledataFix.egtsPosDataArgs; env->egtsTeledataEdit.egtsPosDataArgs.NTM = Egts_EpochTimestampToEgtsTime(timestamp); } if (egtsEventTetedata != EVENT_INVALID_STATE) { env->egtsTeledataEdit.egtsPosDataArgs.SRC = egtsEventTetedata; // определяет источник (событие) addTeledataQueue(env, &env->egtsTeledataEdit); } if (env->egtsPointEnv.isEVENT_NAVIGATION_START_STOP) { env->egtsTeledataEdit.egtsPosDataArgs.SRC = EVENT_NAVIGATION_START_STOP; // определяет источник (событие) addTeledataQueue(env, &env->egtsTeledataEdit); } if (env->egtsPointEnv.isEVENT_ROTATE_ANGLE_LIMIT) { env->egtsTeledataEdit.egtsPosDataArgs.SRC = EVENT_ROTATE_ANGLE_LIMIT; // определяет источник (событие) addTeledataQueue(env, &env->egtsTeledataEdit); } if (env->egtsPointEnv.isEVENT_DISTANCE) { env->egtsTeledataEdit.egtsPosDataArgs.SRC = EVENT_DISTANCE; // определяет источник (событие) addTeledataQueue(env, &env->egtsTeledataEdit); } if (env->egtsPointEnv.isEVENT_TIMEOUT_ENGINE_OFF) { env->egtsTeledataEdit.egtsPosDataArgs.SRC = EVENT_TIMEOUT_ENGINE_OFF; // определяет источник (событие) addTeledataQueue(env, &env->egtsTeledataEdit); } if (env->egtsPointEnv.isEVENT_TIMEOUT_ENGINE_ON) { env->egtsTeledataEdit.egtsPosDataArgs.SRC = EVENT_TIMEOUT_ENGINE_ON; // определяет источник (событие) addTeledataQueue(env, &env->egtsTeledataEdit); } if (env->egtsPointEnv.isEVENT_MOVEMENT_ON) { env->egtsTeledataEdit.egtsPosDataArgs.SRC = EVENT_MOVEMENT_ON; // определяет источник (событие) addTeledataQueue(env, &env->egtsTeledataEdit); } if (env->egtsPointEnv.isEVENT_EMERGENCY_TRACKING_TIMEOUT) { env->egtsTeledataEdit.egtsPosDataArgs.SRC = EVENT_EMERGENCY_TRACKING_TIMEOUT; // определяет источник (событие) if (nmeaRmc.status != 'A') { LoggerInfoStatic(LOGGER, LOG_SIGN, "Посылка точек при экстренном слежении не требуется, навигация не валидна") } else { addTeledataQueue(env, &env->egtsTeledataEdit); } } if (env->egtsPointEnv.isEVENT_MOVEMENT_OFF) { env->egtsTeledataEdit.egtsPosDataArgs.SRC = EVENT_MOVEMENT_OFF; // определяет источник (событие) addTeledataQueue(env, &env->egtsTeledataEdit); } if (env->egtsPointEnv.isEVENT_VEH_STATE_CHANGED) { env->egtsTeledataEdit.egtsPosDataArgs.SRC = EVENT_VEH_STATE_CHANGED; // определяет источник (событие) addTeledataQueue(env, &env->egtsTeledataEdit); } } } } #endif