Gå til innhold
  • Bli medlem
Støtt hjemmeautomasjon.no!

Lading elbil rimeligste timer fra nordpool


picnic84

Anbefalte innlegg

Laget litt script og visuelt grensesnitt for smartlading av elbil (i mitt tilfelle Tesla på Tesla Wall Charger). Kommer til å innarbeide hensyn til effekttariff også etterhvert når det kommer her i distriktet.

 

image.png.5e59cef234607d01c4d8729672ec7912.png

image.png.f56def87cafb1459d39549a8f71a3865.png

Blått viser rimeligste timen(e) frem til fastsatt deadline. Beregner automatisk ut hvor mange timer lading som behøves basert på info fra Tesla. Apexcharts-card for grensesnittet. Apexchart grensesnittet i stor grad kopiert fra en annen forumpost. Deretter kan man sette opp en automasjon som starter og stopper lading basert på binary sensor laget nedenfor.

 

Koden er litt kaotisk nå, men håper den kanskje er til hjelp eller inspirasjon for andre:

Et par forklaringer i koden:

454 = maks rekkevidde på bil

70 = ladehastighet angitt i km/t

 

sensor:
- platform: template
  sensors:
    charge_cheap_hours:
      friendly_name: "Cheapest hours"
      attribute_templates:
          raw_cheapest_hours: >
            {% set nhoursmax = namespace(nhoursmax= 4) %}
            {% if states('sensor.tesla_model_3_range_sensor')|int > 0 %} 
            {% set nhoursmax.nhoursmax = ((454 - states('sensor.tesla_model_3_range_sensor')|int)/70)|round(0,'ceil') %}
            {% else %}
            {% set nhoursmax.nhoursmax = 4 %}
            {% endif %}
            {% if state_attr('sensor.nordpool_kwh_trheim_nok_2_095_025', 'raw_tomorrow')|length > 1 %}
            {% if state_attr('sensor.nordpool_kwh_trheim_nok_2_095_025', 'raw_tomorrow')[0].value == None %}
            {% set c=state_attr('sensor.nordpool_kwh_trheim_nok_2_095_025', 'raw_today') %}
            {% else %}
            {% set c=state_attr('sensor.nordpool_kwh_trheim_nok_2_095_025', 'raw_today')+state_attr('sensor.nordpool_kwh_trheim_nok_2_095_025', 'raw_tomorrow') %}
            {% endif %}
            {% endif %}
            {% if state_attr('sensor.nordpool_kwh_trheim_nok_2_095_025', 'raw_tomorrow')|length == 0 %}
            {% set c=state_attr('sensor.nordpool_kwh_trheim_nok_2_095_025', 'raw_today') %}
            {% endif %}
            {% set c=c|sort(attribute='value')%}
            {% set chargefrom = namespace(chargefrom=now()) %}
            {% set chargeto = namespace(chargeto=now()) %}

            {% if now().hour < 8 %}
            {% set chargeto.chargeto = now().replace(hour=8,minute=0,second=0) %}
            {% endif %}
            {% if now().hour >= 8 %}
            {% set d = now().day + 1 %}
            {% set chargeto.chargeto = now().replace(day=d,hour=8,minute=0,second=0) %}
            {% endif %}

            {% if states('input_select.charge_deadline') == "Evening" %}
            {% if now().hour < 18 %}
            {% set chargeto.chargeto = now().replace(hour=18,minute=0,second=0) %}
            {% endif %}
            {% if now().hour >= 18 %}
            {% set d = now().day + 1 %}
            {% set chargeto.chargeto = now().replace(day=d,hour=18,minute=0,second=0) %}
            {% endif %}
            {% endif %}

            {% if states('input_select.charge_deadline') == "Unlimited" %}
            {% set d = now().day + 3 %}
            {% set chargeto.chargeto = now().replace(day=d,hour=18,minute=0,second=0) %}
            {% endif %}
            
            {% set data = namespace(list=[]) %}
            {% for item in c %}
            {% if item.end >= chargefrom.chargefrom and item.end <= chargeto.chargeto and data.list|length < nhoursmax.nhoursmax %}
            {% set customer = ({"start":item.start|string,"end": item.end|string,"value":item.value}) %}
            {% set data.list=data.list + [customer] %}
            {% endif %}
            {% endfor %}
            {{data.list|sort(attribute='start')|to_json}}

      value_template: 'on'
    charge_cheap_hour_bool:
      friendly_name: "Cheap hour"
      value_template: >
        {% set nhoursmax = namespace(nhoursmax= 4) %}
        {% if states('sensor.tesla_model_3_range_sensor')|int > 0 %} 
        {% set nhoursmax.nhoursmax = ((454 - states('sensor.tesla_model_3_range_sensor')|int)/70)|round(0,'ceil') %}
        {% else %}
        {% set nhoursmax.nhoursmax = 4 %}
        {% endif %}
        {% if state_attr('sensor.nordpool_kwh_trheim_nok_2_095_025', 'raw_tomorrow')|length > 1 %}
        {% if state_attr('sensor.nordpool_kwh_trheim_nok_2_095_025', 'raw_tomorrow')[0].value == None %}
        {% set c=state_attr('sensor.nordpool_kwh_trheim_nok_2_095_025', 'raw_today') %}
        {% else %}
        {% set c=state_attr('sensor.nordpool_kwh_trheim_nok_2_095_025', 'raw_today')+state_attr('sensor.nordpool_kwh_trheim_nok_2_095_025', 'raw_tomorrow') %}
        {% endif %}
        {% endif %}
        {% if state_attr('sensor.nordpool_kwh_trheim_nok_2_095_025', 'raw_tomorrow')|length == 0 %}
        {% set c=state_attr('sensor.nordpool_kwh_trheim_nok_2_095_025', 'raw_today') %}
        {% endif %}
        {% set c=c|sort(attribute='value')%}
        {% set chargefrom = namespace(chargefrom=now()) %}
        {% set chargeto = namespace(chargeto=now()) %}

        {% if now().hour < 8 %}
        {% set chargeto.chargeto = now().replace(hour=8,minute=0,second=0) %}
        {% endif %}
        {% if now().hour >= 8 %}
        {% set d = now().day + 1 %}
        {% set chargeto.chargeto = now().replace(day=d,hour=8,minute=0,second=0) %}
        {% endif %}

        {% if states('input_select.charge_deadline') == "Evening" %}
        {% if now().hour < 18 %}
        {% set chargeto.chargeto = now().replace(hour=18,minute=0,second=0) %}
        {% endif %}
        {% if now().hour >= 18 %}
        {% set d = now().day + 1 %}
        {% set chargeto.chargeto = now().replace(day=d,hour=18,minute=0,second=0) %}
        {% endif %}
        {% endif %}

        {% if states('input_select.charge_deadline') == "Unlimited" %}
        {% set d = now().day + 3 %}
        {% set chargeto.chargeto = now().replace(day=d,hour=18,minute=0,second=0) %}
        {% endif %}
        
        {% set data = namespace(list=[]) %}
        {% for item in c %}
        {% if item.end >= chargefrom.chargefrom and item.end <= chargeto.chargeto and data.list|length < nhoursmax.nhoursmax %}
        {% set customer = item %}
        {% set data.list=data.list + [customer] %}
        {% endif %}
        {% endfor %}
        {% set chargebool = namespace(chargebool=False) %}
        {% for item in data.list %}
        {% if now() >= item.start and now() <= item.end %}
        {% set chargebool.chargebool = True %}
        {% endif %}
        {% endfor %}
        {{ chargebool.chargebool }}

 

input_boolean:
  charge_onoff:
    name: Enable smart charge
    icon: mdi:car
    
input_select:
  charge_deadline:
    name: Smart charge deadline
    options:
      - Morning
      - Evening
      - Unlimited
    icon: mdi:car

 

Apexchart:

type: custom:apexcharts-card
graph_span: 48h
span:
  start: day
  offset: +0H
header:
  title: Electricity Price
  show: false
  show_states: true
  colorize_states: true
  floating: false
hours_12: false
stacked: false
experimental:
  color_threshold: true
all_series_config:
  show:
    legend_value: false
    datalabels: false
    extremas: true
    in_brush: true
  float_precision: 3
  type: area
  invert: false
  fill_raw: last
now:
  show: true
  label: Now
  color: red
series:
  - entity: sensor.nordpool_kwh_trheim_nok_2_095_025
    name: Current day
    opacity: 0.7
    extend_to: false
    color_threshold:
      - value: -1
        color: '#1E90FF'
      - value: 0
        color: '#008000'
      - value: 0.9
        color: '#008000'
      - value: 1.7
        color: '#DAA520'
      - value: 2
        color: '#FF0000'
    data_generator: |
      return entity.attributes.raw_today.map((start, index) => {
        return [new Date(start["start"]).getTime(), entity.attributes.raw_today[index]["value"]];
      });
  - entity: sensor.nordpool_kwh_trheim_nok_2_095_025
    name: Tomorrow
    opacity: 0.5
    extend_to: false
    color_threshold:
      - value: -1
        color: '#1E90FF'
      - value: 0
        color: '#008000'
      - value: 0.9
        color: '#008000'
      - value: 1.7
        color: '#DAA520'
      - value: 2
        color: '#FF0000'
    data_generator: |
      return entity.attributes.raw_tomorrow.map((start, index) => {

        return [new Date(start["start"]).getTime(), entity.attributes.raw_tomorrow[index]["value"]];

      });
  - entity: sensor.charge_cheap_hours
    name: Cheapest Hours
    color: '#380d94'
    type: column
    opacity: 0.9
    extend_to: false
    stroke_width: -2
    data_generator: |
      return entity.attributes.raw_cheapest_hours.map((start, index) => {

        return [new Date(start["start"]).getTime(), entity.attributes.raw_cheapest_hours[index]["value"]];

      });
