line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Travel::Status::DE::IRIS::Result; |
2
|
|
|
|
|
|
|
|
3
|
7
|
|
|
7
|
|
61
|
use strict; |
|
7
|
|
|
|
|
24
|
|
|
7
|
|
|
|
|
223
|
|
4
|
7
|
|
|
7
|
|
62
|
use warnings; |
|
7
|
|
|
|
|
23
|
|
|
7
|
|
|
|
|
182
|
|
5
|
7
|
|
|
7
|
|
178
|
use 5.014; |
|
7
|
|
|
|
|
28
|
|
6
|
7
|
|
|
7
|
|
51
|
use utf8; |
|
7
|
|
|
|
|
17
|
|
|
7
|
|
|
|
|
69
|
|
7
|
|
|
|
|
|
|
|
8
|
7
|
|
|
7
|
|
258
|
no if $] >= 5.018, warnings => 'experimental::smartmatch'; |
|
7
|
|
|
|
|
18
|
|
|
7
|
|
|
|
|
92
|
|
9
|
|
|
|
|
|
|
|
10
|
7
|
|
|
7
|
|
572
|
use parent 'Class::Accessor'; |
|
7
|
|
|
|
|
19
|
|
|
7
|
|
|
|
|
51
|
|
11
|
7
|
|
|
7
|
|
19146
|
use Carp qw(cluck); |
|
7
|
|
|
|
|
17
|
|
|
7
|
|
|
|
|
457
|
|
12
|
7
|
|
|
7
|
|
60
|
use DateTime; |
|
7
|
|
|
|
|
34
|
|
|
7
|
|
|
|
|
242
|
|
13
|
7
|
|
|
7
|
|
38
|
use DateTime::Format::Strptime; |
|
7
|
|
|
|
|
14
|
|
|
7
|
|
|
|
|
62
|
|
14
|
7
|
|
|
7
|
|
6951
|
use List::Compare; |
|
7
|
|
|
|
|
164259
|
|
|
7
|
|
|
|
|
306
|
|
15
|
7
|
|
|
7
|
|
71
|
use List::MoreUtils qw(none uniq lastval); |
|
7
|
|
|
|
|
65
|
|
|
7
|
|
|
|
|
90
|
|
16
|
7
|
|
|
7
|
|
6595
|
use Scalar::Util qw(weaken); |
|
7
|
|
|
|
|
18
|
|
|
7
|
|
|
|
|
37681
|
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
our $VERSION = '1.89'; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
Travel::Status::DE::IRIS::Result->mk_ro_accessors( |
21
|
|
|
|
|
|
|
qw(arrival arrival_delay arrival_has_realtime arrival_is_additional arrival_is_cancelled arrival_hidden |
22
|
|
|
|
|
|
|
date datetime delay |
23
|
|
|
|
|
|
|
departure departure_delay departure_has_realtime departure_is_additional departure_is_cancelled departure_hidden |
24
|
|
|
|
|
|
|
ds100 has_realtime is_transfer is_unscheduled is_wing |
25
|
|
|
|
|
|
|
line_no old_train_id old_train_no operator platform raw_id |
26
|
|
|
|
|
|
|
realtime_xml route_start route_end |
27
|
|
|
|
|
|
|
sched_arrival sched_departure sched_platform sched_route_start |
28
|
|
|
|
|
|
|
sched_route_end start |
29
|
|
|
|
|
|
|
station station_uic |
30
|
|
|
|
|
|
|
stop_no time train_id train_no transfer type |
31
|
|
|
|
|
|
|
unknown_t unknown_o wing_id wing_of) |
32
|
|
|
|
|
|
|
); |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# {{{ Data (message codes, station fixups) |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
my %translation = ( |
37
|
|
|
|
|
|
|
1 => 'Nähere Informationen in Kürze', |
38
|
|
|
|
|
|
|
2 => 'Polizeieinsatz', |
39
|
|
|
|
|
|
|
3 => 'Feuerwehreinsatz auf der Strecke', |
40
|
|
|
|
|
|
|
4 => 'Kurzfristiger Personalausfall', # xlsx: missing |
41
|
|
|
|
|
|
|
5 => 'Ärztliche Versorgung eines Fahrgastes', |
42
|
|
|
|
|
|
|
6 => 'Betätigen der Notbremse', # xlsx: "Unbefugtes Ziehen der Notbremse" |
43
|
|
|
|
|
|
|
7 => 'Unbefugte Personen auf der Strecke', |
44
|
|
|
|
|
|
|
8 => 'Notarzteinsatz auf der Strecke', |
45
|
|
|
|
|
|
|
9 => 'Streikauswirkungen', |
46
|
|
|
|
|
|
|
10 => 'Tiere auf der Strecke', |
47
|
|
|
|
|
|
|
11 => 'Unwetter', |
48
|
|
|
|
|
|
|
12 => 'Warten auf ein verspätetes Schiff', |
49
|
|
|
|
|
|
|
13 => 'Pass- und Zollkontrolle', |
50
|
|
|
|
|
|
|
14 => 'Defekt am Bahnhof', # xlsx: "Technischer Defekt am Bahnhof" |
51
|
|
|
|
|
|
|
15 => 'Beeinträchtigung durch Vandalismus', |
52
|
|
|
|
|
|
|
16 => 'Entschärfung einer Fliegerbombe', |
53
|
|
|
|
|
|
|
17 => 'Beschädigung einer Brücke', |
54
|
|
|
|
|
|
|
18 => 'Umgestürzter Baum auf der Strecke', |
55
|
|
|
|
|
|
|
19 => 'Unfall an einem Bahnübergang', |
56
|
|
|
|
|
|
|
20 => 'Tiere im Gleis', # xlsx: missing |
57
|
|
|
|
|
|
|
21 => 'Warten auf Anschlussreisende', |
58
|
|
|
|
|
|
|
22 => 'Witterungsbedingte Beeinträchtigung', |
59
|
|
|
|
|
|
|
23 => 'Feuerwehreinsatz auf Bahngelände', # xlsx: missing |
60
|
|
|
|
|
|
|
24 => 'Verspätung im Ausland', |
61
|
|
|
|
|
|
|
25 => 'Bereitstellung weiterer Wagen', |
62
|
|
|
|
|
|
|
26 => 'Abhängen von Wagen', |
63
|
|
|
|
|
|
|
28 => 'Gegenstände auf der Strecke', |
64
|
|
|
|
|
|
|
29 => 'Ersatzverkehr mit Bus ist eingerichtet', |
65
|
|
|
|
|
|
|
31 => 'Bauarbeiten', |
66
|
|
|
|
|
|
|
32 => 'Verzögerung beim Ein-/Ausstieg' |
67
|
|
|
|
|
|
|
, # xlsx: "Unterstützung beim Ein- und Ausstieg" |
68
|
|
|
|
|
|
|
33 => 'Defekt an der Oberleitung', # xlsx: "Reparatur an der Oberleitung" |
69
|
|
|
|
|
|
|
34 => 'Defekt an einem Signal', # xlsx: "Reparatur an einem Signal" |
70
|
|
|
|
|
|
|
35 => 'Streckensperrung', |
71
|
|
|
|
|
|
|
36 => 'Defekt am Zug', # xlsx: "Reparatur am Zug" |
72
|
|
|
|
|
|
|
37 => 'Defekt am Wagen', # xlsx: missing |
73
|
|
|
|
|
|
|
38 => 'Defekt an der Strecke', # xlsx: "Reparatur an der Strecke" |
74
|
|
|
|
|
|
|
39 => 'Anhängen von zusätzlichen Wagen', # xlsx: missing |
75
|
|
|
|
|
|
|
40 => 'Defektes Stellwerk', |
76
|
|
|
|
|
|
|
41 => 'Defekt an einem Bahnübergang' |
77
|
|
|
|
|
|
|
, # xlsx: "Technischer Defekt an einem Bahnüburgang" |
78
|
|
|
|
|
|
|
42 => 'Außerplanmäßige Geschwindigkeitsbeschränkung' |
79
|
|
|
|
|
|
|
, # xlsx: "Vorübergehend verminderte Geschwindigkeit auf der Strecke" |
80
|
|
|
|
|
|
|
43 => 'Verspätung eines vorausfahrenden Zuges', |
81
|
|
|
|
|
|
|
44 => 'Warten auf einen entgegenkommenden Zug', |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
# TODO for Oct 2021: switch 45, 46 to "Vorfahrt eines anderen Zuges" |
84
|
|
|
|
|
|
|
45 => 'Überholung durch anderen Zug', # xlsx: "Vorfahrt eines anderen Zuges" |
85
|
|
|
|
|
|
|
46 => 'Warten auf freie Einfahrt', # xlsx: "Vorfahrt eines anderen Zuges" |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
47 => |
88
|
|
|
|
|
|
|
'Verspätete Bereitstellung', # xlsx: "Verspätete Bereitstellung des Zuges" |
89
|
|
|
|
|
|
|
48 => 'Verspätung aus vorheriger Fahrt', |
90
|
|
|
|
|
|
|
49 => 'Kurzfristiger Personalausfall', |
91
|
|
|
|
|
|
|
50 => 'Kurzfristige Erkrankung von Personal', |
92
|
|
|
|
|
|
|
51 => 'Verspätetes Personal aus vorheriger Fahrt', |
93
|
|
|
|
|
|
|
52 => 'Streik', |
94
|
|
|
|
|
|
|
53 => 'Unwetterauswirkungen', |
95
|
|
|
|
|
|
|
54 => 'Verfügbarkeit der Gleise derzeit eingeschränkt', |
96
|
|
|
|
|
|
|
55 => 'Defekt an einem anderen Zug', |
97
|
|
|
|
|
|
|
56 => 'Warten auf Anschlussreisende', # aus einem Bus |
98
|
|
|
|
|
|
|
57 => 'Zusätzlicher Halt', # xslx: "Zusätzlicher Halt zum Ein- und Ausstieg" |
99
|
|
|
|
|
|
|
58 => 'Umleitung', # xlsx: "Umleitung des Zuges" |
100
|
|
|
|
|
|
|
59 => 'Schnee und Eis', |
101
|
|
|
|
|
|
|
60 => 'Witterungsbedingt verminderte Geschwindigkeit', |
102
|
|
|
|
|
|
|
61 => 'Defekte Tür', |
103
|
|
|
|
|
|
|
62 => 'Behobener Defekt am Zug', # r 36 |
104
|
|
|
|
|
|
|
63 => 'Technische Untersuchung am Zug', |
105
|
|
|
|
|
|
|
64 => 'Defekt an einer Weiche', # xlsx: "Reparatur an der Weiche" |
106
|
|
|
|
|
|
|
65 => 'Erdrutsch', |
107
|
|
|
|
|
|
|
66 => 'Hochwasser', |
108
|
|
|
|
|
|
|
67 => 'Behördliche Maßnahme', |
109
|
|
|
|
|
|
|
68 => 'Hohes Fahrgastaufkommen' |
110
|
|
|
|
|
|
|
, # xlsx: "Hohes Fahrgastaufkommen verlängert Ein- und Ausstieg" |
111
|
|
|
|
|
|
|
69 => 'Zug verkehrt mit verminderter Geschwindigeit', |
112
|
|
|
|
|
|
|
70 => 'WLAN nicht verfügbar', |
113
|
|
|
|
|
|
|
71 => 'WLAN in einzelnen Wagen nicht verfügbar', |
114
|
|
|
|
|
|
|
72 => 'Info/Entertainment nicht verfügbar', |
115
|
|
|
|
|
|
|
73 => 'Heute: Mehrzweckabteil vorne', # r 74 |
116
|
|
|
|
|
|
|
74 => 'Heute: Mehrzweckabteil hinten', # r 73 |
117
|
|
|
|
|
|
|
75 => 'Heute: 1. Klasse vorne', # r 76 |
118
|
|
|
|
|
|
|
76 => 'Heute: 1. Klasse hinten', # r 75 |
119
|
|
|
|
|
|
|
77 => '1. Klasse fehlt', |
120
|
|
|
|
|
|
|
78 => 'Ersatzverkehr mit Bus ist eingerichtet', |
121
|
|
|
|
|
|
|
79 => 'Mehrzweckabteil fehlt', |
122
|
|
|
|
|
|
|
80 => 'Abweichende Wagenreihung', |
123
|
|
|
|
|
|
|
81 => 'Fahrzeugtausch', |
124
|
|
|
|
|
|
|
82 => 'Mehrere Wagen fehlen', |
125
|
|
|
|
|
|
|
83 => 'Defekte fahrzeuggebundene Einstiegshilfe', |
126
|
|
|
|
|
|
|
84 => 'Zug verkehrt richtig gereiht', # r 80 82 85 |
127
|
|
|
|
|
|
|
85 => 'Ein Wagen fehlt', |
128
|
|
|
|
|
|
|
86 => 'Gesamter Zug ohne Reservierung', |
129
|
|
|
|
|
|
|
87 => 'Einzelne Wagen ohne Reservierung', |
130
|
|
|
|
|
|
|
88 => 'Keine Qualitätsmängel', # r 80 82 83 85 86 87 90 91 92 93 96 97 98 |
131
|
|
|
|
|
|
|
89 => 'Reservierungen sind wieder vorhanden', # -> 86 87 |
132
|
|
|
|
|
|
|
90 => 'Kein gastronomisches Angebot', |
133
|
|
|
|
|
|
|
91 => 'Fahrradmitnahme nicht möglich', |
134
|
|
|
|
|
|
|
92 => 'Eingeschränkte Fahrradbeförderung', |
135
|
|
|
|
|
|
|
93 => 'Behindertengerechte Einrichtung fehlt', |
136
|
|
|
|
|
|
|
94 => 'Ersatzbewirtschaftung', |
137
|
|
|
|
|
|
|
95 => 'Universal-WC fehlt', |
138
|
|
|
|
|
|
|
96 => 'Der Zug ist stark überbesetzt', # r 97 |
139
|
|
|
|
|
|
|
97 => 'Der Zug ist überbesetzt', # r 96 |
140
|
|
|
|
|
|
|
98 => 'Sonstige Qualitätsmängel', |
141
|
|
|
|
|
|
|
99 => 'Verzögerungen im Betriebsablauf', |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
# Occasionally, there's a message with ID 900. In all cases observed so far, |
144
|
|
|
|
|
|
|
# it was used for "Anschlussbus wartet". However, as we don't know which bus |
145
|
|
|
|
|
|
|
# it refers to, we don't show it to users. |
146
|
|
|
|
|
|
|
); |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
# IRIS may return "Betriebsstelle nicht bekannt" for some recently added |
149
|
|
|
|
|
|
|
# stations. Fix those manually. |
150
|
|
|
|
|
|
|
my %fixup = ( |
151
|
|
|
|
|
|
|
8002795 => 'Herten(Westf)', |
152
|
|
|
|
|
|
|
8003983 => 'Merklingen - Schwäbische Alb', |
153
|
|
|
|
|
|
|
8005493 => 'Schwetzingen-Hirschacker', |
154
|
|
|
|
|
|
|
8070678 => 'Metzingen-Neuhausen', |
155
|
|
|
|
|
|
|
); |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
# }}} |
158
|
|
|
|
|
|
|
# {{{ Constructor |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
sub new { |
161
|
1140
|
|
|
1140
|
1
|
9623
|
my ( $obj, %opt ) = @_; |
162
|
|
|
|
|
|
|
|
163
|
1140
|
|
|
|
|
2406
|
my $ref = \%opt; |
164
|
|
|
|
|
|
|
|
165
|
1140
|
|
|
|
|
9029
|
my ( $train_id, $start_ts, $stop_no ) = split( /.\K-/, $opt{raw_id} ); |
166
|
|
|
|
|
|
|
|
167
|
1140
|
|
|
|
|
2813
|
bless( $ref, $obj ); |
168
|
|
|
|
|
|
|
|
169
|
1140
|
|
33
|
|
|
3023
|
$ref->{strptime_obj} //= DateTime::Format::Strptime->new( |
170
|
|
|
|
|
|
|
pattern => '%y%m%d%H%M', |
171
|
|
|
|
|
|
|
time_zone => 'Europe/Berlin', |
172
|
|
|
|
|
|
|
); |
173
|
|
|
|
|
|
|
|
174
|
1140
|
|
|
|
|
3871
|
$ref->{wing_id} = "${train_id}-${start_ts}"; |
175
|
1140
|
|
|
|
|
2243
|
$ref->{is_wing} = 0; |
176
|
1140
|
|
|
|
|
3716
|
$train_id =~ s{^-}{}; |
177
|
|
|
|
|
|
|
|
178
|
1140
|
|
|
|
|
2974
|
$ref->{start} = $ref->parse_ts($start_ts); |
179
|
|
|
|
|
|
|
|
180
|
1140
|
|
|
|
|
1031591
|
$ref->{train_id} = $train_id; |
181
|
1140
|
|
|
|
|
2731
|
$ref->{stop_no} = $stop_no; |
182
|
|
|
|
|
|
|
|
183
|
1140
|
100
|
|
|
|
3101
|
if ( $opt{transfer} ) { |
184
|
24
|
|
|
|
|
157
|
my ($transfer) = split( /.\K-/, $opt{transfer} ); |
185
|
24
|
|
|
|
|
92
|
$transfer =~ s{^-}{}; |
186
|
24
|
|
|
|
|
52
|
$ref->{transfer} = $transfer; |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
my $ar = $ref->{arrival} = $ref->{sched_arrival} |
190
|
1140
|
|
|
|
|
2994
|
= $ref->parse_ts( $opt{arrival_ts} ); |
191
|
|
|
|
|
|
|
my $dp = $ref->{departure} = $ref->{sched_departure} |
192
|
1140
|
|
|
|
|
874282
|
= $ref->parse_ts( $opt{departure_ts} ); |
193
|
|
|
|
|
|
|
|
194
|
1140
|
50
|
66
|
|
|
829498
|
if ( not( defined $ar or defined $dp ) ) { |
195
|
|
|
|
|
|
|
cluck( |
196
|
|
|
|
|
|
|
sprintf( |
197
|
|
|
|
|
|
|
"Neither arrival '%s' nor departure '%s' are valid " |
198
|
|
|
|
|
|
|
. "timestamps - can't handle this train", |
199
|
|
|
|
|
|
|
$opt{arrival_ts}, $opt{departure_ts} |
200
|
|
|
|
|
|
|
) |
201
|
0
|
|
|
|
|
0
|
); |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
|
204
|
1140
|
|
66
|
|
|
3926
|
my $dt = $ref->{datetime} = $dp // $ar; |
205
|
|
|
|
|
|
|
|
206
|
1140
|
|
|
|
|
6331
|
$ref->{date} = $dt->strftime('%d.%m.%Y'); |
207
|
1140
|
|
|
|
|
65129
|
$ref->{time} = $dt->strftime('%H:%M'); |
208
|
1140
|
|
|
|
|
40092
|
$ref->{epoch} = $dt->epoch; |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
$ref->{route_pre} = $ref->{sched_route_pre} |
211
|
1140
|
|
100
|
|
|
23574
|
= [ split( qr{[|]}, $ref->{route_pre} // q{} ) ]; |
212
|
|
|
|
|
|
|
$ref->{route_post} = $ref->{sched_route_post} |
213
|
1140
|
|
100
|
|
|
13596
|
= [ split( qr{[|]}, $ref->{route_post} // q{} ) ]; |
214
|
|
|
|
|
|
|
|
215
|
1140
|
|
|
|
|
4875
|
$ref->fixup_route( $ref->{route_pre} ); |
216
|
1140
|
|
|
|
|
3018
|
$ref->fixup_route( $ref->{route_post} ); |
217
|
|
|
|
|
|
|
|
218
|
1140
|
100
|
|
|
|
3090
|
$ref->{route_pre_incomplete} = $ref->{route_end} ? 1 : 0; |
219
|
1140
|
50
|
|
|
|
2647
|
$ref->{route_post_incomplete} = $ref->{route_post} ? 1 : 0; |
220
|
|
|
|
|
|
|
|
221
|
1140
|
|
|
|
|
2386
|
$ref->{sched_platform} = $ref->{platform}; |
222
|
|
|
|
|
|
|
$ref->{route_end} |
223
|
|
|
|
|
|
|
= $ref->{sched_route_end} |
224
|
|
|
|
|
|
|
= $ref->{route_end} |
225
|
|
|
|
|
|
|
|| $ref->{route_post}[-1] |
226
|
1140
|
|
66
|
|
|
5943
|
|| $ref->{station}; |
227
|
|
|
|
|
|
|
$ref->{route_start} |
228
|
|
|
|
|
|
|
= $ref->{sched_route_start} |
229
|
|
|
|
|
|
|
= $ref->{route_start} |
230
|
|
|
|
|
|
|
|| $ref->{route_pre}[0] |
231
|
1140
|
|
66
|
|
|
4761
|
|| $ref->{station}; |
232
|
|
|
|
|
|
|
|
233
|
1140
|
|
|
|
|
3967
|
return $ref; |
234
|
|
|
|
|
|
|
} |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
# }}} |
237
|
|
|
|
|
|
|
# {{{ Internal Helpers |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
sub fixup_route { |
240
|
3012
|
|
|
3012
|
0
|
5779
|
my ( $self, $route ) = @_; |
241
|
3012
|
|
|
|
|
4331
|
for my $stop ( @{$route} ) { |
|
3012
|
|
|
|
|
6427
|
|
242
|
27180
|
50
|
|
|
|
49588
|
if ( $stop =~ m{^Betriebsstelle nicht bekannt (\d+)$} ) { |
243
|
0
|
0
|
|
|
|
0
|
if ( $fixup{$1} ) { |
244
|
0
|
|
|
|
|
0
|
$stop = $fixup{$1}; |
245
|
|
|
|
|
|
|
} |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
} |
248
|
|
|
|
|
|
|
} |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
sub parse_ts { |
251
|
5011
|
|
|
5011
|
0
|
10548
|
my ( $self, $string ) = @_; |
252
|
|
|
|
|
|
|
|
253
|
5011
|
100
|
|
|
|
11081
|
if ( defined $string ) { |
254
|
4655
|
|
|
|
|
15075
|
return $self->{strptime_obj}->parse_datetime($string); |
255
|
|
|
|
|
|
|
} |
256
|
356
|
|
|
|
|
954
|
return; |
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
# List::Compare does not keep the order of its arguments (even with unsorted). |
260
|
|
|
|
|
|
|
# So we need to re-sort all stops to maintain their original order. |
261
|
|
|
|
|
|
|
sub sorted_sublist { |
262
|
0
|
|
|
0
|
0
|
0
|
my ( $self, $list, $sublist ) = @_; |
263
|
0
|
|
|
|
|
0
|
my %pos; |
264
|
|
|
|
|
|
|
|
265
|
0
|
0
|
0
|
|
|
0
|
if ( not $sublist or not @{$sublist} ) { |
|
0
|
|
|
|
|
0
|
|
266
|
0
|
|
|
|
|
0
|
return; |
267
|
|
|
|
|
|
|
} |
268
|
|
|
|
|
|
|
|
269
|
0
|
|
|
|
|
0
|
for my $i ( 0 .. $#{$list} ) { |
|
0
|
|
|
|
|
0
|
|
270
|
0
|
|
|
|
|
0
|
$pos{ $list->[$i] } = $i; |
271
|
|
|
|
|
|
|
} |
272
|
|
|
|
|
|
|
|
273
|
0
|
|
|
|
|
0
|
my @sorted = sort { $pos{$a} <=> $pos{$b} } @{$sublist}; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
274
|
|
|
|
|
|
|
|
275
|
0
|
|
|
|
|
0
|
return @sorted; |
276
|
|
|
|
|
|
|
} |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
sub superseded_messages { |
279
|
3
|
|
|
3
|
0
|
8
|
my ( $self, $msg ) = @_; |
280
|
3
|
|
|
|
|
26
|
my %superseded = ( |
281
|
|
|
|
|
|
|
62 => [36], |
282
|
|
|
|
|
|
|
73 => [74], |
283
|
|
|
|
|
|
|
74 => [73], |
284
|
|
|
|
|
|
|
75 => [76], |
285
|
|
|
|
|
|
|
76 => [75], |
286
|
|
|
|
|
|
|
84 => [ 80, 82, 85 ], |
287
|
|
|
|
|
|
|
88 => [ 80, 82, 83, 85, 86, 87, 90, 91, 92, 93, 96, 97, 98 ], |
288
|
|
|
|
|
|
|
89 => [ 86, 87 ], |
289
|
|
|
|
|
|
|
96 => [97], |
290
|
|
|
|
|
|
|
97 => [96], |
291
|
|
|
|
|
|
|
); |
292
|
|
|
|
|
|
|
|
293
|
3
|
|
50
|
|
|
5
|
return @{ $superseded{$msg} // [] }; |
|
3
|
|
|
|
|
28
|
|
294
|
|
|
|
|
|
|
} |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
# }}} |
297
|
|
|
|
|
|
|
# {{{ Internal Setters for IRIS.pm |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
sub set_ar { |
300
|
760
|
|
|
760
|
0
|
39441
|
my ( $self, %attrib ) = @_; |
301
|
|
|
|
|
|
|
|
302
|
760
|
100
|
100
|
|
|
3338
|
if ( $attrib{status} and $attrib{status} eq 'c' ) { |
|
|
50
|
66
|
|
|
|
|
303
|
54
|
|
|
|
|
166
|
$self->{has_realtime} = $self->{arrival_has_realtime} = 1; |
304
|
54
|
|
|
|
|
118
|
$self->{arrival_is_cancelled} = 1; |
305
|
|
|
|
|
|
|
} |
306
|
|
|
|
|
|
|
elsif ( $attrib{status} and $attrib{status} eq 'a' ) { |
307
|
0
|
|
|
|
|
0
|
$self->{arrival_is_additional} = 1; |
308
|
|
|
|
|
|
|
} |
309
|
|
|
|
|
|
|
else { |
310
|
706
|
|
|
|
|
1621
|
$self->{arrival_is_additional} = 0; |
311
|
706
|
|
|
|
|
1852
|
$self->{arrival_is_cancelled} = 0; |
312
|
|
|
|
|
|
|
} |
313
|
|
|
|
|
|
|
|
314
|
760
|
50
|
|
|
|
1555
|
if ( $attrib{arrival_hidden} ) { |
315
|
0
|
|
|
|
|
0
|
$self->{arrival_hidden} = $attrib{arrival_hidden}; |
316
|
|
|
|
|
|
|
} |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
# unscheduled arrivals may not appear in the plan, but we do need to |
319
|
|
|
|
|
|
|
# know their planned arrival time |
320
|
760
|
100
|
|
|
|
1534
|
if ( $attrib{plan_arrival_ts} ) { |
321
|
|
|
|
|
|
|
$self->{sched_arrival} |
322
|
184
|
|
|
|
|
540
|
= $self->parse_ts( $attrib{plan_arrival_ts} ); |
323
|
|
|
|
|
|
|
} |
324
|
|
|
|
|
|
|
|
325
|
760
|
100
|
|
|
|
169520
|
if ( $attrib{arrival_ts} ) { |
326
|
648
|
|
|
|
|
1614
|
$self->{has_realtime} = $self->{arrival_has_realtime} = 1; |
327
|
648
|
|
|
|
|
1677
|
$self->{arrival} = $self->parse_ts( $attrib{arrival_ts} ); |
328
|
648
|
100
|
|
|
|
585786
|
if ( not $self->{arrival_is_cancelled} ) { |
329
|
|
|
|
|
|
|
$self->{delay} = $self->{arrival_delay} |
330
|
640
|
|
|
|
|
2072
|
= $self->arrival->subtract_datetime( $self->sched_arrival ) |
331
|
|
|
|
|
|
|
->in_units('minutes'); |
332
|
|
|
|
|
|
|
} |
333
|
|
|
|
|
|
|
} |
334
|
|
|
|
|
|
|
else { |
335
|
112
|
|
|
|
|
443
|
$self->{arrival} = $self->{sched_arrival}; |
336
|
112
|
|
50
|
|
|
535
|
$self->{arrival_delay} //= 0; |
337
|
112
|
|
50
|
|
|
372
|
$self->{delay} //= 0; |
338
|
|
|
|
|
|
|
} |
339
|
|
|
|
|
|
|
|
340
|
760
|
100
|
|
|
|
324605
|
if ( $attrib{platform} ) { |
341
|
14
|
|
|
|
|
94
|
$self->{platform} = $attrib{platform}; |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
else { |
344
|
746
|
|
|
|
|
3199
|
$self->{platform} = $self->{sched_platform}; |
345
|
|
|
|
|
|
|
} |
346
|
|
|
|
|
|
|
|
347
|
760
|
100
|
|
|
|
1647
|
if ( defined $attrib{route_pre} ) { |
348
|
190
|
|
50
|
|
|
2476
|
$self->{route_pre} = [ split( qr{[|]}, $attrib{route_pre} // q{} ) ]; |
349
|
190
|
|
|
|
|
932
|
$self->fixup_route( $self->{route_pre} ); |
350
|
190
|
100
|
|
|
|
316
|
if ( @{ $self->{route_pre} } ) { |
|
190
|
|
|
|
|
522
|
|
351
|
144
|
|
|
|
|
550
|
$self->{route_start} = $self->{route_pre}[0]; |
352
|
|
|
|
|
|
|
} |
353
|
|
|
|
|
|
|
} |
354
|
|
|
|
|
|
|
else { |
355
|
570
|
|
|
|
|
1424
|
$self->{route_pre} = $self->{sched_route_pre}; |
356
|
570
|
|
|
|
|
1527
|
$self->{route_start} = $self->{sched_route_start}; |
357
|
|
|
|
|
|
|
} |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
# also only for unscheduled arrivals |
360
|
760
|
100
|
|
|
|
1743
|
if ( $attrib{sched_route_pre} ) { |
361
|
|
|
|
|
|
|
$self->{sched_route_pre} |
362
|
184
|
|
50
|
|
|
2446
|
= [ split( qr{[|]}, $attrib{sched_route_pre} // q{} ) ]; |
363
|
184
|
|
|
|
|
833
|
$self->fixup_route( $self->{sched_route_pre} ); |
364
|
184
|
|
|
|
|
448
|
$self->{sched_route_start} = $self->{sched_route_pre}[0]; |
365
|
|
|
|
|
|
|
} |
366
|
|
|
|
|
|
|
|
367
|
760
|
|
|
|
|
2707
|
return $self; |
368
|
|
|
|
|
|
|
} |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
sub set_dp { |
371
|
686
|
|
|
686
|
0
|
33173
|
my ( $self, %attrib ) = @_; |
372
|
|
|
|
|
|
|
|
373
|
686
|
100
|
100
|
|
|
2832
|
if ( $attrib{status} and $attrib{status} eq 'c' ) { |
|
|
50
|
66
|
|
|
|
|
374
|
53
|
|
|
|
|
138
|
$self->{has_realtime} = $self->{arrival_has_realtime} = 1; |
375
|
53
|
|
|
|
|
124
|
$self->{departure_is_cancelled} = 1; |
376
|
|
|
|
|
|
|
} |
377
|
|
|
|
|
|
|
elsif ( $attrib{status} and $attrib{status} eq 'a' ) { |
378
|
0
|
|
|
|
|
0
|
$self->{departure_is_additional} = 1; |
379
|
|
|
|
|
|
|
} |
380
|
|
|
|
|
|
|
else { |
381
|
633
|
|
|
|
|
1264
|
$self->{departure_is_additional} = 0; |
382
|
633
|
|
|
|
|
1259
|
$self->{departure_is_cancelled} = 0; |
383
|
|
|
|
|
|
|
} |
384
|
|
|
|
|
|
|
|
385
|
686
|
50
|
|
|
|
1457
|
if ( $attrib{departure_hidden} ) { |
386
|
0
|
|
|
|
|
0
|
$self->{departure_hidden} = $attrib{departure_hidden}; |
387
|
|
|
|
|
|
|
} |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
# unscheduled arrivals may not appear in the plan, but we do need to |
390
|
|
|
|
|
|
|
# know their planned arrival time |
391
|
686
|
100
|
|
|
|
1320
|
if ( $attrib{plan_departure_ts} ) { |
392
|
|
|
|
|
|
|
$self->{sched_departure} |
393
|
176
|
|
|
|
|
505
|
= $self->parse_ts( $attrib{plan_departure_ts} ); |
394
|
|
|
|
|
|
|
} |
395
|
|
|
|
|
|
|
|
396
|
686
|
100
|
|
|
|
158242
|
if ( $attrib{departure_ts} ) { |
397
|
572
|
|
|
|
|
1246
|
$self->{has_realtime} = $self->{departure_has_realtime} = 1; |
398
|
572
|
|
|
|
|
1467
|
$self->{departure} = $self->parse_ts( $attrib{departure_ts} ); |
399
|
572
|
100
|
|
|
|
509839
|
if ( not $self->{departure_is_cancelled} ) { |
400
|
|
|
|
|
|
|
$self->{delay} = $self->{departure_delay} |
401
|
564
|
|
|
|
|
1842
|
= $self->departure->subtract_datetime( $self->sched_departure ) |
402
|
|
|
|
|
|
|
->in_units('minutes'); |
403
|
|
|
|
|
|
|
} |
404
|
|
|
|
|
|
|
} |
405
|
|
|
|
|
|
|
else { |
406
|
114
|
|
|
|
|
343
|
$self->{departure} = $self->{sched_departure}; |
407
|
114
|
|
100
|
|
|
317
|
$self->{delay} //= 0; |
408
|
114
|
|
50
|
|
|
422
|
$self->{departure_delay} //= 0; |
409
|
|
|
|
|
|
|
} |
410
|
|
|
|
|
|
|
|
411
|
686
|
100
|
|
|
|
283254
|
if ( $attrib{platform} ) { |
412
|
7
|
|
|
|
|
67
|
$self->{platform} = $attrib{platform}; |
413
|
|
|
|
|
|
|
} |
414
|
|
|
|
|
|
|
else { |
415
|
679
|
|
|
|
|
1727
|
$self->{platform} = $self->{sched_platform}; |
416
|
|
|
|
|
|
|
} |
417
|
|
|
|
|
|
|
|
418
|
686
|
100
|
|
|
|
1429
|
if ( defined $attrib{route_post} ) { |
419
|
182
|
|
50
|
|
|
2262
|
$self->{route_post} = [ split( qr{[|]}, $attrib{route_post} // q{} ) ]; |
420
|
182
|
|
|
|
|
794
|
$self->fixup_route( $self->{route_post} ); |
421
|
182
|
100
|
|
|
|
306
|
if ( @{ $self->{route_post} } ) { |
|
182
|
|
|
|
|
477
|
|
422
|
137
|
|
|
|
|
450
|
$self->{route_end} = $self->{route_post}[-1]; |
423
|
|
|
|
|
|
|
} |
424
|
|
|
|
|
|
|
} |
425
|
|
|
|
|
|
|
else { |
426
|
504
|
|
|
|
|
1457
|
$self->{route_post} = $self->{sched_route_post}; |
427
|
504
|
|
|
|
|
1439
|
$self->{route_end} = $self->{sched_route_end}; |
428
|
|
|
|
|
|
|
} |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
# also only for unscheduled departures |
431
|
686
|
100
|
|
|
|
1586
|
if ( $attrib{sched_route_post} ) { |
432
|
|
|
|
|
|
|
$self->{sched_route_post} |
433
|
176
|
|
50
|
|
|
2396
|
= [ split( qr{[|]}, $attrib{sched_route_post} // q{} ) ]; |
434
|
176
|
|
|
|
|
792
|
$self->fixup_route( $self->{sched_route_post} ); |
435
|
176
|
|
|
|
|
427
|
$self->{sched_route_end} = $self->{sched_route_post}[-1]; |
436
|
|
|
|
|
|
|
} |
437
|
|
|
|
|
|
|
|
438
|
686
|
|
|
|
|
3946
|
return $self; |
439
|
|
|
|
|
|
|
} |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
sub set_messages { |
442
|
827
|
|
|
827
|
0
|
2625
|
my ( $self, %messages ) = @_; |
443
|
|
|
|
|
|
|
|
444
|
827
|
|
|
|
|
2501
|
$self->{messages} = \%messages; |
445
|
|
|
|
|
|
|
|
446
|
827
|
|
|
|
|
1823
|
return $self; |
447
|
|
|
|
|
|
|
} |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
sub set_realtime { |
450
|
827
|
|
|
827
|
0
|
1684
|
my ( $self, $xmlobj ) = @_; |
451
|
|
|
|
|
|
|
|
452
|
827
|
|
|
|
|
2045
|
$self->{realtime_xml} = $xmlobj; |
453
|
|
|
|
|
|
|
|
454
|
827
|
|
|
|
|
1627
|
return $self; |
455
|
|
|
|
|
|
|
} |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
sub add_raw_ref { |
458
|
1
|
|
|
1
|
0
|
42
|
my ( $self, %attrib ) = @_; |
459
|
|
|
|
|
|
|
|
460
|
1
|
|
|
|
|
4
|
push( @{ $self->{refs} }, \%attrib ); |
|
1
|
|
|
|
|
4
|
|
461
|
|
|
|
|
|
|
|
462
|
1
|
|
|
|
|
6
|
return $self; |
463
|
|
|
|
|
|
|
} |
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
sub set_unscheduled { |
466
|
121
|
|
|
121
|
0
|
271
|
my ( $self, $unscheduled ) = @_; |
467
|
|
|
|
|
|
|
|
468
|
121
|
|
|
|
|
305
|
$self->{is_unscheduled} = $unscheduled; |
469
|
|
|
|
|
|
|
} |
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
sub add_arrival_wingref { |
472
|
14
|
|
|
14
|
0
|
41
|
my ( $self, $ref ) = @_; |
473
|
|
|
|
|
|
|
|
474
|
14
|
|
|
|
|
31
|
my $backref = $self; |
475
|
|
|
|
|
|
|
|
476
|
14
|
|
|
|
|
79
|
weaken($ref); |
477
|
14
|
|
|
|
|
48
|
weaken($backref); |
478
|
14
|
|
|
|
|
35
|
$ref->{is_wing} = 1; |
479
|
14
|
|
|
|
|
38
|
$ref->{wing_of} = $self; |
480
|
14
|
|
|
|
|
24
|
push( @{ $self->{arrival_wings} }, $ref ); |
|
14
|
|
|
|
|
83
|
|
481
|
14
|
|
|
|
|
52
|
return $self; |
482
|
|
|
|
|
|
|
} |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
sub add_departure_wingref { |
485
|
8
|
|
|
8
|
0
|
27
|
my ( $self, $ref ) = @_; |
486
|
|
|
|
|
|
|
|
487
|
8
|
|
|
|
|
16
|
my $backref = $self; |
488
|
|
|
|
|
|
|
|
489
|
8
|
|
|
|
|
54
|
weaken($ref); |
490
|
8
|
|
|
|
|
29
|
weaken($backref); |
491
|
8
|
|
|
|
|
20
|
$ref->{is_wing} = 1; |
492
|
8
|
|
|
|
|
19
|
$ref->{wing_of} = $self; |
493
|
8
|
|
|
|
|
14
|
push( @{ $self->{departure_wings} }, $ref ); |
|
8
|
|
|
|
|
27
|
|
494
|
8
|
|
|
|
|
29
|
return $self; |
495
|
|
|
|
|
|
|
} |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
sub add_reference { |
498
|
0
|
|
|
0
|
0
|
0
|
my ( $self, $ref ) = @_; |
499
|
|
|
|
|
|
|
|
500
|
0
|
|
|
|
|
0
|
$ref->add_inverse_reference($self); |
501
|
0
|
|
|
|
|
0
|
weaken($ref); |
502
|
0
|
|
|
|
|
0
|
push( @{ $self->{replacement_for} }, $ref ); |
|
0
|
|
|
|
|
0
|
|
503
|
0
|
|
|
|
|
0
|
return $self; |
504
|
|
|
|
|
|
|
} |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
sub merge_with_departure { |
507
|
10
|
|
|
10
|
0
|
19
|
my ( $self, $result ) = @_; |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
# result must be departure-only |
510
|
|
|
|
|
|
|
|
511
|
10
|
|
|
|
|
24
|
$self->{is_transfer} = 1; |
512
|
|
|
|
|
|
|
|
513
|
10
|
|
|
|
|
22
|
$self->{old_train_id} = $self->{train_id}; |
514
|
10
|
|
|
|
|
21
|
$self->{old_train_no} = $self->{train_no}; |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
# departure is preferred over arrival, so overwrite default values |
517
|
10
|
|
|
|
|
26
|
$self->{date} = $result->{date}; |
518
|
10
|
|
|
|
|
24
|
$self->{time} = $result->{time}; |
519
|
10
|
|
|
|
|
19
|
$self->{epoch} = $result->{epoch}; |
520
|
10
|
|
|
|
|
21
|
$self->{datetime} = $result->{datetime}; |
521
|
10
|
|
|
|
|
16
|
$self->{train_id} = $result->{train_id}; |
522
|
10
|
|
|
|
|
19
|
$self->{train_no} = $result->{train_no}; |
523
|
|
|
|
|
|
|
|
524
|
10
|
|
|
|
|
19
|
$self->{departure} = $result->{departure}; |
525
|
10
|
|
|
|
|
19
|
$self->{departure_wings} = $result->{departure_wings}; |
526
|
10
|
|
|
|
|
21
|
$self->{route_end} = $result->{route_end}; |
527
|
10
|
|
|
|
|
20
|
$self->{route_post} = $result->{route_post}; |
528
|
10
|
|
|
|
|
15
|
$self->{sched_departure} = $result->{sched_departure}; |
529
|
10
|
|
|
|
|
45
|
$self->{sched_route_post} = $result->{sched_route_post}; |
530
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
# update realtime info only if applicable |
532
|
10
|
|
33
|
|
|
41
|
$self->{is_cancelled} ||= $result->{is_cancelled}; |
533
|
|
|
|
|
|
|
|
534
|
10
|
|
|
|
|
27
|
return $self; |
535
|
|
|
|
|
|
|
} |
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
sub add_inverse_reference { |
538
|
0
|
|
|
0
|
0
|
0
|
my ( $self, $ref ) = @_; |
539
|
|
|
|
|
|
|
|
540
|
0
|
|
|
|
|
0
|
weaken($ref); |
541
|
0
|
|
|
|
|
0
|
push( @{ $self->{replaced_by} }, $ref ); |
|
0
|
|
|
|
|
0
|
|
542
|
0
|
|
|
|
|
0
|
return $self; |
543
|
|
|
|
|
|
|
} |
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
# }}} |
546
|
|
|
|
|
|
|
# {{{ Public Accessors |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
sub is_additional { |
549
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
550
|
|
|
|
|
|
|
|
551
|
0
|
0
|
0
|
|
|
0
|
if ( $self->{arrival_is_additional} and $self->{departure_is_additional} ) { |
552
|
0
|
|
|
|
|
0
|
return 1; |
553
|
|
|
|
|
|
|
} |
554
|
0
|
0
|
0
|
|
|
0
|
if ( $self->{arrival_is_additional} |
555
|
|
|
|
|
|
|
and not defined $self->{departure_is_additional} ) |
556
|
|
|
|
|
|
|
{ |
557
|
0
|
|
|
|
|
0
|
return 1; |
558
|
|
|
|
|
|
|
} |
559
|
0
|
0
|
0
|
|
|
0
|
if ( not defined $self->{arrival_is_additional} |
560
|
|
|
|
|
|
|
and $self->{departure_is_additional} ) |
561
|
|
|
|
|
|
|
{ |
562
|
0
|
|
|
|
|
0
|
return 1; |
563
|
|
|
|
|
|
|
} |
564
|
0
|
|
|
|
|
0
|
return 0; |
565
|
|
|
|
|
|
|
} |
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
sub is_cancelled { |
568
|
2
|
|
|
2
|
1
|
3018
|
my ($self) = @_; |
569
|
|
|
|
|
|
|
|
570
|
2
|
50
|
66
|
|
|
20
|
if ( $self->{arrival_is_cancelled} and $self->{departure_is_cancelled} ) { |
571
|
1
|
|
|
|
|
7
|
return 1; |
572
|
|
|
|
|
|
|
} |
573
|
1
|
50
|
33
|
|
|
6
|
if ( $self->{arrival_is_cancelled} |
574
|
|
|
|
|
|
|
and not defined $self->{departure_is_cancelled} ) |
575
|
|
|
|
|
|
|
{ |
576
|
0
|
|
|
|
|
0
|
return 1; |
577
|
|
|
|
|
|
|
} |
578
|
1
|
0
|
33
|
|
|
4
|
if ( not defined $self->{arrival_is_cancelled} |
579
|
|
|
|
|
|
|
and $self->{departure_is_cancelled} ) |
580
|
|
|
|
|
|
|
{ |
581
|
0
|
|
|
|
|
0
|
return 1; |
582
|
|
|
|
|
|
|
} |
583
|
1
|
|
|
|
|
8
|
return 0; |
584
|
|
|
|
|
|
|
} |
585
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
sub additional_stops { |
587
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
$self->{comparator} //= List::Compare->new( |
590
|
|
|
|
|
|
|
{ |
591
|
0
|
|
0
|
|
|
0
|
lists => [ $self->{sched_route_post}, $self->{route_post} ], |
592
|
|
|
|
|
|
|
unsorted => 1, |
593
|
|
|
|
|
|
|
} |
594
|
|
|
|
|
|
|
); |
595
|
|
|
|
|
|
|
|
596
|
|
|
|
|
|
|
return $self->sorted_sublist( $self->{route_post}, |
597
|
0
|
|
|
|
|
0
|
[ $self->{comparator}->get_complement ] ); |
598
|
|
|
|
|
|
|
} |
599
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
sub canceled_stops { |
601
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
$self->{comparator} //= List::Compare->new( |
604
|
|
|
|
|
|
|
{ |
605
|
0
|
|
0
|
|
|
0
|
lists => [ $self->{sched_route_post}, $self->{route_post} ], |
606
|
|
|
|
|
|
|
unsorted => 1, |
607
|
|
|
|
|
|
|
} |
608
|
|
|
|
|
|
|
); |
609
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
return $self->sorted_sublist( $self->{sched_route_post}, |
611
|
0
|
|
|
|
|
0
|
[ $self->{comparator}->get_unique ] ); |
612
|
|
|
|
|
|
|
} |
613
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
sub classes { |
615
|
1
|
|
|
1
|
1
|
4489
|
my ($self) = @_; |
616
|
|
|
|
|
|
|
|
617
|
1
|
|
50
|
|
|
8
|
my @classes = split( //, $self->{classes} // q{} ); |
618
|
|
|
|
|
|
|
|
619
|
1
|
|
|
|
|
12
|
return @classes; |
620
|
|
|
|
|
|
|
} |
621
|
|
|
|
|
|
|
|
622
|
|
|
|
|
|
|
sub origin { |
623
|
134
|
|
|
134
|
1
|
86656
|
my ($self) = @_; |
624
|
|
|
|
|
|
|
|
625
|
134
|
|
|
|
|
390
|
return $self->route_start; |
626
|
|
|
|
|
|
|
} |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
sub destination { |
629
|
134
|
|
|
134
|
1
|
91080
|
my ($self) = @_; |
630
|
|
|
|
|
|
|
|
631
|
134
|
|
|
|
|
374
|
return $self->route_end; |
632
|
|
|
|
|
|
|
} |
633
|
|
|
|
|
|
|
|
634
|
|
|
|
|
|
|
sub delay_messages { |
635
|
1
|
|
|
1
|
1
|
4
|
my ($self) = @_; |
636
|
|
|
|
|
|
|
|
637
|
1
|
|
|
|
|
2
|
my @keys = sort keys %{ $self->{messages} }; |
|
1
|
|
|
|
|
11
|
|
638
|
1
|
|
|
|
|
3
|
my @msgs = grep { $_->[1] eq 'd' } map { $self->{messages}{$_} } @keys; |
|
8
|
|
|
|
|
18
|
|
|
8
|
|
|
|
|
20
|
|
639
|
1
|
|
|
|
|
3
|
my @msgids = uniq( map { $_->[2] } @msgs ); |
|
7
|
|
|
|
|
18
|
|
640
|
1
|
|
|
|
|
4
|
my @ret; |
641
|
|
|
|
|
|
|
|
642
|
1
|
|
|
|
|
4
|
for my $id (@msgids) { |
643
|
2
|
50
|
|
|
|
5
|
if ( my @superseded = $self->superseded_messages($id) ) { |
644
|
0
|
|
|
|
|
0
|
@ret = grep { not( $_->[2] ~~ \@superseded ) } @ret; |
|
0
|
|
|
|
|
0
|
|
645
|
|
|
|
|
|
|
} |
646
|
2
|
|
|
3
|
|
18
|
my $msg = lastval { $_->[2] == $id } @msgs; |
|
3
|
|
|
|
|
8
|
|
647
|
2
|
|
|
|
|
8
|
push( @ret, $msg ); |
648
|
|
|
|
|
|
|
} |
649
|
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
@ret = reverse |
651
|
1
|
|
|
|
|
3
|
map { [ $self->parse_ts( $_->[0] ), $self->translate_msg( $_->[2] ) ] } |
|
2
|
|
|
|
|
7
|
|
652
|
|
|
|
|
|
|
@ret; |
653
|
|
|
|
|
|
|
|
654
|
1
|
|
|
|
|
14
|
return @ret; |
655
|
|
|
|
|
|
|
} |
656
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
sub arrival_wings { |
658
|
4
|
|
|
4
|
1
|
6266
|
my ($self) = @_; |
659
|
|
|
|
|
|
|
|
660
|
4
|
100
|
|
|
|
14
|
if ( $self->{arrival_wings} ) { |
661
|
2
|
|
|
|
|
4
|
return @{ $self->{arrival_wings} }; |
|
2
|
|
|
|
|
12
|
|
662
|
|
|
|
|
|
|
} |
663
|
2
|
|
|
|
|
9
|
return; |
664
|
|
|
|
|
|
|
} |
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
sub departure_wings { |
667
|
6
|
|
|
6
|
1
|
17
|
my ($self) = @_; |
668
|
|
|
|
|
|
|
|
669
|
6
|
100
|
|
|
|
22
|
if ( $self->{departure_wings} ) { |
670
|
4
|
|
|
|
|
6
|
return @{ $self->{departure_wings} }; |
|
4
|
|
|
|
|
21
|
|
671
|
|
|
|
|
|
|
} |
672
|
2
|
|
|
|
|
10
|
return; |
673
|
|
|
|
|
|
|
} |
674
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
sub replaced_by { |
676
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
677
|
|
|
|
|
|
|
|
678
|
0
|
0
|
|
|
|
0
|
if ( $self->{replaced_by} ) { |
679
|
0
|
|
|
|
|
0
|
return @{ $self->{replaced_by} }; |
|
0
|
|
|
|
|
0
|
|
680
|
|
|
|
|
|
|
} |
681
|
0
|
|
|
|
|
0
|
return; |
682
|
|
|
|
|
|
|
} |
683
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
sub replacement_for { |
685
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
686
|
|
|
|
|
|
|
|
687
|
0
|
0
|
|
|
|
0
|
if ( $self->{replacement_for} ) { |
688
|
0
|
|
|
|
|
0
|
return @{ $self->{replacement_for} }; |
|
0
|
|
|
|
|
0
|
|
689
|
|
|
|
|
|
|
} |
690
|
0
|
|
|
|
|
0
|
return; |
691
|
|
|
|
|
|
|
} |
692
|
|
|
|
|
|
|
|
693
|
|
|
|
|
|
|
sub qos_messages { |
694
|
1
|
|
|
1
|
1
|
4
|
my ($self) = @_; |
695
|
|
|
|
|
|
|
|
696
|
1
|
|
|
|
|
3
|
my @keys = sort keys %{ $self->{messages} }; |
|
1
|
|
|
|
|
52
|
|
697
|
|
|
|
|
|
|
my @msgs |
698
|
1
|
|
|
|
|
8
|
= grep { $_->[1] ~~ [qw[f q]] } map { $self->{messages}{$_} } @keys; |
|
8
|
|
|
|
|
30
|
|
|
8
|
|
|
|
|
17
|
|
699
|
1
|
|
|
|
|
2
|
my @ret; |
700
|
|
|
|
|
|
|
|
701
|
1
|
|
|
|
|
4
|
for my $msg (@msgs) { |
702
|
1
|
50
|
|
|
|
7
|
if ( my @superseded = $self->superseded_messages( $msg->[2] ) ) { |
703
|
0
|
|
|
|
|
0
|
@ret = grep { not( $_->[2] ~~ \@superseded ) } @ret; |
|
0
|
|
|
|
|
0
|
|
704
|
|
|
|
|
|
|
} |
705
|
1
|
|
|
|
|
4
|
@ret = grep { $_->[2] != $msg->[2] } @ret; |
|
0
|
|
|
|
|
0
|
|
706
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
# 88 is "no qos shortcomings" and only required to cancel previous qos |
708
|
|
|
|
|
|
|
# messages. Same for 84 ("correct wagon order") and 89 ("reservations |
709
|
|
|
|
|
|
|
# display is working again"). |
710
|
1
|
50
|
33
|
|
|
13
|
if ( $msg->[2] != 84 and $msg->[2] != 88 and $msg->[2] != 89 ) { |
|
|
|
33
|
|
|
|
|
711
|
1
|
|
|
|
|
4
|
push( @ret, $msg ); |
712
|
|
|
|
|
|
|
} |
713
|
|
|
|
|
|
|
} |
714
|
|
|
|
|
|
|
|
715
|
|
|
|
|
|
|
@ret |
716
|
1
|
|
|
|
|
3
|
= map { [ $self->parse_ts( $_->[0] ), $self->translate_msg( $_->[2] ) ] } |
|
1
|
|
|
|
|
3
|
|
717
|
|
|
|
|
|
|
reverse @ret; |
718
|
|
|
|
|
|
|
|
719
|
1
|
|
|
|
|
7
|
return @ret; |
720
|
|
|
|
|
|
|
} |
721
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
sub raw_messages { |
723
|
0
|
|
|
0
|
0
|
0
|
my ($self) = @_; |
724
|
|
|
|
|
|
|
|
725
|
0
|
|
|
|
|
0
|
my @messages = reverse sort keys %{ $self->{messages} }; |
|
0
|
|
|
|
|
0
|
|
726
|
|
|
|
|
|
|
my @ret = map { |
727
|
0
|
|
|
|
|
0
|
[ |
728
|
|
|
|
|
|
|
$self->parse_ts( $self->{messages}->{$_}->[0] ), |
729
|
0
|
|
|
|
|
0
|
$self->{messages}->{$_}->[2] |
730
|
|
|
|
|
|
|
] |
731
|
|
|
|
|
|
|
} @messages; |
732
|
|
|
|
|
|
|
|
733
|
0
|
|
|
|
|
0
|
return @ret; |
734
|
|
|
|
|
|
|
} |
735
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
sub messages { |
737
|
1
|
|
|
1
|
1
|
65
|
my ($self) = @_; |
738
|
|
|
|
|
|
|
|
739
|
1
|
|
|
|
|
5
|
my @messages = reverse sort keys %{ $self->{messages} }; |
|
1
|
|
|
|
|
11
|
|
740
|
|
|
|
|
|
|
my @ret = map { |
741
|
1
|
|
|
|
|
5
|
[ |
742
|
|
|
|
|
|
|
$self->parse_ts( $self->{messages}->{$_}->[0] ), |
743
|
8
|
|
|
|
|
30
|
$self->translate_msg( $self->{messages}->{$_}->[2] ) |
744
|
|
|
|
|
|
|
] |
745
|
|
|
|
|
|
|
} @messages; |
746
|
|
|
|
|
|
|
|
747
|
1
|
|
|
|
|
14
|
return @ret; |
748
|
|
|
|
|
|
|
} |
749
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
sub info { |
751
|
1
|
|
|
1
|
1
|
29
|
my ($self) = @_; |
752
|
|
|
|
|
|
|
|
753
|
1
|
|
|
|
|
10
|
my @messages = sort keys %{ $self->{messages} }; |
|
1
|
|
|
|
|
14
|
|
754
|
1
|
|
|
|
|
5
|
my @ids = uniq( map { $self->{messages}{$_}->[2] } @messages ); |
|
8
|
|
|
|
|
52
|
|
755
|
|
|
|
|
|
|
|
756
|
1
|
|
|
|
|
5
|
my @info = map { $self->translate_msg($_) } @ids; |
|
3
|
|
|
|
|
14
|
|
757
|
|
|
|
|
|
|
|
758
|
1
|
|
|
|
|
16
|
return @info; |
759
|
|
|
|
|
|
|
} |
760
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
sub line { |
762
|
268
|
|
|
268
|
1
|
496
|
my ($self) = @_; |
763
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
return sprintf( '%s %s', |
765
|
|
|
|
|
|
|
$self->{type} // 'Zug', |
766
|
268
|
|
50
|
|
|
2785
|
$self->{line_no} // $self->{train_no} // '-' ); |
|
|
|
33
|
|
|
|
|
|
|
|
50
|
|
|
|
|
767
|
|
|
|
|
|
|
} |
768
|
|
|
|
|
|
|
|
769
|
|
|
|
|
|
|
sub route_pre { |
770
|
4
|
|
|
4
|
1
|
9
|
my ($self) = @_; |
771
|
|
|
|
|
|
|
|
772
|
4
|
|
|
|
|
9
|
return @{ $self->{route_pre} }; |
|
4
|
|
|
|
|
25
|
|
773
|
|
|
|
|
|
|
} |
774
|
|
|
|
|
|
|
|
775
|
|
|
|
|
|
|
sub route_post { |
776
|
8
|
|
|
8
|
1
|
23
|
my ($self) = @_; |
777
|
|
|
|
|
|
|
|
778
|
8
|
|
|
|
|
11
|
return @{ $self->{route_post} }; |
|
8
|
|
|
|
|
61
|
|
779
|
|
|
|
|
|
|
} |
780
|
|
|
|
|
|
|
|
781
|
|
|
|
|
|
|
sub route { |
782
|
2
|
|
|
2
|
1
|
17
|
my ($self) = @_; |
783
|
|
|
|
|
|
|
|
784
|
2
|
|
|
|
|
10
|
return ( $self->route_pre, $self->{station}, $self->route_post ); |
785
|
|
|
|
|
|
|
} |
786
|
|
|
|
|
|
|
|
787
|
|
|
|
|
|
|
sub train { |
788
|
134
|
|
|
134
|
1
|
92610
|
my ($self) = @_; |
789
|
|
|
|
|
|
|
|
790
|
134
|
|
|
|
|
356
|
return $self->line; |
791
|
|
|
|
|
|
|
} |
792
|
|
|
|
|
|
|
|
793
|
|
|
|
|
|
|
sub route_interesting { |
794
|
4
|
|
|
4
|
1
|
9
|
my ( $self, $max_parts ) = @_; |
795
|
|
|
|
|
|
|
|
796
|
4
|
|
|
|
|
11
|
my @via = $self->route_post; |
797
|
4
|
|
|
|
|
7
|
my ( @via_main, @via_show, $last_stop ); |
798
|
4
|
|
50
|
|
|
21
|
$max_parts //= 3; |
799
|
|
|
|
|
|
|
|
800
|
|
|
|
|
|
|
# Centraal: dutch main station (Hbf in .nl) |
801
|
|
|
|
|
|
|
# HB: swiss main station (Hbf in .ch) |
802
|
|
|
|
|
|
|
# hl.n.: czech main station (Hbf in .cz) |
803
|
4
|
|
|
|
|
9
|
for my $stop (@via) { |
804
|
16
|
100
|
|
|
|
65
|
if ( $stop =~ m{ HB $ | hl\.n\. $ | Hbf | Centraal | Flughafen }x ) { |
805
|
9
|
|
|
|
|
20
|
push( @via_main, $stop ); |
806
|
|
|
|
|
|
|
} |
807
|
|
|
|
|
|
|
} |
808
|
|
|
|
|
|
|
$last_stop |
809
|
4
|
50
|
|
|
|
18
|
= $self->{route_post_incomplete} ? $self->{route_end} : pop(@via); |
810
|
|
|
|
|
|
|
|
811
|
4
|
100
|
100
|
|
|
21
|
if ( @via_main and $via_main[-1] eq $last_stop ) { |
812
|
2
|
|
|
|
|
4
|
pop(@via_main); |
813
|
|
|
|
|
|
|
} |
814
|
4
|
100
|
66
|
|
|
19
|
if ( @via and $via[-1] eq $last_stop ) { |
815
|
3
|
|
|
|
|
5
|
pop(@via); |
816
|
|
|
|
|
|
|
} |
817
|
|
|
|
|
|
|
|
818
|
4
|
100
|
66
|
|
|
20
|
if ( @via_main and @via and $via[0] eq $via_main[0] ) { |
|
|
|
100
|
|
|
|
|
819
|
1
|
|
|
|
|
3
|
shift(@via_main); |
820
|
|
|
|
|
|
|
} |
821
|
|
|
|
|
|
|
|
822
|
4
|
100
|
|
|
|
11
|
if ( @via < $max_parts ) { |
823
|
2
|
|
|
|
|
5
|
@via_show = @via; |
824
|
|
|
|
|
|
|
} |
825
|
|
|
|
|
|
|
else { |
826
|
2
|
100
|
|
|
|
6
|
if ( @via_main >= $max_parts ) { |
827
|
1
|
|
|
|
|
3
|
@via_show = ( $via[0] ); |
828
|
|
|
|
|
|
|
} |
829
|
|
|
|
|
|
|
else { |
830
|
1
|
|
|
|
|
4
|
@via_show = splice( @via, 0, $max_parts - @via_main ); |
831
|
|
|
|
|
|
|
} |
832
|
|
|
|
|
|
|
|
833
|
2
|
|
66
|
|
|
9
|
while ( @via_show < $max_parts and @via_main ) { |
834
|
4
|
|
|
|
|
8
|
my $stop = shift(@via_main); |
835
|
4
|
50
|
33
|
|
|
22
|
if ( $stop ~~ \@via_show or $stop eq $last_stop ) { |
836
|
0
|
|
|
|
|
0
|
next; |
837
|
|
|
|
|
|
|
} |
838
|
4
|
|
|
|
|
13
|
push( @via_show, $stop ); |
839
|
|
|
|
|
|
|
} |
840
|
|
|
|
|
|
|
} |
841
|
|
|
|
|
|
|
|
842
|
4
|
|
|
|
|
9
|
for (@via_show) { |
843
|
6
|
|
|
|
|
36
|
s{ \s? Hbf .* }{}x; |
844
|
|
|
|
|
|
|
} |
845
|
|
|
|
|
|
|
|
846
|
4
|
|
|
|
|
27
|
return @via_show; |
847
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
} |
849
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
sub sched_route_pre { |
851
|
2
|
|
|
2
|
1
|
19
|
my ($self) = @_; |
852
|
|
|
|
|
|
|
|
853
|
2
|
|
|
|
|
66
|
return @{ $self->{sched_route_pre} }; |
|
2
|
|
|
|
|
16
|
|
854
|
|
|
|
|
|
|
} |
855
|
|
|
|
|
|
|
|
856
|
|
|
|
|
|
|
sub sched_route_post { |
857
|
2
|
|
|
2
|
1
|
7
|
my ($self) = @_; |
858
|
|
|
|
|
|
|
|
859
|
2
|
|
|
|
|
3
|
return @{ $self->{sched_route_post} }; |
|
2
|
|
|
|
|
22
|
|
860
|
|
|
|
|
|
|
} |
861
|
|
|
|
|
|
|
|
862
|
|
|
|
|
|
|
sub sched_route { |
863
|
1
|
|
|
1
|
1
|
3
|
my ($self) = @_; |
864
|
|
|
|
|
|
|
|
865
|
|
|
|
|
|
|
return ( $self->sched_route_pre, $self->{station}, |
866
|
1
|
|
|
|
|
5
|
$self->sched_route_post ); |
867
|
|
|
|
|
|
|
} |
868
|
|
|
|
|
|
|
|
869
|
|
|
|
|
|
|
sub translate_msg { |
870
|
14
|
|
|
14
|
0
|
10015
|
my ( $self, $msg ) = @_; |
871
|
|
|
|
|
|
|
|
872
|
14
|
|
33
|
|
|
107
|
return $translation{$msg} // "?($msg)"; |
873
|
|
|
|
|
|
|
} |
874
|
|
|
|
|
|
|
|
875
|
|
|
|
|
|
|
sub TO_JSON { |
876
|
0
|
|
|
0
|
0
|
|
my ($self) = @_; |
877
|
|
|
|
|
|
|
|
878
|
0
|
|
|
|
|
|
my %copy = %{$self}; |
|
0
|
|
|
|
|
|
|
879
|
0
|
|
|
|
|
|
delete $copy{arrival_wings}; |
880
|
0
|
|
|
|
|
|
delete $copy{departure_wings}; |
881
|
0
|
|
|
|
|
|
delete $copy{realtime_xml}; |
882
|
0
|
|
|
|
|
|
delete $copy{replaced_by}; |
883
|
0
|
|
|
|
|
|
delete $copy{replacement_for}; |
884
|
0
|
|
|
|
|
|
delete $copy{strptime_obj}; |
885
|
0
|
|
|
|
|
|
delete $copy{wing_of}; |
886
|
|
|
|
|
|
|
|
887
|
0
|
|
|
|
|
|
for my $datetime_key ( |
888
|
|
|
|
|
|
|
qw(arrival departure sched_arrival sched_departure start datetime)) |
889
|
|
|
|
|
|
|
{ |
890
|
0
|
0
|
|
|
|
|
if ( defined $copy{$datetime_key} ) { |
891
|
0
|
|
|
|
|
|
$copy{$datetime_key} = $copy{$datetime_key}->epoch; |
892
|
|
|
|
|
|
|
} |
893
|
|
|
|
|
|
|
} |
894
|
|
|
|
|
|
|
|
895
|
0
|
|
|
|
|
|
return {%copy}; |
896
|
|
|
|
|
|
|
} |
897
|
|
|
|
|
|
|
|
898
|
|
|
|
|
|
|
# }}} |
899
|
|
|
|
|
|
|
|
900
|
|
|
|
|
|
|
1; |
901
|
|
|
|
|
|
|
|
902
|
|
|
|
|
|
|
__END__ |
903
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
=head1 NAME |
905
|
|
|
|
|
|
|
|
906
|
|
|
|
|
|
|
Travel::Status::DE::IRIS::Result - Information about a single |
907
|
|
|
|
|
|
|
arrival/departure received by Travel::Status::DE::IRIS |
908
|
|
|
|
|
|
|
|
909
|
|
|
|
|
|
|
=head1 SYNOPSIS |
910
|
|
|
|
|
|
|
|
911
|
|
|
|
|
|
|
for my $result ($status->results) { |
912
|
|
|
|
|
|
|
printf( |
913
|
|
|
|
|
|
|
"At %s: %s to %s from platform %s\n", |
914
|
|
|
|
|
|
|
$result->time, |
915
|
|
|
|
|
|
|
$result->line, |
916
|
|
|
|
|
|
|
$result->destination, |
917
|
|
|
|
|
|
|
$result->platform, |
918
|
|
|
|
|
|
|
); |
919
|
|
|
|
|
|
|
} |
920
|
|
|
|
|
|
|
|
921
|
|
|
|
|
|
|
=head1 VERSION |
922
|
|
|
|
|
|
|
|
923
|
|
|
|
|
|
|
version 1.89 |
924
|
|
|
|
|
|
|
|
925
|
|
|
|
|
|
|
=head1 DESCRIPTION |
926
|
|
|
|
|
|
|
|
927
|
|
|
|
|
|
|
Travel::Status::DE::IRIs::Result describes a single arrival/departure |
928
|
|
|
|
|
|
|
as obtained by Travel::Status::DE::IRIS. It contains information about |
929
|
|
|
|
|
|
|
the platform, time, route and more. |
930
|
|
|
|
|
|
|
|
931
|
|
|
|
|
|
|
=head1 METHODS |
932
|
|
|
|
|
|
|
|
933
|
|
|
|
|
|
|
=head2 ACCESSORS |
934
|
|
|
|
|
|
|
|
935
|
|
|
|
|
|
|
=over |
936
|
|
|
|
|
|
|
|
937
|
|
|
|
|
|
|
=item $result->additional_stops |
938
|
|
|
|
|
|
|
|
939
|
|
|
|
|
|
|
Returns served stops which are not part of the schedule. I.e., this is the |
940
|
|
|
|
|
|
|
set of actual stops (B<route_post>) minus the set of scheduled stops |
941
|
|
|
|
|
|
|
(B<sched_route_post>). |
942
|
|
|
|
|
|
|
|
943
|
|
|
|
|
|
|
=item $result->arrival |
944
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
DateTime(3pm) object for the arrival date and time. undef if the |
946
|
|
|
|
|
|
|
train starts here. Contains realtime data if available. |
947
|
|
|
|
|
|
|
|
948
|
|
|
|
|
|
|
=item $result->arrival_delay |
949
|
|
|
|
|
|
|
|
950
|
|
|
|
|
|
|
Estimated arrival delay in minutes (integer number). undef if no realtime |
951
|
|
|
|
|
|
|
data is available, the train starts at the specified station, or there is |
952
|
|
|
|
|
|
|
no scheduled arrival time (e.g. due to diversions). May be negative. |
953
|
|
|
|
|
|
|
|
954
|
|
|
|
|
|
|
=item $result->arrival_has_realtime |
955
|
|
|
|
|
|
|
|
956
|
|
|
|
|
|
|
True if "arrival" is based on real-time data. |
957
|
|
|
|
|
|
|
|
958
|
|
|
|
|
|
|
=item $result->arrival_hidden |
959
|
|
|
|
|
|
|
|
960
|
|
|
|
|
|
|
True if arrival should not be displayed to customers. |
961
|
|
|
|
|
|
|
This often indicates an entry-only stop near the beginning of a train's journey. |
962
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
=item $result->arrival_is_additional |
964
|
|
|
|
|
|
|
|
965
|
|
|
|
|
|
|
True if the arrival at this stop is an additional (unscheduled) event, i.e., |
966
|
|
|
|
|
|
|
if the train started its journey earlier than planned. |
967
|
|
|
|
|
|
|
|
968
|
|
|
|
|
|
|
=item $result->arrival_is_cancelled |
969
|
|
|
|
|
|
|
|
970
|
|
|
|
|
|
|
True if the arrival at this stop has been cancelled. |
971
|
|
|
|
|
|
|
|
972
|
|
|
|
|
|
|
=item $result->arrival_wings |
973
|
|
|
|
|
|
|
|
974
|
|
|
|
|
|
|
Returns a list of weakened references to Travel::Status::DE::IRIS::Result(3pm) |
975
|
|
|
|
|
|
|
objects which are coupled to this train on arrival. Returns nothing (false / |
976
|
|
|
|
|
|
|
empty list) otherwise. |
977
|
|
|
|
|
|
|
|
978
|
|
|
|
|
|
|
=item $result->canceled_stops |
979
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
Returns stops which are scheduled, but will not be served by this train. |
981
|
|
|
|
|
|
|
I.e., this is the set of scheduled stops (B<sched_route_post>) minus the set of |
982
|
|
|
|
|
|
|
actual stops (B<route_post>). |
983
|
|
|
|
|
|
|
|
984
|
|
|
|
|
|
|
=item $result->classes |
985
|
|
|
|
|
|
|
|
986
|
|
|
|
|
|
|
List of characters indicating the class(es) of this train, may be empty. This |
987
|
|
|
|
|
|
|
is slighty related to B<type>, but more generic. At this time, the following |
988
|
|
|
|
|
|
|
classes are known: |
989
|
|
|
|
|
|
|
|
990
|
|
|
|
|
|
|
D Non-DB train. Usually local transport |
991
|
|
|
|
|
|
|
D,F Non-DB train, long distance transport |
992
|
|
|
|
|
|
|
F "Fernverkehr", long-distance transport |
993
|
|
|
|
|
|
|
N "Nahverkehr", local and regional transport |
994
|
|
|
|
|
|
|
S S-Bahn, rather slow local/regional transport |
995
|
|
|
|
|
|
|
|
996
|
|
|
|
|
|
|
=item $result->date |
997
|
|
|
|
|
|
|
|
998
|
|
|
|
|
|
|
Scheduled departure date if available, arrival date otherwise (e.g. if the |
999
|
|
|
|
|
|
|
train ends here). String in dd.mm.YYYY format. Does not contain realtime data. |
1000
|
|
|
|
|
|
|
|
1001
|
|
|
|
|
|
|
=item $result->datetime |
1002
|
|
|
|
|
|
|
|
1003
|
|
|
|
|
|
|
DateTime(3pm) object for departure if available, arrival otherwise. Does not |
1004
|
|
|
|
|
|
|
contain realtime data. |
1005
|
|
|
|
|
|
|
|
1006
|
|
|
|
|
|
|
=item $result->delay |
1007
|
|
|
|
|
|
|
|
1008
|
|
|
|
|
|
|
Estimated delay in minutes (integer number). Defaults to the departure delay, |
1009
|
|
|
|
|
|
|
except for trains which terminate at the specifed station. Similar to |
1010
|
|
|
|
|
|
|
C<< $result->departure_delay // $result->arrival_delay >>. undef if |
1011
|
|
|
|
|
|
|
no realtime data is available. May be negative. |
1012
|
|
|
|
|
|
|
|
1013
|
|
|
|
|
|
|
=item $result->delay_messages |
1014
|
|
|
|
|
|
|
|
1015
|
|
|
|
|
|
|
Get all delay messages entered for this train. Returns a list of [datetime, |
1016
|
|
|
|
|
|
|
string] listrefs sorted by newest first. The datetime part is a DateTime(3pm) |
1017
|
|
|
|
|
|
|
object corresponding to the point in time when the message was entered, the |
1018
|
|
|
|
|
|
|
string is the message. If a delay reason was entered more than once, only its |
1019
|
|
|
|
|
|
|
most recent record will be returned. |
1020
|
|
|
|
|
|
|
|
1021
|
|
|
|
|
|
|
=item $result->departure |
1022
|
|
|
|
|
|
|
|
1023
|
|
|
|
|
|
|
DateTime(3pm) object for the departure date and time. undef if the train ends |
1024
|
|
|
|
|
|
|
here. Contains realtime data if available. |
1025
|
|
|
|
|
|
|
|
1026
|
|
|
|
|
|
|
=item $result->departure_delay |
1027
|
|
|
|
|
|
|
|
1028
|
|
|
|
|
|
|
Estimated departure delay in minutes (integer number). undef if no realtime |
1029
|
|
|
|
|
|
|
data is available, the train terminates at the specified station, or there is |
1030
|
|
|
|
|
|
|
no scheduled departure time (e.g. due to diversions). May be negative. |
1031
|
|
|
|
|
|
|
|
1032
|
|
|
|
|
|
|
=item $result->departure_has_realtime |
1033
|
|
|
|
|
|
|
|
1034
|
|
|
|
|
|
|
True if "departure" is based on real-time data. |
1035
|
|
|
|
|
|
|
|
1036
|
|
|
|
|
|
|
=item $result->departure_hidden |
1037
|
|
|
|
|
|
|
|
1038
|
|
|
|
|
|
|
True if departure should not be displayed to customers. |
1039
|
|
|
|
|
|
|
This often indicates an exit-only stop near the end of a train's journey. |
1040
|
|
|
|
|
|
|
|
1041
|
|
|
|
|
|
|
=item $result->departure_is_additional |
1042
|
|
|
|
|
|
|
|
1043
|
|
|
|
|
|
|
True if the train's departure at this stop is unscheduled (additional), i.e., |
1044
|
|
|
|
|
|
|
the route has been extended past its scheduled terminal stop. |
1045
|
|
|
|
|
|
|
|
1046
|
|
|
|
|
|
|
=item $result->departure_is_cancelled |
1047
|
|
|
|
|
|
|
|
1048
|
|
|
|
|
|
|
True if the train's departure at this stop has been cancelled, i.e., the train |
1049
|
|
|
|
|
|
|
terminates here and does not continue its scheduled journey. |
1050
|
|
|
|
|
|
|
|
1051
|
|
|
|
|
|
|
=item $result->departure_wings |
1052
|
|
|
|
|
|
|
|
1053
|
|
|
|
|
|
|
Returns a list of weakened references to Travel::Status::DE::IRIS::Result(3pm) |
1054
|
|
|
|
|
|
|
objects which are coupled to this train on departure. Returns nothing (false / |
1055
|
|
|
|
|
|
|
empty list) otherwise. |
1056
|
|
|
|
|
|
|
|
1057
|
|
|
|
|
|
|
=item $result->destination |
1058
|
|
|
|
|
|
|
|
1059
|
|
|
|
|
|
|
Alias for route_end. |
1060
|
|
|
|
|
|
|
|
1061
|
|
|
|
|
|
|
=item $result->has_realtime |
1062
|
|
|
|
|
|
|
|
1063
|
|
|
|
|
|
|
True if arrival or departure time are based on real-time data. Note that this |
1064
|
|
|
|
|
|
|
is different from C<< defined($esult->delay) >>. If delay is defined, some kind |
1065
|
|
|
|
|
|
|
of realtime information for the train is available, but not necessarily its |
1066
|
|
|
|
|
|
|
arrival/departure time. If has_realtime is true, arrival/departure time are |
1067
|
|
|
|
|
|
|
available. This behaviour may change in the future. |
1068
|
|
|
|
|
|
|
|
1069
|
|
|
|
|
|
|
=item $result->info |
1070
|
|
|
|
|
|
|
|
1071
|
|
|
|
|
|
|
List of information strings. Contains both reasons for delays (which may or |
1072
|
|
|
|
|
|
|
may not be up-to-date) and generic information such as missing carriages or |
1073
|
|
|
|
|
|
|
broken toilets. |
1074
|
|
|
|
|
|
|
|
1075
|
|
|
|
|
|
|
=item $result->is_additional |
1076
|
|
|
|
|
|
|
|
1077
|
|
|
|
|
|
|
True if the train's arrival and departure at the stop are unscheduled |
1078
|
|
|
|
|
|
|
additional stops, false otherwise. |
1079
|
|
|
|
|
|
|
|
1080
|
|
|
|
|
|
|
=item $result->is_cancelled |
1081
|
|
|
|
|
|
|
|
1082
|
|
|
|
|
|
|
True if the train was cancelled, false otherwise. Note that this does not |
1083
|
|
|
|
|
|
|
contain information about replacement trains or route diversions. |
1084
|
|
|
|
|
|
|
|
1085
|
|
|
|
|
|
|
=item $result->is_transfer |
1086
|
|
|
|
|
|
|
|
1087
|
|
|
|
|
|
|
True if the train changes its ID at the current station, false otherwise. |
1088
|
|
|
|
|
|
|
|
1089
|
|
|
|
|
|
|
An ID change means: There are two results in the system (e.g. RE 10228 |
1090
|
|
|
|
|
|
|
ME<uuml>nster -> Duisburg, RE 30028 Duisburg -> DE<uuml>sseldorf), but they are |
1091
|
|
|
|
|
|
|
the same train (RE line 2 from ME<uuml>nster to DE<uuml>sseldorf in this case) |
1092
|
|
|
|
|
|
|
and should be treated as such. In this case, Travel::Status::DE::IRIS merges |
1093
|
|
|
|
|
|
|
the results and indicates it by setting B<is_transfer> to a true value. |
1094
|
|
|
|
|
|
|
|
1095
|
|
|
|
|
|
|
In case of a transfer, B<train_id> and B<train_no> are set to the "new" |
1096
|
|
|
|
|
|
|
value, the old ones are available in B<old_train_id> and B<old_train_no>. |
1097
|
|
|
|
|
|
|
|
1098
|
|
|
|
|
|
|
=item $result->is_unscheduled |
1099
|
|
|
|
|
|
|
|
1100
|
|
|
|
|
|
|
True if the train does not appear in the requested plans. This can happen |
1101
|
|
|
|
|
|
|
because of two reasons: Either the scheduled time and the actual time are so |
1102
|
|
|
|
|
|
|
far apart that it should've arrived/departed long ago, or it really is an |
1103
|
|
|
|
|
|
|
unscheduled train. In that case, it can be a replacement or an additional |
1104
|
|
|
|
|
|
|
train. There is no logic to distinguish these cases yet. |
1105
|
|
|
|
|
|
|
|
1106
|
|
|
|
|
|
|
=item $result->is_wing |
1107
|
|
|
|
|
|
|
|
1108
|
|
|
|
|
|
|
Returns true if this result is a wing, false otherwise. |
1109
|
|
|
|
|
|
|
A wing is a train which has its own ID and destination, but is currently |
1110
|
|
|
|
|
|
|
coupled to another train and shares all or some of its route. |
1111
|
|
|
|
|
|
|
|
1112
|
|
|
|
|
|
|
=item $result->line |
1113
|
|
|
|
|
|
|
|
1114
|
|
|
|
|
|
|
Train type with line (such as C<< S 1 >>) if available, type with number |
1115
|
|
|
|
|
|
|
(suc as C<< RE 10126 >>) otherwise. |
1116
|
|
|
|
|
|
|
|
1117
|
|
|
|
|
|
|
=item $result->line_no |
1118
|
|
|
|
|
|
|
|
1119
|
|
|
|
|
|
|
Number of the line, undef if unknown. Seems to be set only for S-Bahn and |
1120
|
|
|
|
|
|
|
regional trains. Note that some regional and most long-distance trains do |
1121
|
|
|
|
|
|
|
not have this field set, even if they have a common line number. |
1122
|
|
|
|
|
|
|
|
1123
|
|
|
|
|
|
|
Example: For the line C<< S 1 >>, line_no will return C<< 1 >>. |
1124
|
|
|
|
|
|
|
|
1125
|
|
|
|
|
|
|
=item $result->messages |
1126
|
|
|
|
|
|
|
|
1127
|
|
|
|
|
|
|
Get all qos and delay messages ever entered for this train. Returns a list of |
1128
|
|
|
|
|
|
|
[datetime, string] listrefs sorted by newest first. The datetime part is a |
1129
|
|
|
|
|
|
|
DateTime(3pm) object corresponding to the point in time when the message was |
1130
|
|
|
|
|
|
|
entered, the string is the message. Note that neither duplicates nor superseded |
1131
|
|
|
|
|
|
|
messages are filtered from this list. |
1132
|
|
|
|
|
|
|
|
1133
|
|
|
|
|
|
|
=item $result->old_train_id |
1134
|
|
|
|
|
|
|
|
1135
|
|
|
|
|
|
|
Numeric ID of the pre-transfer train. Seems to be unique for a year and |
1136
|
|
|
|
|
|
|
trackable across stations. Only defined if a transfer took place, |
1137
|
|
|
|
|
|
|
see also B<is_transfer>. |
1138
|
|
|
|
|
|
|
|
1139
|
|
|
|
|
|
|
=item $result->old_train_no |
1140
|
|
|
|
|
|
|
|
1141
|
|
|
|
|
|
|
Number of the pre-tarnsfer train, unique per day. E.g. C<< 2225 >> for |
1142
|
|
|
|
|
|
|
C<< IC 2225 >>. Only defined if a transfer took |
1143
|
|
|
|
|
|
|
place, see also B<is_transfer>. |
1144
|
|
|
|
|
|
|
|
1145
|
|
|
|
|
|
|
=item $result->origin |
1146
|
|
|
|
|
|
|
|
1147
|
|
|
|
|
|
|
Alias for route_start. |
1148
|
|
|
|
|
|
|
|
1149
|
|
|
|
|
|
|
=item $result->qos_messages |
1150
|
|
|
|
|
|
|
|
1151
|
|
|
|
|
|
|
Get all current qos messages for this train. Returns a list of [datetime, |
1152
|
|
|
|
|
|
|
string] listrefs sorted by newest first. The datetime part is a DateTime(3pm) |
1153
|
|
|
|
|
|
|
object corresponding to the point in time when the message was entered, the |
1154
|
|
|
|
|
|
|
string is the message. Contains neither superseded messages nor duplicates (in |
1155
|
|
|
|
|
|
|
case of a duplicate, only the most recent message is present) |
1156
|
|
|
|
|
|
|
|
1157
|
|
|
|
|
|
|
=item $result->platform |
1158
|
|
|
|
|
|
|
|
1159
|
|
|
|
|
|
|
Arrival/departure platform as string, undef if unknown. Note that this is |
1160
|
|
|
|
|
|
|
not neccessarily a number, platform sections may be included (e.g. |
1161
|
|
|
|
|
|
|
C<< 3a/b >>). |
1162
|
|
|
|
|
|
|
|
1163
|
|
|
|
|
|
|
=item $result->raw_id |
1164
|
|
|
|
|
|
|
|
1165
|
|
|
|
|
|
|
Raw ID of the departure, e.g. C<< -4642102742373784975-1401031322-6 >>. |
1166
|
|
|
|
|
|
|
The first part appears to be this train's UUID (can be tracked across |
1167
|
|
|
|
|
|
|
multiple stations), the second the YYmmddHHMM departure timestamp at its |
1168
|
|
|
|
|
|
|
start station, and the third the count of this station in the train's schedule |
1169
|
|
|
|
|
|
|
(in this case, it's the sixth from thestart station). |
1170
|
|
|
|
|
|
|
|
1171
|
|
|
|
|
|
|
About half of all departure IDs do not contain the leading minus (C<< - >>) |
1172
|
|
|
|
|
|
|
seen in this example. The reason for this is unknown. |
1173
|
|
|
|
|
|
|
|
1174
|
|
|
|
|
|
|
This is a developer option. It may be removed without prior warning. |
1175
|
|
|
|
|
|
|
|
1176
|
|
|
|
|
|
|
=item $result->realtime_xml |
1177
|
|
|
|
|
|
|
|
1178
|
|
|
|
|
|
|
XML::LibXML::Node(3pm) object containing all realtime data. undef if none is |
1179
|
|
|
|
|
|
|
available. |
1180
|
|
|
|
|
|
|
|
1181
|
|
|
|
|
|
|
This is a developer option. It may be removed without prior warning. |
1182
|
|
|
|
|
|
|
|
1183
|
|
|
|
|
|
|
=item $result->replaced_by |
1184
|
|
|
|
|
|
|
|
1185
|
|
|
|
|
|
|
Returns a list of references to Travel::Status::DE::IRIS::Result(3pm) objects |
1186
|
|
|
|
|
|
|
which replace the (usually cancelled) arrival/departure of this train. |
1187
|
|
|
|
|
|
|
Returns nothing (false / empty list) otherwise. |
1188
|
|
|
|
|
|
|
|
1189
|
|
|
|
|
|
|
=item $result->replacement_for |
1190
|
|
|
|
|
|
|
|
1191
|
|
|
|
|
|
|
Returns a list of references to Travel::Status::DE::IRIS::Result(3pm) objects |
1192
|
|
|
|
|
|
|
which this (usually unplanned) train is meant to replace. |
1193
|
|
|
|
|
|
|
Returns nothing (false / empty list) otherwise. |
1194
|
|
|
|
|
|
|
|
1195
|
|
|
|
|
|
|
=item $result->route |
1196
|
|
|
|
|
|
|
|
1197
|
|
|
|
|
|
|
List of all stations served by this train, according to its schedule. Does |
1198
|
|
|
|
|
|
|
not contain realtime data. |
1199
|
|
|
|
|
|
|
|
1200
|
|
|
|
|
|
|
=item $result->route_end |
1201
|
|
|
|
|
|
|
|
1202
|
|
|
|
|
|
|
Name of the last station served by this train. |
1203
|
|
|
|
|
|
|
|
1204
|
|
|
|
|
|
|
=item $result->route_interesting |
1205
|
|
|
|
|
|
|
|
1206
|
|
|
|
|
|
|
List of up to three "interesting" stations served by this train, subset of |
1207
|
|
|
|
|
|
|
route_post. Usually contains the next stop and one or two major stations after |
1208
|
|
|
|
|
|
|
that. Does not contain realtime data. |
1209
|
|
|
|
|
|
|
|
1210
|
|
|
|
|
|
|
=item $result->route_pre |
1211
|
|
|
|
|
|
|
|
1212
|
|
|
|
|
|
|
List of station names the train passed (or will have passed) before this stop. |
1213
|
|
|
|
|
|
|
|
1214
|
|
|
|
|
|
|
=item $result->route_post |
1215
|
|
|
|
|
|
|
|
1216
|
|
|
|
|
|
|
List of station names the train will pass after this stop. |
1217
|
|
|
|
|
|
|
|
1218
|
|
|
|
|
|
|
=item $result->route_start |
1219
|
|
|
|
|
|
|
|
1220
|
|
|
|
|
|
|
Name of the first station served by this train. |
1221
|
|
|
|
|
|
|
|
1222
|
|
|
|
|
|
|
=item $result->sched_arrival |
1223
|
|
|
|
|
|
|
|
1224
|
|
|
|
|
|
|
DateTime(3pm) object for the scheduled arrival date and time. undef if the |
1225
|
|
|
|
|
|
|
train starts here. |
1226
|
|
|
|
|
|
|
|
1227
|
|
|
|
|
|
|
=item $result->sched_departure |
1228
|
|
|
|
|
|
|
|
1229
|
|
|
|
|
|
|
DateTime(3pm) object for the scehduled departure date and time. undef if the |
1230
|
|
|
|
|
|
|
train ends here. |
1231
|
|
|
|
|
|
|
|
1232
|
|
|
|
|
|
|
=item $result->sched_platform |
1233
|
|
|
|
|
|
|
|
1234
|
|
|
|
|
|
|
Scheduled Arrival/departure platform as string, undef if unknown. Note that |
1235
|
|
|
|
|
|
|
this is not neccessarily a number, platform sections may be included (e.g. C<< |
1236
|
|
|
|
|
|
|
3a/b >>). |
1237
|
|
|
|
|
|
|
|
1238
|
|
|
|
|
|
|
=item $result->sched_route |
1239
|
|
|
|
|
|
|
|
1240
|
|
|
|
|
|
|
List of all stations served by this train, according to its schedule. Does |
1241
|
|
|
|
|
|
|
not contain realtime data. |
1242
|
|
|
|
|
|
|
|
1243
|
|
|
|
|
|
|
=item $result->sched_route_end |
1244
|
|
|
|
|
|
|
|
1245
|
|
|
|
|
|
|
Name of the last station served by this train according to its schedule. |
1246
|
|
|
|
|
|
|
|
1247
|
|
|
|
|
|
|
=item $result->sched_route_pre |
1248
|
|
|
|
|
|
|
|
1249
|
|
|
|
|
|
|
List of station names the train is scheduled to pass before this stop. |
1250
|
|
|
|
|
|
|
|
1251
|
|
|
|
|
|
|
=item $result->sched_route_post |
1252
|
|
|
|
|
|
|
|
1253
|
|
|
|
|
|
|
List of station names the train is scheduled to pass after this stop. |
1254
|
|
|
|
|
|
|
|
1255
|
|
|
|
|
|
|
=item $result->sched_route_start |
1256
|
|
|
|
|
|
|
|
1257
|
|
|
|
|
|
|
Name of the first station served by this train according to its schedule. |
1258
|
|
|
|
|
|
|
|
1259
|
|
|
|
|
|
|
=item $result->start |
1260
|
|
|
|
|
|
|
|
1261
|
|
|
|
|
|
|
DateTime(3pm) object for the scheduled start of the train on its route |
1262
|
|
|
|
|
|
|
(i.e. the departure time at its first station). |
1263
|
|
|
|
|
|
|
|
1264
|
|
|
|
|
|
|
=item $result->station |
1265
|
|
|
|
|
|
|
|
1266
|
|
|
|
|
|
|
Name of the station this train result belongs to. |
1267
|
|
|
|
|
|
|
|
1268
|
|
|
|
|
|
|
=item $result->station_uic |
1269
|
|
|
|
|
|
|
|
1270
|
|
|
|
|
|
|
EVA number of the station this train result belongs to. |
1271
|
|
|
|
|
|
|
This is often, but not always, identical with the UIC station number. |
1272
|
|
|
|
|
|
|
|
1273
|
|
|
|
|
|
|
=item $result->stop_no |
1274
|
|
|
|
|
|
|
|
1275
|
|
|
|
|
|
|
Number of this stop on the train's route. 1 if it's the start station, 2 |
1276
|
|
|
|
|
|
|
for the stop after that, and so on. |
1277
|
|
|
|
|
|
|
|
1278
|
|
|
|
|
|
|
=item $result->time |
1279
|
|
|
|
|
|
|
|
1280
|
|
|
|
|
|
|
Scheduled departure time if available, arrival time otherwise (e.g. if the |
1281
|
|
|
|
|
|
|
train ends here). String in HH:MM format. Does not contain realtime data. |
1282
|
|
|
|
|
|
|
|
1283
|
|
|
|
|
|
|
=item $result->train |
1284
|
|
|
|
|
|
|
|
1285
|
|
|
|
|
|
|
Alias for line. |
1286
|
|
|
|
|
|
|
|
1287
|
|
|
|
|
|
|
=item $result->train_id |
1288
|
|
|
|
|
|
|
|
1289
|
|
|
|
|
|
|
Numeric ID of this train, trackable across stations and days. For instance, the |
1290
|
|
|
|
|
|
|
S 31128 (S1) to Solingen, starting in Dortmund on 19:23, has the ID |
1291
|
|
|
|
|
|
|
2404170432985554630 on each station it passes and (usually) on every day of the |
1292
|
|
|
|
|
|
|
year. Note that it may change during the yearly itinerary update in december. |
1293
|
|
|
|
|
|
|
|
1294
|
|
|
|
|
|
|
=item $result->train_no |
1295
|
|
|
|
|
|
|
|
1296
|
|
|
|
|
|
|
Number of this train, unique per day. E.g. C<< 2225 >> for C<< IC 2225 >>. |
1297
|
|
|
|
|
|
|
|
1298
|
|
|
|
|
|
|
=item $result->type |
1299
|
|
|
|
|
|
|
|
1300
|
|
|
|
|
|
|
Type of this train, e.g. C<< S >> for S-Bahn, C<< RE >> for Regional-Express, |
1301
|
|
|
|
|
|
|
C<< ICE >> for InterCity-Express. |
1302
|
|
|
|
|
|
|
|
1303
|
|
|
|
|
|
|
=item $result->wing_of |
1304
|
|
|
|
|
|
|
|
1305
|
|
|
|
|
|
|
If B<is_wing> is true, returns a weakened reference to the |
1306
|
|
|
|
|
|
|
Travel::Status::DE::IRIS::Result(3pm) object which this train is a wing of. So |
1307
|
|
|
|
|
|
|
far, it seems that a train is either not a wing or a wing of exactly one other |
1308
|
|
|
|
|
|
|
train. Returns undef if B<is_wing> is false. |
1309
|
|
|
|
|
|
|
|
1310
|
|
|
|
|
|
|
=back |
1311
|
|
|
|
|
|
|
|
1312
|
|
|
|
|
|
|
=head2 INTERNAL |
1313
|
|
|
|
|
|
|
|
1314
|
|
|
|
|
|
|
=over |
1315
|
|
|
|
|
|
|
|
1316
|
|
|
|
|
|
|
=item $result = Travel::Status::DE::IRIS::Result->new(I<%data>) |
1317
|
|
|
|
|
|
|
|
1318
|
|
|
|
|
|
|
Returns a new Travel::Status::DE::IRIS::Result object. |
1319
|
|
|
|
|
|
|
You usually do not need to call this. |
1320
|
|
|
|
|
|
|
|
1321
|
|
|
|
|
|
|
=back |
1322
|
|
|
|
|
|
|
|
1323
|
|
|
|
|
|
|
=head1 MESSAGES |
1324
|
|
|
|
|
|
|
|
1325
|
|
|
|
|
|
|
A dump of all messages entered for the result is available. Each message |
1326
|
|
|
|
|
|
|
consists of a timestamp (when it was entered), a type (d for delay reasons, |
1327
|
|
|
|
|
|
|
q for other train-related information) and a value (numeric ID). |
1328
|
|
|
|
|
|
|
|
1329
|
|
|
|
|
|
|
At the time of this writing, the following messages are known: |
1330
|
|
|
|
|
|
|
|
1331
|
|
|
|
|
|
|
=over |
1332
|
|
|
|
|
|
|
|
1333
|
|
|
|
|
|
|
=item d 2 : "Polizeiliche Ermittlung" |
1334
|
|
|
|
|
|
|
|
1335
|
|
|
|
|
|
|
=item d 3 : "Feuerwehreinsatz neben der Strecke" |
1336
|
|
|
|
|
|
|
|
1337
|
|
|
|
|
|
|
=item d 5 : "E<Auml>rztliche Versorgung eines Fahrgastes" |
1338
|
|
|
|
|
|
|
|
1339
|
|
|
|
|
|
|
=item d 6 : "BetE<auml>tigen der Notbremse" |
1340
|
|
|
|
|
|
|
|
1341
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). |
1342
|
|
|
|
|
|
|
|
1343
|
|
|
|
|
|
|
=item d 7 : "Personen im Gleis" |
1344
|
|
|
|
|
|
|
|
1345
|
|
|
|
|
|
|
=item d 8 : "Notarzteinsatz am Gleis" |
1346
|
|
|
|
|
|
|
|
1347
|
|
|
|
|
|
|
=item d 9 : "Streikauswirkungen" |
1348
|
|
|
|
|
|
|
|
1349
|
|
|
|
|
|
|
=item d 10 : "Ausgebrochene Tiere im Gleis" |
1350
|
|
|
|
|
|
|
|
1351
|
|
|
|
|
|
|
=item d 11 : "Unwetter" |
1352
|
|
|
|
|
|
|
|
1353
|
|
|
|
|
|
|
=item d 13 : "Pass- und Zollkontrolle" |
1354
|
|
|
|
|
|
|
|
1355
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). |
1356
|
|
|
|
|
|
|
|
1357
|
|
|
|
|
|
|
=item d 15 : "BeeintrE<auml>chtigung durch Vandalismus" |
1358
|
|
|
|
|
|
|
|
1359
|
|
|
|
|
|
|
=item d 16 : "EntschE<auml>rfung einer Fliegerbombe" |
1360
|
|
|
|
|
|
|
|
1361
|
|
|
|
|
|
|
=item d 17 : "BeschE<auml>digung einer BrE<uuml>cke" |
1362
|
|
|
|
|
|
|
|
1363
|
|
|
|
|
|
|
=item d 18 : "UmgestE<uuml>rzter Baum im Gleis" |
1364
|
|
|
|
|
|
|
|
1365
|
|
|
|
|
|
|
=item d 19 : "Unfall an einem BahnE<uuml>bergang" |
1366
|
|
|
|
|
|
|
|
1367
|
|
|
|
|
|
|
=item d 20 : "Tiere im Gleis" |
1368
|
|
|
|
|
|
|
|
1369
|
|
|
|
|
|
|
=item d 21 : "Warten auf weitere Reisende" |
1370
|
|
|
|
|
|
|
|
1371
|
|
|
|
|
|
|
=item d 22 : "Witterungsbedingte StE<ouml>rung" |
1372
|
|
|
|
|
|
|
|
1373
|
|
|
|
|
|
|
=item d 23 : "Feuerwehreinsatz auf BahngelE<auml>nde" |
1374
|
|
|
|
|
|
|
|
1375
|
|
|
|
|
|
|
=item d 24 : "VerspE<auml>tung aus dem Ausland" |
1376
|
|
|
|
|
|
|
|
1377
|
|
|
|
|
|
|
=item d 25 : "Warten auf verspE<auml>tete Zugteile" |
1378
|
|
|
|
|
|
|
|
1379
|
|
|
|
|
|
|
=item d 28 : "GegenstE<auml>nde im Gleis" |
1380
|
|
|
|
|
|
|
|
1381
|
|
|
|
|
|
|
=item d 29 : "Ersatzverkehr mit Bus ist eingerichtet" |
1382
|
|
|
|
|
|
|
|
1383
|
|
|
|
|
|
|
=item d 31 : "Bauarbeiten" |
1384
|
|
|
|
|
|
|
|
1385
|
|
|
|
|
|
|
=item d 32 : "VerzE<ouml>gerung beim Ein-/Ausstieg" |
1386
|
|
|
|
|
|
|
|
1387
|
|
|
|
|
|
|
=item d 33 : "OberleitungsstE<ouml>rung" |
1388
|
|
|
|
|
|
|
|
1389
|
|
|
|
|
|
|
=item d 34 : "SignalstE<ouml>rung" |
1390
|
|
|
|
|
|
|
|
1391
|
|
|
|
|
|
|
=item d 35 : "Streckensperrung" |
1392
|
|
|
|
|
|
|
|
1393
|
|
|
|
|
|
|
=item d 36 : "Technische StE<ouml>rung am Zug" |
1394
|
|
|
|
|
|
|
|
1395
|
|
|
|
|
|
|
=item d 37 : "Technische StE<ouml>rung am Wagen" |
1396
|
|
|
|
|
|
|
|
1397
|
|
|
|
|
|
|
=item d 38 : "Technische StE<ouml>rung an der Strecke" |
1398
|
|
|
|
|
|
|
|
1399
|
|
|
|
|
|
|
=item d 39 : "AnhE<auml>ngen von zusE<auml>tzlichen Wagen" |
1400
|
|
|
|
|
|
|
|
1401
|
|
|
|
|
|
|
=item d 40 : "StellwerksstE<ouml>rung/-ausfall" |
1402
|
|
|
|
|
|
|
|
1403
|
|
|
|
|
|
|
=item d 41 : "StE<ouml>rung an einem BahnE<uuml>bergang" |
1404
|
|
|
|
|
|
|
|
1405
|
|
|
|
|
|
|
=item d 42 : "AuE<szlig>erplanmE<auml>E<szlig>ige GeschwindigkeitsbeschrE<auml>nkung" |
1406
|
|
|
|
|
|
|
|
1407
|
|
|
|
|
|
|
=item d 43 : "VerspE<auml>tung eines vorausfahrenden Zuges" |
1408
|
|
|
|
|
|
|
|
1409
|
|
|
|
|
|
|
=item d 44 : "Warten auf einen entgegenkommenden Zug" |
1410
|
|
|
|
|
|
|
|
1411
|
|
|
|
|
|
|
=item d 45 : "E<Uuml>berholung durch anderen Zug" |
1412
|
|
|
|
|
|
|
|
1413
|
|
|
|
|
|
|
=item d 46 : "Warten auf freie Einfahrt" |
1414
|
|
|
|
|
|
|
|
1415
|
|
|
|
|
|
|
=item d 47 : "VerspE<auml>tete Bereitstellung" |
1416
|
|
|
|
|
|
|
|
1417
|
|
|
|
|
|
|
=item d 48 : "VerspE<auml>tung aus vorheriger Fahrt" |
1418
|
|
|
|
|
|
|
|
1419
|
|
|
|
|
|
|
=item d 55 : "Technische StE<ouml>rung an einem anderen Zug" |
1420
|
|
|
|
|
|
|
|
1421
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). |
1422
|
|
|
|
|
|
|
|
1423
|
|
|
|
|
|
|
=item d 56 : "Warten auf FahrgE<auml>ste aus einem Bus" |
1424
|
|
|
|
|
|
|
|
1425
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). |
1426
|
|
|
|
|
|
|
|
1427
|
|
|
|
|
|
|
=item d 57 : "ZusE<auml>tzlicher Halt" |
1428
|
|
|
|
|
|
|
|
1429
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). |
1430
|
|
|
|
|
|
|
|
1431
|
|
|
|
|
|
|
=item d 58 : "Umleitung" |
1432
|
|
|
|
|
|
|
|
1433
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). Several entries, related |
1434
|
|
|
|
|
|
|
to "Notarzteinsatz am Gleis". |
1435
|
|
|
|
|
|
|
|
1436
|
|
|
|
|
|
|
=item d 59 : "Schnee und Eis" |
1437
|
|
|
|
|
|
|
|
1438
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). |
1439
|
|
|
|
|
|
|
|
1440
|
|
|
|
|
|
|
=item d 60 : "Reduzierte Geschwindigkeit wegen Sturm" |
1441
|
|
|
|
|
|
|
|
1442
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). |
1443
|
|
|
|
|
|
|
|
1444
|
|
|
|
|
|
|
=item d 61 : "TE<uuml>rstE<ouml>rung" |
1445
|
|
|
|
|
|
|
|
1446
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). |
1447
|
|
|
|
|
|
|
|
1448
|
|
|
|
|
|
|
=item d 62 : "Behobene technische StE<ouml>rung am Zug" |
1449
|
|
|
|
|
|
|
|
1450
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). |
1451
|
|
|
|
|
|
|
|
1452
|
|
|
|
|
|
|
=item d 63 : "Technische Untersuchung am Zug" |
1453
|
|
|
|
|
|
|
|
1454
|
|
|
|
|
|
|
=item d 64 : "WeichenstE<ouml>rung" |
1455
|
|
|
|
|
|
|
|
1456
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1457
|
|
|
|
|
|
|
|
1458
|
|
|
|
|
|
|
=item d 65 : "Erdrutsch" |
1459
|
|
|
|
|
|
|
|
1460
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1461
|
|
|
|
|
|
|
|
1462
|
|
|
|
|
|
|
=item d 66 : "Hochwasser" |
1463
|
|
|
|
|
|
|
|
1464
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1465
|
|
|
|
|
|
|
|
1466
|
|
|
|
|
|
|
=item f 67 : "BehE<ouml>rdliche Anordnung" |
1467
|
|
|
|
|
|
|
|
1468
|
|
|
|
|
|
|
Source: L<https://twitter.com/DodoMedia/status/1238816272240070659>. |
1469
|
|
|
|
|
|
|
|
1470
|
|
|
|
|
|
|
=item q 70 : "WLAN nicht verfE<uuml>gbar" |
1471
|
|
|
|
|
|
|
|
1472
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1473
|
|
|
|
|
|
|
|
1474
|
|
|
|
|
|
|
=item q 71 : "WLAN in einzelnen Wagen nicht verfE<uuml>gbar" |
1475
|
|
|
|
|
|
|
|
1476
|
|
|
|
|
|
|
=item q 72 : "Info/Entertainment nicht verfE<uuml>gbar" |
1477
|
|
|
|
|
|
|
|
1478
|
|
|
|
|
|
|
=item q 73 : "Mehrzweckabteil vorne" |
1479
|
|
|
|
|
|
|
|
1480
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1481
|
|
|
|
|
|
|
|
1482
|
|
|
|
|
|
|
=item q 74 : "Mehrzweckabteil hinten" |
1483
|
|
|
|
|
|
|
|
1484
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1485
|
|
|
|
|
|
|
|
1486
|
|
|
|
|
|
|
=item q 75 : "1. Klasse vorne" |
1487
|
|
|
|
|
|
|
|
1488
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1489
|
|
|
|
|
|
|
|
1490
|
|
|
|
|
|
|
=item q 76 : "1. Klasse hinten" |
1491
|
|
|
|
|
|
|
|
1492
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1493
|
|
|
|
|
|
|
|
1494
|
|
|
|
|
|
|
=item q 77 : "Ohne 1. Klasse" |
1495
|
|
|
|
|
|
|
|
1496
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1497
|
|
|
|
|
|
|
|
1498
|
|
|
|
|
|
|
=item q 78 : "Ersatzverkehr mit Bus ist eingerichtet" |
1499
|
|
|
|
|
|
|
|
1500
|
|
|
|
|
|
|
=item q 79 : "Ohne Mehrzweckabteil" |
1501
|
|
|
|
|
|
|
|
1502
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1503
|
|
|
|
|
|
|
|
1504
|
|
|
|
|
|
|
=item q 80 : "Abweichende Wagenreihung" |
1505
|
|
|
|
|
|
|
|
1506
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1507
|
|
|
|
|
|
|
|
1508
|
|
|
|
|
|
|
=item q 81 : "Fahrzeugtausch" |
1509
|
|
|
|
|
|
|
|
1510
|
|
|
|
|
|
|
=item q 82 : "Mehrere Wagen fehlen" |
1511
|
|
|
|
|
|
|
|
1512
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1513
|
|
|
|
|
|
|
|
1514
|
|
|
|
|
|
|
=item q 83 : "StE<ouml>rung der fahrzeuggebundenen Einstiegshilfe" |
1515
|
|
|
|
|
|
|
|
1516
|
|
|
|
|
|
|
=item q 84 : "Zug verkehrt richtig gereiht" |
1517
|
|
|
|
|
|
|
|
1518
|
|
|
|
|
|
|
Obsoletes messages 80, 82, 85. |
1519
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1520
|
|
|
|
|
|
|
|
1521
|
|
|
|
|
|
|
=item q 85 : "Ein Wagen fehlt" |
1522
|
|
|
|
|
|
|
|
1523
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1524
|
|
|
|
|
|
|
|
1525
|
|
|
|
|
|
|
=item q 86 : "Keine Reservierungsanzeige" |
1526
|
|
|
|
|
|
|
|
1527
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1528
|
|
|
|
|
|
|
|
1529
|
|
|
|
|
|
|
=item q 87 : "Einzelne Wagen ohne Reservierungsanzeige" |
1530
|
|
|
|
|
|
|
|
1531
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1532
|
|
|
|
|
|
|
|
1533
|
|
|
|
|
|
|
=item q 88 : "Keine QualitE<auml>tsmE<auml>ngel" |
1534
|
|
|
|
|
|
|
|
1535
|
|
|
|
|
|
|
Obsoletes messages 80, 82, 83, 85, 86, 87, 90, 91, 92, 93, 96, 97, 98. |
1536
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1537
|
|
|
|
|
|
|
|
1538
|
|
|
|
|
|
|
=item q 89 : "Reservierungen sind wieder vorhanden" |
1539
|
|
|
|
|
|
|
|
1540
|
|
|
|
|
|
|
Obsoletes messages 86, 87. |
1541
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1542
|
|
|
|
|
|
|
|
1543
|
|
|
|
|
|
|
=item q 90 : "Kein gastronomisches Angebot" |
1544
|
|
|
|
|
|
|
|
1545
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1546
|
|
|
|
|
|
|
|
1547
|
|
|
|
|
|
|
=item q 91 : "EingeschrE<auml>nkte FahrradbefE<ouml>rderung" |
1548
|
|
|
|
|
|
|
|
1549
|
|
|
|
|
|
|
=item q 92 : "Keine FahrradbefE<ouml>rderung" |
1550
|
|
|
|
|
|
|
|
1551
|
|
|
|
|
|
|
=item q 93 : "Fehlende oder gestE<ouml>rte behindertengerechte Einrichtung" |
1552
|
|
|
|
|
|
|
|
1553
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1554
|
|
|
|
|
|
|
Might also mean "Kein rollstuhlgerechtes WC" (source: frubi). |
1555
|
|
|
|
|
|
|
|
1556
|
|
|
|
|
|
|
=item q 94 : "Ersatzbewirtschaftung" |
1557
|
|
|
|
|
|
|
|
1558
|
|
|
|
|
|
|
Estimated from a comparison with bahn.de/ris messages. Needs to be verified. |
1559
|
|
|
|
|
|
|
|
1560
|
|
|
|
|
|
|
=item q 95 : "Ohne behindertengerechtes WC" |
1561
|
|
|
|
|
|
|
|
1562
|
|
|
|
|
|
|
Estimated from a comparison with bahn.de/iris messages. |
1563
|
|
|
|
|
|
|
|
1564
|
|
|
|
|
|
|
=item q 96 : "Der Zug ist stark E<uuml>berbesetzt" |
1565
|
|
|
|
|
|
|
|
1566
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1567
|
|
|
|
|
|
|
|
1568
|
|
|
|
|
|
|
=item q 97 : "Der Zug ist E<uuml>berbesetzt" |
1569
|
|
|
|
|
|
|
|
1570
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1571
|
|
|
|
|
|
|
|
1572
|
|
|
|
|
|
|
=item q 98 : "Sonstige QualitE<auml>tsmE<auml>ngel" |
1573
|
|
|
|
|
|
|
|
1574
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1575
|
|
|
|
|
|
|
Might also mean "Kein rollstuhlgerechter Wagen" (source: frubi). |
1576
|
|
|
|
|
|
|
|
1577
|
|
|
|
|
|
|
=item d 99 : "VerzE<ouml>gerungen im Betriebsablauf" |
1578
|
|
|
|
|
|
|
|
1579
|
|
|
|
|
|
|
=back |
1580
|
|
|
|
|
|
|
|
1581
|
|
|
|
|
|
|
=head1 DIAGNOSTICS |
1582
|
|
|
|
|
|
|
|
1583
|
|
|
|
|
|
|
None. |
1584
|
|
|
|
|
|
|
|
1585
|
|
|
|
|
|
|
=head1 DEPENDENCIES |
1586
|
|
|
|
|
|
|
|
1587
|
|
|
|
|
|
|
=over |
1588
|
|
|
|
|
|
|
|
1589
|
|
|
|
|
|
|
=item Class::Accessor(3pm) |
1590
|
|
|
|
|
|
|
|
1591
|
|
|
|
|
|
|
=back |
1592
|
|
|
|
|
|
|
|
1593
|
|
|
|
|
|
|
=head1 BUGS AND LIMITATIONS |
1594
|
|
|
|
|
|
|
|
1595
|
|
|
|
|
|
|
Unknown. |
1596
|
|
|
|
|
|
|
|
1597
|
|
|
|
|
|
|
=head1 SEE ALSO |
1598
|
|
|
|
|
|
|
|
1599
|
|
|
|
|
|
|
Travel::Status::DE::IRIS(3pm). |
1600
|
|
|
|
|
|
|
|
1601
|
|
|
|
|
|
|
=head1 AUTHOR |
1602
|
|
|
|
|
|
|
|
1603
|
|
|
|
|
|
|
Copyright (C) 2013-2023 by Birte Kristina Friesel E<lt>derf@finalrewind.orgE<gt> |
1604
|
|
|
|
|
|
|
|
1605
|
|
|
|
|
|
|
=head1 LICENSE |
1606
|
|
|
|
|
|
|
|
1607
|
|
|
|
|
|
|
This module is licensed under the same terms as Perl itself. |