-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
183 lines (154 loc) · 5.99 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
import trilateration from './utils/trilateration.js';
import map from './components/map.js';
import arrayCombinations from './utils/array_combinations.js';
import conversions from './utils/conversions.js';
import url from './utils/url.js';
/* Sends a GET request to fetch the location info
of all the RPIs in DAS FEST */
const getRPIdevices = async () => {
try {
const response = await fetch(url.rpis);
return await response.json();
} catch (err) {
console.error(err.message);
}
};
/* Removes devices older than 5 minutes from the map and
returns a filtered array of devices without the old data*/
const removeAgedDevices = (devices) => {
/* only for logging */
let numOfDevicesBeforeRemoval = devices.length;
/* Filter devices older than two minutes */
const updatedDevices = devices.filter((device) => {
const currTime = new Date();
/* Get the timestamp of the located device */
const deviceTime = new Date(device.timestamp);
/* calculate the located device's age in minutes */
const timeDiff = (currTime.getTime() - deviceTime.getTime()) / 60000;
/* Drop the ones older than the specified threshold */
return timeDiff.toFixed(2) < 5;
});
/* Add the updated data to the map */
map.addDevices(updatedDevices);
/* log the results */
console.log(
`${numOfDevicesBeforeRemoval - updatedDevices.length} devices were removed! New length: ${
updatedDevices.length
}, Old length: ${numOfDevicesBeforeRemoval}`
);
return updatedDevices;
};
getRPIdevices().then((rpiDevices) => {
if (!rpiDevices) {
console.error("No RPIs were fetched!");
return;
}
/* Display the RPIs on map with RPI icons */
for (const device of rpiDevices) {
/* extract device id from name to a new attribute "id" */
device.id = parseInt(device.Name.replace(/^\D+/g, ''));
/* add RPI on the Map */
map.addRPI(device.Latitude, device.Longitude, device.Name);
}
const ws = new WebSocket(url.stream);
/* Attempts a connection to the Web Socket
that streams the devices found by the RPIs */
ws.addEventListener('open', (event) => {
console.log('Connection opened');
});
/* Array holding the displayed devices. Empty at first.*/
let devices = [];
/* Set an interval to check every 5+ minutes for aged data on map */
setInterval(() => {
devices = removeAgedDevices(devices);
}, 300100);
/* listens for fetched devices from the RPIs */
ws.addEventListener('message', (event) => {
const foundDevices = JSON.parse(event.data);
console.log('<///------------------------');
/* search for possible aged data on the array */
devices = removeAgedDevices(devices);
/* counter for the total trilateration points. Only for logging. */
let i = 0;
/* iterate through every fetched device */
for (const foundDevice of foundDevices) {
/* every incoming device was measured by some RPIs.
get every possible combination of three RPIs to
increase the chances of finding trilateration points below */
const rpiCombinations = arrayCombinations.getCombinations(
foundDevice.measurements,
3
);
if (rpiCombinations.length >= 1) {
/* iterate through every combination of RPIs
until you find a trilateration point or reach the end */
for (const combination of rpiCombinations) {
/* Get the RPIs' coordinates (Lat, Lon) from the RPIs' array */
const rpi1 = rpiDevices.find((rpi) => rpi.id === combination[0].rpi);
const rpi2 = rpiDevices.find((rpi) => rpi.id === combination[1].rpi);
const rpi3 = rpiDevices.find((rpi) => rpi.id === combination[2].rpi);
/* create the cartesian spheres
from the 3 RPIs coordinates and their measured signals */
const sphere1 = conversions.getCartesianSphere(
rpi1.Latitude,
rpi1.Longitude,
combination[0].signal_strength
);
const sphere2 = conversions.getCartesianSphere(
rpi2.Latitude,
rpi2.Longitude,
combination[1].signal_strength
);
const sphere3 = conversions.getCartesianSphere(
rpi3.Latitude,
rpi3.Longitude,
combination[2].signal_strength
);
/* Calculate trilateration */
const trilPoint = trilateration.calculate(sphere1, sphere2, sphere3);
/* check if trilateration produced a result */
if (trilPoint) {
/* Convert the trilateration point from cartesian to (Lat, Lon) */
const trilCoords = conversions.ecefToGeodetic(
trilPoint.x,
trilPoint.y,
trilPoint.z
);
/* Add the located device on map with count of 1 */
map.addSingleDevice({
lat: trilCoords.latitude,
lng: trilCoords.longitude,
count: 1,
});
/* Push the located device into the devices array along with a timestamp */
devices.push({
lat: trilCoords.latitude,
lng: trilCoords.longitude,
count: 1,
timestamp: Date.now(),
});
i++;
/* at least one combination of RPIs produced a trilateration point.
We can skip the rest of the combinations */
break;
}
}
}
}
/* Log the results */
console.log('New Fetched Devices: ' + foundDevices.length);
console.log('Located Devices (Successful Trilateration): ' + i);
console.log(
`Number of devices displayed on map: (now) => ${devices.length}`
);
console.log('------------------------///>');
});
/* Print a closing message on closing of the Web Socket */
ws.addEventListener('close', (event) => {
console.log('Connection closed.');
});
/* Print an error message if something goes wrong with the Web Socket */
ws.addEventListener('error', (event) => {
console.log(`WebSocket error: ${event}.`);
});
});