UveosOnNation_VEGA_Egts/EgtsTeledataPoint.c

796 lines
41 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Created by cfif on 12.06.2024.
//
#include <stdlib.h>
#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, &timestamp);
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;
}
_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;
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, &timestamp);
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);
//начало-----------------------------Отслеживание угла поворота и начала и окончания навигации------------------
//начало-----------------------------Отслеживание угла поворота и начала и окончания навигации------------------
//начало-----------------------------Отслеживание угла поворота и начала и окончания навигации------------------
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 (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; // битовый флаг, признак отправки данных из памяти («черный ящик»)
env->egtsTeledataEdit.egtsPosDataArgs.FLG.MV = env->carEventPosition.carPosition; // битовый флаг, признак движения
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 = 0;
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);
}
}
}
}