From 6e28a0fcf7c9bba965ca595969efacac62355528 Mon Sep 17 00:00:00 2001 From: Tristan van Triest Date: Mon, 25 Nov 2024 15:19:34 +0100 Subject: [PATCH 1/8] Bugfixes for GTFS-RT Infoplus feed --- src/Database/Database.ts | 2 +- src/Interfaces/DatabaseRitInfoUpdate.ts | 1 + src/Models/RitInfoUpdate.ts | 29 ++- src/Models/StopUpdateCollection.ts | 20 +- src/Models/StopUpdates/RitinfoStopUpdate.ts | 5 + src/Repositories/InfoplusRepository.ts | 192 ++++++++++---------- 6 files changed, 145 insertions(+), 104 deletions(-) diff --git a/src/Database/Database.ts b/src/Database/Database.ts index ff632f8..7aea479 100644 --- a/src/Database/Database.ts +++ b/src/Database/Database.ts @@ -7,7 +7,7 @@ export const Knex = knex({ user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, - port: 5432 + port: process.env.DB_PORT ? parseInt(process.env.DB_PORT) : 5432 }, pool: { min: 0, diff --git a/src/Interfaces/DatabaseRitInfoUpdate.ts b/src/Interfaces/DatabaseRitInfoUpdate.ts index d3615be..9646d7b 100644 --- a/src/Interfaces/DatabaseRitInfoUpdate.ts +++ b/src/Interfaces/DatabaseRitInfoUpdate.ts @@ -44,4 +44,5 @@ export interface IRitInfoStopUpdate extends IDatabaseStopUpdate { plannedTrack: string | null; actualTrack: string | null; stationCode: string; + name: string; } \ No newline at end of file diff --git a/src/Models/RitInfoUpdate.ts b/src/Models/RitInfoUpdate.ts index eed91a4..07ddb51 100644 --- a/src/Models/RitInfoUpdate.ts +++ b/src/Models/RitInfoUpdate.ts @@ -4,13 +4,14 @@ * Questions? Email: tristantriest@gmail.com */ -import {IDatabaseRitInfoUpdate} from '../Interfaces/DatabaseRitInfoUpdate' +import {IDatabaseRitInfoUpdate, IRitInfoStopUpdate} from '../Interfaces/DatabaseRitInfoUpdate' import {ExtendedStopTimeUpdate} from "./GTFS/StopTimeUpdate"; import {RitInfoStopUpdate} from "./StopUpdates/RitinfoStopUpdate"; import {StopUpdateCollection} from "./StopUpdateCollection"; import {InternationalAgencys, InternationalTrainSeries} from '../Utilities/InternationalAgencys'; import {IJourneyChange} from "../Shared/src/Types/Infoplus/V2/JourneyChange"; import {LogicalJourneyChangeType} from "../Shared/src/Types/Infoplus/V2/Changes/LogicalJourneyChangeType"; +import {TrainType} from "../Shared/src/Types/API/V2/InfoPlus/TrainType"; export class RitInfoUpdate { private readonly _agency: string; @@ -50,12 +51,36 @@ export class RitInfoUpdate { this._timestamp = update.timestamp; this._routeType = update.routeType; - this._routeLongName = update.routeLongName; + this._routeLongName = this.getRouteLongName(update); this._agencyId = update.agencyId; this._isInternationalTrain = this.setInternationalTrain(); } + private getRouteLongName(update: IDatabaseRitInfoUpdate): string { + if(update.routeLongName) + return update.routeLongName; + + const firstStop = this.stops.first(); + const lastStop = this.stops.last(); + + //The trainseries of e.g. 1234 is 1200, 570 is 500, 29290 is 29000 + const trainSeries = update.trainNumber - (update.trainNumber % 100); + const trainType = update.trainType; + const longTrainType = TrainType.shortToLong(TrainType.fromStringToShort(trainType)); + + //Haarlem <-> Amsterdam Sloterdijk BST26000 + //Nachtnettrein Amsterdam Bijlmer ArenA <-> Leiden Centraal + + //Rotterdam Centraal <-> Amsterdam Centraal ICD1100 + if(firstStop.name && lastStop.name) { + return `${firstStop.name} <-> ${lastStop.name} ${trainType}${trainSeries}`; + } + + return `${longTrainType} ${trainSeries}`; + + } + private setInternationalTrain(): boolean { let isInternationalTrain = false; diff --git a/src/Models/StopUpdateCollection.ts b/src/Models/StopUpdateCollection.ts index c54218c..8b1e4c6 100644 --- a/src/Models/StopUpdateCollection.ts +++ b/src/Models/StopUpdateCollection.ts @@ -24,6 +24,12 @@ export class StopUpdateCollection extends Collection { //Make sure all times are increasing this.checkIncreasingTimes(); + + /* + @InfoPlaza - Specific to Infoplaza IFF GTFS + Set all stop sequences sequentually irrespective of the sequence in InfoPlus + */ + this.setSequenceNumbers(); } private setFirstStop() { @@ -101,6 +107,18 @@ export class StopUpdateCollection extends Collection { } } + /** + * Set the sequence number of each stop to its index in the array + 1 + * @private + */ + private setSequenceNumbers() { + for (let i = 0; i < this.length; i++) { + const stop = this.get(i); + stop.sequence = i + 1; + this.set(i, stop); + } + } + /** * Fix the current stop time by setting the arrival time to the planned arrival time + min(delay at previous stop, delay at next stop) * @param previousStop The previous stop in the sequence @@ -136,7 +154,7 @@ export class StopUpdateCollection extends Collection { if (stopToFix.plannedArrivalTime === null) return; // Calculate the new arrival time by adding the departure delay at the previous stop to the planned arrival time at the current stop - const newArrivalTime = stopToFix.plannedArrivalTime.getTime() + previousStop.departureDelay; + const newArrivalTime = (stopToFix.plannedArrivalTime.getTime() / 1000) + previousStop.departureDelay; // If the new arrival time is not increasing, we can't fix the arrival time if (newArrivalTime < previousStop.departureTime) { diff --git a/src/Models/StopUpdates/RitinfoStopUpdate.ts b/src/Models/StopUpdates/RitinfoStopUpdate.ts index c9fd76c..60ce688 100644 --- a/src/Models/StopUpdates/RitinfoStopUpdate.ts +++ b/src/Models/StopUpdates/RitinfoStopUpdate.ts @@ -25,6 +25,8 @@ export class RitInfoStopUpdate extends StopUpdate { public readonly stationCode: string; + public readonly name: string; + constructor(update: IRitInfoStopUpdate) { super(update); @@ -40,6 +42,9 @@ export class RitInfoStopUpdate extends StopUpdate { this.platform = update.platform; this.track = update.track; + + this.name = update.name; + if(this.platform !== this.track) console.log(`[RitInfoStopUpdate] Platform and Track are not the same for stop ${this.stationCode}! Platform: ${this.platform}, Track: ${this.track}`) } diff --git a/src/Repositories/InfoplusRepository.ts b/src/Repositories/InfoplusRepository.ts index e41dc36..d582c80 100644 --- a/src/Repositories/InfoplusRepository.ts +++ b/src/Repositories/InfoplusRepository.ts @@ -15,114 +15,106 @@ export class InfoplusRepository extends Repository implements IInfoPlusRepositor console.time('getCurrentRealtimeTripUpdates'); return this.database.raw(` WITH cal_dates AS (SELECT DISTINCT "serviceId", "date" - FROM "StaticData-NL".calendar_dates - WHERE "date" >= ?::date - AND date <= ?::date), - trips AS (SELECT "tripId", "routeId", "directionId", "tripShortName", "shapeId", "serviceId" - FROM "StaticData-NL".trips - WHERE agency = 'IFF' - AND "serviceId" IN (SELECT DISTINCT "serviceId" - FROM cal_dates)), - stops AS (SELECT "stopId", "stationCode", "platformCode" - FROM "StaticData-NL".stops - WHERE "stationCode" IS NOT NULL) - SELECT jpjl."journeyPartNumber" AS "trainNumber", - jpjl."shortJourneyPartNumber" AS "shortTrainNumber", - r."trainType"->>'code' AS "trainType", - r.agency, - r."operationDate", - r."showsInTravelPlanner" AS "showsInTripPlanner", - r."timestamp", - coalesce(lj."journeyChanges", jpjl."journeyPartChanges") AS "changes", - t."tripId" AS "tripId", - coalesce(t."routeId", t_short."routeId") AS "routeId", - rt."routeType" AS "routeType", - rt."agencyId" AS "agencyId", - rt."routeLongName" AS "routeLongName", - coalesce(t."directionId", t_short."directionId") AS "directionId", - coalesce(t."shapeId", t_short."shapeId") AS "shapeId", - jsonb_agg( - jsonb_build_object( - 'stationCode', - si."stationCode", - 'plannedWillStop', - si."plannedWillStop", - 'actualWillStop', - si."actualWillStop", - 'plannedArrivalTime', - si."plannedArrivalTime", - 'plannedDepartureTime', - si."plannedDepartureTime", - 'departureTime', - coalesce(si."actualDepartureTime", si."plannedDepartureTime"), - 'arrivalTime', - coalesce(si."actualArrivalTime", si."plannedArrivalTime"), - 'departureDelay', - si."actualDepartureTime" - si."plannedDepartureTime", - 'arrivalDelay', - si."actualArrivalTime" - si."plannedArrivalTime", - 'changes', - si.changes, - 'stopId', - COALESCE(s."stopId", lateral_stop."stopId", si."stationCode"), - 'platform', - s."platformCode", - 'plannedTrack', - coalesce(si."plannedArrivalTracks", si."plannedDepartureTracks"), - 'actualTrack', - coalesce(si."actualArrivalTracks", si."actualDepartureTracks"), - 'track', - coalesce(si."actualArrivalTracks", si."actualDepartureTracks", si."plannedArrivalTracks", - si."plannedDepartureTracks"), - 'sequence', - si."stopOrder" - ) ORDER BY si."stopOrder") stops - FROM "InfoPlus-new".ritinfo r - JOIN "InfoPlus-new".logical_journeys lj - ON r."trainNumber" = lj."trainNumber" AND r."operationDate" = lj."operationDate" - JOIN "InfoPlus-new".logical_journey_parts jpjl - ON lj."journeyNumber" = jpjl."journeyNumber" AND - r."operationDate" = jpjl."operationDate" - JOIN "InfoPlus-new".stop_information si - ON jpjl."journeyPartNumber" = si."journeyPartNumber" AND - jpjl."operationDate" = si."operationDate" AND - ("plannedWillStop" = true OR "actualWillStop" = true) AND - (coalesce("plannedDepartureTime", "actualArrivalTime") IS NOT NULL OR - coalesce("plannedArrivalTime", "actualArrivalTime") IS NOT NULL) - LEFT JOIN trips t - ON jpjl."journeyPartNumber" = t."tripShortName"::int + FROM "StaticData-NL".calendar_dates + WHERE "date" >= ?::date + AND date <= ?::date), + trips AS (SELECT "tripId", "routeId", "directionId", "tripShortName", "shapeId", "serviceId" + FROM "StaticData-NL".trips + WHERE agency = 'IFF' + AND "serviceId" IN (SELECT DISTINCT "serviceId" + FROM cal_dates)), + stops AS (SELECT "stopId", "stationCode", "platformCode", "stopName" + FROM "StaticData-NL".stops + WHERE "stationCode" IS NOT NULL) +SELECT jpjl."journeyPartNumber" AS "trainNumber", + jpjl."shortJourneyPartNumber" AS "shortTrainNumber", + r."trainType" ->> 'code' AS "trainType", + r.agency, + r."operationDate", + r."showsInTravelPlanner" AS "showsInTripPlanner", + r."timestamp", + coalesce(lj."journeyChanges", jpjl."journeyPartChanges") AS "changes", + t."tripId" AS "tripId", + coalesce(t."routeId", t_short."routeId") AS "routeId", + rt."routeType" AS "routeType", + rt."agencyId" AS "agencyId", + rt."routeLongName" AS "routeLongName", + coalesce(t."directionId", t_short."directionId") AS "directionId", + coalesce(t."shapeId", t_short."shapeId") AS "shapeId", + jsonb_agg( + CASE + WHEN s."stopId" IS NOT NULL OR lateral_stop."stopId" IS NOT NULL THEN + jsonb_build_object( + 'stationCode', si."stationCode", + 'plannedWillStop', si."plannedWillStop", + 'actualWillStop', si."actualWillStop", + 'plannedArrivalTime', si."plannedArrivalTime", + 'plannedDepartureTime', si."plannedDepartureTime", + 'departureTime', coalesce(si."actualDepartureTime", si."plannedDepartureTime"), + 'arrivalTime', coalesce(si."actualArrivalTime", si."plannedArrivalTime"), + 'departureDelay', si."actualDepartureTime" - si."plannedDepartureTime", + 'arrivalDelay', si."actualArrivalTime" - si."plannedArrivalTime", + 'changes', si.changes, + 'stopId', COALESCE(s."stopId", lateral_stop."stopId"), + 'platform', s."platformCode", + 'plannedTrack', coalesce(si."plannedArrivalTracks", si."plannedDepartureTracks"), + 'actualTrack', coalesce(si."actualArrivalTracks", si."actualDepartureTracks"), + 'track', + coalesce(si."actualArrivalTracks", si."actualDepartureTracks", si."plannedArrivalTracks", + si."plannedDepartureTracks"), + 'sequence', si."stopOrder", + 'name', COALESCE(s."stopName", lateral_stop."stopName", si."stationCode") + ) + END + ORDER BY si."stopOrder" + ) FILTER (WHERE s."stopId" IS NOT NULL OR lateral_stop."stopId" IS NOT NULL) AS stops +FROM "InfoPlus-new".ritinfo r + JOIN "InfoPlus-new".logical_journeys lj + ON r."trainNumber" = lj."trainNumber" AND r."operationDate" = lj."operationDate" + JOIN "InfoPlus-new".logical_journey_parts jpjl + ON lj."journeyNumber" = jpjl."journeyNumber" AND + r."operationDate" = jpjl."operationDate" + JOIN "InfoPlus-new".stop_information si + ON jpjl."journeyPartNumber" = si."journeyPartNumber" AND + jpjl."operationDate" = si."operationDate" AND + ("plannedWillStop" = true OR "actualWillStop" = true) AND + (coalesce("plannedDepartureTime", "actualArrivalTime") IS NOT NULL OR + coalesce("plannedArrivalTime", "actualArrivalTime") IS NOT NULL) + LEFT JOIN trips t + ON jpjl."journeyPartNumber" = t."tripShortName"::int AND EXISTS (SELECT 1 FROM cal_dates cd WHERE cd."serviceId" = t."serviceId" AND cd."date" = r."operationDate") LEFT JOIN trips t_short ON t."tripId" IS NULL AND jpjl."shortJourneyPartNumber" = t_short."tripShortName"::int - AND EXISTS (SELECT 1 + AND EXISTS (SELECT 1 FROM cal_dates cd WHERE cd."serviceId" = t_short."serviceId" - AND cd."date" = r."operationDate") - LEFT JOIN stops s ON (s."stationCode" = lower(si."stationCode") AND - s."platformCode" = - coalesce(si."actualArrivalTracks", si."actualDepartureTracks", si."plannedArrivalTracks", - si."plannedDepartureTracks")) - LEFT JOIN LATERAL ( - SELECT "stopId" - FROM stops lax - WHERE lax."stationCode" = lower(si."stationCode") - LIMIT 1 - ) AS lateral_stop ON s."stopId" IS NULL - LEFT JOIN "StaticData-NL".routes rt ON rt."routeId" = coalesce(t."routeId", t_short."routeId") - WHERE r."operationDate" >= ?::date - AND NOT ( - r."operationDate" > ?::date - AND lj."journeyChanges" IS NULL - ) - GROUP BY r."trainNumber", jpjl."journeyPartNumber", r."shortTrainNumber", jpjl."shortJourneyPartNumber", - r."trainType", r.agency, - r."showsInTravelPlanner", r.timestamp, r."operationDate", t."tripId", coalesce(t."tripId", t_short."tripId"), - coalesce(lj."journeyChanges", jpjl."journeyPartChanges"), - t."tripId", coalesce(t."routeId", t_short."routeId"), - coalesce(t."directionId", t_short."directionId"), coalesce(t."shapeId", t_short."shapeId"), rt."routeType", rt."agencyId", rt."routeLongName"; + AND cd."date" = r."operationDate") + LEFT JOIN stops s ON (s."stationCode" = lower(si."stationCode") AND + s."platformCode" = + coalesce(si."actualArrivalTracks", si."actualDepartureTracks", si."plannedArrivalTracks", + si."plannedDepartureTracks")) + LEFT JOIN LATERAL ( + SELECT "stopId", "stopName" + FROM stops lax + WHERE lax."stationCode" = lower(si."stationCode") + LIMIT 1 + ) AS lateral_stop ON s."stopId" IS NULL + LEFT JOIN "StaticData-NL".routes rt ON rt."routeId" = coalesce(t."routeId", t_short."routeId") +WHERE r."operationDate" >= ?::date + AND NOT ( + r."operationDate" > ?::date + AND lj."journeyChanges" IS NULL + ) +GROUP BY r."trainNumber", jpjl."journeyPartNumber", r."shortTrainNumber", jpjl."shortJourneyPartNumber", + r."trainType", r.agency, + r."showsInTravelPlanner", r.timestamp, r."operationDate", t."tripId", coalesce(t."tripId", t_short."tripId"), + coalesce(lj."journeyChanges", jpjl."journeyPartChanges"), + t."tripId", coalesce(t."routeId", t_short."routeId"), + coalesce(t."directionId", t_short."directionId"), coalesce(t."shapeId", t_short."shapeId"), rt."routeType", + rt."agencyId", rt."routeLongName"; `, [operationDateOfTodayOrYesterday, endOperationDate, operationDateOfTodayOrYesterday, operationDateOfTodayOrTomorrow]).then(result => { console.timeEnd('getCurrentRealtimeTripUpdates'); return result.rows; From a3baf08907e13fa5d016dd75dd82415e32a48df0 Mon Sep 17 00:00:00 2001 From: Tristan Date: Mon, 25 Nov 2024 15:27:45 +0100 Subject: [PATCH 2/8] Update StopUpdateCollection.ts --- src/Models/StopUpdateCollection.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Models/StopUpdateCollection.ts b/src/Models/StopUpdateCollection.ts index 8b1e4c6..fde4f4b 100644 --- a/src/Models/StopUpdateCollection.ts +++ b/src/Models/StopUpdateCollection.ts @@ -24,12 +24,6 @@ export class StopUpdateCollection extends Collection { //Make sure all times are increasing this.checkIncreasingTimes(); - - /* - @InfoPlaza - Specific to Infoplaza IFF GTFS - Set all stop sequences sequentually irrespective of the sequence in InfoPlus - */ - this.setSequenceNumbers(); } private setFirstStop() { @@ -269,4 +263,4 @@ export class StopUpdateCollection extends Collection { return new StopUpdateCollection(withNewIndexes, this.tripId); } -} \ No newline at end of file +} From 0dabd31f0489cf09f1825c96a0a15c31ec42221e Mon Sep 17 00:00:00 2001 From: Tristan van Triest Date: Mon, 25 Nov 2024 15:28:36 +0100 Subject: [PATCH 3/8] Use right shared tracking branch --- src/Shared | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Shared b/src/Shared index 2d549a5..4a57c51 160000 --- a/src/Shared +++ b/src/Shared @@ -1 +1 @@ -Subproject commit 2d549a56a1bc3505153ae135f60c7a32c60508b6 +Subproject commit 4a57c519c587a861c9818e58de448d0738bf4d52 From 4108eb392ea928fee7fd7961207a6c6775fbe11d Mon Sep 17 00:00:00 2001 From: Tristan van Triest Date: Mon, 25 Nov 2024 18:03:44 +0100 Subject: [PATCH 4/8] Don't include "Niet voor Reizigers" stops. Fix stop time fixing. --- src/Models/StopUpdateCollection.ts | 68 +++++++++++++++----------- src/Repositories/InfoplusRepository.ts | 1 + 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/Models/StopUpdateCollection.ts b/src/Models/StopUpdateCollection.ts index 8b1e4c6..1b62334 100644 --- a/src/Models/StopUpdateCollection.ts +++ b/src/Models/StopUpdateCollection.ts @@ -50,10 +50,6 @@ export class StopUpdateCollection extends Collection { * @private */ private checkIncreasingTimes() { - // Initialize variables to keep track of the last stop's arrival and departure times - let lastStopArrivalTime: number | undefined = undefined; - let lastStopDepartureTime: number | undefined = undefined; - // Loop through each stop in the collection for (let i = 0; i < this.length; i++) { // Get the current stop, as well as the previous and next stops (if they exist) @@ -73,25 +69,21 @@ export class StopUpdateCollection extends Collection { // Check if the current stop's planned arrival time is increasing if (currentStop.arrivalTime !== null) { - if (lastStopDepartureTime !== undefined && currentStop.arrivalTime && currentStop.arrivalTime < lastStopDepartureTime) { + if (currentStop.arrivalTime && currentStop.arrivalTime < previousStop.departureTime) { // If the current stop's planned arrival time is not increasing, log a warning message // console.warn(`[StopUpdateCollection ${this.tripId}] Non-increasing arrival time detected for stop ${currentStop.stationCode} [${currentStop.sequence}]`, new Date(currentStop.arrivalTime * 1000), new Date(lastStopDepartureTime * 1000)) arrivalTimeIsIncreasing = false; } - - lastStopArrivalTime = currentStop.arrivalTime; } // Check if the current stop's planned departure time is increasing if (currentStop.departureTime !== null) { - if (lastStopDepartureTime !== undefined && currentStop.departureTime && currentStop.departureTime < lastStopDepartureTime) { + if (currentStop.departureTime && currentStop.departureTime < previousStop.departureTime) { // If the current stop's planned departure time is not increasing, log a warning message // console.warn(`[StopUpdateCollection ${this.tripId}] Non-increasing departure time detected for stop ${currentStop.stationCode} [${currentStop.sequence}]`, new Date(currentStop.departureTime * 1000), new Date(lastStopDepartureTime * 1000)) departureTimeIsIncreasing = false; } - // Update the last stop's departure time to the current stop's planned departure time - lastStopDepartureTime = currentStop.departureTime; } // If both the arrival and departure times are increasing, we don't need to fix anything @@ -99,6 +91,7 @@ export class StopUpdateCollection extends Collection { continue; } + // If there is a previous and next stop, we can fix both times this.fixStopTime(previousStop, currentStop, !arrivalTimeIsIncreasing, !departureTimeIsIncreasing); @@ -127,7 +120,7 @@ export class StopUpdateCollection extends Collection { * @param fixDeparture Whether the departure time should be fixed */ private fixStopTime(previousStop: RitInfoStopUpdate, currentStop: RitInfoStopUpdate, fixArrival: boolean, fixDeparture: boolean) { - // console.info(`[StopUpdateCollection] Fixing stop times for stop ${currentStop.stopId} [${currentStop.sequence}]`) + console.info(`[StopUpdateCollection] Fixing stop times for stop ${currentStop.stopId}: ${currentStop.name} [${currentStop.sequence}]`) if(fixArrival) this.fixArrivalTime(previousStop, currentStop); @@ -153,19 +146,39 @@ export class StopUpdateCollection extends Collection { // If the current stop has no planned arrival time, we can't fix the arrival time if (stopToFix.plannedArrivalTime === null) return; - // Calculate the new arrival time by adding the departure delay at the previous stop to the planned arrival time at the current stop - const newArrivalTime = (stopToFix.plannedArrivalTime.getTime() / 1000) + previousStop.departureDelay; + const orignalStopTime = (stopToFix.departureTime - stopToFix.arrivalTime) / 1000; - // If the new arrival time is not increasing, we can't fix the arrival time - if (newArrivalTime < previousStop.departureTime) { - console.error(`[StopUpdateCollection ${this.tripId}] Tried fixing arrival time for stop ${stopToFix.stationCode} [${stopToFix.sequence}], but the new arrival time is not increasing. New arrival time: ${new Date(newArrivalTime * 1000)}`); - } + // Calculate the base new arrival time + let newArrivalTime = (stopToFix.plannedArrivalTime.getTime() / 1000) + previousStop.departureDelay; - // Update the arrival time of the current stop - stopToFix.arrivalTime = newArrivalTime; + // Ensure the arrival time is strictly greater than the previous stop's departure time + newArrivalTime = Math.max(newArrivalTime, previousStop.departureTime + 1); - // Update the arrival delay of the current stop + stopToFix.arrivalTime = newArrivalTime; stopToFix.arrivalDelay = previousStop.departureDelay; + + //We always stay at the station about 60 seconds, so we cannot run in all delay during the stop. + if(orignalStopTime > 60) + stopToFix.departureDelay = stopToFix.arrivalDelay - (orignalStopTime - 60); + //If we weren't planned to stop for longer than a minute, we don't have to adjust the delay. + else + stopToFix.departureDelay = stopToFix.arrivalDelay; + + //If there is still a departure delay after the stop, we have to adjust the departure time. + if(stopToFix.departureDelay > 0) { + //The departure time will be the delay + the arrival time. + stopToFix.departureTime = stopToFix.arrivalTime + stopToFix.departureDelay; + + //Log what was fixed, the original stop time, the new arrival time, the new departure time and the delay. + console.info(`[StopUpdateCollection] Fixed stop ${stopToFix.stopId}: ${stopToFix.name} [${stopToFix.sequence}] Arrival time: ${new Date(stopToFix.arrivalTime * 1000)} Departure time: ${new Date(stopToFix.departureTime * 1000)} Original stop time: ${orignalStopTime} seconds. Arrival delay: ${stopToFix.arrivalDelay} seconds. Departure delay: ${stopToFix.departureDelay} seconds.`); + } + //If there is no delay, we can just set the departure time to the planned departure time. + else { + stopToFix.departureTime = stopToFix.plannedDepartureTime.getTime() / 1000; + //Log what was fixed, the original stop time, the new arrival time, the new departure time and the delay. + console.info(`[StopUpdateCollection] Fixed stop ${stopToFix.stopId}: ${stopToFix.name} [${stopToFix.sequence}] Arrival time: ${new Date(stopToFix.arrivalTime * 1000)} Departure time: ${new Date(stopToFix.departureTime * 1000)} Original stop time: ${orignalStopTime} seconds. Arrival delay: ${stopToFix.arrivalDelay} seconds. Departure delay: ${stopToFix.departureDelay} seconds.`); + } + } /** @@ -184,21 +197,18 @@ export class StopUpdateCollection extends Collection { // If the current stop has no actual arrival time, we can't fix the departure time if (stopToFix.arrivalTime === null) return; - // Calculate the new departure time by adding the difference between the planned arrival and departure times to the actual arrival time - const newDepartureTime = stopToFix.arrivalTime + ((stopToFix.plannedDepartureTime.getTime() - stopToFix.plannedArrivalTime.getTime()) / 1000); + // Calculate the base new departure time + let newDepartureTime = stopToFix.arrivalTime + ((stopToFix.plannedDepartureTime.getTime() - stopToFix.plannedArrivalTime.getTime()) / 1000); - // If the new departure time is not increasing, we can't fix the departure time - if (newDepartureTime < stopToFix.arrivalTime) { - console.error(`[StopUpdateCollection ${this.tripId}] Tried fixing departure time for stop ${stopToFix.stationCode} [${stopToFix.sequence}], but the new departure time is not increasing. New departure time: ${new Date(newDepartureTime * 1000)}`); - } + // Ensure the departure time is strictly greater than the arrival time + newDepartureTime = Math.max(newDepartureTime, stopToFix.arrivalTime + 1); - // Update the departure time of the current stop stopToFix.departureTime = newDepartureTime; - - // Update the departure delay of the current stop stopToFix.departureDelay = stopToFix.arrivalDelay; } + + /** * Finds the last stop that is still served before only cancelled stops happen. * Updates it so that it does not have a departure time, as it will never depart because it is the last stop now. diff --git a/src/Repositories/InfoplusRepository.ts b/src/Repositories/InfoplusRepository.ts index d582c80..1753d95 100644 --- a/src/Repositories/InfoplusRepository.ts +++ b/src/Repositories/InfoplusRepository.ts @@ -77,6 +77,7 @@ FROM "InfoPlus-new".ritinfo r JOIN "InfoPlus-new".stop_information si ON jpjl."journeyPartNumber" = si."journeyPartNumber" AND jpjl."operationDate" = si."operationDate" AND + si."stopType" != 'N' AND ("plannedWillStop" = true OR "actualWillStop" = true) AND (coalesce("plannedDepartureTime", "actualArrivalTime") IS NOT NULL OR coalesce("plannedArrivalTime", "actualArrivalTime") IS NOT NULL) From 2ed47df7f6ae41fbe2c3d37b23eadff402b194ca Mon Sep 17 00:00:00 2001 From: Tristan van Triest Date: Mon, 25 Nov 2024 18:03:44 +0100 Subject: [PATCH 5/8] Don't include "Niet voor Reizigers" stops. Fix stop time fixing. --- src/Models/StopUpdateCollection.ts | 68 +++++++++++++++----------- src/Repositories/InfoplusRepository.ts | 1 + 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/Models/StopUpdateCollection.ts b/src/Models/StopUpdateCollection.ts index fde4f4b..d8b007b 100644 --- a/src/Models/StopUpdateCollection.ts +++ b/src/Models/StopUpdateCollection.ts @@ -44,10 +44,6 @@ export class StopUpdateCollection extends Collection { * @private */ private checkIncreasingTimes() { - // Initialize variables to keep track of the last stop's arrival and departure times - let lastStopArrivalTime: number | undefined = undefined; - let lastStopDepartureTime: number | undefined = undefined; - // Loop through each stop in the collection for (let i = 0; i < this.length; i++) { // Get the current stop, as well as the previous and next stops (if they exist) @@ -67,25 +63,21 @@ export class StopUpdateCollection extends Collection { // Check if the current stop's planned arrival time is increasing if (currentStop.arrivalTime !== null) { - if (lastStopDepartureTime !== undefined && currentStop.arrivalTime && currentStop.arrivalTime < lastStopDepartureTime) { + if (currentStop.arrivalTime && currentStop.arrivalTime < previousStop.departureTime) { // If the current stop's planned arrival time is not increasing, log a warning message // console.warn(`[StopUpdateCollection ${this.tripId}] Non-increasing arrival time detected for stop ${currentStop.stationCode} [${currentStop.sequence}]`, new Date(currentStop.arrivalTime * 1000), new Date(lastStopDepartureTime * 1000)) arrivalTimeIsIncreasing = false; } - - lastStopArrivalTime = currentStop.arrivalTime; } // Check if the current stop's planned departure time is increasing if (currentStop.departureTime !== null) { - if (lastStopDepartureTime !== undefined && currentStop.departureTime && currentStop.departureTime < lastStopDepartureTime) { + if (currentStop.departureTime && currentStop.departureTime < previousStop.departureTime) { // If the current stop's planned departure time is not increasing, log a warning message // console.warn(`[StopUpdateCollection ${this.tripId}] Non-increasing departure time detected for stop ${currentStop.stationCode} [${currentStop.sequence}]`, new Date(currentStop.departureTime * 1000), new Date(lastStopDepartureTime * 1000)) departureTimeIsIncreasing = false; } - // Update the last stop's departure time to the current stop's planned departure time - lastStopDepartureTime = currentStop.departureTime; } // If both the arrival and departure times are increasing, we don't need to fix anything @@ -93,6 +85,7 @@ export class StopUpdateCollection extends Collection { continue; } + // If there is a previous and next stop, we can fix both times this.fixStopTime(previousStop, currentStop, !arrivalTimeIsIncreasing, !departureTimeIsIncreasing); @@ -121,7 +114,7 @@ export class StopUpdateCollection extends Collection { * @param fixDeparture Whether the departure time should be fixed */ private fixStopTime(previousStop: RitInfoStopUpdate, currentStop: RitInfoStopUpdate, fixArrival: boolean, fixDeparture: boolean) { - // console.info(`[StopUpdateCollection] Fixing stop times for stop ${currentStop.stopId} [${currentStop.sequence}]`) + console.info(`[StopUpdateCollection] Fixing stop times for stop ${currentStop.stopId}: ${currentStop.name} [${currentStop.sequence}]`) if(fixArrival) this.fixArrivalTime(previousStop, currentStop); @@ -147,19 +140,39 @@ export class StopUpdateCollection extends Collection { // If the current stop has no planned arrival time, we can't fix the arrival time if (stopToFix.plannedArrivalTime === null) return; - // Calculate the new arrival time by adding the departure delay at the previous stop to the planned arrival time at the current stop - const newArrivalTime = (stopToFix.plannedArrivalTime.getTime() / 1000) + previousStop.departureDelay; + const orignalStopTime = (stopToFix.departureTime - stopToFix.arrivalTime) / 1000; - // If the new arrival time is not increasing, we can't fix the arrival time - if (newArrivalTime < previousStop.departureTime) { - console.error(`[StopUpdateCollection ${this.tripId}] Tried fixing arrival time for stop ${stopToFix.stationCode} [${stopToFix.sequence}], but the new arrival time is not increasing. New arrival time: ${new Date(newArrivalTime * 1000)}`); - } + // Calculate the base new arrival time + let newArrivalTime = (stopToFix.plannedArrivalTime.getTime() / 1000) + previousStop.departureDelay; - // Update the arrival time of the current stop - stopToFix.arrivalTime = newArrivalTime; + // Ensure the arrival time is strictly greater than the previous stop's departure time + newArrivalTime = Math.max(newArrivalTime, previousStop.departureTime + 1); - // Update the arrival delay of the current stop + stopToFix.arrivalTime = newArrivalTime; stopToFix.arrivalDelay = previousStop.departureDelay; + + //We always stay at the station about 60 seconds, so we cannot run in all delay during the stop. + if(orignalStopTime > 60) + stopToFix.departureDelay = stopToFix.arrivalDelay - (orignalStopTime - 60); + //If we weren't planned to stop for longer than a minute, we don't have to adjust the delay. + else + stopToFix.departureDelay = stopToFix.arrivalDelay; + + //If there is still a departure delay after the stop, we have to adjust the departure time. + if(stopToFix.departureDelay > 0) { + //The departure time will be the delay + the arrival time. + stopToFix.departureTime = stopToFix.arrivalTime + stopToFix.departureDelay; + + //Log what was fixed, the original stop time, the new arrival time, the new departure time and the delay. + console.info(`[StopUpdateCollection] Fixed stop ${stopToFix.stopId}: ${stopToFix.name} [${stopToFix.sequence}] Arrival time: ${new Date(stopToFix.arrivalTime * 1000)} Departure time: ${new Date(stopToFix.departureTime * 1000)} Original stop time: ${orignalStopTime} seconds. Arrival delay: ${stopToFix.arrivalDelay} seconds. Departure delay: ${stopToFix.departureDelay} seconds.`); + } + //If there is no delay, we can just set the departure time to the planned departure time. + else { + stopToFix.departureTime = stopToFix.plannedDepartureTime.getTime() / 1000; + //Log what was fixed, the original stop time, the new arrival time, the new departure time and the delay. + console.info(`[StopUpdateCollection] Fixed stop ${stopToFix.stopId}: ${stopToFix.name} [${stopToFix.sequence}] Arrival time: ${new Date(stopToFix.arrivalTime * 1000)} Departure time: ${new Date(stopToFix.departureTime * 1000)} Original stop time: ${orignalStopTime} seconds. Arrival delay: ${stopToFix.arrivalDelay} seconds. Departure delay: ${stopToFix.departureDelay} seconds.`); + } + } /** @@ -178,21 +191,18 @@ export class StopUpdateCollection extends Collection { // If the current stop has no actual arrival time, we can't fix the departure time if (stopToFix.arrivalTime === null) return; - // Calculate the new departure time by adding the difference between the planned arrival and departure times to the actual arrival time - const newDepartureTime = stopToFix.arrivalTime + ((stopToFix.plannedDepartureTime.getTime() - stopToFix.plannedArrivalTime.getTime()) / 1000); + // Calculate the base new departure time + let newDepartureTime = stopToFix.arrivalTime + ((stopToFix.plannedDepartureTime.getTime() - stopToFix.plannedArrivalTime.getTime()) / 1000); - // If the new departure time is not increasing, we can't fix the departure time - if (newDepartureTime < stopToFix.arrivalTime) { - console.error(`[StopUpdateCollection ${this.tripId}] Tried fixing departure time for stop ${stopToFix.stationCode} [${stopToFix.sequence}], but the new departure time is not increasing. New departure time: ${new Date(newDepartureTime * 1000)}`); - } + // Ensure the departure time is strictly greater than the arrival time + newDepartureTime = Math.max(newDepartureTime, stopToFix.arrivalTime + 1); - // Update the departure time of the current stop stopToFix.departureTime = newDepartureTime; - - // Update the departure delay of the current stop stopToFix.departureDelay = stopToFix.arrivalDelay; } + + /** * Finds the last stop that is still served before only cancelled stops happen. * Updates it so that it does not have a departure time, as it will never depart because it is the last stop now. diff --git a/src/Repositories/InfoplusRepository.ts b/src/Repositories/InfoplusRepository.ts index d582c80..1753d95 100644 --- a/src/Repositories/InfoplusRepository.ts +++ b/src/Repositories/InfoplusRepository.ts @@ -77,6 +77,7 @@ FROM "InfoPlus-new".ritinfo r JOIN "InfoPlus-new".stop_information si ON jpjl."journeyPartNumber" = si."journeyPartNumber" AND jpjl."operationDate" = si."operationDate" AND + si."stopType" != 'N' AND ("plannedWillStop" = true OR "actualWillStop" = true) AND (coalesce("plannedDepartureTime", "actualArrivalTime") IS NOT NULL OR coalesce("plannedArrivalTime", "actualArrivalTime") IS NOT NULL) From 2d471d8b88361351e5495fb36f735f702a6379fc Mon Sep 17 00:00:00 2001 From: Tristan van Triest Date: Mon, 25 Nov 2024 18:05:20 +0100 Subject: [PATCH 6/8] Don't include "Niet voor Reizigers" stops. Fix stop time fixing. --- src/Shared | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Shared b/src/Shared index 2d549a5..4a57c51 160000 --- a/src/Shared +++ b/src/Shared @@ -1 +1 @@ -Subproject commit 2d549a56a1bc3505153ae135f60c7a32c60508b6 +Subproject commit 4a57c519c587a861c9818e58de448d0738bf4d52 From c8fa07bd7216f769eccb1ceac16f4b0a6b24b626 Mon Sep 17 00:00:00 2001 From: Tristan van Triest Date: Thu, 28 Nov 2024 10:37:10 +0100 Subject: [PATCH 7/8] Disable excessive logging --- src/Models/StopUpdateCollection.ts | 6 +++--- src/Models/TrainUpdateCollection.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Models/StopUpdateCollection.ts b/src/Models/StopUpdateCollection.ts index 1b62334..399e6d9 100644 --- a/src/Models/StopUpdateCollection.ts +++ b/src/Models/StopUpdateCollection.ts @@ -120,7 +120,7 @@ export class StopUpdateCollection extends Collection { * @param fixDeparture Whether the departure time should be fixed */ private fixStopTime(previousStop: RitInfoStopUpdate, currentStop: RitInfoStopUpdate, fixArrival: boolean, fixDeparture: boolean) { - console.info(`[StopUpdateCollection] Fixing stop times for stop ${currentStop.stopId}: ${currentStop.name} [${currentStop.sequence}]`) + //console.info(`[StopUpdateCollection] Fixing stop times for stop ${currentStop.stopId}: ${currentStop.name} [${currentStop.sequence}]`) if(fixArrival) this.fixArrivalTime(previousStop, currentStop); @@ -170,13 +170,13 @@ export class StopUpdateCollection extends Collection { stopToFix.departureTime = stopToFix.arrivalTime + stopToFix.departureDelay; //Log what was fixed, the original stop time, the new arrival time, the new departure time and the delay. - console.info(`[StopUpdateCollection] Fixed stop ${stopToFix.stopId}: ${stopToFix.name} [${stopToFix.sequence}] Arrival time: ${new Date(stopToFix.arrivalTime * 1000)} Departure time: ${new Date(stopToFix.departureTime * 1000)} Original stop time: ${orignalStopTime} seconds. Arrival delay: ${stopToFix.arrivalDelay} seconds. Departure delay: ${stopToFix.departureDelay} seconds.`); + //console.info(`[StopUpdateCollection] Fixed stop ${stopToFix.stopId}: ${stopToFix.name} [${stopToFix.sequence}] Arrival time: ${new Date(stopToFix.arrivalTime * 1000)} Departure time: ${new Date(stopToFix.departureTime * 1000)} Original stop time: ${orignalStopTime} seconds. Arrival delay: ${stopToFix.arrivalDelay} seconds. Departure delay: ${stopToFix.departureDelay} seconds.`); } //If there is no delay, we can just set the departure time to the planned departure time. else { stopToFix.departureTime = stopToFix.plannedDepartureTime.getTime() / 1000; //Log what was fixed, the original stop time, the new arrival time, the new departure time and the delay. - console.info(`[StopUpdateCollection] Fixed stop ${stopToFix.stopId}: ${stopToFix.name} [${stopToFix.sequence}] Arrival time: ${new Date(stopToFix.arrivalTime * 1000)} Departure time: ${new Date(stopToFix.departureTime * 1000)} Original stop time: ${orignalStopTime} seconds. Arrival delay: ${stopToFix.arrivalDelay} seconds. Departure delay: ${stopToFix.departureDelay} seconds.`); + //console.info(`[StopUpdateCollection] Fixed stop ${stopToFix.stopId}: ${stopToFix.name} [${stopToFix.sequence}] Arrival time: ${new Date(stopToFix.arrivalTime * 1000)} Departure time: ${new Date(stopToFix.departureTime * 1000)} Original stop time: ${orignalStopTime} seconds. Arrival delay: ${stopToFix.arrivalDelay} seconds. Departure delay: ${stopToFix.departureDelay} seconds.`); } } diff --git a/src/Models/TrainUpdateCollection.ts b/src/Models/TrainUpdateCollection.ts index 53211be..5fd456a 100644 --- a/src/Models/TrainUpdateCollection.ts +++ b/src/Models/TrainUpdateCollection.ts @@ -32,7 +32,7 @@ export class TrainUpdateCollection extends Collection { //We do this so we can check if this update is there the next iteration as well, if not, we add a new stop time update //that cancels the trip. if(trainUpdate.hasCustomTripId && !this.TrainUpdatesWithCustomTripId.find(u => u.trip.tripId == trainUpdate.trip.tripId)) { - console.log(`[TrainUpdateCollection] Adding ${trainUpdate.trip.tripId} to TrainUpdatesWithCustomTripId array.`) + // console.log(`[TrainUpdateCollection] Adding ${trainUpdate.trip.tripId} to TrainUpdatesWithCustomTripId array.`) this.TrainUpdatesWithCustomTripId.push(trainUpdate); } From 7e71d21674933596460b2d99875bdbc3ad2b77e6 Mon Sep 17 00:00:00 2001 From: Tristan van Triest Date: Wed, 4 Dec 2024 11:31:31 +0100 Subject: [PATCH 8/8] Update deploy script --- .github/workflows/deploy.yml | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 888b958..613d048 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -3,18 +3,23 @@ name: Deploy to Production on: push: branches: - - 'main' - - workflow_dispatch: + - main + pull_request: + types: + - closed + branches: + - main jobs: -# build: -# runs-on: ["self-hosted", "main"] -# steps: -# - name: Run compose script in Deployment repository. -# uses: benc-uk/workflow-dispatch@v1 -# with: -# workflow: Deploy Docker Images of R-OV -# repo: R-OV-NL/Deploy -# token: ${{ secrets.SHARED_PAT }} -# ref: main \ No newline at end of file + deploy: + name: Deploy to Production + if: github.event.pull_request.merged == true || github.event_name == 'push' + runs-on: ubuntu-latest + steps: + - name: Run compose script in Deployment repository. + uses: benc-uk/workflow-dispatch@v1 + with: + workflow: Deploy Docker Images + repo: infoplaza-mobility/Deploy + token: ${{ secrets.SHARED_PAT }} + ref: main \ No newline at end of file