Die Häufigkeiten von Zugverspätungen werden nun in der DB gespeichert
This commit is contained in:
parent
137b53d186
commit
b8502c680e
3 changed files with 109 additions and 14 deletions
|
@ -16,6 +16,7 @@ services:
|
||||||
- DURATION=240
|
- DURATION=240
|
||||||
- DELETE_AFTER_MINUTES=30
|
- DELETE_AFTER_MINUTES=30
|
||||||
- UPDATE_INTERVAL_MINUTES=1
|
- UPDATE_INTERVAL_MINUTES=1
|
||||||
|
- TRANSFER_TIME=17:00
|
||||||
# Hildesheim HBF, Braunschweig HBF, Hannover HBF
|
# Hildesheim HBF, Braunschweig HBF, Hannover HBF
|
||||||
- STATION_IDS=8000169,8000049,8000152
|
- STATION_IDS=8000169,8000049,8000152
|
||||||
restart: always
|
restart: always
|
||||||
|
|
18
init.sql
18
init.sql
|
@ -1,3 +1,4 @@
|
||||||
|
-- Tabelle für Zugfahrten
|
||||||
CREATE TABLE IF NOT EXISTS trips (
|
CREATE TABLE IF NOT EXISTS trips (
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
id VARCHAR(36) PRIMARY KEY,
|
||||||
latitude DOUBLE,
|
latitude DOUBLE,
|
||||||
|
@ -7,14 +8,27 @@ CREATE TABLE IF NOT EXISTS trips (
|
||||||
fahrt_nr VARCHAR(20),
|
fahrt_nr VARCHAR(20),
|
||||||
trip_id VARCHAR(255),
|
trip_id VARCHAR(255),
|
||||||
planned_timestamp DATETIME,
|
planned_timestamp DATETIME,
|
||||||
delay INT
|
delay INT,
|
||||||
|
INDEX idx_fahrt_nr_timestamp (fahrt_nr, timestamp)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- Tabelle für tägliche Verspätungsstatistiken
|
||||||
|
CREATE TABLE IF NOT EXISTS today_delay_stats (
|
||||||
|
id VARCHAR(36) PRIMARY KEY,
|
||||||
|
fahrt_nr VARCHAR(255),
|
||||||
|
train_name VARCHAR(255),
|
||||||
|
delay INT,
|
||||||
|
timestamp DATETIME,
|
||||||
|
UNIQUE KEY uk_fahrt_nr_date (fahrt_nr, timestamp)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Tabelle für aggregierte Verspätungsstatistiken
|
||||||
CREATE TABLE IF NOT EXISTS delay_stats (
|
CREATE TABLE IF NOT EXISTS delay_stats (
|
||||||
id VARCHAR(36) PRIMARY KEY,
|
id VARCHAR(36) PRIMARY KEY,
|
||||||
fahrt_nr VARCHAR(255),
|
fahrt_nr VARCHAR(255),
|
||||||
total_trips INT,
|
total_trips INT,
|
||||||
delayed_trips INT,
|
delayed_trips INT,
|
||||||
avg_delay FLOAT,
|
avg_delay FLOAT,
|
||||||
last_updated DATETIME
|
last_updated DATETIME,
|
||||||
|
INDEX idx_fahrt_nr (fahrt_nr)
|
||||||
);
|
);
|
||||||
|
|
104
main.go
104
main.go
|
@ -86,6 +86,16 @@ func main() {
|
||||||
updateInterval = 1
|
updateInterval = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transferTimeStr := os.Getenv("TRANSFER_TIME")
|
||||||
|
transferTime, err := time.Parse("15:04", transferTimeStr)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Ungültiger Wert für TRANSFER_TIME, verwende Standardwert 23:00")
|
||||||
|
transferTime = time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 23, 0, 0, 0, time.Local)
|
||||||
|
} else {
|
||||||
|
now := time.Now()
|
||||||
|
transferTime = time.Date(now.Year(), now.Month(), now.Day(), transferTime.Hour(), transferTime.Minute(), 0, 0, time.Local)
|
||||||
|
}
|
||||||
|
|
||||||
db, err := sql.Open("mysql", dbDSN)
|
db, err := sql.Open("mysql", dbDSN)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Fehler beim Verbinden mit der Datenbank: ", err)
|
log.Fatal("Fehler beim Verbinden mit der Datenbank: ", err)
|
||||||
|
@ -109,12 +119,19 @@ func main() {
|
||||||
deleteOldEntries(db, deleteAfter)
|
deleteOldEntries(db, deleteAfter)
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
logDatabaseStats(db)
|
logDatabaseStats(db)
|
||||||
|
default:
|
||||||
|
now := time.Now()
|
||||||
|
if now.After(transferTime) {
|
||||||
|
transferDailyDelayStats(db)
|
||||||
|
transferTime = time.Date(now.Year(), now.Month(), now.Day()+1, transferTime.Hour(), transferTime.Minute(), 0, 0, time.Local)
|
||||||
|
}
|
||||||
|
time.Sleep(1 * time.Minute)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchDepartures(apiBaseURL, stationID string, duration int) []Departure {
|
func fetchDepartures(apiBaseURL, stationID string, duration int) []Departure {
|
||||||
url := fmt.Sprintf("%s/stops/%s/departures?duration=%d&linesOfStops=false&remarks=true&language=en&nationalExpress=true&national=true®ionalExpress=true®ional=true&suburban=true&bus=false&ferry=false&subway=false&tram=false&taxi=false&pretty=true",
|
url := fmt.Sprintf("%s/stops/%s/departures?duration=%d&linesOfStops=false&remarks=true&language=en&nationalExpress=true&national=true®ionalExpress=true®ional=true&suburban=true&bus=false&ferry=false&subway=false&tram=false&taxi=false&pretty=false",
|
||||||
apiBaseURL, stationID, duration)
|
apiBaseURL, stationID, duration)
|
||||||
resp, err := http.Get(url)
|
resp, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -147,7 +164,7 @@ func fetchDepartures(apiBaseURL, stationID string, duration int) []Departure {
|
||||||
|
|
||||||
func fetchTripDetails(apiBaseURL, tripID string) (*TripDetails, error) {
|
func fetchTripDetails(apiBaseURL, tripID string) (*TripDetails, error) {
|
||||||
escapedTripID := url.QueryEscape(tripID)
|
escapedTripID := url.QueryEscape(tripID)
|
||||||
url := fmt.Sprintf("%s/trips/%s?stopovers=true&remarks=true&polyline=true&language=en", apiBaseURL, escapedTripID)
|
url := fmt.Sprintf("%s/trips/%s?stopovers=true&remarks=true&polyline=true&language=en&pretty=false", apiBaseURL, escapedTripID)
|
||||||
resp, err := http.Get(url)
|
resp, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Fehler beim Abrufen der Zugdetails: %v", err)
|
return nil, fmt.Errorf("Fehler beim Abrufen der Zugdetails: %v", err)
|
||||||
|
@ -225,24 +242,87 @@ func savePosition(db *sql.DB, dep Departure, apiBaseURL string) {
|
||||||
log.Printf("Fehler bei der Überprüfung des existierenden Eintrags für TripID %s: %v\n", dep.TripId, err)
|
log.Printf("Fehler bei der Überprüfung des existierenden Eintrags für TripID %s: %v\n", dep.TripId, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDelayStats(db, dep.Line.FahrtNr, dep.Delay)
|
updateTodayDelayStats(db, dep.Line.FahrtNr, dep.Line.Name, dep.Delay, whenTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateDelayStats(db *sql.DB, fahrtNr string, delay int) {
|
func updateTodayDelayStats(db *sql.DB, fahrtNr, trainName string, delay int, timestamp time.Time) {
|
||||||
var id string
|
var existingID string
|
||||||
err := db.QueryRow("SELECT id FROM delay_stats WHERE fahrt_nr = ?", fahrtNr).Scan(&id)
|
err := db.QueryRow("SELECT id FROM today_delay_stats WHERE fahrt_nr = ? AND DATE(timestamp) = CURDATE()", fahrtNr).Scan(&existingID)
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
id = uuid.New().String()
|
// Kein existierender Eintrag, führe INSERT aus
|
||||||
_, err = db.Exec("INSERT INTO delay_stats (id, fahrt_nr, total_trips, delayed_trips, avg_delay, last_updated) VALUES (?, ?, 1, ?, ?, NOW())",
|
_, err = db.Exec(`
|
||||||
id, fahrtNr, delay > 300, delay)
|
INSERT INTO today_delay_stats (id, fahrt_nr, train_name, delay, timestamp)
|
||||||
|
VALUES (UUID(), ?, ?, ?, ?)
|
||||||
|
`, fahrtNr, trainName, delay, timestamp)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Fehler beim Einfügen der heutigen Verspätungsstatistiken für FahrtNr %s: %v\n", fahrtNr, err)
|
||||||
|
}
|
||||||
} else if err == nil {
|
} else if err == nil {
|
||||||
_, err = db.Exec("UPDATE delay_stats SET total_trips = total_trips + 1, delayed_trips = delayed_trips + ?, avg_delay = ((avg_delay * total_trips) + ?) / (total_trips + 1), last_updated = NOW() WHERE id = ?",
|
// Existierender Eintrag gefunden, führe UPDATE aus
|
||||||
delay > 300, delay, id)
|
_, err = db.Exec(`
|
||||||
|
UPDATE today_delay_stats
|
||||||
|
SET train_name = ?, delay = ?, timestamp = ?
|
||||||
|
WHERE id = ?
|
||||||
|
`, trainName, delay, timestamp, existingID)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Fehler beim Aktualisieren der heutigen Verspätungsstatistiken für FahrtNr %s: %v\n", fahrtNr, err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Printf("Fehler beim Überprüfen der heutigen Verspätungsstatistiken für FahrtNr %s: %v\n", fahrtNr, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func transferDailyDelayStats(db *sql.DB) {
|
||||||
|
rows, err := db.Query("SELECT fahrt_nr, train_name, delay FROM today_delay_stats WHERE DATE(timestamp) = CURDATE()")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Fehler beim Abrufen der heutigen Verspätungsstatistiken: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
var fahrtNr, trainName string
|
||||||
|
var delay int
|
||||||
|
if err := rows.Scan(&fahrtNr, &trainName, &delay); err != nil {
|
||||||
|
log.Printf("Fehler beim Scannen der Verspätungsdaten: %v\n", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var existingID string
|
||||||
|
err := db.QueryRow("SELECT id FROM delay_stats WHERE fahrt_nr = ?", fahrtNr).Scan(&existingID)
|
||||||
|
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
// Kein existierender Eintrag, führe INSERT aus
|
||||||
|
_, err = db.Exec(`
|
||||||
|
INSERT INTO delay_stats (id, fahrt_nr, total_trips, delayed_trips, avg_delay, last_updated)
|
||||||
|
VALUES (UUID(), ?, 1, ?, ?, NOW())
|
||||||
|
`, fahrtNr, delay > 300, delay)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Fehler beim Einfügen der Verspätungsstatistiken für FahrtNr %s: %v\n", fahrtNr, err)
|
||||||
|
}
|
||||||
|
} else if err == nil {
|
||||||
|
// Existierender Eintrag gefunden, führe UPDATE aus
|
||||||
|
_, err = db.Exec(`
|
||||||
|
UPDATE delay_stats
|
||||||
|
SET total_trips = total_trips + 1,
|
||||||
|
delayed_trips = delayed_trips + ?,
|
||||||
|
avg_delay = ((avg_delay * total_trips) + ?) / (total_trips + 1),
|
||||||
|
last_updated = NOW()
|
||||||
|
WHERE id = ?
|
||||||
|
`, delay > 300, delay, existingID)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Fehler beim Aktualisieren der Verspätungsstatistiken für FahrtNr %s: %v\n", fahrtNr, err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Printf("Fehler beim Überprüfen der Verspätungsstatistiken für FahrtNr %s: %v\n", fahrtNr, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Löschen Sie die heutigen Statistiken nach der Übertragung
|
||||||
|
_, err = db.Exec("DELETE FROM today_delay_stats WHERE DATE(timestamp) = CURDATE()")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Fehler beim Aktualisieren der Verspätungsstatistiken für FahrtNr %s: %v\n", fahrtNr, err)
|
log.Printf("Fehler beim Löschen der heutigen Verspätungsstatistiken: %v\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue