Time-Offset für Sensor State

Hallo zusammen,

eine Frage an die Template-Profis unter euch.
Es geht grundsätzlich um den Sachverhalt aus diesen Thread

Mein Ziel ist es die im Chart dargestellte Verschiebung der “Prognose nächste Stunde” durch ein Offset in einem Template auszugleichen. Sprich … am Ende sollen die Kurven von “Prognose nächste Stunde” und “Prognose heute” deckungsgleich sein. Leider bietet das verwendete Chart keine Offset-Option an (wie beispielsweise Apex). Ich möchte trotzdem die custom:energy-custom-graph-card nutzen, da diese mit energy-date-selection funktioniert.

Im Moment fehlt mir gerade noch komplett der richtige Ansatz wie das zu bewerkstelligen ist. (naja… ist ja auch Freitag Abend :wink: )

Hat jemand evtl. dazu eine zündende Idee?

Mit templating kommst Du hier nicht weiter.
Du kannst aber mal die Apexchart Card verwenden
Damit lassen sich je Sensor unterschiedliche Offsets auf der Zeitachse abbilden.

Gruß Osorkon

Danke für deine Nachricht. Ich habe bereits ein Apex laufen mit den gleichen Sensoren. Das passt auch soweit.

Habe aber zwischenzeitlich meinen obigen Post editiert. Es gibt halt Gründe die gegen Apex sprechen.

Es muss ja auch nicht das Templating der richtige Weg sein. Vielleicht gibt’s ja ne andere Möglichkeit.

Ein sehr smarter Weg ist, via SQL (z.B. mit der HA original SQL Integration) die entsprechenden Sensoren / Daten abzufragen.
So kannst Du sehr sehr elegant alles mögliche konfigurieren offset, rechnen, riemann, mehrere Sensoren zusammenfassen, Mittelwerte, Zeiträume, max /min .. der Kreativität sind da absolut keine Grenzen gesetzt..

Ich nutze das z.B. super gern um Vergleiche zu bestimmten Zeiträumen aus der DB zu holen.. ein sehr einfaches Beispiel:

Vergleichstemperatur zum exact selben Zeitpunkt letzes Jahr, das Jahr davor… usw.. es ist eine völlig unterschätze Möglichkeit.. man kann so z.b. auch Riemansensoren einen Startwert verpassen uvm.. ich verstehe nicht warum sich soviele Nutzer mit den Template-Sensoren und dem ganzen Geraffel rumärgern!

BTW: Man kann das auch via YAML machen, wenn einem das lieber ist!

Prinzipiell lässt sich auch das Apex Chart mit der energy.-date-selection nutzen.
Es erfordert allerdings einige Helfer und Zusatzkarten.
Hier habe ich das Energy Dashboard von HA nachgebaut. Ist noch in Arbeit daher nur als Richtung.
Oben ist das Apex Chart mit der Energy Flow Card Plus, unten die HA Energy Karten
1

Im Card-Code sieht das dann so aus:

type: custom:config-template-card
variables:
  SPAN: states['sensor.epsp_span'].state
  OFFSET: states['sensor.epsp_offset'].state
  DURATION: states['sensor.epsp_duration'].state
  START: states['sensor.epsp_start'].state
  PERIOD: states['sensor.epsp_period'].state
entities:
  - sensor.pv_og_energy_direkter_eigenverbrauch
  - sensor.power_meter_og_verbrauch
  - sensor.battery_og_gesamtentladung
  - sensor.power_meter_og_exportierte_energie
  - sensor.battery_og_gesamtladung
  - input_number.dummy_refresh
card:
  type: custom:apexcharts-card
  update_interval: 5min
  apex_config:
    chart:
      height: 440px
    legend:
      show: false
  graph_span: ${SPAN}
  span:
    start: ${START}
    offset: ${OFFSET}
  color_list:
    - orange
    - blue
    - green
    - violet
    - pink
  stacked: true
  series:
    - entity: sensor.pv_og_energy_direkter_eigenverbrauch
      type: column
      float_precision: 2
      show:
        legend_value: false
      group_by:
        func: diff
        duration: ${DURATION}
        start_with_last: true
      statistics:
        type: state
        period: ${PERIOD}
    - entity: sensor.power_meter_og_verbrauch
      type: column
      float_precision: 2
      show:
        legend_value: false
      group_by:
        func: diff
        duration: ${DURATION}
        start_with_last: true
      statistics:
        type: state
        period: ${PERIOD}
    - entity: sensor.battery_og_gesamtentladung
      type: column
      float_precision: 2
      show:
        legend_value: false
      group_by:
        func: diff
        duration: ${DURATION}
        start_with_last: true
      statistics:
        type: state
        period: ${PERIOD}
    - entity: sensor.power_meter_og_exportierte_energie
      transform: return x * -1;
      type: column
      float_precision: 2
      show:
        legend_value: false
      group_by:
        func: diff
        duration: ${DURATION}
        start_with_last: true
      statistics:
        type: state
        period: ${PERIOD}
    - entity: sensor.battery_og_gesamtladung
      transform: return x * -1;
      type: column
      float_precision: 2
      show:
        legend_value: false
      group_by:
        func: diff
        duration: ${DURATION}
        start_with_last: true
      statistics:
        type: state
        period: ${PERIOD}

Energy Period Selector Plus-Karte

type: custom:energy-period-selector-plus
sync_start_entity: input_datetime.epsp_startdatum
sync_end_entity: input_datetime.epsp_enddatum

Energy Date Selection Bridge-Karte

type: custom:energy-date-selection-bridge
show_card: false

sensor.epsp_start

