HomeAssistant ja sähköpörssiohjaus

heebo1974

Aktiivinen jäsen
Datahubin mukaan meillä on käytössä varttinetotus, joten varmuuden vuoksi siirryin virtuaaliseen varttinetotukseen LVV:n kanssa.
Kylllähän tuo LVV kontaktori paukkuu kokoajan ja oikein hirvittää, että koska se paukkuu lopullisesti. :)
Mistään ei tunnu löytyvän tietoa, että onko varttinetotus oikeasti käytössä vai onko se vain kosmeettista.
Siis datahubin mukaan se kyllä netottaa 15min jaksoihin, mutta uiko se myös sähkölaskulle, siitä ei ole tietoa.
Olen tässä vähän tarkkaillut 1h ja 15min virtuaalinetotus graafeja ja kyllä se menee aika perseelleen, jos itse netottelee 1h mukaan ja sähköyhtiö netottaa 15min mukaan. Jos taas itse netottaa 15min mukaan ja yhtiö 1h:n niin ollaan vain turvallisemmalla puolella.
Paljon vaikeampi on löytää hyviä raja-arvoja 15min netotukselle. :(
 

Mikki

Hyperaktiivi
Ei ole kuluttajille varttihinnoittelua! DayAhead hinnoittelu on tukevasti tuntitasolla ja se on mikä laskutuksen ratkaisee, ei se vaikka mitattaisiin kulutus sekunnin välein.
 

heebo1974

Aktiivinen jäsen
Ei ole kuluttajille varttihinnoittelua! DayAhead hinnoittelu on tukevasti tuntitasolla ja se on mikä laskutuksen ratkaisee, ei se vaikka mitattaisiin kulutus sekunnin välein.
Juu ei ole, kun ostaa sähköä pörssisähköllä. Mutta miten on netotuksen kanssa, koska se vaikuttaa siirtohintoihin? Nyt puhutaan siis aurinkopaneeleiden ylituotannosta.

Sähköyhtiölle olisi kannattavaa käyttää tuota 15min netotusta panelisteille. Koska panelisteille tulee todennäköisesti enemmän siirtokuluja.
 

Mikki

Hyperaktiivi
Mielestäni ei myöskään netotus voi olla varteittain ilman ettei siitä ole asiakkaita tiedotettu...

Aivan helppo riitauttaa jos sopimuksen toinen osapuoli muuttaisi ehtoja yksipuolisesti. Ei ne sitä voi tehdä
 

Sukke

Aktiivinen jäsen
Havahduin tässä miettimään MLP:n hyötysuhteita, jos pumppua kuormitetaan lyhyesti kovilla kierroksilla versus kauemmin matalammilla kierroksilla.

Kompressorin ottotehoa on mittaamassa Shelly, mutta tuotosta ei ole mittaustietoa. MLP tosin ilmoittaa jonkinlaista tuottolukemaa, mutta sen tarkkuudesta ei ole tietoa.

Joka tapauksessa edellisten tietojen perusteella olen laskeskellut Home Assistentissa hetkellistä COPia lämmitykselle. Tuolla 6 kW (80-90 % maksimista?) tietämillä COPiksi on tullut luokkaa 5,1 ja 2 kW minimiteholla luokkaa 6,9.

Voiko COP-erot tulla noin suuriksi? Nämä lukemat on havaittu nyt hiljattain, kun lämmitystarve on ollut vähäinen tai melkein olematon. Talviajasta ei ole tässä mielessä havaintoja.

Mitenhän tuota kannattaa ottaa pörssiohjauksessa huomioon tai miten olette ottaneet tuota COP-eroa huomioon?

Oma ohjaus perustuu mitatun ja ennustetun lämpötilan perusteella määritettyyn tarvittaviin lämmitystunteihin. Kun näille tunneilla saadaan laskettua keskihinta, olen ottanut lisäksi mukaan tunnit, jotka poikkeavat enintään valitun prosentin mukaisesti keskihinnasta. Jos esim. 5 tunnin keskihinnaksi tulee 7 c/kWh, sallitaan esim. 15 % säännöllä kaikki tunnit, jotka on enintään 8,05 c/kWh. Ohjaus tehdään sisälämpötilan arvoa muuttamalla ja se toimii ihan ok.

Yksinkertaistetulla laskennalla sähköenergian osuus saa kasvaa aika suureksi ennen kuin paremmalla hyötysuhteella tuotettu energiamäärä tulee siirto huomoituna kalliimmaksi kuin heikommalla hyötysuhteella tuotettu. Jos COP-ero on suuri, voi parempi hyötysuhde kannattaa vaikkapa vielä 1,5- tai jopa 2-kertaisella energian hinnalla.

Epäilen, että olen tässä jotenkin hakoteillä. Auttaisiko joku polulle.
 

Temez

Aktiivinen jäsen
Hei pitkästä aikaa ja pahoittelut hiljaiselosta. HomeAssistant 2023.05 aiheutti ilmeisesti paljon ongelmia. Itsellä ollut tässä mielessä ihan muut asiat kuin pörssisähkö viime aikoina ja oli pitkässä piipussa omankin HA:n päivitys.

Nyt joka tapauksessa pitäisi olla Githubissa tarjolla versio 0.1.11, jossa koetettu korjata kyseinen vika. Ainakin omassa testi-HA:ssa toimii OK.

(En ole nyt lukenut kaikkia tämän ketjun viestejä. Katsotaan, jos muutakin korjaustarvetta on vielä.)
 

exrx

Jäsen
Hei pitkästä aikaa ja pahoittelut hiljaiselosta. HomeAssistant 2023.05 aiheutti ilmeisesti paljon ongelmia. Itsellä ollut tässä mielessä ihan muut asiat kuin pörssisähkö viime aikoina ja oli pitkässä piipussa omankin HA:n päivitys.

Nyt joka tapauksessa pitäisi olla Githubissa tarjolla versio 0.1.11, jossa koetettu korjata kyseinen vika. Ainakin omassa testi-HA:ssa toimii OK.

(En ole nyt lukenut kaikkia tämän ketjun viestejä. Katsotaan, jos muutakin korjaustarvetta on vielä.)
Onko (varmaan on...) jokin keino esittää tuntihinnat HA:ssa taulukkona? Siis kahdella sarakkeella, ensimmäisessä tunnit ja toisessa hinnat? Tuo Apex cards on kyllä "näyttävä", mutta puhelimella vähän hankalakäyttöinen. Ainakin iPhonella hintalaatikko pomppii siten, että se on useimmiten sormen alla.
 

Temez

Aktiivinen jäsen
Onko (varmaan on...) jokin keino esittää tuntihinnat HA:ssa taulukkona? Siis kahdella sarakkeella, ensimmäisessä tunnit ja toisessa hinnat? Tuo Apex cards on kyllä "näyttävä", mutta puhelimella vähän hankalakäyttöinen. Ainakin iPhonella hintalaatikko pomppii siten, että se on useimmiten sormen alla.
Onhan tuo mahdollista. Jos ei muuten, niin sitten lisäosalla. Asenna tämä "uusi kortti": https://github.com/PiotrMachowski/Home-Assistant-Lovelace-HTML-Jinja2-Template-card

Ja lisää käyttöliittymän kautta uusi manuaalinen kortti dashboardille, johon koodiksi seuraava:
YAML:
type: custom:html-template-card
title: Electricity prices
ignore_line_breaks: true
content: >
  <style> table, th, td { border: 1px solid;} </style>
  <table style="border: 1px solid"> {% for value in (state_attr("sensor.shf_electricity_price_now",
  "data")) %} <tr><td>{{strptime(value["DateTime"][:-6], '%Y-%m-%dT%H:%M:%S')}}</td><td>{{ (value["PriceWithTax"]*100) | round(2)}} c/kWh</td> </tr> {% endfor %}
  </table>
Saat ulos jotain tämmöistä:
1687786094590.png
 

tk-

Aktiivinen jäsen
Jos haluaa kalastella tuolta spot-hinta.fi -haetun sensorin attribuuteista suoraan aina tietyn tunnin hinnat ja rankit välittämättä siitä, onko vuorokaudessa aina 24 tuntia, niin onnistuu ainakin tähän tapaan. Tuossa nyt templaattieditorimallissa nuo kaikki arvot, mutta jos haluaa vaikkapa pelkän verollisen hinnan sentteinä kahteen desimaaliin pyöristettynä, niin sitten se olisi esimerkiksi {{ (item.PriceWithTax * 100) | float | round(2) }}

YAML:
{% set curHour = now().strftime('%Y-%m-%dT%H:00:00%z') %}
{% for item in state_attr("sensor.shf_electricity_price_now", "data") %}
  {% if as_datetime(item.DateTime) == as_datetime(curHour) %}
    {{ item.DateTime, item.PriceNoTax, item.PriceWithTax, item.Rank }}
  {% endif %}
{% endfor %}
 

Smuli

Tulokas
Tässä nyt hyvän aikaan opetellut tämän SHF.n hienouksia ja jotain jo saatukkin aikaan, tuo koodaaminen kun ei ole mitenkään tuttua niin miten tuollainen RANK now apex taulukko tehdään että näkee mikä rank milläkin tunnilla on?
 

tk-

Aktiivinen jäsen
Tässä nyt hyvän aikaan opetellut tämän SHF.n hienouksia ja jotain jo saatukkin aikaan, tuo koodaaminen kun ei ole mitenkään tuttua niin miten tuollainen RANK now apex taulukko tehdään että näkee mikä rank milläkin tunnilla on?
Vaihda tuohon edellä olevaan taulumalliin pricewithtax tilalle ”Rank” ja ota kerroin ja filtteri perästä pois, tai tee sille kokonaan uusi sarake.
 

timop

Aktiivinen jäsen
joskus väsäsin tämmösen. näyttää huomisen myös kunhan se ilmestyy
ainut miinus että puhelimelta jos haluaa tarkan hinnan niin välillä osuu tohon rankkiin mutta on tuon apexin ominaisuus.

YAML:
type: custom:apexcharts-card
graph_span: 48h
apex_config:
  legend:
    show: false
experimental:
  color_threshold: true
show:
  last_updated: true
header:
  title: pörssisähkö hinta (c/kWh) ja rank
  show: true
  show_states: true
  colorize_states: true
span:
  start: day
yaxis:
  - id: first
    min: auto
    decimals: 0
    apex_config:
      forceNiceScale: true
  - id: second
    min: auto
    opposite: true
    decimals: 0
    apex_config: null
now:
  show: true
  label: ''
series:
  - entity: sensor.shf_electricity_price
    yaxis_id: first
    show:
      in_header: false
      extremas: true
    type: column
    float_precision: 2
    stroke_width: 6
    data_generator: |
      return entity.attributes.data.map((d, index) => {
        return [new Date(d["DateTime"]).getTime(), entity.attributes.data[index]["PriceWithTax"]*100];
      });
    color_threshold:
      - value: 0
        color: 368f39
      - value: 10
        color: a3b34d
      - value: 20
        color: ffd57e
      - value: 30
        color: f18c56
      - value: 40
        color: de425b
  - entity: sensor.shf_electricity_price
    yaxis_id: first
    show:
      in_header: true
      header_color_threshold: true
      in_chart: false
    type: line
    float_precision: 2
    stroke_width: 0
    data_generator: |
      var currentTime = new Date().setMinutes(0, 0, 0);
      let currentPrice = entity.attributes.data.find(d => {
        return new Date(d["DateTime"]).getTime() === currentTime;
      })["PriceWithTax"];
      return entity.attributes.data.map((d, index) => {
        return [new Date(d["DateTime"]).getTime(), currentPrice*100];
      });
    color_threshold:
      - value: 0
        color: 368f39
      - value: 10
        color: a3b34d
      - value: 20
        color: ffd57e
      - value: 30
        color: f18c56
      - value: 40
        color: de425b
  - entity: sensor.shf_rank_now
    yaxis_id: second
    type: line
    stroke_width: 0
    color: blue
    extend_to: now
  - entity: sensor.shf_electricity_price
    yaxis_id: second
    show:
      in_header: false
      extremas: false
      legend_value: false
    type: line
    color: blue
    stroke_width: 2
    float_precision: 2
    data_generator: |
      return entity.attributes.data.map((d, index) => {
        return [new Date(d["DateTime"]).getTime(), entity.attributes.data[index]["Rank"]];
      });

1689233974530.png
 

tk-

Aktiivinen jäsen
Kuva on tästä ketjusta.
Tässä yksi tapa tehdä tuollainen palkkigraafi. Siinä on periaatteessa vähän turhaa skaalaushommelia kun tein sen vaan nopeasti tuon hintagraafin pohjalta, mutta eipä se nyt haittaakaan.

Näyttökuva 2023-7-15 kello 21.05.34.png

YAML:
type: custom:apexcharts-card
graph_span: 48h
show:
  last_updated: true
experimental:
  color_threshold: true
span:
  start: day
now:
  show: true
  label: Nyt
header:
  show: true
  title: Sähkön tuntirank
  show_states: true
yaxis:
  - min: ~0
    max: ~24
    decimals: 1
    apex_config:
      forceNiceScale: true
series:
  - entity: sensor.shf_electricity_price_now
    show:
      in_header: true
      extremas: false
      legend_value: false
    type: column
    unit: rank
    color: lightgray
    data_generator: |
      let res = [];
      for (const [key, value] of Object.entries(entity.attributes.data)) {
        let d = new Date(value.DateTime).getTime();
        let p = parseFloat(value.Rank);
        res.push([d, p]);
      }
      return res.sort((a, b) => { return a[0] - b[0] });
    color_threshold:
      - value: 0
        color: 368f39
      - value: 5
        color: a3b34d
      - value: 10
        color: ffd57e
      - value: 15
        color: f18c56
      - value: 20
        color: de425b
 
Viimeksi muokattu:

timop

Aktiivinen jäsen
Onko muilla sensor.shf_cheapest_period_start_helper rikki? eilen oli sama mutta arvelin että johtui negatiivisista hinnoista, näytti 16.7 klo15 vaikka mitä laittoi. Tänään 17.7. klo 15 vaikka mitä laittaa paitsi yli 9h niin sitten on unavailable.
 

tk-

Aktiivinen jäsen
Onko muilla sensor.shf_cheapest_period_start_helper rikki? eilen oli sama mutta arvelin että johtui negatiivisista hinnoista, näytti 16.7 klo15 vaikka mitä laittoi. Tänään 17.7. klo 15 vaikka mitä laittaa paitsi yli 9h niin sitten on unavailable.
En tiedä vastausta kysymykseen, mutta tässä yksi vaihtoehto tehdä tuollaiset halvimman ajanjakson aloitus- ja lopetussensorit haluamalleen välille. Tämä on toki sillälailla erilainen toiminnaltaan, että hakee vuorokauden sisältä. Tuo originaali taitaa hakea klo 15-15.

 

s282

Jäsen
Onko muilla sensor.shf_cheapest_period_start_helper rikki? eilen oli sama mutta arvelin että johtui negatiivisista hinnoista, näytti 16.7 klo15 vaikka mitä laittoi. Tänään 17.7. klo 15 vaikka mitä laittaa paitsi yli 9h niin sitten on unavailable.
Kyllä minulla ainakin vaihtuu 5 tunnin kohdalla aika. Mulla oli kyllä joskus samaa vikaa mutta taisi korjaantua itsekseen kun käynnistelin kaikki uusiksi.
 

timop

Aktiivinen jäsen
Eilen se korjaantui jossain kohtaa iltapäivällä. On tuo joskus tullut ennenkin ja sillä arvelin että olisi negatiivisesta hinnasta johtunut. HA restarttia kokeilen heti aluksi ei ollut apua.
 

Temez

Aktiivinen jäsen
Tuohon "Cheapest Period" -asiaan liittyen olen hiukan pohtinut jatkojalostusta, kun HA 2023.07:ssa tuli uusi ominaisuus, että scriptit voivat palauttaa dataa automaatioille.

Tällöin saisi tehtyä SHF-pakettiin valmiin scriptin, jolle voisi kertoa sekä alku- että loppuajan + halutun tuntimäärän ja se palauttaisi sieltä halvimman x tunnin ajanjakson. Jokainen voisi sitten tehdä oman automaationsa ja mahdollisesti useita, että "anna halvin 5 tunnin pätkä sähköauton lataamiseen ja tallenna se helpperiin Start EV Charging" tai "anna halvin 2h illan aikana, jossa pestä pyykkiä".

Jokainen voisi sitten omien tarpeidensa mukaan tehdä 1-N kpl helppereitä ja automaatioita, jotka tiettyyn kellonaikaan laskisivat halvimman halutunpituisen ajanjakson. Tämä vasta ajatuksen tasolla, mutta jospa se tästä koodiksi tulisi jossain vaiheessa.
 

havohej

Tulokas
Olen kehittämässä seinälle näyttöä vanhasta tabletista.
TileBoard on melko pätevä/monipuolinen Home Assistantin kanssa.
Siitä kuitenkin puuttuu graafit joten tein tällaisen virityksen.
Onko muilla TileBoard käytössä ja miten ratkaisitte ongelman?

20230725_085436.jpg
 

havohej

Tulokas
Tässä on vielä koodi mutta varoitus.
Tämä on ensimmäinen kerta kun javaa kokeilen.
Muutenkin viimeksi koodasin 20v sitten paskalilla.




JavaScript:
 {

                  {
                    position: [0, 0.9],
                    height: 2.3,
                    width: 2.1,
                    type: TYPES.CUSTOM,
                    title: null,
                    id: { },
                    state: false,
                    icon: null,
                    customStyles: { 'backgroundColor': 'rgba(0, 0, 0, 0)' },
                    customHtml:
                                function () {
                               
                                var ENTITY_ID = 'sensor.shf_electricity_price_now';
                                var entityState = this.states[ENTITY_ID];
                                const str = '';
                                const d_now = new Date();
                                const day_str = d_now.getHours();
                               
// taulukko. alku.
                                text = '';
                                text = text + '<table width="100%" cellpadding="0" cellspacing="0" style="page-break-before: always; page-break-inside: avoid">';
                                text = text + '<col width="128*"/>';
                                text = text + '<col width="128*"/>';
                                text = text + '<col width="128*"/>';
                                   
                                text = text + '<tr valign="top">';
                               
                                    text = text + '<td style="border: none; padding: 0cm"><p align="left" style="margin-bottom: 0cm">';
                                        text = text + '<p align="left" style="margin-bottom: 0cm; line-height: 100%"><font size="6" style="font-size: 10pt;">';
                                       
                                            for (let i = 0; i < 24; i++) {
                                                if (day_str == i) text = text + '>&nbsp;&nbsp;&nbsp;<br>';
                                                else text = text  + '<br>';
                                               
                                            }
                                        text = text + '</font></p>';
                                    text = text + '</td>';
                                   
                                    text = text + '<td width="30%" style="border: none; padding: 0cm"><p align="left" style="margin-bottom: 0cm">';
                                        text = text + '<p align="left" style="margin-bottom: 0cm; line-height: 100%"><font size="6" style="font-size: 10pt;">';
                                       
                                            for (let i = 0; i < 24; i++) {
                                                
                                                let temp_price = entityState.attributes.today_prices[i];
                                                let str = temp_price.toString();
                                               
                                                str = str.slice(3, 4) + '.' + str.slice(4, 6);
                                                if (str.slice(3, 4) == '') str = str + '0';
                                               
                                                if (i < 10) aika = '0' + i;
                                                else aika = i;
                                               
                                                if (day_str == i) text = text + '<u>' + aika + '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' + str  + '</u><br>';
                                                else text = text + aika + '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' + str  + '<br>';
                                               
                                            }
                                       
                                        text = text + '</font></p>';
                                    text = text + '</td>';
                                   
                                    text = text + '<td width="100%" style="border: none; padding: 0cm"><p align="right" style="margin-bottom: 0cm">';
                                        text = text + '<p align="right" style="margin-bottom: 0cm; line-height: 100%"><font size="6" style="font-size: 10pt;">';
                                            let max_number = 40 / entityState.attributes.today_max;
                                           
                                            for (let i = 0; i < 24; i++) {
                                                let str = '||';
                                                //let temp_price = entityState.attributes.data[i].PriceWithTax;
                                                let temp_price = entityState.attributes.today_prices[i];
                                               
                                                if (temp_price <= 0.04) str = str + '<font color="#63FD02">';
                                                else if (temp_price > 0.04 || temp_price <= 0.08) str = str + '<font color="#378D01">';
                                                else if (temp_price > 0.08 || temp_price <= 0.012) str = str + '<font color="#FBFB02">';
                                                else if (temp_price > 0.012 || temp_price <= 0.018) str = str + '<font color="#8D8D01">';
                                                else if (temp_price > 0.018 || temp_price <= 0.025) str = str + '<font color="#FE7303">';
                                                else if (temp_price > 0.025 || temp_price <= 0.030) str = str + '<font color="#8E3F00">';
                                                else if (temp_price > 0.030 || temp_price <= 0.035) str = str + '<font color="#F80300">';
                                                else if (temp_price > 0.035 || temp_price <= 0.040) str = str + '<font color="#8E0100">';
                                                else if (temp_price > 0.040 || temp_price <= 0.045) str = str + '<font color="#9A171A">';
                                                else if (temp_price > 0.045) str = str + '<font color="#7B1315">';
                                                else str = str + '<font color="">';
                                               
                                                let temp_num = max_number * entityState.attributes.today_prices[i];
                                                for (let y = 0; y < temp_num; y++) {
                                                    str = str + '|';
                                                }
                                                text = text + str + '</font><br>';
                                            }
                                        text = text + '</font></p>';
                                    text = text + '</td>';
                               
                                text = text + '</tr>';
                                   
                                text = text + '</table>';
// taulukko loppuu                               
         
         

                                return text;

                                },
                  },


Korjattu virhe:
entityState.attributes.data.PriceWithTax
pitää olla
entityState.attributes.today_prices;
 
Viimeksi muokattu:

Nikke

Tulokas
Jos käyttää tuota "SHF max price or rank acceptable", mutta haluaisi lisätä lämmitettäviä tunteja yhdellä jos lämpötila on alle x-2 astetta ja toisaalta jos lämpötila on x+2 astetta, niin vähentää yhden tunnin lämmityksestä, niin kuinkas tuo toteutetaan? Talveksi olisi tarkoitus saada lämmityssäädöt joihin ei paljon tarvitsisi koskea. Jos alkaa suoraan lämmittämään kun lämpötila on x-2, niin voi osua kalliille tunnille.
 

tk-

Aktiivinen jäsen
Jos käyttää tuota "SHF max price or rank acceptable", mutta haluaisi lisätä lämmitettäviä tunteja yhdellä jos lämpötila on alle x-2 astetta ja toisaalta jos lämpötila on x+2 astetta, niin vähentää yhden tunnin lämmityksestä, niin kuinkas tuo toteutetaan? Talveksi olisi tarkoitus saada lämmityssäädöt joihin ei paljon tarvitsisi koskea. Jos alkaa suoraan lämmittämään kun lämpötila on x-2, niin voi osua kalliille tunnille.
Itse lähestyisin asiaa niinpäin, että lasketaan vuorokaudelle/sen osalle aina lämpötilaan perustuva lämmitystarve (tuntimäärä/varttimäärä) tallentaen se vaikka johonkin helperiin, ja sen perusteella sitten haettaisiin kyseinen määrä rankiltaan edullisimpia tunteja/vartteja.

Toki jos laskee lyhyemmälle ajalle kun vuorokaudelle, niin sitten ei enää nuo rank-arvot semmoisenaan käy vertailuun kytketäänkö tunti päälle vai pois.
 

HotZone

Vakionaama
^eikös nuo kaiki kannattaisi kirjaialla SQL kantaan ja sitten myös kulutuksen toteutuman mukaan. kannasta sais ajettua suhteellisen vaivattomasti lämmitys tarpeen historian perusteella lämpötila ennusteen mukaan.
Lisäksi jäisi hitoria tiedot ennusteista ja toteumista.
 

Nikke

Tulokas
Itse lähestyisin asiaa niinpäin, että lasketaan vuorokaudelle/sen osalle aina lämpötilaan perustuva lämmitystarve (tuntimäärä/varttimäärä) tallentaen se vaikka johonkin helperiin, ja sen perusteella sitten haettaisiin kyseinen määrä rankiltaan edullisimpia tunteja/vartteja.

Toki jos laskee lyhyemmälle ajalle kun vuorokaudelle, niin sitten ei enää nuo rank-arvot semmoisenaan käy vertailuun kytketäänkö tunti päälle vai pois.
Saisiko rautalankaa kuinka tuon koodata? :)

Se mitä itse sain nyt aikaiseksi on kiinteä automaatio jolla lämpötila ohjaa lämmitettävien tuntien määrää, ehkä tuossa kannattaa se lämpötila ottaakin ulkoa ja sen mukaan säätää tunteja tai sääennusteesta (niin kuin Mikkin jossakin Shellyn ohjelmassa), niin voisi lämmittää (vähän) talteen jos on tulossa kylmää. Tarve on siis ylläpitolämpötila kesämökille, eli lämpötila saa laskea ja (ja miksei noustakin) paljon, kunhan vain olisi halpaa ja pysyisi jonkun verran plussalla.

Tuon kai voi tehdä monelle lämpötilalle yhdellä automaatiolla kun lisää monta sisäkkäistä if-elseä, mutta tässä rautalankaa mitä sain tähän mennessä aikaiseksi. Jos lämpötila on alle 16, niin lämmitetään 12 halvinta tuntia, mutta tämä siis ehkä kannattaa tehdä ulkolämpötilan tai sääennusteen perusteella. Jos jollakulla on esimerkkiä sääennusteen käytöstä automaatiossa, niin mielellään näkisin koodin.

YAML:
alias: testi

description: ""

trigger:

  - platform: homeassistant

    event: start

  - platform: state

    entity_id:

      - sensor.temperature

condition:

  - condition: numeric_state

    entity_id: sensor.temperature

    below: 16

action:

  - service: input_number.set_value

    data:

      value: 12

    target:

      entity_id: input_number.shf_rank_slider

mode: single
 

tk-

Aktiivinen jäsen
Saisiko rautalankaa kuinka tuon koodata? :)

