NEWS
Anzeige von Bahn / Öffi / Zugverbindungen in Jarvis
-
Hi,
jetzt möchte ich hier auch mal wieder etwas zeigen.
Zu lösende Problemstellung: Ich möchte die Abfahrtzeiten von Zügen an zwei Bahnhöfen in Jarvis ausgeben. Der bisher genutzte Adapter "Fahrplan" wird nicht mehr weiterentwickelt und ist fehlerhaft.
Lösung:
- Die Quelle https://dbf.finalrewind.org nutzen (eine Einbindung via iFrame hat mir dabei nicht gefallen)
- Abfragen meines Bahnhofs per API um ein JSON zu erhalten (z. B. https://dbf.finalrewind.org/Hamburg Airport.json)
- die Daten mit Blockly per JSONata filtern (Danke @mickym für die Hilfe in einem anderen Thread zu JSONata!)
- das gekürzte JSON per JavaScript in ein schickes HTML verwandeln und in einen DP schreiben
- Ausgabe in Jarvis (Gerät erstellen, StateHTML Widget usw)
Ergebnis:
Blockly (JSON holen, JavaScript ausführen):
JSONata für den Blockly Teil:
departures[destination = "Hannover Hbf"].{"Zug": train, "Abfahrt" : scheduledDeparture, "Verspätung":delayDeparture, "Hinweis": messages.qos.text, "Verspätungshinweis": messages.delay.text, "fällt aus": isCancelled}
JavaScript zum bauen der Tabelle:
// JSON-Quelle const jsonData = varRB38; //Ziel Datenpunkt const dpiniob = '0_userdata.0.Jarvis.Bahn.SchwarmstedtNachHannover_html'; // Funktion, um neue Abfahrtszeit zu berechnen function calculateNewDeparture(data) { data.forEach(item => { const [hours, minutes] = item.Abfahrt.split(':').map(Number); const newMinutes = minutes + item.Verspätung; const newHours = hours + Math.floor(newMinutes / 60); const newMinutesAdjusted = newMinutes % 60; // Formatieren der neuen Zeit const newTime = `${String(newHours).padStart(2, '0')}:${String(newMinutesAdjusted).padStart(2, '0')}`; item['NeueAbfahrt'] = newTime; }); return data; } // Neue Abfahrtszeiten berechnen const updatedData = calculateNewDeparture(jsonData); // Funktion, um die Tabelle zu generieren function generateTable(data) { let tableHtml = ` <style> table { border-collapse: collapse; font-family: Arial, sans-serif; width: 100%; border: none; } th, td { padding: 10px; border-bottom: 1px solid #ddd; } th { background-color: #f0f0f0; font-weight: bold; text-align: left; } </style> <table> <tr><th style='text-align: left'>Zug</th><th style='text-align: left'>Abfahrt</th><th style='text-align: left'> </th><th style='text-align: left'>Details</th></tr> `; data.forEach(item => { let rowHtml = "<tr>"; // Zug rowHtml += `<td>${item.Zug}</td>`; // Abfahrt if (item.Verspätung > 1) { rowHtml += `<td><b style="color: red">${item.NeueAbfahrt}</b> <font color=red > +${item.Verspätung}</font> </td>`; } else if (item['fällt aus'] == 1){ rowHtml += `<td>${item.Abfahrt}</td>`; } else { rowHtml += `<td><b style="color: green">${item.Abfahrt}</b></td>`; } // Hinweis if (item.Verspätungshinweis) { rowHtml += `<td>${item.Verspätungshinweis}</td>`; } else { rowHtml += "<td></td>"; } // Zuginformationen if (item.Hinweis) { rowHtml += `<td>${item.Hinweis}</td>`; } else if (item['fällt aus'] == 1){ rowHtml += `<td style="text-decoration: none"><font color=red><b>Verbindung fällt aus</font></b></td>`; } else { rowHtml += "<td></td>"; } rowHtml += "</tr>"; // Durchstreichen, wenn fällt aus == 1 if (item['fällt aus'] == 1) { rowHtml = rowHtml.replace(/<td>/g, '<td style="text-decoration: line-through;">'); rowHtml = rowHtml.replace(/<td style="text-decoration: none">/, '<td>'); } tableHtml += rowHtml; }); tableHtml += "</table>"; return tableHtml; } // Tabelle generieren und in ioBroker schreiben const tableHtml = generateTable(updatedData.slice(0, 5)); // Hier wird die Anzahl der Reihen auf 5 begrenzt setState(dpiniob, tableHtml);
Vielleicht inspiriert es ja den ein oder anderen um Zugdaten in seiner Vis auszugeben.
Und auch hier: vermutlich könnte man sich ein paar Schritte im JavaScript sparen wenn man mit JSONata besser zurecht kommt