No description
  • Python 41.9%
  • HTML 38.9%
  • CSS 15.2%
  • JavaScript 4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-08-04 18:53:07 +02:00
static Grenzwertkonfiguration als visuelle Ampeloberfläche gestalten 2026-08-04 18:53:07 +02:00
templates Grenzwertkonfiguration als visuelle Ampeloberfläche gestalten 2026-08-04 18:53:07 +02:00
.gitignore Individuelle Notizen für Buchungen und Exporte ergänzen 2026-08-03 18:30:56 +02:00
app.py Entwicklungsumgebung durch graues ING-Logo kennzeichnen 2026-08-04 18:34:09 +02:00
balance.py Bugfixing 2026-07-13 18:20:10 +02:00
categorize_transactions.py MariaDB synch 2026-08-04 17:54:35 +02:00
database_sync.py MariaDB synch 2026-08-04 17:54:35 +02:00
README.md MariaDB synch 2026-08-04 17:54:35 +02:00
requirements.txt MariaDB-Konfiguration in der Wartungsseite ergänzen 2026-08-04 17:31:49 +02:00
todo.md Individuelle Notizen für Buchungen und Exporte ergänzen 2026-08-03 18:30:56 +02:00
transaction_categories.py Buchungsdetails: manuelle Kategoriezuweisung ermöglichen 2026-07-23 19:13:18 +02:00
transaction_exclusions.py Umsätze einzeln von Auswertungen ausschließen 2026-07-23 18:17:45 +02:00
transaction_notes.py Individuelle Notizen für Buchungen und Exporte ergänzen 2026-08-03 18:30:56 +02:00
transactions.py Umsätze einzeln von Auswertungen ausschließen 2026-07-23 18:17:45 +02:00
VERSION Grenzwertkonfiguration als visuelle Ampeloberfläche gestalten 2026-08-04 18:53:07 +02:00

CR-Löwen-Icon ING FinTS Auswertung

Dashboard

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 ab
  • UPDATE 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/