Se mitä itse sain nyt aikaiseksi on kiinteä automaatio jolla lämpötila ohjaa lämmitettävien tuntien määrää, ehkä tuossa kannattaa se lämpötila ottaakin ulkoa ja sen mukaan säätää tunteja tai sääennusteesta (niin kuin Mikkin jossakin Shellyn ohjelmassa), niin voisi lämmittää (vähän) talteen jos on tulossa kylmää. Tarve on siis ylläpitolämpötila kesämökille, eli lämpötila saa laskea ja (ja miksei noustakin) paljon, kunhan vain olisi halpaa ja pysyisi jonkun verran plussalla.

Tuon kai voi tehdä monelle lämpötilalle yhdellä automaatiolla kun lisää monta sisäkkäistä if-elseä, mutta tässä rautalankaa mitä sain tähän mennessä aikaiseksi. Jos lämpötila on alle 16, niin lämmitetään 12 halvinta tuntia, mutta tämä siis ehkä kannattaa tehdä ulkolämpötilan tai sääennusteen perusteella. Jos jollakulla on esimerkkiä sääennusteen käytöstä automaatiossa, niin mielellään näkisin koodin.

YAML:
alias: testi

description: ""

trigger:

  - platform: homeassistant

    event: start

  - platform: state

    entity_id:

      - sensor.temperature

