Apexchart offset chart driven by buttons

Servus,

I real love this - thx to all who contribute to make this possible .

After about 1 month of HA and some weeks playing arround like a nerd, i think i have the first chart to share. Also because i have looked arround and have not found something similar and ready ( its never ) to start with.

I have a sungrow inverter and they have some rather nice Mobile App.

So i tried to copy a statistics part ( sort of ) .

This is the result

( 21.12 was the best PV Day in December - and the shortest day … )

So what is needed .

A Counter
2 Buttons (to increase and decrease the counter )
a Card which shows the date ( now - counter )
a apex chart sourounded by a template to look for changed counter

A lot of time and look arround for the simplest stuff why it is not working gg

Here is the complete code.

type: vertical-stack
cards:
  - type: horizontal-stack
    cards:
      - show_name: false
        show_icon: true
        type: custom:button-card
        entity: input_number.daily_offset
        show_state: false
        size: 1.5em
        tap_action:
          action: perform-action
          perform_action: counter.decrement
          target:
            entity_id: counter.dail_offset_value
          data: {}
        hold_action:
          action: none
        icon: mdi:less-than
        triggers_update: all
      - type: custom:mushroom-template-card
        primary: >-
          {% set offset_val = states('counter.dail_offset_value') | int(0)  %} 
          {% set offset = now() - timedelta( days = offset_val, hours = 0,
          minutes = 00 )  %}  {{
            as_datetime(offset).strftime('%d/%m/%Y')
           }}
        secondary: ""
        multiline_secondary: false
        tap_action:
          action: none
        hold_action:
          action: none
        double_tap_action:
          action: none
        layout: vertical
        fill_container: false
      - show_name: false
        show_icon: true
        type: custom:button-card
        entity: input_number.daily_offset
        show_state: false
        size: 1.5em
        tap_action:
          action: perform-action
          perform_action: counter.increment
          target:
            entity_id: counter.dail_offset_value
          data: {}
        hold_action:
          action: none
        icon: mdi:greater-than
        triggers_update: all
  - type: custom:config-template-card
    card:
      type: custom:apexcharts-card
      apex_config:
        tooltip:
          shared: true
          intersect: false
          x:
            format: HH:00 - HH:59
            show: true
        legend:
          show: false
        chart:
          height: 250px
        grid:
          show: true
          strokeDashArray: 0
          borderColor: "#444444"
          position: back
          xaxis:
            lines:
              show: true
          yaxis:
            lines:
              show: true
        yaxis:
          forceNiceScale: true
          tooltip:
            enabled: false
        xaxis:
          tooltip:
            enabled: false
          type: datetime
          axisTicks:
            show: true
          tickAmount: 6
          labels:
            format: HH:mm
          lines:
            show: true
        fill:
          type: gradient
          gradient:
            type: vertical
            shade: dark
            stops:
              - 0
              - 90
            opacityFrom:
              - 1
              - 0.2
            opacityTo:
              - 0.2
              - 1
      update_interval: 30m
      span:
        start: day
      graph_span: 24h
      header:
        show: true
        show_states: true
        colorize_states: true
      series:
        - entity: sensor.battery_charging_power
          color: green
          name: Batterie Aufladen
          invert: false
          group_by:
            func: last
            duration: 10m
            fill: last
          offset: ${'-' + states['counter.dail_offset_value'].state +'d'}
          type: area
          opacity: 0.6
          stroke_width: 2
          show:
            in_header: false
            offset_in_name: false
        - entity: sensor.battery_discharging_power
          color: red
          name: Batterie EntLaden
          invert: true
          group_by:
            func: last
            duration: 10m
            fill: last
          offset: ${'-' + states['counter.dail_offset_value'].state +'d'}
          type: area
          opacity: 0.6
          stroke_width: 1
          show:
            in_header: false
            offset_in_name: false
        - entity: sensor.total_dc_power
          color: orange
          name: PV Generiert
          invert: false
          group_by:
            func: last
            duration: 10m
            fill: last
          offset: ${'-' + states['counter.dail_offset_value'].state +'d'}
          type: area
          opacity: 0.6
          stroke_width: 1
          show:
            in_header: false
            offset_in_name: false
        - entity: sensor.daily_battery_charge
          color: green
          name: Batterie Laden
          invert: false
          group_by:
            func: last
            duration: 24h
            fill: last
          offset: ${'-' + states['counter.dail_offset_value'].state +'d'}
          opacity: 0.6
          stroke_width: 1
          show:
            in_chart: false
            in_header: true
            offset_in_name: false
        - entity: sensor.daily_pv_generation
          color: orange
          name: PV Generiert
          invert: false
          group_by:
            func: last
            duration: 24h
            fill: last
          offset: ${'-' + states['counter.dail_offset_value'].state +'d'}
          opacity: 0.6
          stroke_width: 1
          show:
            in_chart: false
            in_header: true
            offset_in_name: false
        - entity: sensor.daily_battery_discharge
          color: red
          name: Batterie EntLaden
          invert: false
          group_by:
            func: last
            duration: 24h
            fill: last
          offset: ${'-' + states['counter.dail_offset_value'].state +'d'}
          opacity: 0.6
          stroke_width: 1
          show:
            in_chart: false
            in_header: true
            offset_in_name: false
    entities:
      - counter.dail_offset_value

