85 lines
2.5 KiB
JavaScript
85 lines
2.5 KiB
JavaScript
const tam = require("./sources/tam");
|
|
const network = require("./network.json");
|
|
|
|
// Time at which the course data needs to be updated next
|
|
let nextUpdate = null;
|
|
|
|
// Current information about courses
|
|
let currentCourses = null;
|
|
|
|
/**
|
|
* Information about the course of a vehicle.
|
|
* @typedef {Object} Course
|
|
* @property {string} id Unique identifier for this course.
|
|
* @property {string} line Transport line number.
|
|
* @property {string} finalStop Final stop to which the course is headed.
|
|
* @property {Object.<string,number>} nextPassings Next stations to which
|
|
* the vehicle will stop, associated to the passing timestamp.
|
|
*/
|
|
|
|
/**
|
|
* Fetch real-time information about active courses in the TaM network.
|
|
*
|
|
* New data will only be fetched from the TaM server once every minute,
|
|
* otherwise pulling from the in-memory cache.
|
|
* @returns {Object.<string,Course>} Mapping from active course IDs to
|
|
* information about each course.
|
|
*/
|
|
const fetch = async() => {
|
|
if (nextUpdate === null || Date.now() >= nextUpdate) {
|
|
const courses = {};
|
|
const passings = tam.fetchRealtime();
|
|
const timing = (await passings.next()).value;
|
|
|
|
nextUpdate = timing.nextUpdate;
|
|
|
|
// Aggregate passings relative to the same course
|
|
for await (const passing of passings) {
|
|
const {
|
|
course: id,
|
|
routeShortName: line,
|
|
stopId,
|
|
destArCode: finalStop
|
|
} = passing;
|
|
|
|
const arrivalTime = (
|
|
timing.lastUpdate +
|
|
parseInt(passing.delaySec, 10) * 1000
|
|
);
|
|
|
|
if (!(id in courses)) {
|
|
courses[id] = {
|
|
id,
|
|
line,
|
|
finalStop,
|
|
nextPassings: { [stopId]: arrivalTime }
|
|
};
|
|
} else {
|
|
courses[id].nextPassings[stopId] = arrivalTime;
|
|
}
|
|
}
|
|
|
|
// Filter courses to only keep those referring to known data
|
|
for (const courseId of Object.keys(courses)) {
|
|
const course = courses[courseId];
|
|
|
|
if (!(course.line in network.lines)) {
|
|
delete courses[courseId];
|
|
} else {
|
|
for (const stopId of Object.keys(course.nextPassings)) {
|
|
if (!(stopId in network.stops)) {
|
|
delete courses[courseId];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
currentCourses = courses;
|
|
}
|
|
|
|
return currentCourses;
|
|
};
|
|
|
|
exports.fetch = fetch;
|