Code kopieren & zu File Editor
1# Deutsche Bahn API Integration
2# Echtzeit-Zugdaten für lokale Bahnhöfe mit Verspätungen und Störungen
3
4# Basis-Konfiguration - API Key über https://developers.deutschebahn.com/
5# Kostenloser Zugang für private Nutzung verfügbar
6
7# REST-Sensoren für Timetable API
8sensor:
9 # Nächste Abfahrten vom Heimatbahnhof
10 - platform: rest
11 name: "DB Abfahrten Heimat"
12 resource_template: >
13 https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/station/{{ states('input_text.db_home_station_id') }}/{{ now().strftime('%y%m%d/%H%M') }}
14 headers:
15 Authorization: !secret db_api_key
16 Accept: application/json
17 scan_interval: 300 # Alle 5 Minuten
18 value_template: "{{ value_json.length if value_json else 0 }}"
19 unit_of_measurement: "Züge"
20 json_attributes_path: "$[0:5]" # Erste 5 Abfahrten
21 json_attributes:
22 - dp
23 - ar
24 - category
25 - number
26 - line
27 - to
28 - platform
29 - delay
30
31 # Nächste Abfahrten vom Arbeitsplatz
32 - platform: rest
33 name: "DB Abfahrten Arbeit"
34 resource_template: >
35 https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/station/{{ states('input_text.db_work_station_id') }}/{{ now().strftime('%y%m%d/%H%M') }}
36 headers:
37 Authorization: !secret db_api_key
38 Accept: application/json
39 scan_interval: 300
40 value_template: "{{ value_json.length if value_json else 0 }}"
41 unit_of_measurement: "Züge"
42 json_attributes_path: "$[0:5]"
43 json_attributes:
44 - dp
45 - ar
46 - category
47 - number
48 - line
49 - to
50 - platform
51 - delay
52
53 # Verbindungssuche Hin (Morgens zur Arbeit)
54 - platform: rest
55 name: "DB Verbindung Hinfahrt"
56 resource_template: >
57 https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/journey/{{ states('input_text.db_home_station_id') }}/{{ states('input_text.db_work_station_id') }}/{{ (now() + timedelta(minutes=30)).strftime('%y%m%d/%H%M') }}
58 headers:
59 Authorization: !secret db_api_key
60 Accept: application/json
61 scan_interval: 600 # Alle 10 Minuten
62 value_template: >
63 {% if value_json and value_json|length > 0 %}
64 {{ value_json[0].duration if value_json[0].duration else "N/A" }}
65 {% else %}
66 "Keine Verbindung"
67 {% endif %}
68 json_attributes_path: "$[0]"
69 json_attributes:
70 - departure
71 - arrival
72 - duration
73 - changes
74 - delay
75 - products
76
77 # Verbindungssuche Rück (Abends nach Hause)
78 - platform: rest
79 name: "DB Verbindung Rückfahrt"
80 resource_template: >
81 https://apis.deutschebahn.com/db-api-marketplace/apis/timetables/v1/journey/{{ states('input_text.db_work_station_id') }}/{{ states('input_text.db_home_station_id') }}/{{ (now() + timedelta(hours=8)).strftime('%y%m%d/%H%M') }}
82 headers:
83 Authorization: !secret db_api_key
84 Accept: application/json
85 scan_interval: 900 # Alle 15 Minuten
86 value_template: >
87 {% if value_json and value_json|length > 0 %}
88 {{ value_json[0].duration if value_json[0].duration else "N/A" }}
89 {% else %}
90 "Keine Verbindung"
91 {% endif %}
92 json_attributes_path: "$[0]"
93 json_attributes:
94 - departure
95 - arrival
96 - duration
97 - changes
98 - delay
99 - products
100
101# StaDa (Station Data) API für Bahnhofsinformationen
102 - platform: rest
103 name: "DB Station Info Heimat"
104 resource_template: >
105 https://apis.deutschebahn.com/db-api-marketplace/apis/station-data/v2/stations/{{ states('input_text.db_home_station_id') }}
106 headers:
107 Authorization: !secret db_api_key
108 Accept: application/json
109 scan_interval: 86400 # Einmal täglich
110 value_template: "{{ value_json.name if value_json else 'Unbekannt' }}"
111 json_attributes:
112 - name
113 - eva
114 - category
115 - federalState
116 - hasWiFi
117 - hasLockerSystem
118 - hasLostAndFound
119 - hasCarRental
120 - hasTravelNecessities
121
122# FaSta API für Facility Status (Aufzüge, Rolltreppen)
123 - platform: rest
124 name: "DB Facilities Status"
125 resource_template: >
126 https://apis.deutschebahn.com/db-api-marketplace/apis/fasta/v2/facilities/{{ states('input_text.db_home_station_id') }}
127 headers:
128 Authorization: !secret db_api_key
129 Accept: application/json
130 scan_interval: 600
131 value_template: >
132 {% if value_json and value_json.facilities %}
133 {{ value_json.facilities | selectattr('state', 'equalto', 'ACTIVE') | list | length }}
134 {% else %}
135 0
136 {% endif %}
137 unit_of_measurement: "Aktiv"
138 json_attributes_path: "$.facilities[*]"
139 json_attributes:
140 - type
141 - state
142 - description
143
144# Template-Sensoren für benutzerfreundliche Darstellung
145 - platform: template
146 sensors:
147 db_next_departure_time:
148 friendly_name: "Nächste Abfahrt"
149 value_template: >
150 {% set departures = state_attr('sensor.db_abfahrten_heimat', 'dp') %}
151 {% if departures and departures|length > 0 %}
152 {% set next_dp = departures[0] %}
153 {% if next_dp.delay %}
154 {{ next_dp.time }} (+{{ next_dp.delay }})
155 {% else %}
156 {{ next_dp.time }}
157 {% endif %}
158 {% else %}
159 "Keine Daten"
160 {% endif %}
161 icon_template: "mdi:train"
162
163 db_next_departure_platform:
164 friendly_name: "Nächster Bahnsteig"
165 value_template: >
166 {% set departures = state_attr('sensor.db_abfahrten_heimat', 'platform') %}
167 {% if departures and departures|length > 0 %}
168 {{ departures[0] }}
169 {% else %}
170 "Unbekannt"
171 {% endif %}
172 icon_template: "mdi:sign-direction"
173
174 db_next_departure_destination:
175 friendly_name: "Nächstes Ziel"
176 value_template: >
177 {% set departures = state_attr('sensor.db_abfahrten_heimat', 'to') %}
178 {% if departures and departures|length > 0 %}
179 {{ departures[0] }}
180 {% else %}
181 "Unbekannt"
182 {% endif %}
183 icon_template: "mdi:map-marker"
184
185 db_commute_duration:
186 friendly_name: "Arbeitsweg Dauer"
187 value_template: >
188 {% set duration = state_attr('sensor.db_verbindung_hinfahrt', 'duration') %}
189 {% if duration %}
190 {{ duration }} min
191 {% else %}
192 "Unbekannt"
193 {% endif %}
194 icon_template: "mdi:clock-outline"
195
196 db_commute_changes:
197 friendly_name: "Arbeitsweg Umstiege"
198 value_template: >
199 {% set changes = state_attr('sensor.db_verbindung_hinfahrt', 'changes') %}
200 {% if changes is not none %}
201 {{ changes }}
202 {% else %}
203 "Unbekannt"
204 {% endif %}
205 icon_template: "mdi:swap-horizontal"
206
207 db_total_delay:
208 friendly_name: "Gesamtverspätung heute"
209 unit_of_measurement: "min"
210 value_template: >
211 {% set home_delay = state_attr('sensor.db_abfahrten_heimat', 'delay') %}
212 {% set work_delay = state_attr('sensor.db_abfahrten_arbeit', 'delay') %}
213 {% set total = 0 %}
214 {% if home_delay %}
215 {% for delay in home_delay %}
216 {% if delay %}
217 {% set total = total + delay %}
218 {% endif %}
219 {% endfor %}
220 {% endif %}
221 {% if work_delay %}
222 {% for delay in work_delay %}
223 {% if delay %}
224 {% set total = total + delay %}
225 {% endif %}
226 {% endfor %}
227 {% endif %}
228 {{ total }}
229
230# Input Helper für Bahnhofs-IDs
231input_text:
232 db_home_station_id:
233 name: "Heimat-Bahnhof ID"
234 initial: "8000105" # Beispiel: Frankfurt Hbf
235 max: 10
236 pattern: '[0-9]*'
237 mode: text
238
239 db_work_station_id:
240 name: "Arbeitsplatz-Bahnhof ID"
241 initial: "8000261" # Beispiel: München Hbf
242 max: 10
243 pattern: '[0-9]*'
244 mode: text
245
246# Boolean Helper für Benachrichtigungen
247input_boolean:
248 db_notifications_enabled:
249 name: "Bahn-Benachrichtigungen aktiviert"
250 initial: true
251 icon: "mdi:bell-ring"
252
253 db_delay_alerts:
254 name: "Verspätungs-Alarme"
255 initial: true
256 icon: "mdi:alert-circle"
257
258 db_commute_mode:
259 name: "Pendler-Modus aktiv"
260 initial: false
261 icon: "mdi:briefcase"
262
263# Number Helper für Verspätungs-Schwelle
264input_number:
265 db_delay_threshold:
266 name: "Verspätungs-Alarm ab"
267 min: 5
268 max: 60
269 step: 5
270 initial: 15
271 unit_of_measurement: "min"
272 icon: "mdi:clock-alert"
273
274# Binäre Sensoren für Alarme
275binary_sensor:
276 - platform: template
277 sensors:
278 db_significant_delay:
279 friendly_name: "Erhebliche Verspätung"
280 value_template: >
281 {{ states('sensor.db_total_delay') | float >
282 states('input_number.db_delay_threshold') | float }}
283 device_class: problem
284 delay_on: "00:02:00"
285
286 db_elevator_outage:
287 friendly_name: "Aufzug-Ausfall"
288 value_template: >
289 {% set facilities = state_attr('sensor.db_facilities_status', 'type') %}
290 {% set states_list = state_attr('sensor.db_facilities_status', 'state') %}
291 {% if facilities and states_list %}
292 {% for i in range(facilities|length) %}
293 {% if facilities[i] == 'ELEVATOR' and states_list[i] != 'ACTIVE' %}
294 true
295 {% endif %}
296 {% endfor %}
297 false
298 {% else %}
299 false
300 {% endif %}
301 device_class: problem
302
303 db_connection_available:
304 friendly_name: "Verbindung verfügbar"
305 value_template: >
306 {{ states('sensor.db_verbindung_hinfahrt') != 'Keine Verbindung' }}
307 device_class: connectivity
308
309 db_commute_time:
310 friendly_name: "Pendelzeit aktiv"
311 value_template: >
312 {% set now_time = now().hour * 100 + now().minute %}
313 {% set is_workday = now().weekday() < 5 %}
314 {% set morning_commute = 600 <= now_time <= 1000 %} # 06:00-10:00
315 {% set evening_commute = 1600 <= now_time <= 2000 %} # 16:00-20:00
316 {{ is_workday and (morning_commute or evening_commute) and
317 is_state('input_boolean.db_commute_mode', 'on') }}
318
319# Automatisierungen für Bahn-Benachrichtigungen
320automation:
321 - alias: "DB Verspätungs-Alarm"
322 trigger:
323 - platform: state
324 entity_id: binary_sensor.db_significant_delay
325 to: "on"
326 condition:
327 - condition: state
328 entity_id: input_boolean.db_delay_alerts
329 state: "on"
330 - condition: state
331 entity_id: binary_sensor.db_commute_time
332 state: "on"
333 action:
334 - service: notify.mobile_app
335 data:
336 title: "🚆 Bahn-Verspätung"
337 message: >
338 Gesamtverspätung: {{ states('sensor.db_total_delay') }} Minuten
339 Nächste Abfahrt: {{ states('sensor.db_next_departure_time') }}
340 data:
341 tag: "train_delay"
342 group: "transport"
343 actions:
344 - action: "check_alternatives"
345 title: "Alternativen prüfen"
346
347 - alias: "DB Aufzug-Ausfall"
348 trigger:
349 - platform: state
350 entity_id: binary_sensor.db_elevator_outage
351 to: "on"
352 condition:
353 - condition: state
354 entity_id: input_boolean.db_notifications_enabled
355 state: "on"
356 action:
357 - service: notify.mobile_app
358 data:
359 title: "♿ Aufzug außer Betrieb"
360 message: "Aufzug am {{ state_attr('sensor.db_station_info_heimat', 'name') }} defekt"
361 data:
362 tag: "elevator_outage"
363
364 - alias: "DB Morgendliche Pendler-Info"
365 trigger:
366 - platform: time
367 at: "07:00:00"
368 condition:
369 - condition: state
370 entity_id: input_boolean.db_commute_mode
371 state: "on"
372 - condition: time
373 weekday:
374 - mon
375 - tue
376 - wed
377 - thu
378 - fri
379 action:
380 - service: notify.mobile_app
381 data:
382 title: "🌅 Pendler-Info"
383 message: >
384 Arbeitsweg: {{ states('sensor.db_commute_duration') }}
385 Umstiege: {{ states('sensor.db_commute_changes') }}
386 Nächste Abfahrt: {{ states('sensor.db_next_departure_time') }}
387 Bahnsteig: {{ states('sensor.db_next_departure_platform') }}
388
389 - alias: "DB Abendliche Rückfahrt-Erinnerung"
390 trigger:
391 - platform: time
392 at: "17:30:00"
393 condition:
394 - condition: state
395 entity_id: input_boolean.db_commute_mode
396 state: "on"
397 - condition: time
398 weekday:
399 - mon
400 - tue
401 - wed
402 - thu
403 - fri
404 action:
405 - service: notify.mobile_app
406 data:
407 title: "🏠 Rückfahrt-Info"
408 message: >
409 Rückfahrt: {{ states('sensor.db_verbindung_rückfahrt') }}
410 {% if states('sensor.db_total_delay') | float > 10 %}
411 ⚠️ Aktuelle Verspätung: {{ states('sensor.db_total_delay') }} min
412 {% endif %}
413
414# Script für manuelle Verbindungssuche
415script:
416 db_search_connection:
417 alias: "DB Verbindung suchen"
418 fields:
419 from_station:
420 description: "Start-Bahnhof ID"
421 example: "8000105"
422 to_station:
423 description: "Ziel-Bahnhof ID"
424 example: "8000261"
425 departure_time:
426 description: "Abfahrtszeit (optional)"
427 example: "08:00"
428 sequence:
429 - service: notify.persistent_notification
430 data:
431 title: "DB Verbindungssuche"
432 message: "Suche Verbindung von {{ from_station }} nach {{ to_station }}..."
433 - service: homeassistant.update_entity
434 target:
435 entity_id: sensor.db_verbindung_hinfahrt
436 - delay: 5
437 - service: notify.mobile_app
438 data:
439 title: "🔍 Verbindung gefunden"
440 message: >
441 Dauer: {{ state_attr('sensor.db_verbindung_hinfahrt', 'duration') }} min
442 Umstiege: {{ state_attr('sensor.db_verbindung_hinfahrt', 'changes') }}
443 Abfahrt: {{ state_attr('sensor.db_verbindung_hinfahrt', 'departure') }}
444
445# Utility Meter für Statistiken
446utility_meter:
447 db_delays_monthly:
448 source: sensor.db_total_delay
449 cycle: monthly
450 name: "Monatliche Verspätungen"
451
452# Counter für Störungen
453counter:
454 db_disruptions_today:
455 name: "Störungen heute"
456 initial: 0
457 step: 1
458 icon: "mdi:train-car-passenger-door"