Files
edr-platform/apps/edr-gps-tracker/src/gps/gps-ingest.service.ts
natib21 15fc21a6c9 gps
2026-07-10 15:23:49 +00:00

73 lines
2.4 KiB
TypeScript

import { Injectable, Logger } from "@nestjs/common";
import { GpsDeviceRepository, GpsPositionRepository } from "./gps.repository";
import { GpsDevice } from "./entities/gps-device.entity";
import { Gt06Gps, Gt06Status } from "./gt06/gt06.codec";
/**
* Write path for GT06 ingestion: upserts device state and appends position
* history. Mirrors the ingestion half of @edr/freight-api's GpsTrackingService
* (the REST/query half stays in freight-api). Auto-registers unknown IMEIs on
* first contact.
*/
@Injectable()
export class GpsIngestService {
private readonly logger = new Logger(GpsIngestService.name);
constructor(
private readonly devices: GpsDeviceRepository,
private readonly positions: GpsPositionRepository,
) {}
/** Find the device for an IMEI, auto-registering it on first contact. */
private async ensureDevice(imei: string): Promise<GpsDevice> {
const existing = await this.devices.findByImei(imei);
if (existing) return existing;
this.logger.log(`Auto-registering new GPS tracker ${imei}`);
return this.devices.create({ imei, status: "REGISTERED", lastSeenAt: new Date() });
}
async handleLogin(imei: string): Promise<void> {
const device = await this.ensureDevice(imei);
await this.devices.update(device.id, { lastSeenAt: new Date(), status: "ONLINE" });
}
async handleHeartbeat(imei: string, status: Gt06Status): Promise<void> {
const device = await this.ensureDevice(imei);
await this.devices.update(device.id, {
lastSeenAt: new Date(),
status: "ONLINE",
voltageLevel: status.voltageLevel,
gsmLevel: status.gsmLevel,
});
}
async handleFix(imei: string, gps: Gt06Gps, alarm = 0, status?: Gt06Status): Promise<void> {
const device = await this.ensureDevice(imei);
const now = new Date();
await this.devices.update(device.id, {
lastSeenAt: now,
status: "ONLINE",
lastLat: gps.latitude,
lastLng: gps.longitude,
lastSpeed: gps.speed,
lastCourse: gps.course,
lastFixAt: new Date(gps.time),
...(status ? { voltageLevel: status.voltageLevel, gsmLevel: status.gsmLevel } : {}),
});
await this.positions.create({
deviceId: device.id,
imei,
vehicleId: device.vehicleId ?? null,
lat: gps.latitude,
lng: gps.longitude,
speed: gps.speed,
course: gps.course,
satellites: gps.satellites,
positioned: gps.positioned,
gpsTime: new Date(gps.time),
alarm,
});
}
}