Ziel
Mein Ziel war es, mein Bankkonto mit Home Assistant zu verbinden, um mein Guthaben und meine Transaktionen in Echtzeit zu verfolgen. Zu diesem Zweck habe ich die Powens-API (ehemals Budget Insight) verwendet, eine Plattform, die den kostenlosen Zugang zu Bankdaten auf sichere und PSD2-konforme Weise ermöglicht.
Ich habe ein Powens-Konto erstellt
Ich habe mich auf der Powens-Website registriert, um ein Konto zu erstellen. Powens bietet eine Bankaggregationslösung an, mit der Finanzinformationen über APIs abgerufen werden können. Das ist perfekt für mein Hausautomationsprojekt.

Wer ist Powens?
Powens (ehemals Budget Insight) ist eine führende Plattform fürBankenaggregation und derOpen Banking. Mit APIs, die der PSD2 (Richtlinie über Zahlungsdienste) entsprechen, ermöglicht Powens Entwicklern und Unternehmen den sicheren Zugriff auf die Bankdaten der Nutzer (mit deren Zustimmung). Ihre Technologie wird von Fintechs, Banken und Finanzverwaltungsanwendungen genutzt, um innovative Dienstleistungen wie Ausgabenanalyse, Transaktionskategorisierung oder Budgetmanagement anzubieten.
In meinem Fall verwende ich eine winziger Teil das Potenzial von Powens durch ihre sandbox, eine Testumgebung, in der ich mich bei meinem Bankkonto anmelden kann, um Informationen wie den Kontostand und die letzten Transaktionen abzurufen. Diese Nutzung erzeugt sehr wenig Verkehr und bleibt Teil der kostenlosen Angebote von Powens für Entwickler und kleine Projekte. Dies ermöglicht es mir, diese Daten ohne zusätzliche Kosten in mein Hausautomationssystem zu integrieren und gleichzeitig von der Leistung und Zuverlässigkeit ihrer Plattform zu profitieren.
Meines Erachtens handelt es sich um eine sehr gute Initiative Powens will das zulassen. Indem sie kostenlosen Zugang zu ihrer Sandbox bieten, ermöglichen sie es Hausautomationshackern wie mir, zu experimentieren und maßgeschneiderte Lösungen zu entwickeln. Diese Hacker, die oft leidenschaftlich und einflussreich in ihren beruflichen oder persönlichen Kreisen sind, können dann solide und seriöse Plattformen wie Powens für breitere Dienste oder Unternehmen empfehlen. Dies ist eine Win-Win-Strategie: Powens gewinnt an Sichtbarkeit und Glaubwürdigkeit, während die Nutzer von einem zuverlässigen und leistungsfähigen Instrument profitieren.
Ich habe einen Workspace hinzugefügt
Nach der Anmeldung habe ich einen neuen Workspace eingerichtet. Ein Workspace ist ein Arbeitsbereich, in dem meine Konfigurationen und Anwendungen zusammengefasst sind. Ich habe meinen ernannt. Sigalou-domotisch um einen klaren Überblick über mein Projekt zu behalten.

Ich habe einen Bereich hinzugefügt
Anschließend habe ich meinem Workspace eine Domain hinzugefügt. Dadurch kann die Umgebung für API-Abfragen konfiguriert werden. Ich habe den Bereich ausgewählt Sigalou.


Die Konfiguration dauerte einige Minuten. Als ich fertig war, stellte ich fest, dass API-Bestellungen an folgende Adresse gesendet werden sollten: https://sigalou-sandbox.biapi.pro.
Ich habe eine App hinzugefügt
Um eine Verbindung zu meinem Bankkonto herzustellen, muss eine App hinzugefügt werden. Diese Anwendung generiert eindeutige Kennungen (Client-ID und geheimer Client), die zur Authentifizierung von API-Anfragen verwendet werden.


Diese App hat mir eine Client-ID und ein Geheimer Kunde. Ich habe sie sorgfältig bewertet, da sie benötigt werden, um einen API-Benutzer zu erstellen.
Ich habe Postman für Windows installiert
Um mit der Powens-API zu interagieren, habe ich Postman verwendet, ein sehr praktisches Tool zum Senden und Testen von API-Anfragen. Postman ermöglicht es, API-Aufrufe zu simulieren und Antworten in Echtzeit anzuzeigen.

