Ich warne sofort davor, dass dieser Retex nur pädagogischen Zwecken dient, ich schreibe ihn, um eine Methodik zu teilen, nämlich dass ich diese Funktion seitdem anders umgesetzt habe, also habe ich diesen Prozess nicht in der Hand.
Integration zum Ausführen des Python-Skripts
Aus einem Grund, den ich nie verstanden habe, sind die in HA integrierten Python-Skriptfunktionen archi-mini, kein Import ist möglich, daher muss ich eine Integration verwenden, die als Pyscript.
Ich übergebe die Details, um es zu installieren, es ist sehr einfach mit HACS und alles ist in der Dok.
In configuration.yaml habe ich folgende Zeilen:
pyscript: allow_all_imports: true hass_is_global: true
Ich hole ein Token
Ich öffne die Home Assistant-Benutzeroberfläche.
In der unteren linken Ecke klicke ich auf meinen Benutzernamen (oder das Profilsymbol).
Ich klicke auf "Profil".
Ich scrolle nach unten zum Abschnitt „Langzeit-Token“.
Ich klicke auf "Token erstellen", um ein neues Token zu generieren.
Ich gebe meinem Token einen Namen, damit ich ihn leichter finden kann.
Sobald das Token erstellt wurde, sehe ich seinen Inhalt. Ich kopiere den Wert des Tokens, d. h. den alphanumerischen Zeichensatz, und füge ihn in meine Konfiguration ein (nachfolgender Absatz).
Erklärung der Plattform, die Python mit dem Sensor verbindet
In configuration.yaml füge ich folgende Zeilen hinzu:
rest_command: send_data_to_api: URL: 'http://homeAssistant.local:8123/api/states/sensor.wallbox_charges' method: 'post' content_type: 'application/json' headers: Autorisierung: 'Bearer TOKEN' # Ersetzen Sie TOKEN durch den Token cf vorherigen Absatz payload: '{{ data | tojson }}}'
Dies ist die Eingangstür, die über das Python-Skript (unten) bereitgestellt wird und die Informationen an die sensor.wallbox_charges sendet.
Mein Python-Skript
Ich lege die Datei wallbox_charges.py in den Ordner /config/pyscript
import datetime import pytz @service def wallbox_charges(lastdata=None, action=None, preis="123", km="123", dateDebut="01/01/2000 12:00:00", Wert="123"): Zeitzone_paris = pytz.timezone("Europa/Paris") jetzt_timestamp = int(datetime.datetime.now().timestamp()) jetzt_heure_paris = datetime.datetime.fromtimestamp(jetzt_timestamp, Zeitzone_paris) jetzt_formate = jetzt_heure_paris.strftime("%d/%m/%Y %H:%M:%S") jetztMinus20min = datetime.datetime.now() - datetime.timedelta(minutes=20) jetztMinus20min_formatee = jetztMinus20min.strftime("%H:%M") dateDebutRecue = datetime.datetime.strptime(dateDebut, '%d/%m/%Y %H:%M:%S').replace(tzinfo=Zeitzone_paris) debut_timestamp_formatee = dateDebutRecue.strftime("%d/%m/%Y %H:%M:%S") debut_timestamp_formatee_OhneSekunden = DatumDebutRecue.strftime("%d/%m/%Y %H:%M") # Verwandeln Sie Zeichenfolgen jetzt in datetime-Objekte_dt = datetime.datetime.strptime(jetzt_formatee, "%d/%m/%Y %H:%M:%S") debut_dt = datetime.datetime.strptime(debut_timestamp_formatee, "%d/%m/%Y %H:%M:%S") # Berechnen Sie die Differenz zwischen Objekten datetime ZeitDeCharge = jetzt_dt - debut_dt - datetime.timedelta(minutes=20) # Formatieren Sie die Dauer in Stunden, Minuten und Sekunden Stunden, Rest = divmod(timeDeCharge.seconds, 3600) Minuten, Sekunden = divmod(reste, 60) # Zeigen Sie die Dauer im HH:MM:SS-Format anDeCharge_formatee = f"{Stunden:02}:{Minuten:02}" # Schreiben Sie eine Informationsnachricht in das Tagebuch #log.info(action) if action == "speichern": wertaadd = [{ "saved_at": _timestamp, "Anfang": debut_timestamp_formatee_OhneSekunden, "Ende": jetztWeniger20min_formatee, "Dauer": ZeitDeCharge_formatee, "Verbrauch": Wert, "km": km, "Kosten": round(Wert * Preis, 2) }] if lastdata is not None: wertaadd = lastdata + wertaadd data = { "state": debut_timestamp_formatee_OhneSekunden, "Attribute": { "updated_at": jetzt_dt.strftime("%d/%m/%Y %H:%M:%S"), "Sessionscharge": wertaadd } } if action == "init": data = { "state": "on", "attributes": { "updated_at": „14/10/2023 16:42:39“, „Sessionscharge“: [ { "Verbrauch": 2.14 "Kosten": 0.43, "Dauer": "00:27", "Anfang": „19/09/2023 20:36“, „Ende“: "21:03", "km": 17, "saved_at": 1695150359 }, { "Verbrauch": 23.29, "Kosten": 4.66, "Dauer": "04:19", "Anfang": „21/09/2023 21:06“, „Ende“: "01:25", "km": 192, "saved_at": 1695323159 }, { "Verbrauch": 7.68, "Kosten": 1.54, "Dauer": "01:23", "Anfang": „22/09/2023 08:45“, „Ende“: "10:08", "km": 63, "saved_at": 1695409559 }, { "Verbrauch": 23.80, "Kosten": 4.76, "Dauer": "04:26", "Anfang": „23/09/2023 16:57“, „Ende“: "21:23", "km": 196, "saved_at": 1695495959 } ] } } # Rufen Sie den REST-Dienst an, um die Daten zu senden _data = { "token": "xxxxxx", # Ersetzen durch das "Data"-Token: data } if action == "speichern" or action == "init": # Rufen Sie den REST-Dienst asynchron an await hass.services.async_call('rest_command', 'send_data_to_api', service_data) # Schreiben Sie eine Fehlermeldung in das Protokoll #log.error("End script")
Zwei Automatisierungen hinzufügen
Eine zum Initialisieren des Sensors, die andere zum Hinzufügen von Daten
Initialisieren von Daten
alias: Initialisiert Ladesitzungen Beschreibung: "" Trigger: [] Bedingung: [] Maßnahme: - Dienststelle: pyscript.wallbox_charges data: Maßnahme: Init Mode: Single
Daten speichern
alias: Speichert eine Ladesitzung Beschreibung: >- Diese Automatisierung wird ausgelöst, wenn der Sensor den Wert seit 20 Minuten nicht geändert hat und sich nicht bei 0 Trigger befindet: - platform: state entity_id: - sensor.wallbox_portal_added_range for: hours: 0 Minuten: 20 Zweite: 0 enabled: true condition: - Bedingung: numeric_state entity_id: sensor.wallbox_portal_added_energy above: 0 - Bedingung: not conditions: - Bedingung: state entity_id: sensor.wallbox_charges state: >- {{ as_timestamp(states('sensor.wallbox_portal_added_range_min')) | int | timestamp_custom('%d/%m/%Y %H:%M:%S', true)} enabled: False Action: - Dienststelle: pyscript.wallbox_charges data: Maßnahme: Wert speichern: "{{states('sensor.wallbox_portal_added_energy')}}" Preis: "{{states('sensor.wallbox_portal_energy_price')}}" km: "{{states('sensor.wallbox_portal_added_range')}}" lastdata: "{{state_attr('sensor.wallbox_charges', 'sessionscharge')}}" DatumBeginn: >- {{ as_timestamp(states('sensor.wallbox_portal_added_range_min')) | int | timestamp_custom('%d/%m/%Y %H:%M:%S', true)} - Service: variable.update_sensor data: replace_attributes: false value: >- {{ as_timestamp(states('sensor.wallbox_portal_added_range_min')) | int | timestamp_custom('%d/%m/%Y %H:%M:%S', true)}} target: entity_id: sensor.wallbox_charges enabled: False Mode: Single
Um den minimalen Lastwert zu erhalten, verwende ich statistic, um den min-Wert zu erhalten.
Dieser Sensor wird in sensors.yaml deklariert
- platform: statistics name: "Wallbox Portal Added Range Min" entity_id: sensor.wallbox_portal_added_range state_characteristic: datetime_value_min max_age: hours: 10
Ergebnis der Informationsspeicherung
Anzeigekarte für alle Sitzungen
<div>Ladesitzungen</div>
Letzte Aktualisierung: {{ state_attr('sensor.wallbox_charges','updated_at')}} <br><br>
{% set items = state_attr('sensor.wallbox_charges', 'sessionscharge') %}
<table width='100%'>
<tbody>
{% for i in range(0, items | count, 1) %}
<tr>
<td>{{ items[i].Anfang }} bis {{ items[i].fin }} ({{ items[i].Dauer }})</td>
<td>{{ items[i].Verbrauch }} kWh</td>
<td>+{{ items[i].km }} km</td>
<td>{{ items[i].cost }} €</td>
</tr>
{% endfor %}
</tbody>
</table>
Plakatkarte mit Summen pro Jahr, Monat, Woche
Typ: Markdown Content: >-
<div><h1>Ladesitzungen</div> {%- set default_language = 'de' %} Letzte Aktualisierung: {{ state_attr('sensor.wallbox_charges','updated_at')}} <br><br>
{% set items = state_attr('sensor.wallbox_charges', 'sessionscharge') %} {% set sieben Tage = now() - timedelta(days=7) %} {% set power_Woche = namespace(value=0) %} {% set cost_woche = namespace(value=0) %} {% set einen Monat = now() - timedelta(days=30) %} {% set power_Monat = namespace(value=0) %} {% set cot_mois = namespace(value=0) %} {% set uneannee = now() - timedelta(days=365) %} {% set power_annee = namespace(value=0) %} {% set cout_annee = namespace(value=0) %} {% for i in range(0, items | count, 1) %} {% if items[i].saved_at | int >= as_timestamp(uneannee) %} {% set power_annee.value = power_annee.value + items[i].Verbrauch %} {% set cot_annee.value = cot_annee.value + items[i].kosten %} {% if items[i].saved_at | int >= as_timestamp(ein Monat) %} {% set power_mois.value = power_mois.value + items[i].Verbrauch %} {% set cot_mois.value = cot_mois.value + items[i].kosten %} {% if items[i].saved_at | int >= as_timestamp(sieben Tage) %} {% set power_woche.value = power_woche.value + items[i].Verbrauch %} {% set cout_swoche.value = cout_swoche.value + items[i].kosten %} {% endif %} {% endif %} {% endif %} {% endfor %}
</ha-alert> <ha-alert alert-type="info" title="Letzter Monat: {{ power_mois.value | int }} kWh - {{ cot_mois.value | float | round(2) }} €"></ha-alert> <ha-alert alert-type="info" title="Letztes Jahr: {{ power_annee.value | int }} kWh - {{ cot_annee.value | float | round(2) }} €"></ha-alert>
<br>
{% set items = state_attr('sensor.wallbox_charges', 'sessionscharge') %} {% set sieben Tage = now() - timedelta(days=7) %}
<table width='100%'> <tbody> {% for i in range(0, items | count, 1) %} {% if items[i].saved_at | int >= as_timestamp(sieben Tage) %} {% set datetime_obj = strptime(items[i].Anfang, '%d/%m/%Y %H:%M') %}
<tr> <td><h5>{{items[i].Anfang }} bis {{ items[i].fin }} ({{ items[i].Dauer }})</td> <td>{{ items[i].Verbrauch }} kWh</td> <td>+{{ items[i].km }} km</td> <td>{{ items[i].cost }} €</td> </tr> {% endif %} {% endfor %} </tbody> </table>
<ha-alert alert-type="success" title="Letzte Woche: {{ power_semaine.value | int}} kWh - {{ cot_semaine.value | float | round(2) }}€">
Stil: .: | ha-card { margin: 0px 0px 0px 0px; Box-Shadow: none; } ha-markdown: $: | h5 { font-size: 15px!wichtig; font-weight: normal! wichtig; Padding: 0px 0px 0px 8px!wichtig; Border-Left: 3px solid #429f46; }




