Zonneplan ONE custom component

Hi Ronald,

Thanks for your reply. I have the data in the energy dashboard and also to total cost and now I want to display these on the lovelace. I have no clue how, coming from homey where I first pushed these values using mqtt to the lovelace. But my homey died so going all the way into HA :slight_smile:

Thanks, John

Hi John, you can use the statics card:

type: statistic
entity: sensor.gas_consumption_cost
period:
  calendar:
    period: month
stat_type: change

That picks up the cost change from the LT statistics database. You may need to change the sensor as this is mine. Hope this is helpful.

Ronald

1 Like

And with the statistics card you can make a Graph as well:

chart_type: bar
period: month
days_to_show: 1000
type: statistics-graph
entities:
  - sensor.gas_consumption_cost
stat_types:
  - change
1 Like

Yeah, found it, using the ‘dev tools’ and then the tab ‘statics’ for the correct entities and displaying it with your yaml.

Thanks a lot! :+1:t2:

Created a new zonneplan chart using plotly-graph from HACS. Uses same colors as in the zonneplan app, and shows all from forecast scrollable over time. Time window and pricing shown on mouse over. Reset button to reset to default setting after scrolling. See image and cde attached.

plotly

Edit: updated the api change of may 10 (see below)

type: custom:plotly-graph
title: Zonneplan electricity forecast
hours_to_show: 18
time_offset: 14h
fn: |
  $fn ({ hass, vars }) => {
    vars.x = []; vars.y = []; vars.color = []; vars.hover = []
    vars.min = {p: 999,t: null}; vars.max = {p:-999,t:null}
    vars.ymin = 999; vars.ymax = -999
    vars.unit_of_measurement = hass.states['sensor.zonneplan_current_electricity_tariff'].attributes.unit_of_measurement
    hass.states['sensor.zonneplan_current_electricity_tariff']?.attributes?.forecast?.map(e => {
      var t = new Date(e.datetime).getTime()+1800000 
      var p = e.electricity_price/10000000
      var c = e.tariff_group.replace("low", "#00a964").replace("normal", "#365651").replace("high","#ed5e18")
      if (t>=Date.now()-1800000) {
        if (p<vars.min.p) vars.min = {p,t,c}
        if (p>vars.max.p) vars.max = {p,t,c}
      }
      if (p<vars.ymin) vars.ymin = p
      if (p>vars.ymax) vars.ymax = p
      vars.x.push(t)
      vars.y.push(p)
      vars.color.push(c)
      vars.hover.push(String(new Date(t).getHours()).padStart(2,"0") + "-" + 
        String(new Date((new Date(t).getTime()+3600000)).getHours()).padStart(2,"0") + ": <b>" + 
        p.toFixed(3) + "</b> " + vars.unit_of_measurement)
    })
  }
layout:
  yaxis:
    fixedrange: true
    tickformat: .2f
    range: $fn ({vars}) => [ vars.ymin-0.02, vars.ymax+0.02 ]
  xaxis:
    tickformat: '%H:%M'
config:
  displayModeBar: false
entities:
  - entity: ''
    unit_of_measurement: $ex vars.unit_of_measurement
    name: Tariff
    showlegend: false
    x: $ex vars.x
    'y': $ex vars.y
    marker:
      color: $ex vars.color
    type: bar
    hovertemplate: $ex vars.hover
  - entity: ''
    mode: markers
    textposition: top
    showlegend: true
    name: >-
      $fn ({vars}) => vars.min.p.toFixed(3) + " " + vars.unit_of_measurement + "
      @ " + new Date(vars.min.t).getHours() + ":00"
    yaxis: y0
    marker:
      symbol: diamond
      color: $ex vars.min.c
      opacity: 0.7
    x:
      - $ex vars.min.t
    'y':
      - $ex vars.min.p
  - entity: ''
    mode: markers
    textposition: top
    showlegend: true
    name: >-
      $fn ({vars}) => vars.max.p.toFixed(3) + " " + vars.unit_of_measurement + "
      @ " +  new Date(vars.max.t).getHours() + ":00"
    yaxis: y0
    marker:
      symbol: diamond
      color: $ex vars.max.c
      opacity: 0.7
    x:
      - $ex vars.max.t
    'y':
      - $ex vars.max.p
  - entity: ''
    name: Now
    yaxis: y9
    showlegend: false
    line:
      width: 1
      dash: dot
      color: deepskyblue
    x: $ex [Date.now(), Date.now()]
    'y':
      - 0
      - 1
3 Likes

I love it!

How to add the “current” price next to the min/max diamonds at the top?

simplest way is probably to using vertical stack adding an extra entity card I guess? The current price is not used as variable in the chart. Can be derived from the forecast, but extra card is way simpler.

The current price is avail as the state of the sensor sensor.zonneplan_current_electricity_tariff that is used in the card anyways. I just don’t know how to plot it on now() and get it in the legend. If you can give me a little push into the right direction?

