Files
LocationHub/server/src/controller/ttnController.ts

131 lines
4.4 KiB
TypeScript

import express, { Request, Response } from "express";
import { StatusCodes } from "http-status-codes";
import { container } from "tsyringe";
import { authenticateHeader } from "../middleware/authentificationMiddleware";
import { validateData } from "../middleware/validationMiddleware";
import { TtnMessage } from "../models/ttnMessage";
import { LocationService } from "../services/locationService";
import { LpTtnEndDeviceUplinksService } from "../services/lpTtnEndDeviceUplinksService";
import { TtnGatewayReceptionService } from "../services/ttnGatewayReceptionService";
import { WifiScanService } from "../services/wifiScanService";
import { ttnMessageValidator } from "../validation/ttn/ttnMessageValidation";
const lpTtnEndDeviceUplinksService = container.resolve(
LpTtnEndDeviceUplinksService
);
const ttnGatewayReceptionService = container.resolve(
TtnGatewayReceptionService
);
const wifiScanService = container.resolve(WifiScanService);
const locationService = container.resolve(LocationService);
const router = express.Router();
router.post(
"/webhook",
[authenticateHeader, validateData(ttnMessageValidator)],
async (req: Request, res: Response) => {
try {
const message = req.body as TtnMessage;
const { lp_ttn_end_device_uplinks_id } =
await lpTtnEndDeviceUplinksService.createUplink({
device_id: message.end_device_ids.device_id,
application_ids:
message.end_device_ids.application_ids.application_id,
dev_eui: message.end_device_ids.dev_eui,
join_eui: message.end_device_ids.join_eui,
dev_addr: message.end_device_ids.dev_addr,
received_at_utc: new Date(message.received_at),
battery: message.uplink_message.decoded_payload?.messages[0].find(
(e) => e.type === "Battery"
)?.measurementValue,
});
const messageData = message.uplink_message.decoded_payload?.messages[0];
const latitudeData = messageData?.find((e) => e.type === "Latitude");
const longitudeData = messageData?.find((e) => e.type === "Longitude");
const gnnsLocation = {
latitude: latitudeData?.measurementValue,
longitude: longitudeData?.measurementValue,
};
const gnssTimestamp = {
timestamp: latitudeData?.timestamp
? new Date(latitudeData.timestamp)
: longitudeData?.timestamp
? new Date(longitudeData.timestamp)
: undefined,
};
const wifiMessage =
message.uplink_message.decoded_payload?.messages[0].find(
(e) => e.type === "Wi-Fi Scan"
);
const wifiScans =
wifiMessage?.measurementValue?.map((w) => ({
lp_ttn_end_device_uplinks_id,
mac: w.mac,
rssi: w.rssi,
scanned_at_utc: wifiMessage?.timestamp
? new Date(wifiMessage.timestamp)
: undefined,
})) ?? [];
const ttnGatewayReceptions = message.uplink_message.rx_metadata.map(
(g) => ({
lp_ttn_end_device_uplinks_id,
gateway_id: g.gateway_ids.gateway_id,
eui: g.gateway_ids.eui,
rssi: g.rssi,
latitude: g.location?.latitude,
longitude: g.location?.longitude,
altitude: g.location?.altitude,
})
);
const createDatabaseEntries = async () => {
const [wifiResults, gatewayResults] = await Promise.all([
wifiScanService.createWifiScans(wifiScans),
ttnGatewayReceptionService.filterAndInsertGatewayReception(
ttnGatewayReceptions
),
]);
locationService.createLocationFromTriangulation({
lp_ttn_end_device_uplinks_id,
wifi: wifiResults.map(({ mac, rssi }) => ({
mac,
rssi,
})),
ttn_gw: gatewayResults.map(({ latitude, longitude, rssi }) => ({
latitude,
longitude,
rssi,
})),
gnss:
gnnsLocation.latitude && gnnsLocation.longitude
? {
latitude: gnnsLocation.latitude,
longitude: gnnsLocation.longitude,
}
: undefined,
gnss_timestamp: gnssTimestamp.timestamp,
});
};
createDatabaseEntries().then();
res.status(StatusCodes.OK).send();
} catch (error) {
console.log(error);
res
.status(StatusCodes.INTERNAL_SERVER_ERROR)
.json({ error: "Error creating uplink" });
}
}
);
export default router;