My (in)complete Dashboard for Solar looks like this atm.

And it would be great if someone could use it, or even better make some improvements !

Have a great time in HA ,

Best regards, Dietmar

Have not checked a whole code.
Just 1 remark:
if you place a graph into config-template-card (CTC) and DO NOT declare sensors as “monitored” (i.e. in the “entities” option of CTC) - then the graph will not be updated real-time on every change of these sensors (may be not critical for rarely updating sensors). From other side, if you DO declare them - the whole graph card will be redrawn on every change (not just a curve; and may be even with changing a card’s height which causes a whole view’s flickering). Pro vs contra.

Hi ,

Thx for your reply.

I hope i do understand, but the template used is history per day only . So i ONLY want to refresh the chart if the count(date) changes, and NOT if an current entity changes. I had the chart entity in the “entries” of the template - and if new Data was incoming in refreshed - not need .

EDIT: I do work with offset Data only - so they do not change at all.

Best regards, Dietmar

Servus,

I have made 2 Version of this Chart.

Make your counter start with 0 - it will show the current day …

I really shows that with PV Data the Statistics data are not very good to plot . I needed to use “mean” . The other types did something complete wrong ( more Battery KW load than from the panels - whichi is simple not possible in my case )

Left:

  • Working with raw data
  • More accurate and up-2-date on current summary on the header ( offset = 0 , current date )
  • Scroll in “History” only as long as retention goes (10 days per default )

Right:

  • Working with Statistics Data
  • Not very accurtate and hours Late on the current day summary of the header
  • Scroll in History as you have data

I think it is not possible to have both advantages in 1 chart .


I am still a nyb in HA - so i will keep both of them for now and will look into increasing the retention in the recorder , because i do not like the history graph so much . Need to look how granular this could be set …

Code “left” :slight_smile: .

