Skip to content

fsaris/home-assistant-zonneplan-one

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Zonneplan integration for Home Assistant

GitHub Release Active installations hacs_badge stability-stable GitHub License

Unofficial integration for Zonneplan. This integration uses the official Zonneplan API to pull the same data available in the Zonneplan app into your Home Assistant instance.

Available sensors

Zonneplan:

  • Solar panels: (available when you have 1 or more Zonneplan solar inverters)
    • Yield today: kWh (combined yield of all Zonneplan solar inverters) (can be used as entity on Energy Dashboard)
  • General energy values: (available when there is a Zonneplan Connect P1 reader)
    • Electricity consumed today: kWh (can be used as entity on Energy Dashboard)
    • Electricity returned today: kWh (can be used as entity on Energy Dashboard)
    • Gas consumption today:

Zonneplan Connect (P1 reader):

Sensors available if you have a Zonneplan Connect P1 reader
  • Dsmr version (default disabled)
  • Electricity consumption: W
  • Electricity production: W
  • Electricity average: W (average use over the last 5min)
  • Electricity first measured: date (default disabled)
  • Electricity last measured: date
  • Electricity last measured production: date
  • Gas first measured: date (default disabled)
  • Gas last measured: date

Zonneplan Energy contract related:

Sensors available if you have a Zonneplan energy contract
  • Current Zonneplan Electricity tariff: €/kWh
    • The full Electricity forecast is available as a forecast attribute of this sensor
  • Current Zonneplan Gas tariff: €/m³
  • Next Zonneplan Gas tariff: €/m³
  • 8 hours forecast of Zonneplan Electricity tariff: €/kWh (default disabled, available when you have a energy contract)
  • Current electricity usage
  • Sustainability score
  • Electricity delivery costs today
  • Electricity production costs today
  • Gas delivery costs today

Zonneplan Solar inverter:

Sensors available if you have a Zonneplan solar inverter
  • Yield total: kWh
  • First measured: date (default disabled)
  • Last measured value: W
  • Last measured: date
  • Powerplay enabled: on/off (default disabled)
  • Powerplay/power limit active: on/off (default disabled)
  • Powerplay total: (default disabled)
  • Powerplay today: (default disabled)

Zonneplan Charge point/Laadpaal:

Sensors available if you have a Zonneplan charge point/laadpaal
  • Charge point state
  • Charge point power W
  • Charge point energy delivered session kWh
  • Charge point next schedule start date
  • Charge point next schedule end date
  • Charge point dynamic load balancing health (default disabled)
  • Charge point connectivity state on/off
  • Charge point can charge on/off
  • Charge point can schedule on/off
  • Charge point charging manually on/off
  • Charge point charging automatically on/off
  • Charge point plug and charge on/off
  • Charge point overload protection active on/off (default disabled)
  • Charge point session cost
  • Charge point cost total
  • Charge point flex result
  • Charge point session average costs €/kWh
  • Charge point start mode (default disabled)
  • Charge point dynamic load desired distance km
  • Charge point dynamic load desired end time datetime
  • Charge point session start time datetime
  • Charge point session charged distance km
  • Charge point dynamic charging enabled on/off
  • Charge point dynamic charging flex enabled on/off
  • Charge point dynamic charging flex suppressed on/off (default disabled)
  • Buttons to start/stop charge

Zonneplan Battery:

Sensors available if you have a Zonneplan Nexus battery
  • Average day:
  • Battery cycles
  • Dynamic charging enabled on/off
  • Battery state
  • Percentage %
  • Power W (default disabled)
  • Delivery today kWh
  • Production today kWh
  • Today
  • Total
  • Dynamic charging enabled on/off
  • Dynamic load balancing overload active on/off
  • Dynamic load balancing overload enabled on/off
  • Manual control enabled on/off
  • Inverter state (default disabled)
  • Manual control state (default disabled)
  • First measured datetime (default disabled)
  • Last measured datetime
  • Grid congestion active on/off
  • Home optimization active on/off
  • Home optimization enabled on/off
  • Self consumption enabled on/off

Installation

Install with HACS (recommended)

Ensure you have HACS installed.

Direct link to Zonneplan in HACS

  1. Click the above My button or search HACS integrations for Zonneplan
  2. Click Install
  3. Restart Home Assistant
  4. Continue with setup

