camera - (real) remote control, brandschutz - configurable course, dashboard - vbb licensed API (a real vbb license, how cool)

This commit is contained in:
2026-09-08 18:21:51 +02:00
parent 3f98cf2663
commit ce90820094
24 changed files with 3044 additions and 2065 deletions
@@ -425,7 +425,7 @@
const age = now - departureData.updatedAt;
// Der globale Feed-Zeitstempel kann älter sein; entscheidend sind die
// Prognosen der einzelnen Fahrten und das Alter unseres letzten Abrufs.
const fresh = age < 300000;
const fresh = age < 300000 && !departureData.unavailable;
const rows = (age < 7200000 ? departureData.departures : [])
.map(d => ({ ...d, timestamp: Date.parse(d.when || d.plannedWhen) }))
.filter(d => Number.isFinite(d.timestamp) && d.timestamp >= now)
@@ -433,7 +433,7 @@
const live = fresh && Number.isFinite(d.delay) && Boolean(d.when);
const state = !fresh ? 'stale' : d.cancelled ? 'cancelled' : !live ? 'scheduled'
: d.delay > 0 ? 'delayed' : d.delay < 0 ? 'early' : 'ontime';
const status = { stale: 'veraltet', cancelled: 'entfällt', scheduled: 'pünktlich', ontime: 'pünktlich',
const status = { stale: 'veraltet', cancelled: 'entfällt', scheduled: 'Fahrplaninfo', ontime: 'pünktlich',
delayed: '+' + Math.ceil(d.delay / 60) + ' Min.', early: '−' + Math.ceil(-d.delay / 60) + ' Min.' }[state];
const minutes = Math.ceil((d.timestamp - now) / 60000);
const planned = Date.parse(d.plannedWhen);
@@ -445,7 +445,7 @@
departures.update(rows, fresh ? 'Keine Busabfahrten in den nächsten 120 Minuten.' : 'Live-Abfahrten derzeit nicht verfügbar.');
}
const refreshDepartures = createRefresh('departures_eich', data => {
if (!Array.isArray(data.departures) || !Number.isFinite(data.updatedAt)) throw new Error('Ungültige BVG-Antwort');
if (!Array.isArray(data.departures) || !Number.isFinite(data.updatedAt)) throw new Error('Ungültige VBB-Antwort');
Object.assign(departureData, data);
nextDepartureRequest = Number(data.retryAt) * 1000 || 0;
renderDepartures(Date.now());