Rynkowe ceny energii elektrycznej

ja na przykład robię sobie porównanie używając jak najbardziej rzeczywistych wartości, co daje większy profit: rozliczanie miesięczne czy godzinowe, bazując na mojej prawdziwej produkcji (net-biling), kilka dni na razie ale wygrywa godzinowe:
image

w PLNach dziennie:
image

Pytanie czy na bank jestes pewien ze dobrze to obliczasz? RCEm za maj zostalo opublikowane dopiero dzisiaj rano > https://www.pse.pl/oire/rcem-rynkowa-miesieczna-cena-energii-elektrycznej

tak, tu niestety będzie rozjazd, bo publikują wyceny RCEm z opóźnieniem prawie 2 tygodnie.
Trzeba by eksportować dane do jakieś tabeli i wyliczać w offline, dużo zachodu.
Na razie różnica niewielka maj/kwiecień 255 vs 253 PLN/MWh

Na potrzeby szacunkowe wystarczy, i np taka obserwacja: w tygodniu wygrywa RCE ale w weekend już nie tak bardzo, wręcz w niedzielę wyższy profit jest z RCEm:
Screenshot 2024-06-11 09.05.02

Nie dwa tygodnie, a szesc, poniewaz te ceny RCEm publikowane w czerwcu sa dla pradu w maju. Wiec dla pradu w czerwcu cene dostaniesz w polowie lipca. Tak wiec jedyne sensowne wyliczenia jakie mozna zrobic sa dla danych historycznych dla ktorych posiada sie cene RCEm.

CO do oplacalnosci z wlasnych obserwacji wychodzi mi ze RCMm dalej jest bardziej oplacalny dla domu (farmy mnie nie interesuja) poniewaz jesli przejdziesz na rozliczanie godzinowe to prad potem tez kupujesz po stawkach godzinowych, z moich wyliczen dla mojego przypadku wychodzi mi ze sie RCEm nie oplaca bez dorzucenia magazynu energii. Takze sensor ktory tu wspolnymi silami zrobilismy jest calkiem przydatny.

W automatyzacji musisz wywołać usługę calendar.get_events. to zwróci ci tablicę przyszłych wartości i z tym robisz co potrzebujesz

PSE zmieniło sposób raportowania. Ma ktoś link do pobierania danych CSV czy trzeba parsować stronę?

Dobra - mam coś takiego, ale te kwoty są dla mnie podejrzanie wysokie:
https://api.raporty.pse.pl/api/rce-pln?$filter=doba%20eq%20'2024-06-14'

1 polubienie

Witajcie !
Korzystałem z obecnej metody kilka dni i nadeszły zmiany.
Zmiany jednak oczekiwane bo mamy API do dyspozycji:
https://api.raporty.pse.pl/

Teraz wszelka automatyka może ruszyć z kopyta.

Prawda jest taka że operatorzy rynku energii też nie mogliby
wprowadzić godzinowych rozliczeń prosumentów i taryf dynamicznych bez tego API

1 polubienie

Wczoraj rynki szalały z niewiadomych powodów i takie ceny były zawierane na RDN

1 polubienie

Taki oto sensor wymodziłem. Przydałoby się inteligentniej rozwiązać moment pobierania danych, ale na szybko działa:

  - platform: rest
    scan_interval: 60
    name: pse_market_energy_price_current_hour
    unique_id: pse_market_energy_price_current_hour
    resource: 'https://api.raporty.pse.pl/api/rce-pln'
    params:
      '$first': 1
      '$select': 'rce_pln'
      '$filter': "udtczas ge %27{{ now().strftime('%Y-%m-%d %H:%M') }}%27"
    unit_of_measurement: "PLN/MWh"
    value_template: "{{ value_json.value[0].rce_pln }}"
    icon: mdi:cash
1 polubienie

Projekt: Monitoring Rynkowych Cen Energii (RCE) z PSE

14 czerwca Państwowe Sieci Elektroenergetyczne (PSE) uruchomiły API, za pomocą którego publikują różne parametry, w tym Rynkowe Ceny Energii (RCE) w interwałach piętnastominutowych. Ceny te są pochodną Cen Rynku Dnia Następnego. Te ceny będą podstawą przy godzinowych rozliczeniach prosumentów.

Opis działania projektu

Projekt ma na celu automatyczne pobieranie i monitorowanie cen RCE na dzisiaj i jutro z API PSE, oraz wyświetlanie aktualnej ceny energii na dany moment.

Sensory do wklejenia do sensors.yaml

  1. Sensor pobierający dzisiejsze ceny RCE
