From 6d20f4e54cf8b52c2a74cb160b82ab76913b487e3c60863cd822eea0b4317b3a Mon Sep 17 00:00:00 2001 From: localhorst Date: Thu, 2 Jan 2025 11:38:27 +0100 Subject: [PATCH] cleanup --- .../ttnMessageReceivedEventHandler.ts | 197 +++++++++++------- 1 file changed, 124 insertions(+), 73 deletions(-) diff --git a/server/src/eventHandler/ttnMessageReceivedEventHandler.ts b/server/src/eventHandler/ttnMessageReceivedEventHandler.ts index 84293a2..05a94c6 100644 --- a/server/src/eventHandler/ttnMessageReceivedEventHandler.ts +++ b/server/src/eventHandler/ttnMessageReceivedEventHandler.ts @@ -11,6 +11,119 @@ import { getLocationForWifiMemoized } from "../proxy/wigle"; const locationService = container.resolve(LocationService); const wifiScanService = container.resolve(WifiScanService); +const CalculateTtnGatewayLocation = async (event: TtnMessageReceivedEvent) => { + // Get location based on TTN Gateways + const virtualLocation = { + latitude: undefined as number | undefined, + longitude: undefined as number | undefined, + }; + + if (!event.ttnGateways || event.ttnGateways.length === 0) { + console.log("No TTN Gateway location received!") + } else { + let totalWeight = 0; + let weightedLatitude = 0; + let weightedLongitude = 0; + + event.ttnGateways.forEach(gw => { + const weight = 1 / Math.abs(gw.rssi); // Higher RSSI (closer to 0) gives more weight + totalWeight += weight; + weightedLatitude += gw.latitude * weight; + weightedLongitude += gw.longitude * weight; + }); + + // Calculate the weighted average to get the virtual location + const virtualLocation = { + latitude: weightedLatitude / totalWeight, + longitude: weightedLongitude / totalWeight + }; + + console.log("Tracker location based on TTN Gateway location:", virtualLocation); + } + return { + ttn_latitude: virtualLocation.latitude, + ttn_longitude: virtualLocation.longitude, + }; +}; + +const CalculateWifiLocation = async (event: TtnMessageReceivedEvent) => { + // Get location based on WiFi Scans + const virtualLocation = { + latitude: undefined as number | undefined, + longitude: undefined as number | undefined, + }; + + if (!event.wifis || event.wifis.length === 0) { + console.log("No WiFi scans received!") + } else { + // Process Wi-Fi data to compute weighted location + const wifiScans = await Promise.all( + event.wifis.map(async (wifi) => { + // Create new WiFi Scan entry if wigle.net reported location + const apiResponse = await getLocationForWifiMemoized(wifi.mac); + return { + lp_ttn_end_device_uplinks_id: event.lp_ttn_end_device_uplinks_id, + mac: wifi.mac, + rssi: wifi.rssi, + latitude: apiResponse?.results[0]?.trilat, + longitude: apiResponse?.results[0]?.trilong, + }; + }) + ); + + await wifiScanService.createWifiScans(wifiScans); + + const { totalWeight, weightedLatitude, weightedLongitude } = + wifiScans.reduce( + (acc, { latitude, longitude, rssi }) => { + if (latitude && longitude && rssi !== 0) { + const weight = 1 / Math.abs(rssi); + + acc.totalWeight += weight; + acc.weightedLatitude += latitude * weight; + acc.weightedLongitude += longitude * weight; + } + + return acc; + }, + { + totalWeight: 0, + weightedLatitude: 0, + weightedLongitude: 0, + } + ); + + // Calculate the weighted average to get the virtual location + virtualLocation.latitude = weightedLatitude / totalWeight; + virtualLocation.longitude = weightedLongitude / totalWeight; + + console.log("Tracker location based on WiFi Scan location:", virtualLocation); + } + return { + wifi_latitude: virtualLocation.latitude, + wifi_longitude: virtualLocation.longitude, + }; +}; + +const CalculateGnssLocation = async (event: TtnMessageReceivedEvent) => { + // Default virtual location with undefined coordinates + const virtualLocation = { + latitude: undefined as number | undefined, + longitude: undefined as number | undefined, + }; + + if (virtualLocation.latitude === undefined || virtualLocation.longitude === undefined) { + console.log("No valid GNSS location received!"); + } + + return { + gnss_latitude: virtualLocation.latitude, + gnss_longitude: virtualLocation.longitude, + }; +}; + + + domainEventEmitter.on( TtnMessageReceivedEventName, async (event: TtnMessageReceivedEvent) => { @@ -23,83 +136,21 @@ domainEventEmitter.on( var ttn_gw_based_latitude: number | undefined = undefined; var ttn_gw_based_longitude: number | undefined = undefined; - // Get location based on TTN Gateways - if (!event.ttnGateways || event.ttnGateways.length === 0) { - console.log("No TTN Gateway location received!") - } else { - let totalWeight = 0; - let weightedLatitude = 0; - let weightedLongitude = 0; - - event.ttnGateways.forEach(gw => { - const weight = 1 / Math.abs(gw.rssi); // Higher RSSI (closer to 0) gives more weight - totalWeight += weight; - weightedLatitude += gw.latitude * weight; - weightedLongitude += gw.longitude * weight; - }); - - // Calculate the weighted average to get the virtual location - const virtualLocation = { - latitude: weightedLatitude / totalWeight, - longitude: weightedLongitude / totalWeight - }; - - console.log("Tracker location based on TTN Gateway location:", virtualLocation); - ttn_gw_based_latitude = virtualLocation.latitude; - ttn_gw_based_longitude = virtualLocation.longitude; + if (event.ttnGateways && event.ttnGateways.length > 0) { + const virtualLocation = await CalculateTtnGatewayLocation(event); + ttn_gw_based_latitude = virtualLocation.ttn_latitude; + ttn_gw_based_longitude = virtualLocation.ttn_longitude; } - // Get location based on WiFi Scans - if (!event.wifis || event.wifis.length === 0) { - console.log("No WiFi scans received!") - } else { - let totalWeight = 0; - let weightedLatitude = 0; - let weightedLongitude = 0; - - // Process Wi-Fi data to compute weighted location - await Promise.all( - event.wifis.map(async (wifi) => { - const apiResponse = await getLocationForWifiMemoized(wifi.mac); - if ((apiResponse != undefined) && (apiResponse?.totalResults > 0)) { - // Create new WiFi Scan entry if wigle.net reported location - const newWifiScan = wifiScanService.createWifiScan({ - lp_ttn_end_device_uplinks_id: event.lp_ttn_end_device_uplinks_id, - mac: wifi.mac, - rssi: wifi.rssi, - latitude: apiResponse?.results[0]?.trilat, - longitude: apiResponse?.results[0]?.trilong, - }) - - // Calculate weight based on RSSI (higher signal strength gives more weight) - const weight = 1 / Math.abs((await newWifiScan).rssi); - totalWeight += weight; - - // Accumulate weighted latitude and longitude - weightedLatitude += (await newWifiScan).latitude * weight; - weightedLongitude += (await newWifiScan).longitude * weight; - } - }) - ); - - // Calculate the weighted average to get the virtual location - const virtualLocation = { - latitude: weightedLatitude / totalWeight, - longitude: weightedLongitude / totalWeight - }; - - console.log("Tracker location based on WiFi Scan location:", virtualLocation); - wifi_based_latitude = virtualLocation.latitude; - wifi_based_longitude = virtualLocation.longitude; + if (event.wifis && event.wifis.length > 0) { + const virtualLocation = await CalculateWifiLocation(event); + wifi_based_latitude = virtualLocation.wifi_latitude; + wifi_based_longitude = virtualLocation.wifi_longitude; } - // Get location based on GNSS - if ((event.gnssLocation.latitude) && (event.gnssLocation.longitude)) { - gnss_based_latitude = event.gnssLocation.latitude; - gnss_based_longitude = event.gnssLocation.longitude; - } else { - console.log("No GNSS location received!") - } + const virtualLocation = await CalculateGnssLocation(event); + gnss_based_latitude = virtualLocation.gnss_latitude; + gnss_based_longitude = virtualLocation.gnss_longitude; const newLocation = await locationService.createLocation({ lp_ttn_end_device_uplinks_id: event.lp_ttn_end_device_uplinks_id,