Closed lamBOOO closed 1 year ago
Thank you for documenting this. I'm not sure yet if this is something that hafas-client
can influence though.
If possible, can you provide another example, ideally with more time in advance? Alternatively, you can run the script you provided above with DEBUG=hafas-client
; It will print the raw (JSON) HAFAS request & response bodies; Paste these here, so that we can have a look if the cancelled trip is actually in the data.
Also, we should check if the routing mode, which is set to "do routing on realtime data" by hafas-client
, affects this trip. It might be that the DB Navigator app requests with FULL
(or some special DB-specific mode).
Hi @derhuerst,
thanks for the tips! I did some further research and looked for canceled trains. Luckily, there are a lot of cancelled S-Bahn connections between Stuttgart University and Stuttgart Mainstation 😂
Using the debug option, I tried the following prompt:
let {createDbHafas} = await import('db-hafas'); // REPL
let hafas = createDbHafas('test@test.com')
let journeys = await hafas.journeys('8006513', '8000096', {
results: 5,
departure: new Date("2023-04-05T19:39:00+02:00"),
remarks: true
})
console.log(JSON.stringify(journeys, null, 4))
Again, the resulting raw response did not include the cancelled 19:39 train (see image). Note that realtime data vanishes like 60-90mins after departure (or arrival). So, reproducing this example might not be possible.
However, I also logged the network request from the iOS DB Navigator app with the Charles app and found out, that it's raw response did include the cancelled trains. Further inspecting the iOS request header showed, that the mobile app is now using the HYBRID
routing mode (see image below).
I then changed the routing mode to HYBRID
in /p/db/index.js and db-hafas
was able to also show the cancelled train. They were also correctly labelled and got the "cancelled": true
information in the journey (see image).
So should we include a mechanism to allow changing the rtMode
?
Thanks for looking into this!
Conceptually, and assuming that the explanation on HAFAS routing modes that someone has posted is accurate, this makes sense:
HYBRID
AND FULL
search on plan/schedule data, therefore also find cancelled connections.REALTIME
does routing on realtime data, so cancelled journeys shouldn't ever show up because they are not feasible ways to get from origin to destination.I think that when doing a journeys()
query ("I want to go from A to B at a specific point in time"), I'd argue most users want the REALTIME
behaviour.
But given that, to my knowledge, HAFAS doesn't provide sufficiently powerful APIs to query those cancelled trips/journeys for use cases that do require them (e.g. "Can I get from A to B as usual today?"), I think we should make rtMode
configurable.
I would happily merge a PR that adds an option! If you want to tackle this, please check if rtMode
works with other endpoints too, of if it is DB-specific.
There is another aspect to this:
It seem like that, with rtMode: REALTIME
, pagination (via earlierRef
a.k.a. outCtxScrB
& laterRef
a.k.a. outCtxScrF
) is not possible! So effectively, there is no reliable way to do a 2nd call to get more than the initial set of journeys. This is another reason why we should make rtMode
user-configurable IMO.
I would gladly accept a PR that adds an option rtMode
to journeys()
; It would be sufficient to just 1) add an entry realtimeRouting: true
to opt
's defaults, and b) check ctx.opt.realtimeRouting
in transformReqBody()
. Also, documenting this in p/db/readme.md
would be helpful.
Thanks for the suggestions 👍 I once had a quick look but didn't figure out the options handling. Now it's clearer.
p/bls/example.js
, for example, throws an error if I change the rtMode
to HYBRID
in the same way that worked for db
.
hafasMessage: 'HCI Core: Parse fail : Parser error: root.svcReqL.svcReqL.cfg.rtMode(HYBRID)'
opt.realtimeRouting
in journeys()
then doesn't have any effect. Is that the correct plan?[...] It would be sufficient to just 1) add an entry
realtimeRouting: true
toopt
's defaults [...].Wouldn't it be better to allow for all the strings of https://pastebin.com/qZ9WS3Cx instead of just a bool-switch?
My idea behind opt.realtimeRouting: true
was that it's a more intuitive API and that almost all people probably don't need the flexibility that the HAFAS routing modi provide. But maybe my gut feeling is wrong, and it makes sense to expose the modi as-is (but behind properly named constants, similar to how it's done with DB's traveller age groups). What do you think?
- I think that [
rtMode: HYBRID
] does not work with all endpoints.. Thep/bls/example.js
, for example, throws an error […].
It's likely specific to the DB endpoint, given that they have historically often had some cusomisations done to HAFAS; Or it's specific to some (multiple individual) endpoints, not sure.
- So let's test which endpoints are affected and for the unaffected ones, the
opt.realtimeRouting
injourneys()
then doesn't have any effect. Is that the correct plan?
My idea would be to only recognise the opt.realtimeRouting
/opt.routingMode
field in those profiles whose HAFAS endpoints support it, just like how the DB profile currently always sets rtMode: HYBRID
:
I would also assume that most people want the realtime, but just thought about what the other option should be if realtimeRouting: false
is set.
So should it be FULL
, INFO
, OFF
or the actual data that is shown on the mobile app with HYBRID
. So a binary switch for these five options (currently) doesn't sound right 😄 I personally like the idea of exposing everything via the constants (age-group style). It's the same construction as for the loyality cards right?
If we decide to export all modi, then there no need to add something to the default opt
s, right? Since it's endpoint specific, we can apply the same strategy as for the loyality cards, as explained here. Is that a good idea?
[…] via the constants (age-group style). It's the same construction as for the loyality cards right?
Yes, pretty much. I like the use of Symbol
s (as with the loyalty cards) even more, because this API is harder to use in a wrong way, but Symbol
s don't work well with serialisation, e.g. in hafas-client-rpc
, so I now prefer the age-groups style (plain string constants).
If we decide to export all modi, then there no need to add something to the default
opt
s, right? Since it's endpoint specific, we can apply the same strategy as for the loyality cards, as explained here. Is that a good idea?
Yes. I would just make the constants available via lib/routing-modes.js
.
I have published the fix (#295) as hafas-client@6.1.0
. 🎉
I noticed that some Deutsche Bahn journeys are missing in the response. Especially, canceled trains seem to not show up.
For example, the ICE 595 from Mannheim to Stuttgart today at 12:30 (
2023-04-02T12:30:00+02:00
) is missing in the response, although it is listed in thereiseauskunft.bahn.de
and in the DB Navigator App (see images below).I try to use the API with the following code:
The result is:
In the response, the cancelled train at 12:30 is missing. Am I doing something wrong or miss a parameter to also include cancelled trains?
When researching, I also found the
bahn.expert
website where the specific train is also missing in https://bahn.expert/routing/8000244/8000096/2023-04-02T10:14:28.904Z/DB Website:
DB Navigator:
Bahn Expert: