- Python 41.9%
- HTML 38.9%
- CSS 15.2%
- JavaScript 4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| static | ||
| templates | ||
| .gitignore | ||
| app.py | ||
| balance.py | ||
| categorize_transactions.py | ||
| database_sync.py | ||
| README.md | ||
| requirements.txt | ||
| todo.md | ||
| transaction_categories.py | ||
| transaction_exclusions.py | ||
| transaction_notes.py | ||
| transactions.py | ||
| VERSION | ||
ING FinTS Auswertung
Python-Skripte und Flask-Dashboard zur Auswertung eines ING-Kontos über FinTS.
Funktionen
- aktueller Kontostand aus ioBroker
- Verlaufsgrafik des Kontostands mit Vergleich zum Mittel der Vormonate
- Ampelstatus und Differenz zum Vormonatsmittel im Dashboard
- Transaktionen der aktuellen Kalenderwoche
- unbekannte Buchungen mit direktem Einstieg in die Kategorienpflege
- Kategorienverwaltung mit Schlüsselwörtern
- automatische Neukategorisierung nach neuem Schlüsselwort
- Wartungsbereich mit Reitern für Ausführung, Zeitpläne, Auswertung und System
- getrennte manuelle Scriptstarts und Cron-Verwaltung für die drei Hauptscripts
- Log-Anzeige und Log-Download
- Hell-/Dunkelmodus
- Versionsanzeige mit Git-Commit, Änderungsstatus und Update-Hinweis
Scripts
balance.py
- ruft den aktuellen Kontostand ab
- schreibt den Kontostand nach ioBroker
- protokolliert den Lauf in
logs/ing.log
transactions.py
- lädt Kontobewegungen für eine Kalenderwoche
- erzeugt CSV- und JSON-Dateien
- schreibt Kennzahlen nach ioBroker
- protokolliert den Lauf in
logs/ing.log
categorize_transactions.py
- kategorisiert Transaktionen anhand von
Kategorien.json - erzeugt kategorisierte CSV- und JSON-Dateien
- erstellt Wochenzusammenfassungen
- aktualisiert die Excel-Jahresauswertung
- protokolliert den Lauf in
logs/ing.log
Dashboard
Kontostand
Der aktuelle Kontostand wird groß hervorgehoben. Die Farbe der Zahl zeigt das absolute Risiko:
- grün: unkritisch
- orange: Warnbereich
- rot: kritisch oder negativer Kontostand
Das Reload-Symbol neben der Kalenderwoche startet das vollständige Wochenupdate: Kontostand laden, Transaktionen abrufen und kategorisieren.
Die kleine Ampel darunter vergleicht den aktuellen Stand mit dem Mittel der Vormonate am gleichen Periodentag:
- grün: aktueller Stand liegt über dem Mittel
- orange: aktueller Stand liegt nahe am Mittel
- rot: aktueller Stand liegt darunter
- grau: kein Vergleich möglich
Daneben steht die Differenz, zum Beispiel:
+200,00 € zum Mittel der Vormonate
-30,00 € zum Mittel der Vormonate
Tabellen
Das Dashboard zeigt:
- Transaktionen in dieser Woche inklusive Gesamtanzahl
- unbekannte Buchungen inklusive Anzahl offener Buchungen
Jeder Umsatz kann direkt im Dashboard als nicht berücksichtigt markiert werden. Markierte Umsätze bleiben sichtbar und erhalten eine eindeutige Kennzeichnung, fließen aber nicht in Einnahmen, Ausgaben, Saldo, Kategoriesummen, Diagramme, ioBroker-Wochenkennzahlen und Excel-Kennzahlen ein. Über denselben Schalter oder die Wartungsseite lassen sie sich jederzeit wieder berücksichtigen. Die Originaldaten in den Roh-JSON- und CSV-Dateien bleiben unverändert.
Datumswerte werden im deutschen Format angezeigt.
Kategorien
Kategorien werden in Kategorien.json gepflegt. Jede Kategorie kann mehrere
Schlüsselwörter enthalten. Zusätzlich lässt sich in der Kategorienverwaltung
getrennt festlegen, ob positive Buchungen als Einnahmen und negative Buchungen
als Ausgaben in den Auswertungen berücksichtigt werden. Beide Einstellungen
sind bei neuen und älteren Kategorien standardmäßig aktiv.
Beispiel:
{
"Einnahme": {
"keywords": ["Gehalt"],
"include_income": true,
"include_expenses": false
}
}
Eine deaktivierte Buchungsart bleibt kategorisiert und in der Transaktionsliste sichtbar, fließt aber nicht in Summen, Saldo, Diagramme und Excel-Kennzahlen ein.
Bei der Zuordnung werden die Felder in dieser Reihenfolge geprüft: Buchungsname, Verwendungszweck, Buchungstext. Ein Treffer im Buchungsnamen hat damit Vorrang vor Händlern oder anderen Begriffen im Verwendungszweck.
Im Buchungsdetail-Overlay kann eine Kategorie manuell zugewiesen werden.
Zusätzlich kann dort für jede Buchung eine individuelle Notiz hinterlegt werden.
In der Kachel „Transaktionen in dieser Woche“ öffnet das Stiftsymbol direkt
das Notizfeld. Die Notizen bleiben bei erneuten Bankabrufen erhalten und werden
als eigene Spalte in den kategorisierten CSV- und Excel-Export übernommen.
Manuelle Zuordnungen werden in .transaction_categories.json gespeichert und
haben bei späteren Kategorisierungsläufen Vorrang. Mit Automatisch zuordnen
wird die manuelle Festlegung für die Buchung wieder aufgehoben.
Wenn einer Kategorie ein neues Schlüsselwort hinzugefügt wird, führt die App automatisch aus:
python3 categorize_transactions.py <aktuelles-jahr> <aktuelle-kw>
Die aktuelle Kalenderwoche wird dadurch direkt neu kategorisiert.
Wartung
Im Wartungsbereich können folgende Aktionen manuell gestartet werden:
- Wochenupdate ausführen
- Kontostand aktualisieren
- Transaktionen laden
Die Kategorisierung wird automatisch beim Laden der Transaktionen und beim Wochenupdate ausgeführt. Ihr Zeitplan bleibt im Reiter Zeitpläne separat konfigurierbar.
Der Reiter Zeitpläne zeigt zusätzlich die vollständige Crontab des Dienstbenutzers. Auf dem Linux-Server kann sie direkt bearbeitet und gespeichert werden. Unter Windows und macOS wird eine schreibgeschützte Vorschau der lokal gespeicherten Zeitpläne angezeigt. Alle vier Kacheln lassen sich über das Symbol oben rechts einzeln ein- und ausklappen; der Zustand wird im Browser gespeichert.
Im Reiter Zugang & System kann die App auf dem Linux-Server über App Neustart neu gestartet werden. Vor dem Neustart erscheint ein Bestätigungsdialog. Unter Windows und macOS bleibt der Button deaktiviert; dort erfolgt der Neustart weiterhin in der Entwicklungsumgebung.
Unter Dashboard-Kennzahlen lassen sich Verwendungszwecke pflegen, die bei
der Rücklagen-Kennzahl nicht berücksichtigt werden. Die Begriffe werden ohne
Beachtung der Groß-/Kleinschreibung als Teil des Verwendungszwecks gesucht.
Die lokale Konfiguration liegt in .dashboard_metrics.json; standardmäßig sind
WP.ABRECHNUNG und Kindergeld ausgeschlossen.
Unter Grenzwerte & Indikatoren lassen sich Kontostand-Ampel,
Vormonatsvergleich, Betragsfarben und Gehalts-Countdown einzeln aktivieren
und konfigurieren. Die Einstellungen
werden ebenfalls in .dashboard_metrics.json gespeichert. Noch nicht dort
gespeicherte Kontostandgrenzen übernehmen zunächst die Werte aus .ing.conf.
Die Kachel lässt sich über das Symbol oben rechts ein- und ausklappen.
Unter Authentik-Anmeldung lassen sich Aktivierung, Issuer-URL, Client-ID
und Client-Secret direkt in .ing.conf speichern. Der Schalter Sicheres
Cookie aktivieren setzt AUTHENTIK_COOKIE_SECURE auf true oder false;
standardmäßig ist er ausgeschaltet. Ein leeres Secret-Feld behält das bereits
gespeicherte Secret bei. Bei ausgeschalteter Authentik-Anmeldung sind die
zugehörigen Einstellungen deaktiviert und ausgegraut; gespeicherte Werte
bleiben erhalten. Bei der Aktivierung ergänzt die Wartungsseite automatisch:
AUTHENTIK_REDIRECT_URI=<aktuelle Adresse>/auth/callback
AUTHENTIK_POST_LOGOUT_REDIRECT_URI=<aktuelle Adresse>/auth/logged-out
AUTHENTIK_ALLOWED_GROUPS=
AUTHENTIK_SESSION_HOURS=8
Die automatische Abmeldung wegen Inaktivität ist ausschließlich
clientseitig. Standardmäßig wird die lokale ING-Sitzung in einem normalen
Browser nach fünf Minuten beendet; in der als Home-Bildschirm-WebApp
gestarteten iOS-Version ist sie ausgeschaltet. Die Browserdauer und beide
Schalter sind unter Authentik-Anmeldung konfigurierbar. Die iOS-WebApp
verwendet bei Aktivierung dieselbe Dauer wie der Browser. Dabei wird kein
Authentik-End-Session-Aufruf ausgeführt. Ist die automatische Abmeldung für
die aktuelle Umgebung aktiv, zeigt die Kopfzeile die verbleibende Zeit direkt
rechts neben dem Benutzernamen an.
Erkannte Aktivität setzt den Countdown zurück; mehrere Browser-Tabs verwenden
denselben Aktivitätszeitpunkt. Andere Authentik-Anwendungen und andere Geräte
bleiben angemeldet. Die erneute Anmeldung fordert mit
prompt=login und max_age=0 eine frische Authentifizierung für die ING-App
an, ohne die zentrale Authentik-Sitzung zu beenden.
Wenn Authentik in der Windows- oder macOS-Entwicklungsumgebung deaktiviert ist, zeigt die Kopfzeile automatisch eine rein lokale Vorschau von Benutzerprofil, Countdown und Abmeldemenü. Die Vorschau verändert keine Sitzung und wird auf dem Linux-Server nicht eingeblendet.
Fehlt FLASK_SECRET_KEY, wird ebenfalls automatisch ein sicherer zufälliger
Wert erzeugt. Nach dem Speichern fordert ein Overlay den erforderlichen
Neustart an. Auf dem Linux-Server kann der über SYSTEMD_SERVICE konfigurierte
Dienst direkt aus dem Overlay neu gestartet werden. Unter Windows und macOS
erfolgt der Neustart weiterhin manuell in der Entwicklungsumgebung.
Unter Nicht berücksichtigte Umsätze zeigt die Wartungsseite alle aktuell
markierten Buchungen und bietet deren Reaktivierung an. Die lokale
Ausschlussliste liegt in .ignored_transactions.json und wird nicht in Git
versioniert.
Das Wochenupdate führt nacheinander aus:
transactions.py
categorize_transactions.py
Automatik und Cron
Für die drei Hauptscripts gibt es eigene Kacheln:
- Kontostand
- Transaktionen
- Kategorisierung
Jede Kachel hat:
- manuellen Startbutton
- Automatik-Schalter
- Cron-Editor, wenn Automatik aktiv ist
- Testfunktion für den geplanten Lauf
Unter Linux wird die echte Crontab geschrieben. In Mac- und Windows-Testumgebungen werden die Einstellungen lokal in .cron_jobs.json gespeichert.
Versionierung
Die Basisversion steht in:
VERSION
In der Fußzeile wird zusätzlich der aktuelle Git-Stand angezeigt:
Version 1.0.0 · 0ee6aa9a · 01.07.2026
Zusätze:
lokal geändert: getrackte Dateien weichen vom letzten Commit abUPDATE verfügbar (n Versionen): der lokale Stand liegt n Commits hinter dem Upstream- Ein Klick auf die Commit-ID öffnet den zugehörigen Commit im Repository in einem neuen Browser-Tab.
Die Update-Prüfung nutzt den konfigurierten Git-Upstream, normalerweise:
origin/main
Beim Update über die Fußzeile werden zunächst der aktuelle Git-Stand und das
Server-Repository geprüft. Lokale Änderungen, eigene Server-Commits oder ein
vom Upstream abweichender Branch blockieren das Update mit einer sichtbaren
Meldung in einem Overlay. Auch die Rückmeldung, dass kein Update erforderlich
ist, erscheint direkt auf der geöffneten Seite. Zulässige Aktualisierungen
erfolgen ausschließlich mit
git pull --ff-only. Danach werden die Abhängigkeiten aus requirements.txt
mit dem Python-Interpreter des laufenden Dienstes installiert und anschließend
der konfigurierte systemd-Dienst neu gestartet. Schlägt ein Schritt fehl, wird
der Dienst nicht neu gestartet.
Der Interpreterpfad der virtuellen Umgebung wird dabei bewusst ohne Auflösen
des Linux-Symlinks verwendet, damit pip innerhalb von .venv und nicht im
durch PEP 668 geschützten System-Python ausgeführt wird.
Repository:
https://git.hintergasse.de/hubobel/ING.git
Konfiguration
Die Konfiguration wird zuerst aus ~/.ing.conf gelesen. Wenn diese Datei nicht existiert, wird .ing.conf im Projektverzeichnis verwendet.
Beispiel:
ING_USER=12345678
ING_PIN=geheim
ING_IBAN=DExxxxxxxx
IOBROKER_HOST=10.0.1.122
IOBROKER_PORT=8087
IOBROKER_DP=javascript.0.Variablen.Konto
INFLUX_URL=http://localhost:8086
INFLUX_ORG=home
INFLUX_BUCKET=banking
INFLUX_TOKEN=token
BALANCE_YELLOW_DAY=15
BALANCE_YELLOW_LIMIT=400
BALANCE_RED_DAY=28
BALANCE_RED_LIMIT=300
# optional; Standardwert ist ing-web
SYSTEMD_SERVICE=ing-web
MariaDB
Die Zugangsdaten für eine spätere MariaDB-Anbindung lassen sich unter
Wartung → Datenbank verwalten. Das Passwort wird nie zurück in das Formular
geschrieben; ein leeres Passwortfeld behält den bereits gespeicherten Wert bei.
Die Datenbankanbindung wird mit folgenden Werten in .ing.conf vorbereitet:
DATABASE_ENABLED=false
DATABASE_HOST=127.0.0.1
DATABASE_PORT=3306
DATABASE_NAME=ing
DATABASE_USER=ing
DATABASE_PASSWORD=<Datenbankpasswort>
Über Verbindung testen werden die aktuell im Formular stehenden Werte
geprüft, ohne sie zu speichern. Der Test öffnet die Verbindung mit einem kurzen
Timeout und führt ausschließlich SELECT 1 aus.
Datenbank synchronisieren liest alle vorhandenen Roh- und kategorisierten
JSON-Dateien aus sämtlichen Jahren ein. Aktuelle Notizen, manuelle
Kategoriezuweisungen und Ausschlüsse werden dabei ergänzt. Die Anwendung legt
bei Bedarf die Tabellen ing_transactions, ing_categories und
ing_sync_runs an. Die Transaktions-ID ist der eindeutige Primärschlüssel;
wiederholte Synchronisierungen aktualisieren geänderte Datensätze und erzeugen
keine Duplikate. Excel- und CSV-Dateien bleiben reine Exporte.
Nach jedem erfolgreichen Kategorisierungslauf wird die betroffene Kalenderwoche
automatisch nach MariaDB synchronisiert, sofern DATABASE_ENABLED=true ist.
Fehler werden protokolliert, verhindern aber nicht die Erstellung der lokalen
JSON-, CSV- und Excel-Ausgaben.
Unter Windows und macOS ist die Datenbankintegration fest im Simulationsmodus. Der Verbindungstest darf die echte Erreichbarkeit lesend prüfen; spätere Datenbankänderungen werden dort jedoch nur simuliert. Reale Schreibvorgänge sind ausschließlich für die Linux-Produktivumgebung vorgesehen. Der aktive Modus wird im Datenbank-Reiter deutlich angezeigt.
Anmeldung über Authentik
Die Weboberfläche kann optional vollständig über Authentik und OpenID Connect geschützt werden. Ohne Authentik-Konfiguration bleibt die Anmeldung deaktiviert, damit lokale Windows- und macOS-Entwicklungsumgebungen weiterhin direkt funktionieren.
In Authentik wird eine Anwendung mit einem OAuth2/OpenID-Provider angelegt.
Für eine Anwendung unter https://bank.example.de werden zwei strikte
Weiterleitungsadressen eingetragen:
https://bank.example.de/auth/callback
https://bank.example.de/auth/logged-out
Die Authentik-Ausstelleradresse enthält den Slug der Anwendung:
https://auth.example.de/application/o/ing
Anschließend werden in der produktiven ~/.ing.conf ergänzt:
AUTHENTIK_ENABLED=true
AUTHENTIK_ISSUER_URL=https://auth.example.de/application/o/ing
AUTHENTIK_CLIENT_ID=<Client-ID aus Authentik>
AUTHENTIK_CLIENT_SECRET=<Client-Secret aus Authentik>
AUTHENTIK_REDIRECT_URI=https://bank.example.de/auth/callback
AUTHENTIK_POST_LOGOUT_REDIRECT_URI=https://bank.example.de/auth/logged-out
FLASK_SECRET_KEY=<zufälliger langer Wert>
# optional: Zugriff auf eine oder mehrere Authentik-Gruppen beschränken
AUTHENTIK_ALLOWED_GROUPS=ING-Benutzer
# optional
AUTHENTIK_SESSION_HOURS=8
AUTHENTIK_COOKIE_SECURE=true
AUTHENTIK_IDLE_BROWSER_ENABLED=true
AUTHENTIK_IDLE_MINUTES=5
AUTHENTIK_IDLE_IOS_ENABLED=false
Erfüllt ein angemeldeter Benutzer die Einschränkung aus
AUTHENTIK_ALLOWED_GROUPS nicht, erscheint eine eigene Hinweisseite. Über
Mit anderem Benutzer anmelden wird die bestehende Authentik-Sitzung
beendet und unmittelbar eine neue Anmeldung gestartet. Auch abgelaufene oder
bereits verwendete OIDC-Callbacks bieten diesen kontrollierten Neustart an,
statt nur eine technische Fehlermeldung auszugeben.
Ein sicherer Flask-Schlüssel lässt sich beispielsweise so erzeugen:
python3 -c "import secrets; print(secrets.token_urlsafe(48))"
Der Wert für AUTHENTIK_COOKIE_SECURE wird über den Schalter auf der
Wartungsseite festgelegt. Sobald AUTHENTIK_ENABLED=true gesetzt ist, startet
die App bei fehlenden Pflichteinstellungen bewusst nicht, damit sie nicht
versehentlich ungeschützt bereitgestellt wird.
Projektpfad und Python-Interpreter werden automatisch aus der laufenden Installation ermittelt. Dadurch kann das Projekt unter Linux in einem beliebigen Verzeichnis und auch in einer virtuellen Python-Umgebung liegen. Die Cron-Einträge verwenden automatisch genau diesen Interpreter.
Installation
Repository klonen:
git clone https://git.hintergasse.de/hubobel/ING.git
Abhängigkeiten installieren:
pip install -r requirements.txt
App starten:
python3 app.py
Wichtige Befehle
Repository aktualisieren:
git -C ~/ING pull
Kontostand abrufen:
python3 ~/ING/balance.py
Transaktionen der aktuellen Woche laden:
python3 ~/ING/transactions.py
Bestimmte Kalenderwoche laden:
python3 ~/ING/transactions.py 2026 25
Aktuelle Woche kategorisieren:
python3 ~/ING/categorize_transactions.py
Bestimmte Kalenderwoche kategorisieren:
python3 ~/ING/categorize_transactions.py 2026 25
Logging
Linux:
~/logs/ing.log
Mac und Windows/Testumgebung:
<Projektverzeichnis>/logs/ing.log
Der Excel-Export wird weiterhin durch categorize_transactions.py geloggt.
Verzeichnisstruktur
ING/
├── app.py
├── balance.py
├── transactions.py
├── categorize_transactions.py
├── Kategorien.json
├── VERSION
├── requirements.txt
├── static/
├── templates/
├── logs/
└── Transaktionen/
└── YYYY/
├── csv/
├── json/
├── categorized_csv/
├── categorized_json/
├── summary/
└── jahresauswertung/
