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 