condition:

  - condition: numeric_state

    entity_id: sensor.temperature

    below: 16

action:

  - service: input_number.set_value

    data:

      value: 12

    target:

      entity_id: input_number.shf_rank_slider

mode: single
Minäpäs kokeilen tässä rakennella. Meillä on tarkoitus tehdä tuonne Pörssärin serverille tämä ominaisuus myös, niin samalla tulee testailua logiikkaa erilaisten parametrien ja säätöjen kera tuolla ha:n puolella.
 

timop

Aktiivinen jäsen
Onko muilla sensor.shf_cheapest_period_start_helper rikki? eilen oli sama mutta arvelin että johtui negatiivisista hinnoista, näytti 16.7 klo15 vaikka mitä laittoi. Tänään 17.7. klo 15 vaikka mitä laittaa paitsi yli 9h niin sitten on unavailable.
eilen klo 15 meni rikki taas, ei aika pysyy 13.8. klo 15 myös tänään.
 

tk-

Aktiivinen jäsen
eilen klo 15 meni rikki taas, ei aika pysyy 13.8. klo 15 myös tänään.
Onko tämä cheapest period kuinka paljon tarpeellisempi kuin x määrä haluttuja tunteja mahdollisesti vain osalla vuorokauden tunneista? Pörssäriin on nyt jo testattu toimivaksi tuo jälkimmäinen, mutta ehdittäisiin tuohon tulevaan päivitykseen tekemään varmaankin myös tuo, että vuorokauden tunnit kytketään yhtenäisenä jaksona.

