178 lines
5.3 KiB
JavaScript
178 lines
5.3 KiB
JavaScript
const axios = require('axios');
|
||
const csv = require('csv-parse');
|
||
|
||
const network = require('./network');
|
||
const {TAM_REALTIME} = require('./endpoints');
|
||
|
||
const sortByFirstKey = (a, b) => a[0] - b[0];
|
||
|
||
const fetchRealtime = () => new Promise((res, rej) =>
|
||
{
|
||
const stream = axios.get(TAM_REALTIME, {
|
||
responseType: 'stream'
|
||
}).then(stream =>
|
||
{
|
||
const parser = csv({
|
||
delimiter: ';',
|
||
});
|
||
|
||
const courses = {};
|
||
stream.pipe(parser);
|
||
|
||
stream.on('readable', () =>
|
||
{
|
||
let row;
|
||
|
||
while (row = stream.read())
|
||
{
|
||
if (row.length === 0 || row[0] === 'course')
|
||
{
|
||
// Ignore les lignes invalides et l’en-tête
|
||
continue;
|
||
}
|
||
|
||
const course = row[0];
|
||
const stopRef = row[2];
|
||
const lineRef = row[4];
|
||
const eta = row[9];
|
||
const destinationRef = row[10];
|
||
|
||
if (!(course in courses))
|
||
{
|
||
courses[course] = {
|
||
lineRef,
|
||
destinationRef,
|
||
stops: [],
|
||
};
|
||
}
|
||
|
||
courses[course].stops.push([parseInt(eta, 10), stopRef]);
|
||
courses[course].stops.sort(sortByFirstKey);
|
||
}
|
||
});
|
||
|
||
stream.on('end', () => res(courses));
|
||
stream.on('error', err => rej(err));
|
||
});
|
||
});
|
||
|
||
const updateVehicles = async (lines, vehicles) =>
|
||
{
|
||
const courses = await fetchRealtime();
|
||
const currentTime = Math.floor(Date.now() / 1000);
|
||
|
||
for (let [courseRef, course] of Object.entries(courses))
|
||
{
|
||
if (course.lineRef in lines)
|
||
{
|
||
if (!(courseRef in vehicles))
|
||
{
|
||
// New vehicle: identify which route it pertains to
|
||
const line = lines[course.lineRef];
|
||
let routeIndex = null;
|
||
|
||
for (let [index, route] of Object.entries(line.routes))
|
||
{
|
||
const destRef = route.stops[route.stops.length - 1].ref;
|
||
|
||
if (destRef === course.destinationRef)
|
||
{
|
||
routeIndex = index;
|
||
}
|
||
}
|
||
|
||
if (routeIndex !== null)
|
||
{
|
||
const route = line.routes[routeIndex];
|
||
|
||
// Convert ETAs to absolute times
|
||
const nextStops = course.stops.map(([eta, ref]) => [
|
||
eta + currentTime,
|
||
ref
|
||
]);
|
||
|
||
// Convert stop refs to indices
|
||
const stopIndices = course.stops.map(([eta, ref]) => [
|
||
eta,
|
||
]);
|
||
|
||
// Find the preceding stop from which the vehicle is coming
|
||
const arrivingStop = stopIndices[0][1];
|
||
const arrivingStopIndex = route.stops.findIndex(
|
||
stop => stop.ref === arrivingStop
|
||
);
|
||
|
||
const leavingStop = arrivingStopIndex === 0
|
||
? route.stops[0]
|
||
: route.stops[arrivingStopIndex - 1];
|
||
|
||
if (nextStop === 0)
|
||
{
|
||
// Vehicle at starting point
|
||
vehicles[courseRef] = {
|
||
lineRef: course.lineRef,
|
||
stopRef
|
||
|
||
stopIndex: 0,
|
||
nextStops: stopIndices,
|
||
|
||
distance: 0,
|
||
speed: 0,
|
||
};
|
||
}
|
||
else
|
||
{
|
||
// Vehicle in transit between two stops
|
||
vehicles[courseRef] = {
|
||
lineRef: course.lineRef,
|
||
routeIndex,
|
||
|
||
stopIndex: nextStop - 1,
|
||
nextStops: stopIndices,
|
||
|
||
distance: 0,
|
||
speed: route.distances[nextStop - 1] / eta,
|
||
};
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Existing vehicle: update information
|
||
const vehicle = vehicles[courseRef];
|
||
|
||
const line = lines[vehicle.lineRef];
|
||
const route = line.routes[vehicle.routeIndex];
|
||
|
||
// Convert stop refs to indices
|
||
const stopIndices = course.stops.map(([eta, ref]) => [
|
||
eta,
|
||
route.stops.findIndex(stop => stop.ref === ref),
|
||
]);
|
||
|
||
console.log(stopIndices);
|
||
console.log(vehicle);
|
||
console.log(course);
|
||
console.log('---');
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
const sleep = time => new Promise(res => setTimeout(res, time));
|
||
|
||
const updateLoop = async (lines, vehicles = {}) =>
|
||
{
|
||
await updateVehicles(lines, vehicles);
|
||
await sleep(30000);
|
||
return updateLoop(lines, vehicles);
|
||
};
|
||
|
||
(async () =>
|
||
{
|
||
const lines = {'1': await network.fetchLineData('1')};
|
||
updateLoop(lines);
|
||
|
||
// console.log(require('util').inspect(vehicles, true, 10));
|
||
})();
|