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

Mitt forsøk på "Prediktiv reduksjon av strømbruk"


Anbefalte innlegg

haraldov skrev (11 minutter siden):

Du kan også prøve å bruke en automasjon med delay. Du bruker da bare automasjonsentiteten i schedy.

Synes generelt også at timer helper er nyttig til sånne formål. De ivaretar state etter en reboot, sånn at automasjoner ikke påvirkes av at man restarter HA underveis.

Lenke til kommentar
Del på andre sider

Det skal sjekkes ut @haraldov!
Har akkurat oppgradert HA til siste versjon, litt endringer for mqtt (ikke mye) og fått lagt til easee, bmw og noen andre integrasjoner.

Endrer usage step fra 5 til 10, så nå ser det ca slik ut. Om noen har innspill så tar jeg i mot.

Ang VVB vs elbil-lader så er tankegangen å spare 10øre pr kwt og lade mellom 22-06 og i helgene.

VVB trenger ca 10kwt om alle dusjer, den er 3kw så dette tar omtrentlig 3.5t.

Rest av tid fra 0130 til 0600 får elbil, tenker lade med 13 eller 16A som skulle bli 2300-2900W frem til 0600.

I helgene (primærtid for lading) er lading tilgjengelig frem til 2200, men PID må gjerne regulere denne ned ifbm middag og andre ting.
Derfor tror jeg easee må komme langt tidligere på listen, kanskje allerede på nr 9.

Med dagens laderegime er det stort sett 1 dag i uka som er behovet så det burde vel gå bra.
Kloke tanker tas alltid i mot med takk :)

 

@RVM beklager så ikke svaret ditt men skal kikke på dette også!

 

Spoiler
        {%if states.sensor.regulator_energy_usage.state | float<=10 %}1 Alt AV - VVB 3000W
        {% elif states.sensor.regulator_energy_usage.state | float<=20 | float>10 %}2 Easee (6-10-13-16A) (1380-2300-2990-3680W)
        {% elif states.sensor.regulator_energy_usage.state | float<=30 | float>20 %}3 Soverom3 1050W
        {% elif states.sensor.regulator_energy_usage.state | float<=40 | float>30 %}4 Soverom2 1050W
        {% elif states.sensor.regulator_energy_usage.state | float<=50 | float>40 %}5 Soverom1 1050W
        {% elif states.sensor.regulator_energy_usage.state | float<=60 | float>50 %}6 Hall 1200W
        {% elif states.sensor.regulator_energy_usage.state | float<=70 | float>60 %}7 Walkin 650W og kontor 600W
        {% elif states.sensor.regulator_energy_usage.state | float<=80 | float>70 %}8 Vaskerom 840W 
        {% elif states.sensor.regulator_energy_usage.state | float<=90 | float>80 %}9 Bad 500W
        {% elif states.sensor.regulator_energy_usage.state | float<=100 | float>90 %}10 

 

 

Endret av hjemmedude
Lenke til kommentar
Del på andre sider

Har forsøkt en binary_sensor for termostat på bad. Den viser state on eller off (det er binærsensor statuser antakelig, on, off, unknown er de jeg har sett)

seconds endres til minutes, bare jeg som ville se om dette ga en delay på state. Noe jeg ikke er sikker på :P

Neste steg er å bruke denne i schedy, men vet ikke helt hvordan det skal la seg gjøre..

- platform: template
  sensors:
    baderomstermostat_delay:
      friendly_name: "Baderomstermostat delay"
      delay_on: 
        seconds: 5
      delay_off:
        seconds: 5
      value_template: >-
        {{ is_state('climate.bad', 'on') }}

 

Lenke til kommentar
Del på andre sider

@Kim123jeg ønsker 5 min delay på alle termostater, for jeg ser at PID kan endres ganske raskt etter hver hele time. Så for eks bad kan endres fra heat til off og motsatt 4 ganger ila en 10 min periode (kan sjekke nøyaktig men du ser nok poenget).

