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;