Sillälailla Pörssärikään ei nyt ihan suoranaisesti ole pilvipalvelu, että senkin kanssa riittää kun HA saa kerran päivässä haettua ohjaustiedot palvelimelta. Toki niiden päivitystä kysellään 2min välein ja haetaan aina vähintään kerran tunnissa. Ne vain tulee valmiiksi jalostettuna päälläolotietona vs muiden rajapintojen (NordPoolin lisenssiehtojen vastainen) hintatietojen jako. Automaatiossa tuota kanavatietoa tunneittain -1/0/1 voi sitten käyttää päälläolotriggerinä samaan tapaan kuin rank_acceptablea.
 
Viimeksi muokattu:

timop

Aktiivinen jäsen
olen käyttänyt tuota autonlataukseen yöaikaan. lähinnä helppouden takia olen veivannut vaan liukua että kellon aika on sopiva. :D
tein nyt muutoksen että oma input_number autonlatuksen hinnalle ja koitan tehdä automaation jossa latauksen määrää rank_slider tai tuo input_numberin maksimihintana. kuitenkin ladattava on välillä oli se hinta sitten 2 tai 5 senttiä. rankilla siten jos menee yli.

edit: uudet hinnat korjasi taas tuon "SHF Cheapest period hours"
 
Viimeksi muokattu:

tk-

Aktiivinen jäsen
olen käyttänyt tuota autonlataukseen yöaikaan. lähinnä helppouden takia olen veivannut vaan liukua että kellon aika on sopiva. :D
tein nyt muutoksen että oma input_number autonlatuksen hinnalle ja koitan tehdä automaation jossa latauksen määrää rank_slider tai tuo input_numberin maksimihintana. kuitenkin ladattava on välillä oli se hinta sitten 2 tai 5 senttiä. rankilla siten jos menee yli.

edit: uudet hinnat korjasi taas tuon "SHF Cheapest period hours"
Itsellä on kanssa ajatus, että aina yöllä on sähköä tarjolla 4 edullisinta tuntia välillä 00-08, ja aina arkisin klo 07-08 jolloin lähdetään liikkeelle ja viikonloppuisin 09-11 jolloin yleisimmin on esilämmityksen tarve. Ja muut tunnit sitten ehkä jollain hintaehdolla, esim vuorokauden keskihinta -1SD.
 
Viimeksi muokattu:

havohej

Tulokas
Tein vähän parannuksia aikaisempaan. Nyt hinnasto vierii eteenpäin. Näin illalla voi nähdä jo seuraavan päivän hinnat ja suunnitella tekemisensä. Joitakin virheita korjattu. Miinus hinnat luultavasti sekoilee mutta korjaillaan sen mukaan kun näkee.