Med en delay på samtlige termostater kan jeg unngå mye heat/off switching.

Lenke til kommentar
Del på andre sider

hjemmedude skrev (25 minutter siden):

@Kim123jeg ønsker 5 min delay på alle termostater, for jeg ser at PID kan endres ganske raskt etter hver hele time.

 

Jeg hadde samme problemstilling etter hver hele time. Har prøvd litt forskjellig, bl.a:

  • Nokså "myke" verdier for PID gains. Gir treigere respons, men ikke nok til at det forhindrer prematur avslåing. Ønsker uansett rask nok respons senere i timen.
  • Eksponensiell glatting av estimert timesforbruk første 15 minutter etter hel time, med lineært økende glattekonstant fra 0-1 mellom 0-15 minutter. Da unngår man i alle fall plutselige hopp i estimert timesforbruk. I praksis ser estimert forbruk penere ut på grafen, men det løste ikke problemet helt.
  • En konfigurerbar verdi for tidligste tillatte avslåing per enhet (f.eks. bare tillate å skru av VVB 30 minutter etter hel time). Det fungerer, men ser litt rart ut når PID outputen går mot 0 mens alle enheter forblir påslått.
  • Og så den endelige løsningen min: Bare tillatte at PID output øker i verdi første 15 minutter etter hel time. Dersom PID synker, forkast verdien.
  • Like 1
Lenke til kommentar
Del på andre sider

Jeg har bare hatt et "problem" med dette kl 06:00. Da står begge biler på lading og en ovn i hagestue på maks. Så jeg la inn at pid regulator blir ignorert hver arbeidsdag mellom 06:00 og 06:20. Det skjer i andre tilfeller også at timeskifte får mye av varmen til å gå av, men jeg har slått meg til ro med at sånn får det bare være. Men ditt siste punkt er notert, @RVM og mulig jeg legger inn noe slikt jeg også.

Lenke til kommentar
Del på andre sider

stigvi skrev (8 minutter siden):

Men ditt siste punkt er notert, @RVM og mulig jeg legger inn noe slikt jeg også.

 

Det er i alle fall en veldig enkel løsning. Har ikke koden foran meg her nå, men tror det var noe sånt som:

pid.output_limits = (last_c, 1.0)

... i de første 15 minuttene, og så (0.0, 1.0) etterpå. Bruker normaliserte verdier 0-1 for PID output.

Lenke til kommentar
Del på andre sider

RVM skrev (8 minutter siden):

 

Det er i alle fall en veldig enkel løsning. Har ikke koden foran meg her nå, men tror det var noe sånt som:

pid.output_limits = (last_c, 1.0)

... i de første 15 minuttene, og så (0.0, 1.0) etterpå. Bruker normaliserte verdier 0-1 for PID output.

Setter du output_limits bare en gang i starten på timen eller blir den kontinuerlig oppdatert fram til 15m over?

Lenke til kommentar
Del på andre sider

stigvi skrev (5 minutter siden):

Setter du output_limits bare en gang i starten på timen eller blir den kontinuerlig oppdatert fram til 15m over?

Husker ikke detaljene, skal sjekke koden seinere. Men det må ha vært kontinuerlig ja, og alltid nedad begrensa mot forrige verdi.

 

Edit: Men jeg har ikke elbil, så for min del gjør det ingenting om absolutt alt er på de første 15 minuttene, jeg klarer ikke å bryte 5 kWh-grensa på 15 minutter.

Endret av RVM
Lenke til kommentar
Del på andre sider

RVM skrev (3 minutter siden):

Husker ikke detaljene, skal sjekke koden seinere. Men det må ha vært kontinuerlig ja, og alltid nedad begrensa mot forrige verdi.

 

Edit: Men jeg har ikke elbil, så for min del gjør det ingenting om absolutt alt er på de første 15 minuttene, jeg klarer ikke å bryte 5 kWh-grensa på 15 minutter.

