diff --git a/server/.env.template b/server/.env.template index d54c511..0151408 100644 --- a/server/.env.template +++ b/server/.env.template @@ -7,6 +7,6 @@ DB_PORT="" WIGLE_TOKEN="" WIGLE_BASE_URL="https://api.wigle.net" WIGLE_NETWORK_SEARCH="/api/v2/network/search" -GET_LOCATION_WIFI_MAX_AGE=1209600000 # 14 Tage in Millisekunden (14 * 24 * 60 * 60 * 1000) +GET_LOCATION_WIFI_MAX_AGE=1209600000 # 14 days in milliseconds (14 * 24 * 60 * 60 * 1000) GET_LOCATION_WIFI_MAX=10000 GET_LOCATION_WIFI_PRIMITIVE=true \ No newline at end of file diff --git a/server/package.json b/server/package.json index a71e8c3..d550a8e 100644 --- a/server/package.json +++ b/server/package.json @@ -13,11 +13,11 @@ "license": "ISC", "devDependencies": { "@types/express": "^5.0.0", + "@types/memoizee": "^0.4.11", "@types/node": "^22.10.2", "nodemon": "^3.1.9", "ts-node": "^10.9.2", - "typescript": "^5.7.2", - "@types/memoizee": "^0.4.11" + "typescript": "^5.7.2" }, "dependencies": { "cors": "^2.8.5", diff --git a/server/src/eventHandler/ttnMessageReceivedEventHandler.ts b/server/src/eventHandler/ttnMessageReceivedEventHandler.ts index 4385352..84293a2 100644 --- a/server/src/eventHandler/ttnMessageReceivedEventHandler.ts +++ b/server/src/eventHandler/ttnMessageReceivedEventHandler.ts @@ -5,21 +5,25 @@ import { } from "../event/ttnMessageReceivedEvent"; import { container } from "tsyringe"; import { LocationService } from "../services/locationService"; +import { WifiScanService } from "../services/wifiScanService"; +import { getLocationForWifiMemoized } from "../proxy/wigle"; const locationService = container.resolve(LocationService); +const wifiScanService = container.resolve(WifiScanService); domainEventEmitter.on( TtnMessageReceivedEventName, async (event: TtnMessageReceivedEvent) => { console.log(event); - var wifi_based_latitude: number; - var wifi_based_longitude: number; + var wifi_based_latitude: number | undefined = undefined; + var wifi_based_longitude: number | undefined = undefined; var gnss_based_latitude: number | undefined = undefined; var gnss_based_longitude: number | undefined = undefined; 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 { @@ -45,11 +49,51 @@ domainEventEmitter.on( ttn_gw_based_longitude = virtualLocation.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; - { - // TODO: parse Wifi location here + // 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; } + // Get location based on GNSS if ((event.gnssLocation.latitude) && (event.gnssLocation.longitude)) { gnss_based_latitude = event.gnssLocation.latitude; gnss_based_longitude = event.gnssLocation.longitude; @@ -63,6 +107,8 @@ domainEventEmitter.on( ttn_gw_longitude: ttn_gw_based_longitude, gnss_latitude: gnss_based_latitude, gnss_longitude: gnss_based_longitude, + wifi_latitude: wifi_based_latitude, + wifi_longitude: wifi_based_longitude, }); console.log(newLocation)