# Pobieranie dzisiejszych cen RCE z PSE
- platform: rest
  name: RCE Prices Today
  resource_template: "https://api.raporty.pse.pl/api/rce-pln?$filter=doba eq '{{ now().strftime('%Y-%m-%d') }}'"
  method: GET
  headers:
    accept: "application/json"
  value_template: "{{ value_json.value[0]['rce_pln'] }}"
  json_attributes:
    - value
  scan_interval: 3600

  1. Sensor pobierający jutrzejsze ceny RCE
# Pobieranie jutrzejszych cen RCE z PSE
- platform: rest
  name: RCE Prices Tomorrow
  resource_template: "https://api.raporty.pse.pl/api/rce-pln?$filter=doba eq '{{ (now() + timedelta(days=1)).strftime('%Y-%m-%d') }}'"
  method: GET
  headers:
    accept: "application/json"
  value_template: "{{ value_json.value[0]['rce_pln'] }}"
  json_attributes:
    - value
  scan_interval: 3600

  1. Template sensor z bieżącą ceną RCE
# Sensor z bieżącą ceną
- platform: template
  sensors:
    current_rce_price:
      friendly_name: "Current RCE Price"
      value_template: >
        {% set current_time = now().strftime('%H:%M') %}
        {% set prices = state_attr('sensor.rce_prices_today', 'value') %}
        {% for price in prices %}
          {% set start_time = price.udtczas_oreb.split(' - ')[0] %}
          {% set end_time = price.udtczas_oreb.split(' - ')[1] %}
          {% if start_time <= current_time < end_time %}
            {{ price.rce_pln }}
          {% endif %}
        {% endfor %}
      unit_of_measurement: "PLN/MWh"

Automatyzacja do wklejenia do automations.yaml

Automatyzacja aktualizująca bieżącą cenę co 15 minut:

automations.yaml:
- id: '1718249833122'
  alias: Update Current RCE Price
  trigger:
    - platform: time_pattern
      minutes: "/15"
  action:
    - service: homeassistant.update_entity
      target:
        entity_id: sensor.current_rce_price

Plany rozwoju

W planach jest rozwój projektu w kierunku:

  • Obliczania najwyższych cen danej doby, co pozwoli na sterowanie oddaniem energii z magazynu energii w najbardziej korzystnym momencie.
  • Połączenie cen dzisiejszych z jutrzejszymi w celu zrobienia wykresu.
2 polubienia

Spoko. Ja podszedłem inaczej bo zależy mi na pobraniu wszystkich cen do analizy żeby planować np. oddanie w dobrych cenach

:slight_smile: robiłem wykresy pokazujące ceny na dzisiaj i jutro.


Trzeba zainstalować ApexCharts Card prze HACS:

Kod kart wykresów do wklejenia:

Ceny dzisiaj:

type: custom:apexcharts-card
graph_span: 24h
span:
  start: day
update_interval: 15min
experimental:
  color_threshold: true
series:
  - entity: sensor.rce_prices_today
    attribute: value
    data_generator: |
      return entity.attributes.value.map(item => {
        return [new Date(item.udtczas).getTime(), item.rce_pln];
      });
    type: line
    name: Cena energii (jutro)
    curve: smooth
    stroke_width: 4
    color_threshold:
      - value: 0
        color: red
      - value: 300
        color: orange
      - value: 500
        color: yellow
      - value: 700
        color: green
header:
  show: true
  title: Ceny energii (PLN)
  show_states: false
  colorize_states: true
now:
  show: true
  label: Teraz
  color: red

Ceny Jutro:

type: custom:apexcharts-card
graph_span: 24h
span:
  start: day
  offset: +1d
update_interval: 15min
experimental:
  color_threshold: true
series:
  - entity: sensor.rce_prices_tomorrow
    attribute: value
    data_generator: |
      return entity.attributes.value.map(item => {
        return [new Date(item.udtczas).getTime(), item.rce_pln];
      });
    type: line
    name: Cena energii (jutro)
    curve: smooth
    stroke_width: 4
    color_threshold:
      - value: 0
        color: red
      - value: 300
        color: orange
      - value: 500
        color: yellow
      - value: 700
        color: green
header:
  show: true
  title: Ceny energii (PLN) - Jutro
  show_states: false
now:
  show: true
  label: Teraz
  color: red

Miłej zabawy :slight_smile:

jacek2511/ha_rce: Rynkowa cena energii elektrycznej (RCE) (github.com)

Przyjemna integracja