Det er bil-lading som er utfordringen min. Kommer pid-regulator så lavt at den stopper ladingen så bruker bilen en liten evighet på å komme i gang igjen. Mulig jeg legger inn slik at pid regulator begrenses nedad til en verdi som er akkurat stor nok til at lading fortsetter som normalt de første 15 minutter. 

Lenke til kommentar
Del på andre sider

stigvi skrev (Akkurat nå):

Det er bil-lading som er utfordringen min. Kommer pid-regulator så lavt at den stopper ladingen så bruker bilen en liten evighet på å komme i gang igjen. Mulig jeg legger inn slik at pid regulator begrenses nedad til en verdi som er akkurat stor nok til at lading fortsetter som normalt de første 15 minutter. 

Lurt!

Lenke til kommentar
Del på andre sider

RVM skrev (11 timer siden):

Husker ikke detaljene, skal sjekke koden seinere. Men det må ha vært kontinuerlig ja, og alltid nedad begrensa mot forrige verdi.

Har sjekka nå, sånn ser update_regulator funksjonen ut hos meg:

 

@state_trigger("pyscript.electricity_estimated_hour_consumption")
def update_regulator():
    global pid

    last_c = float(pyscript.regulator_electric_power)
    
    now = datetime.now()
    if now.minute < 15:
        pid.output_limits = (last_c, 1.0)       # Only allow increase first 15 mins
    else:
        pid.output_limits = (0.0, 1.0)
    
    c = pid(float(pyscript.electricity_estimated_hour_consumption))

    if round(c, 2) != last_c:
        pyscript.regulator_electric_power = round(c, 2)

 

  • Like 2
Lenke til kommentar
Del på andre sider

I frykt for lite varmtvann la jeg inn vvb manuelt i dag. Etter en halvtimes tid så balanserer det seg, men neste time er ikke like balansert. Her spiller kanskje noe i reguleringen inn, jeg bruker samme pid som stigvi men har selvfølgelig andre forbrukere. Er ikke nye å få gjort med de annet enn ny rekkefølge på hvem som slår seg av hvilket nivå. 
Jeg maser stadig om 15 min delay, men jeg vet ikke hva det vil medføre i praksis. I teorien går jeg fra hyppige endringer (for eks 2 min) til Max 4 endringer a 15 min. 
Hva tenker dere? 
Må også finne et bedre kort å vise dette i…

 

edit: matlaging og diverse forbruk glemte jeg ut. Kan være at det er det som gjør det ustabilt i denne perioden. 

 

93BEA9F0-B09D-4DA8-AD01-FB7827930A92.jpeg

Endret av hjemmedude
Lenke til kommentar
Del på andre sider

@RVM jeg vil gjerne prøve din løsning i stigvi's script, er dette rett? Ingen feilmeldinger enn så lenge.

 

from datetime import datetime


@state_trigger("sensor.forbruk_denne_timen")
def new_state():
    global pid
    global last_c
    global turned_off_all
    global turned_off_car
    
    c = (0.9 * last_c) + (0.1 * pid(float(sensor.estimert_timeforbruk_filtrert)))
    p, i, d = pid.components
    state.set("sensor.regulator_p", round(p,1))
    state.set("sensor.regulator_i", round(i,1))
    state.set("sensor.regulator_d", round(d,1))
    
    now = datetime.now()
    if now.minute < 15:
        pid.output_limits = (last_c, 1.0)       # Only allow increase first 15 mins
    else:
        pid.output_limits = (0.0, 1.0)	

    if round(last_c, 0) != round(c, 0):
        sensor.regulator_energy_usage = round(c, 0)

    last_c = c

 

 

Nei her er det noe feil, tok ikke mange minutter før alt var av her.

Kanskje ikke så enkelt likevel ..:)

Endret av hjemmedude
Lenke til kommentar
Del på andre sider

 