JavaScript:
                 {
                    position: [0, 0.9],
                    height: 2.3,
                    width: 2.25,
                    type: TYPES.CUSTOM,
                    title: null,
                    id: { },
                    state: false,
                    icon: null,
                    customStyles: { 'backgroundColor': 'rgba(0, 0, 0, 0)'},
                    customHtml:
                                function () {
                             
                                var ENTITY_ID = 'sensor.shf_electricity_price_now';
                                var entityState = this.states[ENTITY_ID];
                                const str = '';
                                const day_now = new Date();
                                const hour_now = day_now.getHours();
                                var first_hour = 0;
                             
                                const temp_day_1 = new Date(entityState.attributes.data[0].DateTime);
                                const tomorrow_prices = entityState.attributes.tomorrow_avg;
                             
                                if (day_now.getDate() == temp_day_1.getDate()){
                                    if (tomorrow_prices) first_hour = hour_now - 5;
                                }
                                else{
                                    first_hour = 24;
                                }
                             
// taulukko. alku.
                                text = '';
                                text = text + '<table width="100%" cellpadding="0" cellspacing="0" style="page-break-before: always; page-break-inside: avoid">';
                                text = text + '<col width="128*"/>';
                                text = text + '<col width="128*"/>';
                                text = text + '<col width="128*"/>';
                                text = text + '<col width="128*"/>';
                                text = text + '<col width="128*"/>';
                             
                                text = text + '<tr valign="top">';
                             
                                    text = text + '<td width="5%" style="border: none; padding: 0cm"><p align="left" style="margin-bottom: 0cm">';
                                        text = text + '<p align="left" style="margin-bottom: 0cm; line-height: 100%"><font size="6" style="font-size: 10pt;">';
                                     
                                            for (let i = first_hour; i < 24+first_hour; i++) {
                                             
                                                if (hour_now == i || hour_now == i-24) text = text + '>&nbsp;&nbsp;<br>';
                                                else text = text  + '<br>';
                                             
                                            }
                                        text = text + '</font></p>';
                                    text = text + '</td>';
// aika                                
                                    text = text + '<td width="5%" style="border: none; padding: 0cm"><p align="left" style="margin-bottom: 0cm">';
                                        text = text + '<p align="right" style="margin-bottom: 0cm; line-height: 100%"><font size="6" style="font-size: 10pt;">';
                                     
                                            for (let i = first_hour; i < 24+first_hour; i++) {
                                             
                                                let aika = entityState.attributes.data[i].DateTime;
                                             
                                                aika = aika.slice(11, 13);
                                             
                                                if (hour_now == i || hour_now == i-24) text = text + '<u>' + aika + '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</u><br>';
                                                else text = text + aika + '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>';
                                             
                                            }
                                     
                                        text = text + '</font></p>';
                                    text = text + '</td>';
// hinta
                                    text = text + '<td width="5%" style="border: none; padding: 0cm"><p align="left" style="margin-bottom: 0cm">';
                                        text = text + '<p align="right" style="margin-bottom: 0cm; line-height: 100%"><font size="6" style="font-size: 10pt;">';
                                     
                                            for (let i = first_hour; i < 24+first_hour; i++) {
                                             
                                                let temp_price = Math.round(entityState.attributes.data[i].PriceWithTax * 10000) / 100;
                                                let str = temp_price.toFixed(2);
                                             
                                                if (hour_now == i || hour_now == i-24) text = text + '<u>' + str  + '</u><br>';
                                                else text = text + str  + '<br>';
                                             
                                            }
                                     
                                        text = text + '</font></p>';
                                    text = text + '</td>';
// palkit
                                    text = text + '<td width="80%" style="border: none; padding: 0cm"><p align="right" style="margin-bottom: 0cm">';
                                        text = text + '<p align="right" style="margin-bottom: 0cm; line-height: 100%"><font size="6" style="font-size: 10pt;">';
                                         
                                            let max_price = 0;
                                            for (let i = first_hour; i < 24+first_hour; i++) {
                                                if (max_price < entityState.attributes.data[i].PriceWithTax) max_price = entityState.attributes.data[i].PriceWithTax;
                                            }
                                            let max_number = 50 / max_price;
                                         
                                            for (let i = first_hour; i < 24+first_hour; i++) {
                                                let str = '||';
                                                let temp_price = entityState.attributes.data[i].PriceWithTax;
                                                //let temp_price = entityState.attributes.today_prices[i];
                                             
                                                if (temp_price <= 0.04) str = str + '<font color="#63FD02">';
                                                else if (temp_price > 0.04 && temp_price <= 0.08) str = str + '<font color="#378D01">';
                                                else if (temp_price > 0.08 && temp_price <= 0.12) str = str + '<font color="#FBFB02">';
                                                else if (temp_price > 0.12 && temp_price <= 0.18) str = str + '<font color="#8D8D01">';
                                                else if (temp_price > 0.18 && temp_price <= 0.25) str = str + '<font color="#FE7303">';
                                                else if (temp_price > 0.25 && temp_price <= 0.30) str = str + '<font color="#8E3F00">';
                                                else if (temp_price > 0.30 && temp_price <= 0.35) str = str + '<font color="#F80300">';
                                                else if (temp_price > 0.35 && temp_price <= 0.40) str = str + '<font color="#8E0100">';
                                                else if (temp_price > 0.40 && temp_price <= 0.45) str = str + '<font color="#9A171A">';
                                                else if (temp_price > 0.45) str = str + '<font color="#7B1315">';
                                                else str = str + '<font color="">';
                                             
                                                let temp_num = max_number * entityState.attributes.data[i].PriceWithTax;
                                                for (let y = 0; y < temp_num; y++) {
                                                    str = str + '|';
                                                }
                                                text = text + str + '</font><br>';
                                            }
                                        text = text + '</font></p>';
                                    text = text + '</td>';
                                 
                                    text = text + '<td width="5%" style="border: none; padding: 0cm"><p align="left" style="margin-bottom: 0cm">';
                                        text = text + '<p align="right" style="margin-bottom: 0cm; line-height: 100%"><font size="6" style="font-size: 10pt;">';
                                     
                                            for (let i = first_hour; i < 24+first_hour; i++) {
                                             
                                                if (hour_now == i || hour_now == i-24) text = text + '&nbsp;&nbsp;<<br>';
                                                else text = text  + '<br>';
                                             
                                            }
                                        text = text + '</font></p>';
                                    text = text + '</td>';
                                 
                                text = text + '</tr>';
                                 
                                text = text + '</table>';
// taulukko loppuu                            
       
       

                                return text;

                                },
                  },
 