Ewentualnie:
PePeLLee/home-assistant-rce: integration for Rynkowa cena energii elektrycznej (RCE) (github.com)

Potrafi ktoś wyskrobać kod sensora który obliczy najtańsze okno 3 godzinne i zwróci godzinę startu tego okna? Siedzę nad tym 2 dzień i nie potrafię tego napisać.

Popracuję nad tym bo w sumie temu służy pobieranie tych cen żeby wykorzystać je do zarządzania oddaniem do sieci / ładowaniem magazynu.

Teraz pytanie praktyczne do czego chcemy tego używać.
Czy do uruchamiania urządzeń kiedy jest najtaniej (nie ma sensu dopóki nie wejdą w życie taryfy dynamiczne), czy np. do ładowania magazynu kiedy jest najtaniej, żeby w tym okresie zminimalizować oddawanie do sieci.
Ja tak bym kombinował. Jeśli więc do ładowania to okno czasowe trzeba określać w zakresie godzin kiedy jest słońce.

Jakieś pomysły?

Ja PV jeszcze nie uruchomiłem i pewnie nie wszyscy mają. Z mojego punktu widzenia sensor który pozwoli mi uruchomić zmywarkę (program ma 2:45h) lub pralkę na programie eko 2:30h byłby idealny.

Tak na szybko, skrypt przeszukuje ceny zawarte w sensorze sensor.rce_prices_today (opisywany wcześniej w tym wątku) na zasadzie okna przesuwnego. Sprawdza sumę 12 cen (3 godziny po 15 min) i wybiera ten zakres gdzie ceny są jest najniższe.
Na razie dla prostoty brane są pod uwagę ceny w zakresie godzinowym 6:00 - 18:00, bo wtedy jest ładowanie.

Wynikiem działania skryptu sensor.lowest_price_window_daytime przyjmuje wartość np. 2024-06-24 09:15/2024-06-24 12:00 będącą zakresem trzech godzin najniższych cen.
Dodatkowo atrybut sensora min_avg przyjmuje wartość średniej z 12 cen dla danego okna 3 godzin.

image

Skrypt python find_lowest_price_window_daytime.py do dodania do folderu python_scripts:

# Pobierz ceny energii z sensora
prices = hass.states.get('sensor.rce_prices_today').attributes['value']

# Filtruj ceny, aby uwzględnić tylko przedział od 06:00 do 18:00
filtered_prices = [entry for entry in prices if '06:00' <= entry['udtczas_oreb'].split(' - ')[0] <= '18:00']

# Lista cen energii (rce_pln) w przefiltrowanym przedziale
price_list = [entry['rce_pln'] for entry in filtered_prices]

# Liczba interwałów w 3 godzinach (12 * 15 minut)
window_size = 12

# Inicjalizacja zmiennych do przechowywania minimalnej średniej i jej indeksu
min_avg = float('inf')
min_index = 0

# Przesuwanie okna po liście cen
for i in range(len(price_list) - window_size + 1):
    # Obliczenie średniej cen w bieżącym oknie
    current_avg = sum(price_list[i:i + window_size]) / window_size

    # Sprawdzenie, czy bieżąca średnia jest najmniejsza
    if current_avg < min_avg:
        min_avg = current_avg
        min_index = i

# Zwrócenie indeksu początkowego okna o najniższej średniej oraz tę średnią
start_time = filtered_prices[min_index]['udtczas']
end_time = filtered_prices[min_index + window_size - 1]['udtczas']

hass.states.set('sensor.lowest_price_window_daytime', f'{start_time}/{end_time}', {
    'min_avg': min_avg
})

Sensor template do dodania w sensors.yaml:

# Okno czasowe najniższej ceny RCE w dzień
  - platform: template
    sensors:
      lowest_price_window_daytime:
        value_template: "{{ states('sensor.lowest_price_window_daytime').split('/')[0] }} - {{ states('sensor.lowest_price_window_daytime').split('/')[1] }}"
        friendly_name: "Lowest Price Window Daytime"
        attribute_templates:
          min_avg: "{{ state_attr('sensor.lowest_price_window_daytime', 'min_avg') }}"
          start_time: "{{ states('sensor.lowest_price_window_daytime').split('/')[0] }}"
          end_time: "{{ states('sensor.lowest_price_window_daytime').split('/')[1] }}"

Temat pozostaje rozwojowy.
Można pobierać godziny wschodu i zachodu słońca z sensora sun, można wiele innych rzeczy ale ja najpierw muszę spiąć swój falownik z HA w sposób umożliwiający sterowanie nim, a wtedy to wszystko dopiero nabierze sensu.