hjemmedude skrev (33 minutter siden):

@RVM jeg vil gjerne prøve din løsning i stigvi's script, er dette rett? Ingen feilmeldinger enn så lenge.

 

[...]

    if now.minute < 15:
        pid.output_limits = (last_c, 1.0)       # Only allow increase first 15 mins
    else:
        pid.output_limits = (0.0, 1.0)	

    if round(last_c, 0) != round(c, 0):
        sensor.regulator_energy_usage = round(c, 0)

[...]

 

 

Nei her er det noe feil, tok ikke mange minutter før alt var av her.

Kanskje ikke så enkelt likevel ..:)

 

Ville ikke rundet av mot 0 desimaler hvis PID outputen skal gå fra 0-1. Eller bruker du 0-100 for PID output andre steder? I så fall bør pid.output_limits gå opp til 100.0.

Lenke til kommentar
Del på andre sider

        pid.output_limits = (last_c, 100)       # Only allow increase first 15 mins
    else:
        pid.output_limits = (0.0, 100)
    
    if round(last_c, 0) != round(c, 0):
        sensor.regulator_energy_usage = round(c, 0)

Endret til 100 og tester det, jeg tror det er 0-100 som brukes da dette er definert på toppen av filen og regulator_energy_usage varierer mellom 100 (fullt) og 0 (minst) pådrag ?

 

  • Like 1
Lenke til kommentar
Del på andre sider

hjemmedude skrev (4 minutter siden):

Endret til 100 og tester det, jeg tror det er 0-100 som brukes da dette er definert på toppen av filen og regulator_energy_usage varierer mellom 100 (fullt) og 0 (minst) pådrag ?

 

Ja, det gjelder å være konsistent. Da du rundet av til 0 desimaler med limits på 0 og 1 hadde du bare to mulige utfall, 0.0 og 1.0, og du hadde sikkert høyere terskelverdier enn det for å skru av hvis du hadde lagt opp til PID output mellom 0 og 100.

Endret av RVM
Lenke til kommentar
Del på andre sider

Forresten, er det noen grunn til at du/dere legger på enda et lavpassfilter på PID output når timesestimatet allerede er filtrert?

 

hjemmedude skrev (1 time siden):
[...]
    c = (0.9 * last_c) + (0.1 * pid(float(sensor.estimert_timeforbruk_filtrert)))
    p, i, d = pid.components
    state.set("sensor.regulator_p", round(p,1))
    state.set("sensor.regulator_i", round(i,1))
    state.set("sensor.regulator_d", round(d,1))
[...]

 

 

Blir mest nysgjerrig siden du til og med lagrer PID gains til en entity, så du bruker dem tydeligvis andre steder. Men de reelle PID parametrene er vel ikke de samme som de du lagrer siden outputen går gjennom et filter (dvs. filteret y[n] = 0.9*y[n-1] + 0.1*x[n])?

 

Edit: Ser nå at pid.components ikke gir gains direkte, men hvert av bidragene i PID outputen. Men spørsmålet består :)

Endret av RVM
Lenke til kommentar
Del på andre sider

  • 3 uker senere...
stigvi skrev (På 9.12.2021 den 11.24):

Hva med dette:

 

- platform: template
  sensors:
    - name: "estimert timeforbruk ufiltrert"
      unit_of_measurement: "kWh"
      device_class: power
      state: "{{ (states('sensor.energy')|float(15)+states('sensor.derivert_effekt')|float(0) *(3600-now().minute*60-now().second)/3600) | round(3) }}"



Altså, sjekk opp syntax. Et annet tips: HA har en helt ny måte å definere template sensorer på. I de gamle innleggene på forumet er det gjort på gamle måten. I dokumentasjon hos HA er det vist på nye måten.

 