Ich habe über die API einen Nutzer hinzugefügt
Um einen Benutzer zu erstellen, habe ich einen POST-Befehl an folgende URL gesendet: https://sigalou-sandbox.biapi.pro/2.0/auth/init. Ich habe den zuvor abgerufenen ID-Client und den geheimen Client verwendet.

Im Hauptteil der Klageschrift (Body / raw / JSON) habe ich hinzugefügt:
In der Antwort habe ich auf Folgendes hingewiesen: id_user und auth_token, die für die nächsten Schritte verwendet werden.
Ich habe einen temporären Code erhalten
Dieser temporäre Code ist erforderlich, um die Verbindung zu meinem Bankkonto herzustellen. Um dies zu erreichen, habe ich einen GET-Befehl an folgende URL gesendet: https://sigalou-sandbox.biapi.pro/2.0/auth/token/code?type=singleAccess.

Ich habe den auth_token zuvor im Autorisierungs-Header (Authorization/Bearer Token) abgerufen. In der Antwort habe ich auf Folgendes hingewiesen: code Vorübergehend.
Ich habe die Webview gestartet, um mein Bankkonto zu verbinden

Um die Verbindung zu meinem Bankkonto herzustellen, habe ich die Webview-URL in Link Builder erstellt und die Verbindung gestartet, indem ich auf Öffnen und Testen

Ich habe die Wiederherstellung des Kontostands getestet
Um meinen Kontostand wiederzuerlangen, habe ich einen GET-Befehl an folgende URL gesendet: https://sigalou-sandbox.biapi.pro/2.0/users/1/accounts, wo 1 Das ist meine _user-ID.

In der Antwort habe ich den Saldo meines Kontos von 599.84€ In meinem Test.
Ich habe die Wiederherstellung der letzten Transaktionen getestet.
Um die letzten Transaktionen abzurufen, habe ich einen GET-Befehl an folgende URL gesendet: https://sigalou-sandbox.biapi.pro/2.0/users/1/transactions?limit=10, wo 1 Das ist meine _user-ID.

Die Antwort enthielt ein JSON mit meinen letzten 10 Transaktionen.
Ich habe API-Abfragen in Home Assistant-Sensoren umgewandelt
Um diese Daten in den Home Assistant zu integrieren, habe ich zwei REST-Sensoren erstellt: _bank-Transaktionen und Saldo_bank. Hier der verwendete Code:
- platform: rest name: "Transaktionen_bank" resource: https://sigalou-sandbox.biapi.pro/2.0/users/1/transactions params: limit: 25 headers: Autorisierung: !secret token_bank scan_interval: 31536000 # Deaktiviert automatische Updates (1 Jahr) json_attributes: - first_date - last_date - transaktionen - total value_template: "{{ now().strftime(')%d/%m/%Y %H:%M:%S') }}" - platform: rest name: "_banksaldo" resource: https://sigalou-sandbox.biapi.pro/2.0/users/1/accounts headers: Autorisierung: !secret token_bank scan_interval: 31536000 # Deaktiviert automatische Updates value_template: "{{ value_json.balance }}" unit_of_measurement: "€"
Diese Sensoren sind in der Datei zu platzieren sensors.yaml.

Damit der Token korrekt gesendet wird, habe ich diese Zeile in die Datei eingefügt. secrets.yaml :
token_bank: Bearer a8N5q1aUVEa33wl0dCJM...

Nach der Konfiguration erschienen die Sensoren im Home Assistant:

Anmerkungen zu diesen Sensoren:
- Die Aktualisierung ist auf 3153600 Sekunden (ca. 1 Jahr) eingestellt, da ich geplant habe, die Daten mittags täglich zu automatisieren. Dies ermöglicht es mir, Benachrichtigungen basierend auf dem Kontostand oder den letzten Transaktionen zu erhalten.
- Sensoren können vereinfacht werden. Ursprünglich hatte ich Daten wie first_date und last_date, aber ich habe sie schließlich zurückgezogen, weil sie in der Produktion nicht nützlich waren.
- Der Parameter limit: 25 kann an die Bildschirmgröße und die auf dem Dashboard gewählte Karte angepasst werden.
Ich habe Templates hinzugefügt, um zu berechnen, was ich benötige
In der Datei templates.yaml, unter Sensor, habe ich diese Templates hinzugefügt:

- name: "Transaktionen_a_venir_montant" state: >- {% set transactions = state_attr('sensor.transactions_bank', 'transactions') %} {% set total = namespace(amount=0) %} {% for transaction in transaktionen if transaction.coming %} {% set total.amount = total.amount + transaction.value %} {% endfor %} {{ total.amount }} unit_of_measurement: "€" - name: Einzigartiger _id-Saldo: sensor.solde_verfügbar unit_of_measurement: "€" state: >- {% set balance = states('sensor.solde_bank') | float %} {% set depenses = states('sensor.transactions_a_venir_montant') | float %} {{ (Saldo + Ausgaben) | round(2) }}
- Der Sensor Transaktionen_a_venir_Betrag berechnet den Gesamtbetrag zukünftiger Transaktionen (wie geplanter Lastschriften).
- Der Sensor _-Guthabenverfügbar berechnet den tatsächlichen Saldo durch Subtrahieren zukünftiger Transaktionen vom aktuellen Saldo.
Ich füge eine Automatisierung hinzu, um die Daten zu aktualisieren
Wie ich bereits erläutert habe, habe ich die automatische Aktualisierung der REST-Sensoren absichtlich deaktiviert, indem ich ihnen einen sehr hohen _intervallwert (31536000 Sekunden, d. h. etwa 1 Jahr) zugewiesen habe. Dadurch kann ich manuell steuern, wann die Daten aktualisiert werden, anstatt sie alle x Minuten zu aktualisieren. Dieser Ansatz ist besser auf meine Bedürfnisse zugeschnitten, da ich plane, diese Daten zu verwenden, um Benachrichtigungen basierend auf meinem Kontostand oder den letzten wichtigen Transaktionen auszulösen.
Um dies zu bewältigen, habe ich im Home Assistant eine Automatisierung hinzugefügt, mit der meine beiden Sensoren aktualisiert werden (Saldo_bank und _bank-Transaktionen) täglich mittags. Hier der Code für diese Automatisierung:
alias: Aktualisieren Bankkonto Beschreibung: "" Trigger: - trigger: time at: "12:00:00" Bedingungen: [] Maßnahmen: - Aktion: homeassistant.update_entity data: entity_id: - sensor.solde_bank - sensor.transactions_bank mode: single

Diese Automatisierung ist einfach, aber effektiv: Die Sensoren werden täglich um 12:00 Uhr aktualisiert. Dadurch kann ich meine Daten auf dem neuesten Stand halten, ohne die API oder mein System mit unnötigen Abfragen zu überlasten. Darüber hinaus habe ich die Möglichkeit, später weitere Aktionen hinzuzufügen, z. B. das Senden von Benachrichtigungen oder das Ausführen von Skripten auf der Grundlage der abgerufenen Daten.
Ich realisiere die Karten und den Dashboard-Screen
Nachdem ich die Sensoren und Automatisierungen konfiguriert hatte, entwarf ich im Home Assistant ein Dashboard, um meine Bankdaten übersichtlich und organisiert anzuzeigen. Hier das Endergebnis meiner Tests:

Hier ist der vollständige Code der Seite, den ich aufschlüsseln werde, um jeden Teil zu erklären:
Typ: max_columns-Abschnitte: 4 Pfad: ss Abschnitte: - Typ: grid cards: - Typ: entity entity: sensor.solde_bank name: Icon-Banksaldo: mdi:bank-transfer grid_options: columns: full card_mod: Stil: | ha-card { padding: 4px; border-radius: 15px; } .icon ha-state-icon { --mdc-icon-size: 50px!wichtig; /* Symbolgröße */ margin-bottom: 10px; } - Typ: markdown content: > {% set transactions = state_attr('sensor.transactions_bank', 'transactions') %} ## HEUTE {% for transaction in transaktionen %} {% if not transaction.coming %} {% if transaction.date %} {% set date_obj = transaction.date | as_datetime %} {% set formatted_date = date_obj.strftime('%d/%m/%Y') %} {% else %} {% set formatted_date = 'Unbekanntes Datum' %} {% endif %} {% if transaction.type == 'card' %}💳 {{ formatted_date }} {% elif transaction.type == 'bank' %} 🏦 {{ formatted_date }} {% elif transaction.type == 'check' %} 📝 {{ formatted_date }} {% elif transaction.type == 'transfer' %}💸 {{ formatted_date }} {% else %}⚪ {{ formatted_date }} {% endif %}
<strong>
{% if transaction.value > 0 %} 🟢 {{ transaction.formatted_value }} {% else %} 🔴 {{ transaction.formatted_value }} {% endif %}
</strong>
<small>{{ transaction.wording }}</small>
{% endif %} {% endfor %} grid_options: columns: 24 rows: Auto - Typ: vertikale Stack-Karten: - Typ: markdown content: > {% set transactions = state_attr('sensor.transactions_bank', 'transactions') %} ## ZURÜCK {{ states('sensor.transactions_a_venir_montant')|float|round(2) }}} € {% for transaction in transaktionen %} {% if transaction.coming %} {% if transaction.date %} {% set date_obj = transaction.date | as_datetime %} {% set formatted_date = date_obj.strftime('%d/%m/%Y') %} {% else %} {% set formatted_date = 'Unbekanntes Datum' %} {% endif %} {% if transaction.type == 'card' %}💳 {{ formatted_date }} {% elif transaction.type == 'bank' %} 🏦 {{ formatted_date }} {% elif transaction.type == 'check' %} 📝 {{ formatted_date }} {% elif transaction.type == 'transfer' %}💸 {{ formatted_date }} {% else %}⚪ {{ formatted_date }} {% endif %} {% if transaction.value > 0 %} 🟢 {{ transaction.formatted_value }} - {{ transaction.wording }} {% else %} 🔴 {{ transaction.formatted_value }} - {{ transaction.wording }} {% endif %} {% endif %} {% endfor %} grid_options: columns: 12 rows: Auto - Typ: entity entity: sensor.solde_verfügbar name: Verfügbarer Saldo icon: mdi:bank-transfer grid_options: columns: full card_mod: Stil: | ha-card { padding: 4px; border-radius: 15px; } .icon ha-state-icon { --mdc-icon-size: 50px!wichtig; /* Symbolgröße */ margin-bottom: 10px; } - Typ: entities entities: - entity: sensor.transactions_bank name: Letzte Aktualisierung der Datenformate: datetime column_span: 3 Karten: [] icon: mdi:currency-eur
Zersetzung des Dashboards
Mein Dashboard ist in mehrere Abschnitte und Karten gegliedert, um die Informationen übersichtlich und intuitiv anzuzeigen. Hier ist, was jede Karte tut:
1. Karte "Bankguthaben"
Diese Karte zeigt den aktuellen Kontostand meines Bankkontos an. Sie nutzt den Sensor sensor.solde_bank und enthält ein stilisiertes Symbol (mdi:bank-transfer) für eine bessere Sichtbarkeit. Ich habe einen benutzerdefinierten Stil hinzugefügt, um die Ecken der Karte zu runden und das Symbol zu vergrößern.
2. Karte „HEUTE“
Diese Karte zeigt die heute getätigten Transaktionen. Sie verwendet ein Markdown-Template, um die Daten zu formatieren:
- Die Transaktionen sind nach Typ geordnet (💳 für Karten, 🏦 für Überweisungen usw.).
- Die Beträge werden für Gutschriften grün (🟢) und für Belastungen rot (🔴) angezeigt.
- Das Datum jeder Transaktion wird im Format TT.MM.JJJJ.
3. Karte "Zum Kommen"
Diese Karte zeigt anstehende Transaktionen (wie geplante Lastschriften) an. Sie verwendet auch ein Markdown-Template:
- Der Gesamtbetrag der anstehenden Transaktionen wird oben auf der Karte angezeigt.
- Jede Transaktion wird mit ihrem Typ, Datum und Betrag aufgelistet.
4. Karte "Saldo verfügbar"
Diese Karte zeigt das verfügbare Guthaben nach Abzug zukünftiger Transaktionen an. Sie nutzt den Sensor sensor.solde_verfügbar und teilt den gleichen Stil wie die Karte "Bankguthaben".
5. Karte "Letzte Datenaktualisierung"
Diese Karte zeigt das Datum und die Uhrzeit der letzten Aktualisierung der Bankdaten an. Sie nutzt den Sensor sensor.transactions_bank und formatiert das Datum im Format datetime.

