fix(rail): Montpellier tram speeds are converted from km/h

TaM publishes km/h where GTFS-Realtime asks m/s, and the Transit layer's
entry for the same feed already sets speedUnit: 'km/h'. The Rail entry did
not, so the proxy passed the readings through and the card multiplied them
by 3.6 again: a tram at 30 km/h read about 108 km/h. A registry test now
requires a Rail feed that Transit also reads to declare the same unit.
This commit is contained in:
Sameh Khamis committed 2026-11-11 14:54:01 -08:00
1 parent 9b3ca481ce
commit ace2160002
2 files changed
+25 -1

No files matched your search

+8 -1
View File
@@ -476,7 +476,9 @@ const OWNER_AUTHORIZED_NO_TERMS =
* 64 MiB: railMaxBodyBytes; the feeds that set one publish small documents
* and set a lower cap), and `headerClock: 'untrusted'` marks a feed whose
* header time is wrong and whose vehicles carry none: every train is then
* stamped with the fetch time.
* stamped with the fetch time. `speedUnit: 'km/h'` marks a feed that
* publishes km/h where the spec requires m/s; the proxy converts it, as for
* Transit (src/data/transitFeeds.js).
* `tripUpdatesUrl` is the operator's GTFS-RT TripUpdates feed, served as
* `/api/rail/updates/<id>`.
*
@@ -509,6 +511,7 @@ const OWNER_AUTHORIZED_NO_TERMS =
* url: string,
* positions?: 'gps'|'event',
* headers?: Record<string, string>, headerClock?: 'untrusted',
* speedUnit?: 'km/h',
* pollIntervalMs?: number, tripUpdatesUrl?: string,
* tripUpdatesIntervalMs?: number, maxBodyBytes?: number,
* limits?: {quote: string, note?: string},
@@ -1307,6 +1310,10 @@ export const RAIL_FEED_REGISTRY = Object.freeze([
format: 'gtfs-rt',
// Every TaM vehicle (about 15 KB); the tram routes are kept.
url: 'https://gtfsproxy.e-tam.fr/COMMON/VehiclePosition.pb',
// Speeds are km/h where the spec asks m/s (the Transit layer's entry for
// this feed measured readings at 3.3 times the movement); the proxy
// converts them.
speedUnit: 'km/h',
tripUpdatesUrl: 'https://gtfsproxy.e-tam.fr/COMMON/TripUpdate.pb',
tripUpdatesIntervalMs: 60_000,
staticGtfsUrl: 'https://gtfsproxy.e-tam.fr/COMMON/GTFS.zip',
+17
View File
@@ -66,6 +66,7 @@ const REGISTRY_FIELDS = new Set([
'positions',
'headers',
'headerClock',
'speedUnit',
'pollIntervalMs',
'tripUpdatesUrl',
'tripUpdatesIntervalMs',
@@ -472,3 +473,19 @@ test('feeds that read routes from their schedule pack can build one', () => {
}))
assert.ok(!/@/.test(value), feed.id);
});
test('a feed Transit also reads declares the same speed unit', async () => {
const { TRANSIT_FEED_REGISTRY } = await import('./transitFeeds.js');
const transitByUrl = new Map(
TRANSIT_FEED_REGISTRY.map((feed) => [feed.url, feed]),
);
let shared = 0;
for (const feed of RAIL_FEED_REGISTRY) {
const transit = transitByUrl.get(feed.url);
if (!transit) continue;
shared += 1;
assert.equal(feed.speedUnit, transit.speedUnit, feed.id);
}
assert.ok(shared > 0);
assert.equal(getRegisteredRailFeed('tam-montpellier').speedUnit, 'km/h');
});