feat(gps): valid=false от протокола H02 → точка сохраняется как LBS-примерная (не выбрасывается), сигнал потери GPS
This commit is contained in:
@@ -167,9 +167,9 @@ services:
|
|||||||
image: osrm/osrm-backend:latest
|
image: osrm/osrm-backend:latest
|
||||||
container_name: osrm
|
container_name: osrm
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: osrm-routed --algorithm mld /data/volga.osrm
|
command: osrm-routed --algorithm mld /data/region.osrm
|
||||||
volumes:
|
volumes:
|
||||||
- ./osrm-data:/data:ro
|
- ./osrm-data-ru:/data:ro
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
crm_data:
|
crm_data:
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ export interface ProcessPositionInput {
|
|||||||
course?: number | null;
|
course?: number | null;
|
||||||
accuracy?: number | null;
|
accuracy?: number | null;
|
||||||
recordedAt?: Date;
|
recordedAt?: Date;
|
||||||
|
/** Протокольный признак «GPS невалиден» (Traccar valid=false) — LBS-точка */
|
||||||
|
forceLbs?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Вердикт фильтрации точки относительно предыдущей принятой
|
// Вердикт фильтрации точки относительно предыдущей принятой
|
||||||
@@ -500,6 +502,50 @@ export async function processPosition(
|
|||||||
? { lat: asset.lastLat, lng: asset.lastLng, recordedAt: asset.lastRecordedAt, speed: asset.lastSpeed }
|
? { lat: asset.lastLat, lng: asset.lastLng, recordedAt: asset.lastRecordedAt, speed: asset.lastSpeed }
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
|
// Протокольный флаг «GPS невалиден» (Traccar valid=false): это точка по вышкам.
|
||||||
|
// Сохраняем как примерную (is_lbs), маркер двигаем, но walker/геозоны/пробег
|
||||||
|
// не трогаем. Заодно это сигнал потери GPS — как stale re-send.
|
||||||
|
if (input.forceLbs) {
|
||||||
|
assetLastStaleAt.set(assetId, Date.now());
|
||||||
|
if (!asset.gpsLost) {
|
||||||
|
await gpsStorage.setGpsLost(assetId, true);
|
||||||
|
console.log(`[GPS] gps_lost ON: asset=${assetId} (valid=false от протокола)`);
|
||||||
|
}
|
||||||
|
await gpsStorage.insertPosition({
|
||||||
|
assetId,
|
||||||
|
organizationId,
|
||||||
|
lat: input.lat,
|
||||||
|
lng: input.lng,
|
||||||
|
speed: input.speed ?? null,
|
||||||
|
course: input.course ?? null,
|
||||||
|
accuracy: input.accuracy ?? null,
|
||||||
|
isLbs: true,
|
||||||
|
recordedAt,
|
||||||
|
});
|
||||||
|
await gpsStorage.updateAssetLastPosition(assetId, {
|
||||||
|
lat: input.lat,
|
||||||
|
lng: input.lng,
|
||||||
|
speed: input.speed,
|
||||||
|
course: input.course,
|
||||||
|
recordedAt,
|
||||||
|
isLbs: true,
|
||||||
|
});
|
||||||
|
eventBus.publishEvent({
|
||||||
|
type: "gps_asset_moved",
|
||||||
|
data: {
|
||||||
|
assetId,
|
||||||
|
lat: input.lat,
|
||||||
|
lng: input.lng,
|
||||||
|
speed: input.speed ?? null,
|
||||||
|
course: input.course ?? null,
|
||||||
|
recordedAt: recordedAt.toISOString(),
|
||||||
|
isLbs: true,
|
||||||
|
},
|
||||||
|
organizationId,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Фильтры stale/jump/echo с гистерезисом подтверждения (устаревшие копии,
|
// Фильтры stale/jump/echo с гистерезисом подтверждения (устаревшие копии,
|
||||||
// LBS-скачки, heartbeat-эхо стоянки)
|
// LBS-скачки, heartbeat-эхо стоянки)
|
||||||
const walker = getAssetWalker(assetId, prev, settings);
|
const walker = getAssetWalker(assetId, prev, settings);
|
||||||
|
|||||||
@@ -261,16 +261,12 @@ async function handleIngest(req: AuthenticatedRequest, res: Response) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Traccar пометил позицию как невалидную (valid=false) — не сохраняем,
|
|
||||||
// но считаем признаком жизни устройства
|
|
||||||
if (!point.valid) {
|
|
||||||
await gpsStorage.touchAssetSeen(asset.id);
|
|
||||||
processed++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await processPosition(asset.id, asset.organizationId, {
|
await processPosition(asset.id, asset.organizationId, {
|
||||||
|
// Traccar пометил позицию как невалидную (valid=false) — протокольный
|
||||||
|
// признак «нет GPS-фикса»: сохраняем как примерную (LBS), в геозоны
|
||||||
|
// и пробег не пускаем
|
||||||
|
forceLbs: !point.valid,
|
||||||
lat: point.lat,
|
lat: point.lat,
|
||||||
lng: point.lng,
|
lng: point.lng,
|
||||||
speed: point.speed,
|
speed: point.speed,
|
||||||
|
|||||||
Reference in New Issue
Block a user