template:
  - sensor:
    - unique_id: estimated_hourly_consumption_unfiltered
      name: "estimated_hourly_consumption_unfiltered"
      unit_of_measurement: 'kWh'
      device_class: power
      state: "{{ (states('sensor.energy')|float(15)+states('sensor.real_time_consumption_gabriel_edlands_veg_16_integral_derivative')|float(0) *(3600-now().minute*60-now().second)/3600) | round(3) }}"

 

 

Nå har jeg sittet fast på denne i flere uker... Uansett hva jeg prøver så får jeg bare feilmeldinger.
 

#bergnet forbruk denne time
  - platform: template
    sensors:
    - name: "estimert timeforbruk ufiltrert"
      unit_of_measurement: "kWh"
      device_class: power
      state: "{{ (states('sensor.energy')|float(15)+states('sensor.stromforbruk_derivert_effekt')|float(0) *(3600-now().minute*60-now().second)/3600) | round(3) }}"

gir:

Sitat

Invalid config for [sensor.template]: expected dictionary for dictionary value @ data['sensors']. Got [OrderedDict([('name', 'estimert timeforbruk ufiltrert'), ('unit_of_measurement', 'kWh'), ('device_class', 'power'), ('state', "{{ (states('sensor.energy')|float(15)+states('sensor.stromforbruk_derivert_effekt')|float(0) *(3600-now().minute*60-now().second)/3600) | round(3) }}")])]. (See ?, line ?).

Noen forslag? Disse feilmeldingene er ikke helt enkle å tolke når man er nybegynner...

Lenke til kommentar
Del på andre sider

thoralex skrev (28 minutter siden):

 

Nå har jeg sittet fast på denne i flere uker... Uansett hva jeg prøver så får jeg bare feilmeldinger.

 

Noen forslag? Disse feilmeldingene er ikke helt enkle å tolke når man er nybegynner...

 

For meg ser det ut som en sammenblanding av nytt og gammelt template format.

 

Nytt format:

template:
  - sensor:
      - name: "estimert timeforbruk ufiltrert"
        unit_of_measurement: "kWh"
        device_class: power
        state: "{{ (states('sensor.energy')|float(15)+states('sensor.stromforbruk_derivert_effekt')|float(0) *(3600-now().minute*60-now().second)/3600) | round(3) }}"

 

Gammelt format:

- platform: template
  sensors:
    estimert_timeforbruk_ufiltrert:
      friendly_name: "estimert timeforbruk ufiltrert"
      unit_of_measurement: "kWh"
      device_class: power
      value_template: "{{ (states('sensor.energy')|float(15)+states('sensor.stromforbruk_derivert_effekt')|float(0) *(3600-now().minute*60-now().second)/3600) | round(3) }}"

 

Endret av RVM
Lenke til kommentar
Del på andre sider

RVM skrev (19 minutter siden):

 

For meg ser det ut som en sammenblanding av nytt og gammelt template format.

 

Nytt format:

template:
  - sensor:
      - name: "estimert timeforbruk ufiltrert"
        unit_of_measurement: "kWh"
        device_class: power
        state: "{{ (states('sensor.energy')|float(15)+states('sensor.stromforbruk_derivert_effekt')|float(0) *(3600-now().minute*60-now().second)/3600) | round(3) }}"

 

 

Da får jeg feilmelding:

Sitat

Invalid config for [sensor.derivative]: [template] is an invalid option for [sensor.derivative]. Check: sensor.derivative->template. (See ?, line ?). Invalid config for [sensor]: required key not provided @ data['platform']. Got None. (See /config/configuration.yaml, line 16).

Ser ut som det blir noe feil med syntaxen og at det blir lest i sammenheng med sensoren over?

Endret av thoralex
Lenke til kommentar
Del på andre sider

thoralex skrev (24 minutter siden):

Da får jeg feilmelding:

Ser ut som det blir noe feil med syntaxen og at det blir lest i sammenheng med sensoren over?

 

Høres ut som du må sjekke syntaks for "sensor.stromforbruk_derivert_effekt" også ja. Hvordan ser den ut?

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.