Shelly 3EM, Photovoltaik und Home Assistant: Richtig saldieren.

Für wen ist diese Anleitung?

Ihr nutzt eine Shelly 3EM um den Stromverbrauch eures Hauses oder Wohnung zu messen. Gleichzeitig betreibt ihr eine Photovoltaik-Anlage, deren Überschuss über in das öffentliche Netzeingespeist wird (und diese ist nicht an einen separaten Stromzähler oder dergleichen angeschlossen). Ihr nutzt bereits Home Assistant, um euren Energieverbrauch zu messen oder eure Home Automation darüber zu steuern. Ihr wollt genau sehen, wieviel von eurem produzierten Strom ins Stromnetz eingespeist wird und wie hoch der Eigenverbrauch ist, habt aber das Problem, dass die Shelly 3EM dies leider korrekt darstellen kann, weil die Shelly (noch) nicht saldieren kann. Mit dieser Anleitung helfe ich euch dieses Problem zu lösen.

Die Einkaufsliste

Warum kann ich nicht direkt in der Shelly 3EM sehen, wieviel Strom ich aus Photovoltaik eingespeist habe?

Grundsätzlich muss man sagen, die Shelly 3EM macht alles korrekt und man sieht den Strom der eingespeist wird technisch korrekt dargestellt. “Abrechnungstechnisch” stimmt das jedoch nicht. Denn wenn ihr den Stromverbrauch in der Shelly mit den auf deinem Stromzähler vergleicht, werdet ihr teils erhebliche Differenzen feststellen.

Warum: Dein Stromzähler saldiert, die Shelly 3EM nicht. Was bedeutet das?

Dazu muss man kurz ausholen: Dein Haushaltsstrom kommt über drei Phasen zu Dir nach nach Hause – das nennt man Dreiphasenwechselstrom und ist ein europäischer Standard. Kurz gesagt: In dein Haus / Wohnung kommen drei Stromleitungen mit 230V Spannung. Jeder deiner Verbraucher (Lampe, Steckdose, usw) hängt an einer der drei Phasen. Auch das Balkonkraftwerk. Wenn dein Balkonkraftwerk mehr Strom erzeugt als die Verbraucher an der Phase gerade an Strom benötigen, wird der überschüssige Strom ins Netz eingespeist. Der überschüssige Strom kann auch nicht auf die anderen beiden Phasen überspringen, das geht technisch nicht.

Dein Stromzähler ist – fast immer – saldierend. Bei saldierenden Zählern werden Verbräuche und Erträge aller drei Phasen noch vor der Anzeige auf dem Stromzähler miteinander verrechnet. So sieht man also nicht, wie viel auf den jeweiligen Phasen verbraucht beziehungsweise erzeugt wurde. Stattdessen sieht man nur das Ergebnis der Verrechnung. Genauso verhält sich der Zähler, wenn du Strom auf einer Phase einspeist. Der saldierende Stromzähler verrechnet die Einspeisung auf einer Phase mit dem Verbrauch der anderen beiden Phasen. Dies ist besonders vorteilhaft, da man andernfalls weniger Nutzen davon hätte, sich ein Balkonkraftwerk anzuschaffen.

Der Shelly 3EM kann nicht saldieren – er schaut sich Phase für Phase an. Zwar war vor längerem schon man angekündigt worden, dass dieses Feature durch ein Software Update nachgereicht werden soll, aber bis zum aktuellen Zeitpunkt ist das noch nicht der Fall. Das ist aber kein Problem, denn wir bilden das einfach in HomeAssistant ab, was bei mir ohnehin im Betrieb ist.

Energieflüsse darstellen

In HomeAssistant bekommt man gute Übersichten, auf denen man sehr übersichtlich sehen kann, wieviel Kilowattstunden man aus dem Netz bezogen hat. Darüber hinaus wird angezeigt, wieviel Solarenergie produziert worden ist, sowie wieviel davon selbstbezogen worden ist.

Wie sieht der Aufbau der Anlage aus?

