796 lines
41 KiB
C
796 lines
41 KiB
C
//
|
||
// 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, ×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;
|
||
|
||
}
|
||
|
||
_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, ×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);
|
||
|
||
|
||
//начало-----------------------------Отслеживание угла поворота и начала и окончания навигации------------------
|
||
//начало-----------------------------Отслеживание угла поворота и начала и окончания навигации------------------
|
||
//начало-----------------------------Отслеживание угла поворота и начала и окончания навигации------------------
|
||
|
||
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 = (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);
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
} |