Install manually

  1. Install this platform by creating a custom_components folder in the same folder as your configuration.yaml, if it doesn't already exist.
  2. Create another folder zonneplan_one in the custom_components folder.
  3. Copy all files from custom_components/zonneplan_one into the newly created zonneplan_one folder.

Installing main/beta version using HACS

  1. Go to HACS => Integrations
  2. Click on the three dots icon in right bottom of the Zonneplan card
  3. Click Reinstall
  4. Make sure Show beta versions is checked
  5. Select version main
  6. Click install and restart HA

Setup

Open your Home Assistant instance and start setting up Zonneplan.

  1. Click the above My button (or navigate to Configuration -> Integrations -> + Add integration and search for and select Zonneplan ONE)
  2. Enter you emailaddress you also use in the Zonneplan app
  3. You will get an email to verify the login.
  4. Click "Save"
  5. Enjoy

Setup Energy Dashboard

Open your Home Assistant instance and start setting up Energy sensors.

Solar production

Zonneplan Yield total is what your panels produced

Grid consumption

Zonneplan Electricity consumption today is what you used from the grid

Return to grid

Zonneplan Electricity returned today is what you returned to the grid

Using full forecast in graphs, tables and/or automations

The full forecast is available as attributes of the Current Zonneplan Electricity tariff sensor. The incl. tax and excl. tax values are present. Zonneplan doesn't deliver a constant set of forecast values.

Using a helper you can turn this data into a single "cheapest price at" sensor. Or with some template magic you can turn it in a nice table so shown on your dashboard. Or fill a graph like shown in the official app.

Cheapest price sensor

Setup template sensor helper

Go to Helpers and create and new Template -> Template sensor helper to create a sensor that shows the cheapest time based on the forecast data

From discussions/41

{% set cheapest_hour_next_twelve_hours = state_attr('sensor.zonneplan_current_electricity_tariff', 'forecast') 
  | selectattr('datetime', '>', utcnow().isoformat())
  | selectattr('datetime', '<', (utcnow() + timedelta(hours = 11)).isoformat())  
  | sort(attribute='price')  
  | first %}

{{ as_local(as_datetime(cheapest_hour_next_twelve_hours.datetime)) }}

Setup template sensor helper

Forecast table

From discussions/41