sicherungskasten shelly plug s 3em photovoltaik
  1. Das PV Modul hängt an eurem Mikrowechselrichter. Bei mir nennt man das Balkonkraftwerk (BKW).
  2. Der Mikrowechselrichter ist mit einem Shelly Plug S verbunden. Dieser smarte Aus- und Einschalter misst den Stromverbrauch, hier die Stromgenerierung durch das PV Modul.
  3. Der generierte Strom des PV Moduls landet an einer der drei Phasen im “Sicherungskasten”.
  4. Im Sicherungskasten ist die Shelly 3EM installiert und überwacht die Stromverbräuche – sowohl den bezogenen Strom als auch den eingespeisten Strom. Eine Anleitung wie man die Shelly 3EM installiert findet ihr hier.

Vorraussetzung

Diese Anleitung geht davon aus, das eure Shelly 3EM korrekt in Betrieb ist und in eurem Netzwerk eingebunden ist. Ebenfalls setzt diese Anleitung voraus, dass im gleichen Netzwerk Home Assistant installiert ist und dort bereits die Shelly 3EM mit der Shelly Integration eingebunden ist.

Schritt für Schritt Anleitung zum Saldieren

1. Das File Editor Add-On in Home Assistant installieren


Um in Home Assistant die Konfigurationsdatei zu öffnen, solltet ihr euch zunächst das Addon “File Editor” installieren. Auf diese Weise kann man am einfachsten die Konfiguration verändern. Um dies zu erreichen, geht wie folgt vor:

  1. Öffne HomeAssistant in einem Browser
  2. Klicke auf “Settings”
  3. Klicke dann auf “Add-ons”
  4. Klicke auf “Add-On Store”
  5. Gibt im Suchfeld “File editor” an
  6. Klicke auf “Installieren”.
  7. Aktiviere folgende Parameter:
    “Start on Boot”
    “Show in Sidebar”
  8. Nach der Installation solltet ihr im Menü an der linken Seite den Menüpunkt “File editor” sehen, klickt auf diesen.
  9. Danach solltet ihr oben einen Ordner-Symbol sehen, dieses anklicken.
  10. In der Dateiliste dann die Datei “configuration.yaml” öffnen

2. Die “configuration.yaml” ändern

Als nächstes kopiert den nachstehenden Yaml-Code in die Datei “configuration.yaml”, die ihr mit dem File Editor aus dem vorherigen Schritt geöffnet habt. Fügt es einfach ganz am Ende an und verändert die bestehende Konfiguration nicht.

Es kann sein, dass ihr etwas Anpassen müsst: In der Datei findet ihr wiederkehrend die drei Namen der Phasen der Shelly 3EM in Home Assistant sensor.shelly3em_channel_a_power, sensor.shelly3em_channel_b_power, sensor.shelly3em_channel_c_power.

Diese müsst ihr mit euren jeweiligen Namen für die “Power” Entity der Shelly 3EM ersetzen. Im Zuge der Integration des Shelly 3EM in HomeAssistant wurden die Namen bei mir automatisch erstellt. Solltet ihr dieselben Namen verwenden, dann ist alles gut.

Ihr habt die Möglichkeit die Konfiguration mit Hilfe des nachstehenden Textfile selbst anzupassen oder ihr lasst euch mit Hilfe des Konfigurator alles generieren.

