This commit is contained in:
Hendrik Schutter 2025-01-02 11:38:27 +01:00
parent f341e6039f
commit 6d20f4e54c

View File

@ -11,19 +11,13 @@ 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 | 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;
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 {
@ -45,62 +39,119 @@ domainEventEmitter.on(
};
console.log("Tracker location based on TTN Gateway location:", virtualLocation);
ttn_gw_based_latitude = virtualLocation.latitude;
ttn_gw_based_longitude = virtualLocation.longitude;
}
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 {
let totalWeight = 0;
let weightedLatitude = 0;
let weightedLongitude = 0;
// Process Wi-Fi data to compute weighted location
await Promise.all(
const wifiScans = 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({
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,
})
// 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;
}
};
})
);
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
const virtualLocation = {
latitude: weightedLatitude / totalWeight,
longitude: weightedLongitude / totalWeight
};
virtualLocation.latitude = weightedLatitude / totalWeight;
virtualLocation.longitude = weightedLongitude / totalWeight;
console.log("Tracker location based on WiFi Scan location:", virtualLocation);
wifi_based_latitude = virtualLocation.latitude;
wifi_based_longitude = virtualLocation.longitude;
}
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!");
}
// 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!")
return {
gnss_latitude: virtualLocation.latitude,
gnss_longitude: virtualLocation.longitude,
};
};
domainEventEmitter.on(
TtnMessageReceivedEventName,
async (event: TtnMessageReceivedEvent) => {
console.log(event);
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;
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;
}
if (event.wifis && event.wifis.length > 0) {
const virtualLocation = await CalculateWifiLocation(event);
wifi_based_latitude = virtualLocation.wifi_latitude;
wifi_based_longitude = virtualLocation.wifi_longitude;
}
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,
ttn_gw_latitude: ttn_gw_based_latitude,