|  |  |  | @ -7,6 +7,7 @@ import { container } from "tsyringe"; | 
		
	
		
			
				|  |  |  |  | import { LocationService } from "../services/locationService"; | 
		
	
		
			
				|  |  |  |  | import { WifiScanService } from "../services/wifiScanService"; | 
		
	
		
			
				|  |  |  |  | import { getLocationForWifiMemoized } from "../proxy/wigle"; | 
		
	
		
			
				|  |  |  |  | import { WifiScan } from "../models/wifiScan"; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | const locationService = container.resolve(LocationService); | 
		
	
		
			
				|  |  |  |  | const wifiScanService = container.resolve(WifiScanService); | 
		
	
	
		
			
				
					
					|  |  |  | @ -54,47 +55,52 @@ const CalculateWifiLocation = async (event: TtnMessageReceivedEvent) => { | 
		
	
		
			
				|  |  |  |  |     console.log("No WiFi scans received!") | 
		
	
		
			
				|  |  |  |  |   } else { | 
		
	
		
			
				|  |  |  |  |     // Process Wi-Fi data to compute weighted location | 
		
	
		
			
				|  |  |  |  |     const wifiScans = await Promise.all( | 
		
	
		
			
				|  |  |  |  |     let 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, | 
		
	
		
			
				|  |  |  |  |         }; | 
		
	
		
			
				|  |  |  |  |         const apiResponse = await getLocationForWifiMemoized(wifi.mac);; | 
		
	
		
			
				|  |  |  |  |         // Only return valid data wifiScans (location for MAC was found) | 
		
	
		
			
				|  |  |  |  |         if ((apiResponse?.success == true) && (apiResponse.totalResults > 0)) { | 
		
	
		
			
				|  |  |  |  |           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, | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         return undefined; | 
		
	
		
			
				|  |  |  |  |       }) | 
		
	
		
			
				|  |  |  |  |     ); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     await wifiScanService.createWifiScans(wifiScans); | 
		
	
		
			
				|  |  |  |  |     const wifiScansFiltered = wifiScans.filter(w => (w !== undefined)); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     const { totalWeight, weightedLatitude, weightedLongitude } = | 
		
	
		
			
				|  |  |  |  |       wifiScans.reduce( | 
		
	
		
			
				|  |  |  |  |         (acc, { latitude, longitude, rssi }) => { | 
		
	
		
			
				|  |  |  |  |           if (latitude && longitude && rssi !== 0) { | 
		
	
		
			
				|  |  |  |  |     // Store valid wifiScans into DB | 
		
	
		
			
				|  |  |  |  |     const locatedWifiScans = await wifiScanService.createWifiScans(wifiScansFiltered); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     if (locatedWifiScans.length !== 0) { | 
		
	
		
			
				|  |  |  |  |       const { totalWeight, weightedLatitude, weightedLongitude } = | 
		
	
		
			
				|  |  |  |  |         locatedWifiScans.reduce( | 
		
	
		
			
				|  |  |  |  |           (acc, { latitude, longitude, rssi }) => { | 
		
	
		
			
				|  |  |  |  |             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, | 
		
	
		
			
				|  |  |  |  |           } | 
		
	
		
			
				|  |  |  |  |         ); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |           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; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     // 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); | 
		
	
		
			
				|  |  |  |  |       console.log("Tracker location based on WiFi Scan location:", virtualLocation); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  |   return { | 
		
	
		
			
				|  |  |  |  |     wifi_latitude: virtualLocation.latitude, | 
		
	
	
		
			
				
					
					|  |  |  | 
 |