type: vertical-stack
cards:
  - type: horizontal-stack
    cards:
      - show_name: false
        show_icon: true
        type: custom:button-card
        entity: input_number.daily_offset
        show_state: false
        size: 1.5em
        tap_action:
          action: perform-action
          perform_action: counter.decrement
          target:
            entity_id: counter.dail_offset_value
          data: {}
        hold_action:
          action: none
        icon: mdi:less-than
        triggers_update: all
      - type: custom:mushroom-template-card
        primary: >-
          {% set offset_val = states('counter.dail_offset_value') | int(0)  %} 
          {% set offset = now() - timedelta( days = offset_val, hours = 0,
          minutes = 00 )  %}  {{
            as_datetime(offset).strftime('%d/%m/%Y')
           }}
        secondary: ""
        multiline_secondary: false
        tap_action:
          action: none
        hold_action:
          action: none
        double_tap_action:
          action: none
        layout: vertical
        fill_container: false
      - show_name: false
        show_icon: true
        type: custom:button-card
        entity: input_number.daily_offset
        show_state: false
        size: 1.5em
        tap_action:
          action: perform-action
          perform_action: counter.increment
          target:
            entity_id: counter.dail_offset_value
          data: {}
        hold_action:
          action: none
        icon: mdi:greater-than
        triggers_update: all
  - type: custom:config-template-card
    card:
      type: custom:apexcharts-card
      now:
        show: false
      apex_config:
        tooltip:
          shared: true
          intersect: false
          x:
            format: HH:00 - HH:59
            show: true
        legend:
          show: false
        chart:
          height: 310px
        grid:
          show: true
          strokeDashArray: 0
          borderColor: "#444444"
          position: back
          xaxis:
            lines:
              show: true
          yaxis:
            lines:
              show: true
        yaxis:
          forceNiceScale: true
          tooltip:
            enabled: false
        xaxis:
          tooltip:
            enabled: false
          type: datetime
          axisTicks:
            show: true
          tickAmount: 6
          labels:
            format: HH:mm
          lines:
            show: true
        fill:
          type: gradient
          gradient:
            type: vertical
            shade: dark
            stops:
              - 0
              - 90
            opacityFrom:
              - 1
              - 0.2
            opacityTo:
              - 0.2
              - 1
      update_interval: 10m
      span:
        start: day
      graph_span: 24h
      header:
        show: true
        show_states: true
        colorize_states: true
      series:
        - entity: sensor.battery_charging_power
          color: green
          name: Batterie Aufladen
          invert: false
          group_by:
            func: avg
            duration: 5m
            fill: last
          extend_to: now
          offset: ${'-' + states['counter.dail_offset_value'].state +'d'}
          type: area
          opacity: 0.6
          stroke_width: 2
          show:
            in_header: false
            offset_in_name: false
        - entity: sensor.battery_discharging_power
          color: red
          name: Batterie Ent Laden
          invert: true
          group_by:
            func: avg
            duration: 5m
            fill: last
          extend_to: now
          offset: ${'-' + states['counter.dail_offset_value'].state +'d'}
          type: area
          opacity: 0.6
          stroke_width: 1
          show:
            in_header: false
            offset_in_name: false
        - entity: sensor.total_dc_power
          color: orange
          name: Batterie EntLaden
          invert: false
          group_by:
            func: avg
            duration: 5m
            fill: last
          extend_to: now
          offset: ${'-' + states['counter.dail_offset_value'].state +'d'}
          type: area
          opacity: 0.6
          stroke_width: 1
          show:
            in_header: false
            offset_in_name: false
        - entity: sensor.daily_battery_charge
          color: green
          name: Batterie Laden
          invert: false
          group_by:
            func: last
            duration: 24h
            fill: last
          extend_to: now
          offset: ${'-' + states['counter.dail_offset_value'].state +'d'}
          opacity: 0.6
          stroke_width: 1
          show:
            in_chart: false
            in_header: true
            offset_in_name: false
        - entity: sensor.daily_battery_discharge
          color: red
          name: Batterie EntLaden
          invert: false
          group_by:
            func: last
            duration: 24h
            fill: last
          extend_to: now
          offset: ${'-' + states['counter.dail_offset_value'].state +'d'}
          opacity: 0.6
          stroke_width: 1
          show:
            in_chart: false
            in_header: true
            offset_in_name: false
        - entity: sensor.daily_pv_generation
          color: orange
          name: PV Generiert
          invert: false
          group_by:
            func: last
            duration: 24h
            fill: last
          extend_to: now
          offset: ${'-' + states['counter.dail_offset_value'].state +'d'}
          opacity: 0.6
          stroke_width: 1
          show:
            in_chart: false
            in_header: true
            offset_in_name: false
    entities:
      - counter.dail_offset_value

2nd:

type: vertical-stack
cards:
  - type: horizontal-stack
    cards:
      - show_name: false
        show_icon: true
        type: custom:button-card
        entity: input_number.daily_offset
        show_state: false
        size: 1.5em
        tap_action:
          action: perform-action
          perform_action: counter.decrement
          target:
            entity_id: counter.dail_offset_value
          data: {}
        hold_action:
          action: none
        icon: mdi:less-than
        triggers_update: all
      - type: custom:mushroom-template-card
        primary: >-
          {% set offset_val = states('counter.dail_offset_value') | int(0)  %} 
          {% set offset = now() - timedelta( days = offset_val, hours = 0,
          minutes = 00 )  %}  {{
            as_datetime(offset).strftime('%d/%m/%Y')
           }}
        secondary: ""
        multiline_secondary: false
        tap_action:
          action: none
        hold_action:
          action: none
        double_tap_action:
          action: none
        layout: vertical
        fill_container: false
      - show_name: false
        show_icon: true
        type: custom:button-card
        entity: input_number.daily_offset
        show_state: false
        size: 1.5em
        tap_action:
          action: perform-action
          perform_action: counter.increment
          target:
            entity_id: counter.dail_offset_value
          data: {}
        hold_action:
          action: none
        icon: mdi:greater-than
        triggers_update: all
  - type: custom:config-template-card
    card:
      type: custom:apexcharts-card
      now:
        show: false
      apex_config:
        tooltip:
          shared: true
          intersect: false
          x:
            format: HH:00 - HH:59
            show: true
        legend:
          show: false
        chart:
          height: 310px
        grid:
          show: true
          strokeDashArray: 0
          borderColor: "#444444"
          position: back
          xaxis:
            lines:
              show: true
          yaxis:
            lines:
              show: true
        yaxis:
          forceNiceScale: true
          tooltip:
            enabled: false
        xaxis:
          tooltip:
            enabled: false
          type: datetime
          axisTicks:
            show: true
          tickAmount: 6
          labels:
            format: HH:mm
          lines:
            show: true
        fill:
          type: gradient
          gradient:
            type: vertical
            shade: dark
            stops:
              - 0
              - 90
            opacityFrom:
              - 1
              - 0.2
            opacityTo:
              - 0.2
              - 1
      update_interval: 10m
      span:
        start: day
      graph_span: 24h
      header:
        show: true
        show_states: true
        colorize_states: true
      series:
        - entity: sensor.battery_charging_power
          color: green
          name: Batterie Aufladen
          invert: false
          statistics:
            type: mean
            period: hour
            align: start
          extend_to: now
          offset: ${'-' + states['counter.dail_offset_value'].state +'d'}
          type: area
          opacity: 0.6
          stroke_width: 2
          show:
            in_header: false
            offset_in_name: false
        - entity: sensor.battery_discharging_power
          color: red
          name: Batterie Ent Laden
          invert: true
          statistics:
            type: mean
            period: hour
            align: start
          extend_to: now
          offset: ${'-' + states['counter.dail_offset_value'].state +'d'}
          type: area
          opacity: 0.6
          stroke_width: 1
          show:
            in_header: false
            offset_in_name: false
        - entity: sensor.total_dc_power
          color: orange
          name: Batterie EntLaden
          invert: false
          statistics:
            type: mean
            period: hour
            align: start
          extend_to: now
          offset: ${'-' + states['counter.dail_offset_value'].state +'d'}
          type: area
          opacity: 0.6
          stroke_width: 1
          show:
            in_header: false
            offset_in_name: false
        - entity: sensor.daily_battery_charge
          color: green
          name: Batterie Laden
          invert: false
          statistics:
            type: state
            period: hour
            align: end
          extend_to: now
          offset: ${'-' + states['counter.dail_offset_value'].state +'d'}
          opacity: 0.6
          stroke_width: 1
          show:
            in_chart: false
            in_header: true
            offset_in_name: false
        - entity: sensor.daily_battery_discharge
          color: red
          name: Batterie EntLaden
          invert: false
          statistics:
            type: state
            period: hour
            align: end
          extend_to: now
          offset: ${'-' + states['counter.dail_offset_value'].state +'d'}
          opacity: 0.6
          stroke_width: 1
          show:
            in_chart: false
            in_header: true
            offset_in_name: false
        - entity: sensor.daily_pv_generation
          color: orange
          name: PV Generiert
          invert: false
          statistics:
            type: state
            period: hour
            align: end
          extend_to: now
          offset: ${'-' + states['counter.dail_offset_value'].state +'d'}
          opacity: 0.6
          stroke_width: 1
          show:
            in_chart: false
            in_header: true
            offset_in_name: false
    entities:
      - counter.dail_offset_value

Best regards, Dietmar

Servus,

It seems that i have changed some settings via MODBUS (ups) , and therefore my Inverter was degraded - my “Solarteur” fixxed it . But to get the idea that something is wrong HA helped a lot :slight_smile: . So i could just advise to show the Inverter State , my updated Dashboad:

Have a great time in HA .

Best regards, Dietmar