sensor:
  - platform: template
    sensors:
      # Template sensor for values of power import (active_power > 0)
      power_import:
        friendly_name: "Power Import"
        unit_of_measurement: 'W'
        value_template: >-
          {% if (states('sensor.shelly3em_channel_a_power')|float + states('sensor.shelly3em_channel_b_power')|float + states('sensor.shelly3em_channel_c_power')|float) > 0 %}
            {{ states('sensor.shelly3em_channel_a_power')|float + states('sensor.shelly3em_channel_b_power')|float + states('sensor.shelly3em_channel_c_power')|float }}
          {% else %}
            {{ 0 }}
          {% endif %}
        availability_template: "{{
            [ states('sensor.shelly3em_channel_a_power'),
              states('sensor.shelly3em_channel_b_power'),
              states('sensor.shelly3em_channel_c_power')
            ] | map('is_number') | min
          }}"

      # Template sensor for values of power export (active_power < 0)
      power_export:
        friendly_name: "Power Export"
        unit_of_measurement: 'W'
        value_template: >-
          {% if (states('sensor.shelly3em_channel_a_power')|float + states('sensor.shelly3em_channel_b_power')|float + states('sensor.shelly3em_channel_c_power')|float) < 0 %}
            {{ (states('sensor.shelly3em_channel_a_power')|float + states('sensor.shelly3em_channel_b_power')|float + states('sensor.shelly3em_channel_c_power')|float) * -1 }}
          {% else %}
            {{ 0 }}
          {% endif %}
        availability_template: "{{
            [ states('sensor.shelly3em_channel_a_power'),
              states('sensor.shelly3em_channel_b_power'),
              states('sensor.shelly3em_channel_c_power')
            ] | map('is_number') | min
          }}"

      # Template sensor for values of power consumption
      power_consumption:
        friendly_name: "Power Consumption"
        unit_of_measurement: 'W'
        value_template: >-
          {% if (states('sensor.power_export')|float(0)) > 0 and (states('sensor.power_solargen')|float(0) - states('sensor.power_export')|float(0)) < 0 %}
            {{ 0 }} 
          {% elif (states('sensor.power_export')|float(0)) > 0 and (states('sensor.power_solargen')|float(0) - states('sensor.power_export')|float(0)) > 0 %}
            {{ (states('sensor.power_solargen')|float(0)) - states('sensor.power_export')|float(0) }}    
          {% else %}
            {{ states('sensor.power_import')|float(0) + states('sensor.power_solargen')|float(0) }}
          {% endif %}

      # Template sensor for values of energy Solar generation (solar_power > 0)
      # YOU NEED TO UPDATE THE NAMES BELOW!!!
      power_solargen:
        friendly_name: "Power Solar Generation"
        unit_of_measurement: 'W'
        value_template: >-
          {% if (states('your_pv_source_1.power')|float(0) + states('your_pv_source_2.powerplugs2')|float(0)) > 0 %}
            {{ (states('your_pv_source_1.power')|float(0) + states('your_pv_source_2.powerplugs2')|float(0)) }}
          {% else %}
            {{ 0 }}
          {% endif %}

  # Sensor for Riemann sum of energy import (W -> Wh)
  - platform: integration
    source: sensor.power_import
    name: energy_import_sum
    unit_prefix: k
    round: 2
    method: left

  # Sensor for Riemann sum of energy export (W -> Wh)
  - platform: integration
    source: sensor.power_export
    name: energy_export_sum
    unit_prefix: k
    round: 2
    method: left

  # Sensor for Riemann sum of energy consumption (W -> Wh)
  - platform: integration
    source: sensor.power_consumption
    name: energy_consumption_sum
    unit_prefix: k
    round: 2
    method: left

utility_meter:
  energy_import_daily:
    source: sensor.energy_import_sum
    name: Energy Import Daily
    cycle: daily
  energy_import_monthly:
    source: sensor.energy_import_sum
    name: Energy Import Monthly
    cycle: monthly
  energy_export_daily:
    source: sensor.energy_export_sum
    name: Energy Export Daily
    cycle: daily
  energy_export_monthly:
    source: sensor.energy_export_sum
    name: Energy Export Monthly
    cycle: monthly
  energy_consumption_daily:
    source: sensor.energy_consumption_sum
    name: Energy Consumption Daily
    cycle: daily
  energy_consumption_monthly:
    source: sensor.energy_consumption_sum
    name: Energy Consumption Monthly
    cycle: monthly