apex_config:
  chart:
    height: 400px
    animations:
      enabled: true
      easing: easeinout
      speed: 800
      animateGradually:
        enabled: true
        delay: 150
    zoom:
      enabled: true
      type: x
      autoScaleYaxis: true
      zoomedArea:
        fill:
          color: '#90CAF9'
          opacity: 0.4
        stroke:
          color: '#0D47A1'
          opacity: 0.4
          width: 1
  legend:
    show: false
    floating: true
    offsetY: 25
  yaxis:
    opposite: false
    reversed: false
    logarithmic: false
    decimalsInFloat: 2
    min: 0
    labels:
      show: true
    tooltip:
      enabled: true
    crosshairs:
      show: true
  xaxis:
    labels:
      show: true
      rotate: -45
      rotateAlways: true
    logarithmic: true
  stroke:
    show: true
    curve: stepline
    lineCap: butt
    colors: undefined
  plotOptions:
    candlestick:
      colors:
        upward: '#00B746'
        downward: '#EF403C'
      wick:
        useFillColor: true
  markers:
    size: 1
  grid:
    show: true
    strokeDashArray: 1
    position: front
    xaxis:
      lines:
        show: true

 

  • Thanks 2
Lenke til kommentar
Del på andre sider

On 05/05/2022 at 13:18, picnic84 said:

Laget litt script og visuelt grensesnitt for smartlading av elbil (i mitt tilfelle Tesla på Tesla Wall Charger). Kommer til å innarbeide hensyn til effekttariff også etterhvert når det kommer her i distriktet.

Hvordan hadde du tenkt å lage logikken for å ta hensyn til effekt-tariff? Tenker ikke på kode, men hvordan tenker du dette skal fungere. Det blir jo motstridende mål. Enten lade billig eller å lade med lavere effekt. Ofte vanskelig å kombinere.

Lenke til kommentar
Del på andre sider

  

5 hours ago, OlavT said:

Hvordan hadde du tenkt å lage logikken for å ta hensyn til effekt-tariff? Tenker ikke på kode, men hvordan tenker du dette skal fungere. Det blir jo motstridende mål. Enten lade billig eller å lade med lavere effekt. Ofte vanskelig å kombinere.

 

Det må jeg nesten se på når jeg vet hvordan den prisingen blir. Mest sannsynlig må jeg nok bare på forhånd ta stilling til hvilket nivå jeg skal legge meg på, og mest sannsynlig vil det nok aldri være prismessig verdt det med hensyn til elbillading å betale for et høyere effektnivå. Så da må jeg kanskje bare vurdere om jeg f.eks. vil betale for <5kw, >=5kw eller >=10kw (har ingen varme i huset som går på det ordinære elnettet mitt).

Endret av picnic84
Lenke til kommentar
Del på andre sider

  • 5 måneder senere...
hellowlol skrev (8 timer siden):

Knall at noen gidder å skrive en template for dette 👏

Synd at det ikke er noen etablerte standarder for å styre dette. Ladebokser som i det hele tatt lar seg styre, bruker forskjellige måter å gjøre det på. Teknologien i bunn er i tillegg svak og gir ingen informasjon om ladestatus når en bruker AC lader. Og det gjør jo alle med lading hjemme. Så en blir henvist til bilens mangelfulle kommunikasjon hvis den i det hele tatt har noe.

Egentlig ganske merkelig at vi i 2022 ikke har kommet lenger.

Lenke til kommentar
Del på andre sider

Min hypotese er nok at dette er noe som vil bli mer og mer styrt via bilene. Praktisk talt alle biler som leveres i dag har nettilkobling og solide "datamaskiner". Hvorfor vi da skal trenge enda en kompliserende styringsenhet oppå dette (ladeboks) igjen skjønner jeg ikke. Den kan være dum som et brød for min del. Standarder er fint, men jeg tror vi skal se langt etter noe standard API løsning på tvers av bilmodellene.

 

Jeg har uansett utvidet modellen ovenfor nå med noen få ting:

- knapp til å angi om man skal lade med maxrange eller ikke (100%/80%)

- en mer smooth justering av opp og ned justering ved hjelp av en "average" modul som er mye bedre enn den som finnes i HA

- har også laget script hvor jeg justerer effektbelastningen med hensyn til nettselskapenes trinnprising - (bruker amsleser.no for å lese totalbelastning som fungerer utrolig bra)

 

Kan oppdatere her etterhvert.

Endret av picnic84
Lenke til kommentar
Del på andre sider

Bli med i samtalen

Du kan publisere innhold nå og registrere deg senere. Hvis du har en konto, logg inn nå for å poste med kontoen din.

Gjest
Skriv svar til emnet...

×   Du har limt inn tekst med formatering.   Lim inn uten formatering i stedet

  Du kan kun bruke opp til 75 smilefjes.

×   Lenken din har blitt bygget inn på siden automatisk.   Vis som en ordinær lenke i stedet

×   Tidligere tekst har blitt gjenopprettet.   Tøm tekstverktøy

×   Du kan ikke lime inn bilder direkte. Last opp eller legg inn bilder fra URL.

×
×
  • Opprett ny...

Viktig informasjon

Vi har plassert informasjonskapsler/cookies på din enhet for å gjøre denne siden bedre. Du kan justere dine innstillinger for informasjonskapsler, ellers vil vi anta at dette er ok for deg.