Viimeksi muokattu:

Gilean

Jäsen
Onko ideaa miksi tuo SHF Electricity price now näyttää omiaan? On tehnyt tätä jo jonkin aikaa. Esim tällä hetkellä tuo kaavio näyttää tältä (tässä tuntikohtaiset hinnat oikein):
1692783221334.png

Mutta sitten kun katson tuon kyseisen sensorin arvoja niin ne näyttää tältä:
1692783308549.png
 

Mikki

Hyperaktiivi
Eikös tuossa ole vain niin, että graafi on muutettu senteiksi ja sensori on euroina. Molemmat ns. oikein, makuasia.
 

Gilean

Jäsen
Eikös tuossa ole vain niin, että graafi on muutettu senteiksi ja sensori on euroina. Molemmat ns. oikein, makuasia.
Ei, vaan kuten tuossa ylemmän kuvan alaosassa oleva infolaatikko kertoo, SHF Electricity price now on 21,08c/kWh (tämä on oikea hinta tuolle tunnille), mutta sitten taas tuo alempi graafi ja ylemmän kuvan "otsikko" SHF Electricity price now väittääkin hinnan olevan 49,78c/kWh. Tuollaista hintaahan ei tälle päivälle ole edes tulossa joten en ymmärrä mistä se tuon luvun on kaivanut...
 