Nachdem ihr die Konfiguration am Ende der “configuration.yaml” angefügt habt bitte die folgenden Schritte durchführen:

  1. Klicke unten links im Hauptmenü auf “Developer Tools”
  2. Klicke dann auf “Check configuration”
  3. Kommt dann die Meldung “Configuration will not prevent Home Assistant from starting” passt alles.
  4. Klickt danach auf “Restart”
  5. Nach 1-2 Minuten ist HomeAssistant wieder erreichbar und hat die neue Konfiguration geladen.

3. Das Energy Dashboard konfigurieren

Im letzten Schritt konfigurieren wir noch das Energy Dashboard, damit die neuen Entities dort auch eingebunden sind und die richtigen Werte angezeigt werden. Dazu gehen wir wie folgt vor:

  1. Klicke unten links im Hauptmenü auf “Settings”.
  2. Klicke dann auf “Dashboards”.
  3. Klicke dann auf das “Energy” Dashboard.
  4. Füge die neue Entity “Energy Import Daily” bei “Grid Consumption” hinzu.
  5. Füge die neue Entity “Energy Export Daily” bei “Return to Grid” hinzu (Achtung: Unter Umständen dauert es einige Stunden, bis diese Entity auswählbar ist!)
  6. Bei den “Solar Panels” bitte den Zähler für eure PV Produktion hinzufügen. In meinem Fall sind das zwei Shelly Plug S, weil ich zwei Module habe.

Am Ende sieht die Konfiguration bei mir wie folgt aus:

energy dashboard konfiguration home assistant shelly

Hier seht ihr das Ergebnis im Home Assistant Energy Dashboard

Ihr seht nun schon übersichtlich den Stromverbrauch aus dem Netz und eurer Photovoltaik Anlage und wieviel eures selbst produzierenden Stroms durch euch verbraucht worden ist – zumindest rechnerisch.

home assistant energy dashboard photovoltaik

Achtung!

1. Es dauert eine Weile bis ihr Daten im Energie Dashboard seht. Es dauert mindestens eine Stunde, kann aber auch bis zu 3 Stunden benötigen. Habt ein wenig Geduld! Insbesondere wird unten in den Kommentaren oft berichtet, dass “Energy Export Daily” nicht ausgewählt werden kann.
2. Ich habe zu Testzwecken eine neue Home Assistant Installation gemacht. Ich konnte dies reproduzieren, “Energy Export Daily” war unmittelbar nicht auswählbar. Aber nach einige Stunden hingegen war er vorhanden und ich konnte ihn einbinden. Habt ein wenig Geduld. Jede weitere Veränderung der Konfiguration führt unweigerlich dazu, dass es noch länger dauert!
3. “Energy Export Daily” wird erst dann auf tauchen, wenn ihr Stromüberschuss ins Netz eingespeist habt. Ist das noch nicht erfolgt, wird die Riemann Integration nicht aktiv. Siehe Kommentar von @Uwe.

Hinterlasst mir gerne Kommentare wenn die Beschreibung Schwächen hat, oder verbessert werden kann! Vielen Dank an James von dem die Ursprungsversion kam.

Wollt ihr lieber ein Home Assistant Addon als mit Config-Dateien herumfummeln?

Mit deiner Unterstützung entwickle ich ein Home Assistant Add-on. Mit diesem Add-on entfällt das Erzeugen einer YAML-Konfiguration.


Comments