The current price is broken as of today, as Zonneplan changed their API response.

I’ve PR’d a fix here:

Can’t wait?
Change it manually in your custom_components/zonneplan_one/const.py, line 85, change price to electricity_price and restart HA.

If you’re using the forecast_prices (for the next 8 hrs), also edit the next few occurences of .price (see Fix current tariff by hmmbob · Pull Request #64 · fsaris/home-assistant-zonneplan-one · GitHub for which lines to touch)


Using the plotly card setup mentioned few posts above?
Change var p = e.price/10000000 to var p = e.electricity_price/10000000


Using the Apex Charts solution?
Change data_generator: | return entity.attributes.forecast.map((entry) => { return [new Date(entry.datetime), entry.price/10000000]; });
into
data_generator: | return entity.attributes.forecast.map((entry) => { return [new Date(entry.datetime), entry.electricity_price/10000000]; });

same for plotly chart, script above is updated. Manual update change

      var p = e.price/10000000

to

      var p = e.electricity_price/10000000

Yeah, that’s what I said :wink:

Btw, also figured out how to get the “now” value as well!

image

      - type: custom:plotly-graph
        title: Electriciteitsprijs
        hours_to_show: 18
        time_offset: 14h
        fn: |
          $fn ({ hass, vars }) => {
            vars.x = []; vars.y = []; vars.color = []; vars.hover = [];
            vars.min = {p: 999,t: null}; vars.max = {p:-999,t:null}
            vars.ymin = 999; vars.ymax = -999
            vars.p_now = parseFloat(hass.states['sensor.zonneplan_current_electricity_tariff'].state)
            vars.unit_of_measurement = hass.states['sensor.zonneplan_current_electricity_tariff'].attributes.unit_of_measurement
            hass.states['sensor.zonneplan_current_electricity_tariff']?.attributes?.forecast?.map(e => {
              var t = new Date(e.datetime).getTime()+1800000 
              var p = e.electricity_price/10000000
              var c = e.tariff_group.replace("low", "#00a964").replace("normal", "#227153").replace("high","#ed5e18")
              if (t>=Date.now()-1800000) {
                if (p<vars.min.p) vars.min = {p,t,c}
                if (p>vars.max.p) vars.max = {p,t,c}
              }
              if (p<vars.ymin) vars.ymin = p
              if (p>vars.ymax) vars.ymax = p
              vars.x.push(t)
              vars.y.push(p)
              vars.color.push(c)
              vars.hover.push(String(new Date(t).getHours()).padStart(2,"0") + ":00-" + 
                String(new Date((new Date(t).getTime()+3600000)).getHours()).padStart(2,"0") + ":00 : <b>" + 
                p.toFixed(3) + "</b> " + vars.unit_of_measurement)
            })
            console.log(vars)
          }
        layout:
          yaxis:
            fixedrange: true
            tickformat: .2f
            range: $fn ({vars}) => [ vars.ymin-0.02, vars.ymax+0.02 ]
          xaxis:
            tickformat: "%H:%M"
        config:
          displayModeBar: false
        entities:
          - entity: ""
            unit_of_measurement: $ex vars.unit_of_measurement
            name: Tariff
            showlegend: false
            x: $ex vars.x
            "y": $ex vars.y
            marker:
              color: $ex vars.color
            type: bar
            hovertemplate: $ex vars.hover
          - entity: ""
            mode: markers
            textposition: top
            showlegend: true
            name: >-
              $fn ({vars}) => vars.min.p.toFixed(3) + " " + vars.unit_of_measurement + "
              @ " + new Date(vars.min.t).getHours() + ":00"
            yaxis: y0
            marker:
              symbol: diamond
              color: $ex vars.min.c
            x:
              - $ex vars.min.t
            "y":
              - $ex vars.min.p
          - entity: ""
            mode: markers
            textposition: top
            showlegend: true
            name: >-
              $fn ({vars}) => vars.max.p.toFixed(3) + " " + vars.unit_of_measurement + "
              @ " +  new Date(vars.max.t).getHours() + ":00"
            yaxis: y0
            marker:
              symbol: diamond
              color: $ex vars.max.c
            x:
              - $ex vars.max.t
            "y":
              - $ex vars.max.p
          - entity: ""
            name: Now
            yaxis: y0
            showlegend: false
            line:
              width: 2
              dash: dot
              color: deepskyblue
            x: $ex [Date.now(), Date.now()]
            "y":
              - 0
              - 1
          - entity: ""
            yaxis: y0
            mode: markers
            textposition: top
            showlegend: true
            name: >-
              $fn ({vars}) => "Nu: " + vars.p_now.toFixed(3) + " " + vars.unit_of_measurement
            marker:
              symbol: diamond
              color: deepskyblue
            x: $ex [Date.now(), Date.now()]
            "y":
              - $ex vars.p_now
1 Like

Looking good! I did not want to add an extra line, but this actually looks nice :+1:

1 Like

Can’t understand what the issue is, I’ve changed the values due to the new API but for some reason are there not any charts in color…

Anybody got a clue?

The data_generator part is missing in your screenshot. Please post the complete yaml of this card.

Sorry, forgot to copy it…

type: custom:stack-in-card
cards:
  - type: horizontal-stack
    cards:
      - type: custom:mushroom-template-card
        entity: sensor.avg_energy_price
        secondary: Gemiddeld tarief
        primary: € {{ states('sensor.avg_energy_price') | round(2) }} /kWh
        icon: mdi:currency-eur
        icon_color: orange
        tap_action:
          action: more-info
      - type: custom:mushroom-template-card
        entity: sensor.hours_low_coming
        secondary: Goedkoopste tarief
        primary: Over {{ states('sensor.hours_low_coming_far') | round(0) }} uur
        icon: mdi:clock-check
        icon_color: orange
        tap_action:
          action: more-info
      - type: custom:mushroom-template-card
        entity: sensor.zonneplan_current_electricity_tariff
        secondary: Huidig tarief
        primary: >-
          € {{ states('sensor.zonneplan_current_electricity_tariff') | round(2)
          }} /kWh
        icon: mdi:currency-eur
        icon_color: orange
        tap_action:
          action: more-info
  - type: custom:config-template-card
    variables:
      MOVINGAVERAGE: states['sensor.avg_energy_price_cnt']
    entities:
      - ${MOVINGAVERAGE.entity_id}
    card:
      type: custom:apexcharts-card
      apex_config:
        chart:
          height: 200px
          fontFamily: Raleway,sans-serif
        xaxis:
          labels:
            format: HH
        legend:
          show: false
        stroke:
          width: 2
        plotOptions:
          bar:
            columnWidth: 100%
        grid:
          show: true
          borderColor: '#00000030'
          strokeDashArray: 4
          position: back
        dataLabels:
          offsetY: -8
          background:
            opacity: 0.01
            enabled: true
            foreColor: '#CF7524'
            padding: 2
            borderRadius: 4
            borderWidth: 0
          style:
            fontSize: 9px
            color: rgb(200,200,200)
      experimental:
        color_threshold: true
      graph_span: 30h
      span:
        start: day
        offset: +6h
      update_interval: +1h
      header:
        title: Zonneplan Forecast
        show: true
      now:
        show: true
        label: NOW
      series:
        - entity: sensor.zonneplan_current_electricity_tariff
          color_threshold:
            - value: ${MOVINGAVERAGE.state * .50}
              color: '#7bd75d'
            - value: ${MOVINGAVERAGE.state * .50}
              color: '#7bd75d'
            - value: ${MOVINGAVERAGE.state * .75}
              color: '#228B22'
            - value: ${MOVINGAVERAGE.state * 1}
              color: '#d35400'
            - value: ${MOVINGAVERAGE.state * 1.25}
              color: '#c0392b'
          show:
            extremas: true
          type: column
          float_precision: 2
          data_generator: |
            return entity.attributes.forecast.map((entry) => {
              return [new Date(entry.datetime), entry.electricity_price/10000000];
            });
      yaxis:
        - id: '1'
          decimals: 1
          min: 10
          apex_config:
            tickAmount: 6

I have a Zonneplan pv-system and Zonneplan P1 sensor. The P1 sensor is visible in HA but i can’t see my solar system.
In the Zonneplan app everything works fine. Do i need additional steps to do?

Hi there, I’m using Zonneplan ONE since two months now. I have a question: the total cost in the energy tab doesn’t correspond with my invoice from Zonneplan. I know I have to pay € 6,26 per connection, but even then the invoice is 30% higher than what comes from the energy tab. Any thoughts?

Yes, zonneplan charges the taxes based on annual expected usage divided by 12. This reduces the cost in expensive months and increases it in cheap months.

As an example, I expect 1200m3 of gas per annum, they charge actual usage * gross price + 100 * tax

Same applies to electricity.

In addition you pay grid cost.

The explanation is actually in their app.

Thanks, check! So to forecast your invoice per month, you need to:

  • sensor.zonneplan_current_electricity_tariff - tax (about € 0,15 per KWh) * actual usage
  • Tax: expected difference per year (if difference >0) between generated KWh and used KWh * tax / 12
  • Zonneplan i.e. € 6,25
  • Grid cost
  • Tax deduction i.e. € 49,74
  • sensor.zonneplan_current_gas_tariff -tax (about € 0,59 per m3) * actual usage
  • tax expected gas usage per year * € 0,59 / 12
  • Zonneplan i.e. € 6,25
  • Grid cost

The only difference I now have is the gas component: about 3 cents per m3. The integration says an average price of € 1,136 per m3 and the invoice says 1,162 per m3. What am I missing?

(Would be nice to make a tile to forecast your monthly invoice :smiley: )