{% set timezone_offset = 2 %} {# Verander 2 naar je gewenste offset in uren #}
{% set cheapest_hour_next_fifteen_hours =
state_attr('sensor.zonneplan_current_electricity_tariff', 'forecast') |
selectattr('datetime', '>', utcnow().isoformat()) |
selectattr('datetime', '<', (utcnow() + timedelta(hours = 15)).isoformat())
| sort(attribute='price') %}
{% if cheapest_hour_next_fifteen_hours | length > 0 %}
{% set cheapest_hour = cheapest_hour_next_fifteen_hours | first %}
{% set cheapest_hour_local_time = as_timestamp(strptime(cheapest_hour.datetime, '%Y-%m-%dT%H:%M:%S.%fZ')) + timezone_offset * 3600 %}
De goedkoopste tijd is {{ 'vandaag' if as_timestamp(utcnow())|timestamp_custom('%Y-%m-%d') == cheapest_hour_local_time|timestamp_custom('%Y-%m-%d') else 'morgen' }} om {{ (cheapest_hour_local_time)|timestamp_custom('%H') }} uur en kost €{{"{:.2f}".format(cheapest_hour.electricity_price_excl_tax|float/10000000) }}/kWh.
  {% endif %}
  
  {%- set cheapest_forecast =
  state_attr('sensor.zonneplan_current_electricity_tariff', 'forecast') |
  selectattr('datetime', '>', utcnow().isoformat()) | selectattr('datetime',
  '<', (utcnow() + timedelta(hours = 15)).isoformat()) | list |
  sort(attribute='electricity_price_excl_tax') | first %}
  
  {%- set expensive_forecast =
  state_attr('sensor.zonneplan_current_electricity_tariff', 'forecast') |
  selectattr('datetime', '>', utcnow().isoformat()) | selectattr('datetime',
  '<', (utcnow() + timedelta(hours = 15)).isoformat()) | list |
  sort(attribute='electricity_price_excl_tax') | last %}
  
  {%- for forecast in
  state_attr('sensor.zonneplan_current_electricity_tariff', 'forecast') |
  selectattr('datetime', '>', utcnow().isoformat()) | selectattr('datetime',
  '<', (utcnow() + timedelta(hours = 15)).isoformat()) | list |
  sort(attribute='datetime') %}
  
  {%- set forecast_local_time = as_timestamp(strptime(forecast.datetime, '%Y-%m-%dT%H:%M:%S.%fZ')) + timezone_offset * 3600 %}
  • {{ (forecast_local_time)|timestamp_custom('%H:%M') }}    €{{ (forecast.electricity_price / 10000000) | round(2) }} (€{{ (forecast.electricity_price_excl_tax / 10000000) | round(2) }} excl.) {% if forecast == cheapest_forecast %}⭐{% endif %}{% if forecast == expensive_forecast %}🔴{% endif %}
  {%- endfor %}

Example:

Forecast

Forecast graph

Graph example

Setup graph card

From HomeAssistant community

Install the PlotlyGraph custom component and setup a card with next config:

type: custom:plotly-graph
hours_to_show: 20
refresh_interval: 600
time_offset: 18h
disable_pinch_to_zoom: true
fn: |
  $fn ({ hass, vars, getFromConfig }) => {
    const hours_to_show = getFromConfig('hours_to_show');
    const time_offset = parseInt(getFromConfig('time_offset'));
    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
    vars.now = {t: Date.now(), p: parseFloat(hass.states['sensor.zonneplan_current_electricity_tariff'].state)} 
    vars.now.h = "<b>" + vars.now.p.toFixed(3) + "</b> " + vars.unit_of_measurement + " @now " 
    vars.avg = { p: 0, c: 0 }
    let start = new Date();
    start.setHours(start.getHours() - (hours_to_show - time_offset));
    let end = new Date();
    end.setHours(start.getHours() + hours_to_show - 1);
    hass.states['sensor.zonneplan_current_electricity_tariff']?.attributes?.forecast?.map(e => {
      if (start >= new Date(e.datetime) || end <  new Date(e.datetime)) return;
      var t = new Date(e.datetime).getTime()+1800000 
      var p = e.electricity_price/10000000
      vars.avg.p += p
      vars.avg.c++
      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)
    })
    vars.min.h = "<b>" + vars.min.p.toFixed(3) + "</b> " + vars.unit_of_measurement + " @ " + new Date(vars.min.t).getHours() + ":00"
    vars.max.h = "<b>" + vars.max.p.toFixed(3) + "</b> " + vars.unit_of_measurement + " @ " +  new Date(vars.max.t).getHours() + ":00"
    vars.avg.p = vars.avg.p / vars.avg.c
    vars.avg.h = "<b>" + vars.avg.p.toFixed(3) + "</b> " + vars.unit_of_measurement + " average"
    //console.log(vars, hass.states['sensor.zonneplan_current_electricity_tariff']?.attributes?.forecast);
  }
layout:
  margin:
    l: 20
    r: 20
    b: 40
  dragmode: false
  clickmode: none
  legend:
    itemclick: false
    itemdoubleclick: false
  yaxis:
    fixedrange: false
    tickformat: .2f
    range: $fn ({vars}) => [ vars.ymin-0.02, vars.ymax+0.02 ]
    showgrid: false
    visible: false
    showticklabels: true
    showline: false
    title: null
  xaxis:
    tickformat: "%H"
    showgrid: false
    visible: true
    showticklabels: true
    showline: false
    dtick: 3600000
config:
  displayModeBar: false
  scrollZoom: false
  doubleClick: false
entities:
  - entity: ""
    unit_of_measurement: $ex vars.unit_of_measurement
    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: $ex vars.min.h
    hovertemplate: $ex vars.min.h
    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: $ex vars.max.h
    hovertemplate: $ex vars.max.h
    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
    hovertemplate: Now
    yaxis: y9
    showlegend: false
    line:
      width: 0.5
      color: gray
      opacity: 1
    x: $ex [vars.now.t, vars.now.t]
    "y":
      - 0
      - 1

Troubleshooting

If you run into issues during setup or when entries do not update anymore please enable debug logging and provide them when creating an issue.

  1. Go to the integration

    Open your Home Assistant instance and show an integration.

  2. Enable debug log by clicking Enable debug logging

  3. Wait a few minutes for the integration to fetch new data

  4. Disable debug logging again (same button as step 2)

  5. Log will be presented for download

  6. Be sure to remove sensitive data from the log before attaching it to a ticket