223 responses to “Shelly 3EM, Photovoltaik und Home Assistant: Richtig saldieren.”

  1. Hallo zusammen, bin absoluter Anfänger in Home Assistant.
    Die Anleitung hat bei mir gut funktioniert und der beim Haus Installierte Shelly 3EM (im Zählerschrank) und Shelly plus 1PM (an BKW) liefert glaubwürdige Werte (Saldierend). Nun zu meinem Vorhaben: Ich habe in meiner Werkstatt ebenfalls einen 3EM im ZS und einen 1Plus PM an (BKW) installiert und schon in Homeassistant eingebunden. Mein Problem ist nun wenn ich nach dem Konfigurieren die Datei in den File Editor (configuration.yaml) einfüge dann kommen diverse Fehler. Hoffe ich kann das Bild anhängen.

    Im Endeffekt möchte ich im Dashboard bei HA zwei (Haus und Werkstatt) getrennte saldierende Anzeigen haben um den Verbrauch im Auge zu haben.

    Ich freue mich auf Antworten

    Gruß

    Tom

  2. Habe auch die gleichen Fehlermeldungen im Log:
    ………………………..
    ValueError: Sensor sensor.power_consumption has device class ‘None’, state class ‘None’ unit ‘W’ and suggested precision ‘None’ thus indicating it has a numeric value; however, it has the non-numeric value: ” ()

  3. Vielen geloggtDank für die super Arbeit.
    Es funktioniert alles, aber im System Log werden immer wieder die gleichen Fehlermeldungen und füllen damit den Log an.
    Hat jemand eine Idee wie man die .yaml anpassen muss damit die Fehlermeldungen weg sind ?

    Logger: homeassistant.helpers.event
    Source: components/sensor/__init__.py:593
    First occurred: October 4, 2023 at 09:15:27 (298 occurrences)
    Last logged: 15:06:42

    Error while dispatching event for sensor.power_export to <Job track state_changed event {'sensor.power_solargen', 'sensor.power_export'} HassJobType.Callback <bound method TrackTemplateResultInfo._refresh of <TrackTemplateResultInfo {Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=22740>: <RenderInfo Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=22740> all_states=False all_states_lifecycle=False domains=frozenset() domains_lifecycle=frozenset() entities=frozenset({‘sensor.power_solargen’, ‘sensor.power_export’}) rate_limit=None has_time=False exception=None is_static=False>}>>>
    Error while dispatching event for sensor.power_export to <Job track state_changed event {'sensor.power_solargen', 'sensor.power_export'} HassJobType.Callback <bound method TrackTemplateResultInfo._refresh of <TrackTemplateResultInfo {Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=22744>: <RenderInfo Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=22744> all_states=False all_states_lifecycle=False domains=frozenset() domains_lifecycle=frozenset() entities=frozenset({‘sensor.power_solargen’, ‘sensor.power_export’}) rate_limit=None has_time=False exception=None is_static=False>}>>>
    Error while dispatching event for sensor.power_solargen to <Job track state_changed event {'sensor.power_solargen', 'sensor.power_export'} HassJobType.Callback <bound method TrackTemplateResultInfo._refresh of <TrackTemplateResultInfo {Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=22766>: <RenderInfo Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=22766> all_states=False all_states_lifecycle=False domains=frozenset() domains_lifecycle=frozenset() entities=frozenset({‘sensor.power_solargen’, ‘sensor.power_export’}) rate_limit=None has_time=False exception=None is_static=False>}>>>
    Error while dispatching event for sensor.power_export to <Job track state_changed event {'sensor.power_solargen', 'sensor.power_export'} HassJobType.Callback <bound method TrackTemplateResultInfo._refresh of <TrackTemplateResultInfo {Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=22782>: <RenderInfo Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=22782> all_states=False all_states_lifecycle=False domains=frozenset() domains_lifecycle=frozenset() entities=frozenset({‘sensor.power_solargen’, ‘sensor.power_export’}) rate_limit=None has_time=False exception=None is_static=False>}>>>
    Error while dispatching event for sensor.power_solargen to <Job track state_changed event {'sensor.power_solargen', 'sensor.power_export'} HassJobType.Callback <bound method TrackTemplateResultInfo._refresh of <TrackTemplateResultInfo {Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=22790>: <RenderInfo Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=22790> all_states=False all_states_lifecycle=False domains=frozenset() domains_lifecycle=frozenset() entities=frozenset({‘sensor.power_solargen’, ‘sensor.power_export’}) rate_limit=None has_time=False exception=None is_static=False>}>>>
    Traceback (most recent call last):
    File “/usr/src/homeassistant/homeassistant/components/sensor/__init__.py”, line 586, in state
    numerical_value = int(value)
    ^^^^^^^^^^
    ValueError: invalid literal for int() with base 10: ”

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
    File “/usr/src/homeassistant/homeassistant/components/sensor/__init__.py”, line 589, in state
    numerical_value = float(value)
    ^^^^^^^^^^^^
    ValueError: could not convert string to float: ”

    The above exception was the direct cause of the following exception:

    Traceback (most recent call last):
    File “/usr/src/homeassistant/homeassistant/helpers/event.py”, line 293, in _async_dispatch_entity_id_event
    hass.async_run_hass_job(job, event)
    File “/usr/src/homeassistant/homeassistant/core.py”, line 625, in async_run_hass_job
    hassjob.target(*args)
    File “/usr/src/homeassistant/homeassistant/helpers/event.py”, line 1211, in _refresh
    self.hass.async_run_hass_job(self._job, event, updates)
    File “/usr/src/homeassistant/homeassistant/core.py”, line 625, in async_run_hass_job
    hassjob.target(*args)
    File “/usr/src/homeassistant/homeassistant/components/template/template_entity.py”, line 429, in _handle_results
    self.async_write_ha_state()
    File “/usr/src/homeassistant/homeassistant/helpers/entity.py”, line 730, in async_write_ha_state
    self._async_write_ha_state()
    File “/usr/src/homeassistant/homeassistant/helpers/entity.py”, line 830, in _async_write_ha_state
    state, attr = self._async_generate_attributes()
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File “/usr/src/homeassistant/homeassistant/helpers/entity.py”, line 771, in _async_generate_attributes
    state = self._stringify_state(available)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File “/usr/src/homeassistant/homeassistant/helpers/entity.py”, line 736, in _stringify_state
    if (state := self.state) is None:
    ^^^^^^^^^^
    File “/usr/src/homeassistant/homeassistant/components/sensor/__init__.py”, line 593, in state
    raise ValueError(
    ValueError: Sensor sensor.power_consumption has device class ‘None’, state class ‘None’ unit ‘W’ and suggested precision ‘None’ thus indicating it has a numeric value; however, it has the non-numeric value: ” ()

  4. Also ein sher kurioser Weg den jemand hier schon gegangen ist hat nun funktioniert!

    Ich habe ein weiteres UtilityMeter für Export Daily angelegt:
    energy_export_daily2:
    source: sensor.energy_export_sum
    name: Energy Export Daily2
    cycle: daily

    Das war dann innerhalb Minuten verfügbar. Verstehe das wer will.
    Möglicherweise sollte man das Meter nicht anlegen bis Daten unter dem sensor.energy_exort_sum verfügbar sind.
    Ich habe die erste Konfig gemacht während meine OpenDTU keine Daten geliefert hat weil es Nacht war.

    Ich würde mal als Tipp mit aufnehmen die gesamte Konfig mit Ausnahme des UtilityMeter energy_export_daily anzulegen, für einige Stunden laufen zu lassen und dann diese Utility Meter hinzuzufügen.
    Damit sind beim erstellen Daten da und ich vermute das damit die richtige Zuordnung passiert.

  5. Eigentlich ist das genau richtig mit “Ins Netz eingespeist” Er hat 1.4 kwh eingespeist und nur 0.4 bezogen. Damit hat er immer noch 1,02kwh eingespeist. Ist der zeiger auf lila hast du mehr eingespeist als bezogen. Für das optimumm sollte der Zeiger gerade nach oben zeigen. (Es sei denn du bist Einspeiser)

  6. Also bei mir bleibt der Energy Export Daily nicht verfügbar für das Energie Dashboard.
    Ich habe im Sensor folgende Settings angezeigt so das es eigentlich passen sollte:

    sensor.energy_export_daily
    Energy Export Daily
    1.16 state_class: total_increasing
    source: sensor.energy_export_sum
    status: collecting
    last_period: 0.54
    last_valid_state: 1.70
    meter_period: daily
    cron pattern: 0 0 * * *
    last_reset: 2023-09-05T22:00:00.019139+00:00
    icon: mdi:counter
    friendly_name: Energy Export Daily
    unit_of_measurement: kWh
    device_class: energy

    Die gleichen Settings natürlich bis meter-period und cron pattern habe ich beim Energy Export Monthly und diesen könnte ich im Dashboard auswählen.
    In einem Standard Dashboard kann ich den Export Daily natürlich einwandfrei anzeigen lassen.

    Ich bin ratlos. und natürlich habe ich immer Stunden gewartet. Auch habe ich heute dafür gesorgt das 1kw export überschritten wird damit keine 0 vorne steht. Alles nix gebracht

  7. Meinst du damit die Anzeige im Energy Dashboard? Wenn ja, dann müsstest du dich hier an die Entwickler von Home Assistant wenden. Denn das liegt leider nicht in meiner Hand :-(

  8. Hallo, habe das ganze gestern erfolgreich umgesetzt. Keinerlei Probleme. Was sehr schön wäre: auf der “Energie”-Seite wird die aktuell erbrachte Leistung der PV-Anlage in Watt angezeigt. Vielleicht ist das möglich? Dankesehr! :-)

  9. Rudolf Zampa

    Ahhh das war ein Gedankenfehler von mir. Du hast ja 2 Paneele und daher 2 Shelly Plug S und ist in der YAML abgebildet.

  10. Rudolf Zampa

    Hallo,

    habe heute im Protokoll folgende Fehlermeldung erhalten. Habt Ihr auch diese Meldungen schon erhalten?

    ChatGPD sowie das HA -Forum meinen dass ein Wert hier fehlt:

    ChatGPD:
    It seems like you’re creating a template sensor for power consumption based on various conditions involving solar power generation and export/import. The first condition checks if power is being exported and if the difference between solar generation and export is negative, but you haven’t specified what value to use in that case.

    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    HA Forum
    What is the sensor state if that first if test revolves to true?
    # Template sensor for values of power consumption
    power_consumption:
    friendly_name: “Power Consumption”
    unit_of_measurement: ‘W’
    value_template: >-
    {% if (states(‘sensor.power_export’)|float(0)) > 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %}
    {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }}
    {% else %}
    {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }}
    {% endif %}

    XXXXXXXXXXXXXXXXXXXXXXXx Hier das Protokoll:
    Logger: homeassistant.helpers.event
    Source: components/sensor/__init__.py:594
    First occurred: 10. August 2023 um 07:58:05 (964 occurrences)
    Last logged: 14:37:38

    Error while dispatching event for sensor.power_import to <Job track state_changed event {'sensor.power_import', 'sensor.power_solargen', 'sensor.power_export'} HassJobType.Callback <bound method TrackTemplateResultInfo._refresh of <TrackTemplateResultInfo {Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=191822>: <RenderInfo Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=191822> all_states=False all_states_lifecycle=False domains=frozenset() domains_lifecycle=frozenset() entities=frozenset({‘sensor.power_solargen’, ‘sensor.power_export’}) rate_limit=None has_time=False exception=None is_static=False>}>>>
    Error while dispatching event for sensor.power_import to <Job track state_changed event {'sensor.power_import', 'sensor.power_solargen', 'sensor.power_export'} HassJobType.Callback <bound method TrackTemplateResultInfo._refresh of <TrackTemplateResultInfo {Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=193700>: <RenderInfo Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=193700> all_states=False all_states_lifecycle=False domains=frozenset() domains_lifecycle=frozenset() entities=frozenset({‘sensor.power_solargen’, ‘sensor.power_export’}) rate_limit=None has_time=False exception=None is_static=False>}>>>
    Error while dispatching event for sensor.power_import to <Job track state_changed event {'sensor.power_import', 'sensor.power_solargen', 'sensor.power_export'} HassJobType.Callback <bound method TrackTemplateResultInfo._refresh of <TrackTemplateResultInfo {Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=194128>: <RenderInfo Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=194128> all_states=False all_states_lifecycle=False domains=frozenset() domains_lifecycle=frozenset() entities=frozenset({‘sensor.power_solargen’, ‘sensor.power_export’}) rate_limit=None has_time=False exception=None is_static=False>}>>>
    Error while dispatching event for sensor.power_import to <Job track state_changed event {'sensor.power_import', 'sensor.power_solargen', 'sensor.power_export'} HassJobType.Callback <bound method TrackTemplateResultInfo._refresh of <TrackTemplateResultInfo {Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=194206>: <RenderInfo Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=194206> all_states=False all_states_lifecycle=False domains=frozenset() domains_lifecycle=frozenset() entities=frozenset({‘sensor.power_solargen’, ‘sensor.power_export’}) rate_limit=None has_time=False exception=None is_static=False>}>>>
    Error while dispatching event for sensor.power_import to <Job track state_changed event {'sensor.power_import', 'sensor.power_solargen', 'sensor.power_export'} HassJobType.Callback <bound method TrackTemplateResultInfo._refresh of <TrackTemplateResultInfo {Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=194230>: <RenderInfo Template 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) 0 and (states(‘sensor.power_solargen’)|float(0) – states(‘sensor.power_export’)|float(0)) > 0 %} {{ (states(‘sensor.power_solargen’)|float(0)) – states(‘sensor.power_export’)|float(0) }} {% else %} {{ states(‘sensor.power_import’)|float(0) + states(‘sensor.power_solargen’)|float(0) }} {% endif %}) renders=194230> all_states=False all_states_lifecycle=False domains=frozenset() domains_lifecycle=frozenset() entities=frozenset({‘sensor.power_solargen’, ‘sensor.power_export’}) rate_limit=None has_time=False exception=None is_static=False>}>>>
    Traceback (most recent call last):
    File “/usr/src/homeassistant/homeassistant/components/sensor/__init__.py”, line 590, in state
    numerical_value = int(value)
    ^^^^^^^^^^
    ValueError: invalid literal for int() with base 10: ”

    The above exception was the direct cause of the following exception:

    Traceback (most recent call last):
    File “/usr/src/homeassistant/homeassistant/helpers/event.py”, line 274, in _async_dispatch_entity_id_event
    hass.async_run_hass_job(job, event)
    File “/usr/src/homeassistant/homeassistant/core.py”, line 627, in async_run_hass_job
    hassjob.target(*args)
    File “/usr/src/homeassistant/homeassistant/helpers/event.py”, line 1156, in _refresh
    self.hass.async_run_hass_job(self._job, event, updates)
    File “/usr/src/homeassistant/homeassistant/core.py”, line 627, in async_run_hass_job
    hassjob.target(*args)
    File “/usr/src/homeassistant/homeassistant/helpers/template_entity.py”, line 362, in _handle_results
    self.async_write_ha_state()
    File “/usr/src/homeassistant/homeassistant/helpers/entity.py”, line 742, in async_write_ha_state
    self._async_write_ha_state()
    File “/usr/src/homeassistant/homeassistant/helpers/entity.py”, line 810, in _async_write_ha_state
    state = self._stringify_state(available)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File “/usr/src/homeassistant/homeassistant/helpers/entity.py”, line 748, in _stringify_state
    if (state := self.state) is None:
    ^^^^^^^^^^
    File “/usr/src/homeassistant/homeassistant/components/sensor/__init__.py”, line 594, in state
    raise ValueError(
    ValueError: Sensor sensor.power_consumption has device class ‘None’, state class ‘None’ unit ‘W’ and suggested precision ‘None’ thus indicating it has a numeric value; however, it has the non-numeric value: ” ()

Leave a Reply

Your email address will not be published. Required fields are marked *

The maximum upload file size: 128 MB. You can upload: image, audio, video, document, archive, other. Links to YouTube, Facebook, Twitter and other services inserted in the comment text will be automatically embedded. Drop files here