{% set start_day = states('input_datetime.epsp_startdatum') | as_datetime %}
{% set end_day = states('input_datetime.epsp_enddatum') | as_datetime %}
{% set span = (end_day - start_day).days + 1 %}
{% if span > 360 %}
  {% set start = 'year' %}
{% else %}
  {% set start = 'day' %}
{% endif %}
{{ start }}

sensor.epsp_span

{% set start_day = states('input_datetime.epsp_startdatum') | as_datetime %}
{% set end_day = states('input_datetime.epsp_enddatum') | as_datetime %}
{% set span = (end_day - start_day).days + 1 %}
{% if span > 360 %}
  {% set span = '1year' %}
{% elif span > 20 %}
  {% set span = ((start_day.replace(day=28) + timedelta(days=7)).replace(day=1) - timedelta(days=1)).day ~ 'd' %}
{% elif span > 1 %}
  {% set span = '7d' %}
{% else %}
  {% set span = '1d' %}
{% endif %}
{{ span }}

sensor.epsp_period

{% set start_day = states('input_datetime.epsp_startdatum') | as_datetime %}
{% set end_day = states('input_datetime.epsp_enddatum') | as_datetime %}
{% set span = (end_day - start_day).days + 1 %}
{% if span > 360 %}
  {% set period = 'month' %}
{% elif span > 1 %}
  {% set period = 'day' %}
{% else %}
  {% set period = 'hour' %}
{% endif %}
{{ period }}

sensor.epsp_offset

{% set start_day = states('input_datetime.epsp_startdatum') | as_datetime %}
{% set end_day = states('input_datetime.epsp_enddatum') | as_datetime %}
{% set span = (end_day - start_day).days + 1 %}
{% if span > 360 %}
  {% set offset = start_day.year - now().year %}
  {% if offset >=0 %}
    {% set offset = '+' ~ offset %}
  {% endif %} 
  {% set offset = offset ~ 'year' %}
{% else %}
  {% set offset = (start_day - now().date() | as_datetime).days %}
  {% if offset >=0 %}
    {% set offset = '+' ~ offset %}
  {% endif %} 
  {% set offset = offset ~ 'd' %}
{% endif %}
{{ offset }}

sensor.epsp_duration

{% set start_day = states('input_datetime.epsp_startdatum') | as_datetime %}
{% set end_day = states('input_datetime.epsp_enddatum') | as_datetime %}
{% set span = (end_day - start_day).days + 1 %}
{% if span > 360 %}
  {% set duration = '1month' %}
{% elif span > 1 %}
  {% set duration = '1d' %}
{% else %}
  {% set duration = '1h' %}
{% endif %}
{{ duration }}

Ob die Energy Brige Karte noch notwendig ist, weiß ich nicht. Habe da einiges auf eigene Sensoren umgebaut und noch nicht getestet, ob sie notwendig ist für die Aktualisierung der Daten.

Die Aktualisierung bei Jahreswerten ist etwas träge, aber es geht.

1 „Gefällt mir“

Danke … das werde ich mir auf alle Fälle mal ansehen und sicher auch umsetzen. Denn Apex bietet ja nun doch einiges mehr an Möglichkeiten als andere Charts.

Für mein spezielles “Problem” verfolge ich gerade einen anderen Weg … werde berichten ob der funktioniert hat.

@Osorkon
@Tom-HA
@bigmirror

Manchmal sieht man halt den Wald vor lauter Bäumen nicht. Die Lösung war dann am Ende doch ziemlich simpel - ohne Templating und SQL-Abfragen.

Das war die Ausgangs-Situation:
SFML “Prognose nächste Stunde” wurde (logischerweise) im Chart um eine Stunde nach vorn versetzt, gegenüber der tatsächlichen “Prognose heute”.

Die Lösung:
Die “custom:energy-custom-graph-card” bietet die Möglichkeit der Kalkulation. In dieser Kalkulation nutze ich jetzt die “Prognose nächste Stunde” zwei mal.

  1. “Prognose nächste Stunde” als “State”
  2. Vom “State - Prognose nächste Stunde” subtrahiere ich die “Prognose nächste Stunde” als Change.

Das Ergebnis ist logischerweise, dass der Graph sich um 1 Stunde nach hinten verschiebt.

et voila :smiley:


type: custom:energy-custom-graph-card
series:
  - statistic_id: sensor.sf_solar_gesamt
    chart_type: line
    stat_type: change
    fill: true
    name: Tatsächlich
    color: rgb(255,140,0)
    fill_opacity: 0.5
    line_opacity: 1
    line_width: 1
  - chart_type: line
    stat_type: change
    source: forecast
    pv_production_entity: sensor.energie_total_hub2000
    color: "--energy-water-color"
    fill: true
    name: SFML
    hidden_by_default: false
    line_style: dotted
    show_in_legend: false
  - chart_type: line
    stat_type: change
    fill: true
    name: SFML
    show_in_legend: true
    line_style: dotted
    hidden_by_default: false
    calculation:
      terms:
        - operation: add
          statistic_id: sensor.solar_forecast_ml_prognose_nachste_stunde
          stat_type: state
        - operation: subtract
          statistic_id: sensor.solar_forecast_ml_prognose_nachste_stunde
          stat_type: change
      unit: kWh
    source: calculation
    color: "--energy-water-color"
timespan:
  mode: energy
grid_options:
  columns: 24
  rows: 6
title: Ertrag und PV-Prognose
aggregation:
  energy_picker:
    hour: raw
    day: hour
    week: hour
    month: hour
    year: hour
  compute_current_hour: true
expand_legend: true
collection_key: energy_5
1 „Gefällt mir“

Super! Cool das Du dran geblieben bist und nicht locker gelassen hast!