Zerknij proszę w logi, bo u mnie wywala co jakiś czas błędy zbyt dużego rozmiaru ściąganych danych:

2024-06-24 22:13:34.257 WARNING (Recorder) [homeassistant.components.recorder.db_schema] State attributes for sensor.rce_prices_tomorrow exceed maximum size of 16384 bytes. This can cause database performance issues; Attributes will not be stored

Dodatkowo warto zmienić zapytanie do API z:

resource_template: "https://api.raporty.pse.pl/api/rce-pln?$filter=doba eq '{{ now().strftime('%Y-%m-%d') }}'"

na

resource_template: "https://api.raporty.pse.pl/api/rce-pln?$select=rce_pln,udtczas_oreb&$filter=doba eq '{{ now().strftime('%Y-%m-%d') }}'"

No i analogicznie dla dnia +1.

Dzięki temu dla każdego okresu 15-minutowego zamiast:

{
      "doba": "2024-06-14",
      "rce_pln": 876.1,
      "udtczas": "2024-06-14 00:15",
      "udtczas_oreb": "00:00 - 00:15",
      "business_date": "2024-06-14",
      "source_datetime": "2024-06-13 17:05:05"
    },

Ściągamy

{
      "rce_pln": 876.1,
      "udtczas_oreb": "00:00 - 00:15"
}

Zarówno pomoże to nam, bo nie będziemy przechowywać pełnych wartości sensora dla każdego dnia, jak i sprawi że nie będziemy obciążać tak bardzo API PSE więc będzie sporo mniejsza szansa że je zlimitują za jakiś czas albo każą sobie płącić za dostęp.

Dzięki za sugestię, bardzo zasadna zmiana. Faktycznie teraz sensory przechowują mniej niepotrzebnych danych.

W kwestii zmniejszenia odpytywania API to obecnie scan_interval jest ustawiony 3600 czyli odczytuje stan co godzinę pomimo, że stan zmienia się raz na dobę.
Zmieniłem to na 86400 czy raz na 24h, ale do tego trzeba dołożyć automatyzację, która aktualizuje to po godzinie 00:00

Automatyzacja:

- id: '1718249833123'
  alias: Update RCE Prices Today at Midnight
  trigger:
  - platform: time
    at: '00:01:00'
  action:
  - service: homeassistant.update_entity
    target:
      entity_id: sensor.rce_prices_today

Sensory

# Pobieranie dzisiejszych cen RCE z PSE
  - platform: rest
    name: RCE Prices Today
    resource_template: "https://api.raporty.pse.pl/api/rce-pln?$select=rce_pln,udtczas_oreb&$filter=doba eq '{{ now().strftime('%Y-%m-%d') }}'"
    method: GET
    headers:
      accept: "application/json"
    value_template: "{{ value_json.value[0]['rce_pln'] }}"
    json_attributes:
      - value
    scan_interval: 86400

# Pobieranie jutrzejszych cen RCE z PSE
  - platform: rest
    name: RCE Prices Tomorrow
    resource_template: "https://api.raporty.pse.pl/api/rce-pln?$select=rce_pln,udtczas_oreb&$filter=doba eq '{{ now().strftime('%Y-%m-%d') }}'"
    method: GET
    headers:
      accept: "application/json"
    value_template: "{{ value_json.value[0]['rce_pln'] }}"
    json_attributes:
      - value
    scan_interval: 3600

Trzeba było też zmienić kod karty ApexCharts bo przestała mi działać:

type: custom:apexcharts-card
graph_span: 24h
span:
  start: day
update_interval: 15min
experimental:
  color_threshold: true
series:
  - entity: sensor.rce_prices_today
    attribute: value
    data_generator: |
      const startOfDay = new Date();
      startOfDay.setHours(0, 0, 0, 0);
      return entity.attributes.value.map(item => {
        const timeRange = item.udtczas_oreb.split(" - ")[0];
        const [hours, minutes] = timeRange.split(":");
        const timestamp = new Date(startOfDay);
        timestamp.setHours(hours, minutes);
        return [timestamp.getTime(), item.rce_pln];
      });
    type: line
    name: Cena energii (jutro)
    curve: smooth
    stroke_width: 4
    color_threshold:
      - value: 0
        color: red
      - value: 300
        color: orange
      - value: 500
        color: yellow
      - value: 700
        color: green
header:
  show: true
  title: Ceny energii (PLN)
  show_states: false
  colorize_states: true
now:
  show: true
  label: Teraz
  color: red

image