Mikki

Hyperaktiivi
Ei, vaan kuten tuossa ylemmän kuvan alaosassa oleva infolaatikko kertoo, SHF Electricity price now on 21,08c/kWh (tämä on oikea hinta tuolle tunnille), mutta sitten taas tuo alempi graafi ja ylemmän kuvan "otsikko" SHF Electricity price now väittääkin hinnan olevan 49,78c/kWh. Tuollaista hintaahan ei tälle päivälle ole edes tulossa joten en ymmärrä mistä se tuon luvun on kaivanut...
Tuo hinta on tosiaan eilen ollut. Kannattaisikohan buutata se HA ja katsoa lähtisikö luvut päivittymään.
 

Gilean

Jäsen
Tuo hinta on tosiaan eilen ollut. Kannattaisikohan buutata se HA ja katsoa lähtisikö luvut päivittymään.
Näköjään tuli boottaamalla kuntoon. Historiagraafia se ei tietenkään korjannut eli se näyttää yhä tälle päivälle about 50c/kWh -lukemaa tuolle yhdelle tunnille :) Tämä "hinnanjumittumisongelma" tuntuu tosiaan toistuvan aika ajoin.
 

Pretor

Aktiivinen jäsen
Itse (koitan) minimoida sähkön kulutusta kalliina tunteina käyttämällä SHF Control factoria säätämään VILP (Pansu) lattialämmityksen offsettia. Ajatuksena siis että halpoina tunteina ladataan laattaan lämpöä ja kun siirrytään kalliimmille tunneille niin tavoitelämpöä (offset) lasketaan ja pumpun ei tarvitse tehdä (niin paljon) töitä tavoitelämmön saavuttamiseksi. Lattialämpöä en siis pyri ohjaamaan ON/OFF tyyppisesti.

Käyttöveden tuoton taas teen (koitan tehdä) niin että lataan VILP varaajan (force DWH mode) kun vuorokauden halvin tunti alkaa (SHF Cheapest period hours start). Lataukseen (pari sataa litraa) menee tyypillisesti puolisen tuntia ja kun lämminvesivaraajan tavoitelämpö saavutetaan niin pumppu osaa itsekseen lopettaa käyttöveden lämmityksen. Varaaja sitten pitää lämpönsä 12h-24h riippuen kuinka ahkerasti suihkua käytetään.

Saas nähdä kuinka luotettavasti automatisointi onnistuu, kuinka paljon euroja säästyy ja kuinka paljon sivuvaikutuksia (esim huonelämmön vaihtelu) tapahtuu.
Ihan mielenkiinnosta olisi kiva nähdä millaisia automaatioita olet saanut tuon Panan kanssa kyhättyä.
 

heebo1974

Aktiivinen jäsen
Olisiko Temez iso rypistys lisätä "SHF Electricity price now":lle atribuutteihin vielä nämä ?

Today min notax
Today avg notax
Today max notax
Tomorrow min notax
Tomorrow avg notax
Tomorrow max notax

En kyllä onnistunut ottamaan tuosta perus sensoristakaan PriceNoTax arvoa. :)
No puolen vuoden tauon jälkeen vähän kesäterässä. Taitaa vaatia data atribuuttia ja jotain koodia, joka parsii sen siitä. :(

EDIT: Voit ehkä unohtaa koko homman. Hoidin homman apex cardissa "transform: return x * 100 / 1.24;"
 
Viimeksi muokattu:
Back
Ylös Bottom