Last active
February 18, 2023 18:36
-
-
Save luuuis/25a1030327a6ff9713a5a6747ebb6154 to your computer and use it in GitHub Desktop.
Preços do mercado diário e do mecanismo de ajuste MIBEL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
homeassistant: | |
customize: | |
sensor.omie_daily_spot_pt: | |
device_class: monetary | |
state_class: measurement | |
sensor.omie_daily_ajuste_pt: | |
device_class: monetary | |
state_class: measurement | |
sensor: | |
- platform: command_line | |
unique_id: omie_daily_spot_pt | |
name: omie_daily_spot_pt | |
command: "python3 /config/omie.py spot" | |
value_template: "{{ value_json.spot_price_pt_hourly[now().hour] }}" | |
unit_of_measurement: 'EUR/MWh' | |
json_attributes: | |
- row | |
- header | |
- source | |
- spot_price_pt_day_average | |
- spot_price_pt_hourly | |
- platform: command_line | |
name: omie_daily_ajuste_pt | |
unique_id: omie_daily_ajuste_pt | |
command: "python3 /config/omie.py ajuste" | |
value_template: "{{ value_json.ajuste_price_pt_hourly[now().hour] }}" | |
unit_of_measurement: 'EUR/MWh' | |
json_attributes: | |
- row | |
- header | |
- source | |
- ajuste_price_pt_day_average | |
- ajuste_price_pt_hourly | |
- platform: command_line | |
unique_id: omie_tomorrow_spot_pt | |
name: omie_tomorrow_spot_pt | |
command: "python3 /config/omie.py spot {{ (today_at()+timedelta(days=1)).date().isoformat() }}" | |
scan_interval: 3600 | |
value_template: > | |
{% if value != '' %} | |
{{ value_json.spot_price_pt_hourly[now().hour] }} | |
{% else %} | |
{{ 'unavailable' }} | |
{% endif %} | |
unit_of_measurement: 'EUR/MWh' | |
json_attributes: | |
- row | |
- header | |
- source | |
- spot_price_pt_day_average | |
- spot_price_pt_hourly | |
- platform: command_line | |
name: omie_tomorrow_ajuste_pt | |
unique_id: omie_tomorrow_ajuste_pt | |
command: "python3 /config/omie.py ajuste {{ (today_at()+timedelta(days=1)).date().isoformat() }}" | |
scan_interval: 3600 | |
value_template: "{{ value_json.ajuste_price_pt_hourly[now().hour] }}" | |
unit_of_measurement: 'EUR/MWh' | |
json_attributes: | |
- row | |
- header | |
- source | |
- ajuste_price_pt_day_average | |
- ajuste_price_pt_hourly |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import csv | |
import json | |
import statistics | |
import sys | |
from datetime import date, datetime | |
import requests | |
def to_dict(source, fetch_date, short_names): | |
with requests.get(source) as resp: | |
if resp.status_code == 404: | |
return None | |
lines = resp.text.splitlines() | |
header = lines[0] | |
data = lines[2:] | |
reader = csv.reader(data, delimiter=';', skipinitialspace=True) | |
rows = {row[0]: [float(row[i + 1].replace(',', '.')) for i in list(range(24))] for row in reader if row[0] != ''} | |
file_data = { | |
'header': header, | |
'fetched': datetime.now().isoformat(), | |
'market_date': fetch_date.isoformat(), | |
'source': source, | |
} | |
for k in rows: | |
hourly = rows[k] | |
if k in short_names: | |
# hourly & daily avg/sum | |
key = short_names[k] | |
suffix, daily = ['average', round(statistics.mean(hourly), 2)] if "(EUR/MWh)" in k else ['total', round(sum(hourly), 1)] | |
file_data.update({ | |
f'{key}_day_{suffix}': daily, | |
f'{key}_hourly': hourly, | |
}) | |
else: | |
# unprocessed: | |
file_data.update({k: hourly}) | |
return file_data | |
def spot_url(yy, MM, dd): | |
dd_MM_yy = f'{dd}_{MM}_{yy}' | |
return f'https://www.omie.es/sites/default/files/dados/AGNO_{yy}/MES_{MM}/TXT/INT_PBC_EV_H_1_{dd_MM_yy}_{dd_MM_yy}.TXT' | |
def ajuste_url(yy, MM, dd): | |
dd_MM_yy = f'{dd}_{MM}_{yy}' | |
return f'https://www.omie.es/sites/default/files/dados/AGNO_{yy}/MES_{MM}/TXT/INT_MAJ_EV_H_{dd_MM_yy}_{dd_MM_yy}.TXT' | |
# _daily_total | |
# _daily_average | |
def spot_price(fetch_date): | |
source = spot_url(fetch_date.year, str.zfill(str(fetch_date.month), 2), str.zfill(str(fetch_date.day), 2)) | |
return to_dict(source, fetch_date, { | |
"Energía total con bilaterales del mercado Ibérico (MWh)": 'energy_with_bilaterals_es_pt', | |
"Energía total de compra sistema español (MWh)": 'energy_purchases_es', | |
"Energía total de compra sistema portugués (MWh)": 'energy_purchases_pt', | |
"Energía total de venta sistema español (MWh)": 'energy_sales_es', | |
"Energía total de venta sistema portugués (MWh)": 'energy_sales_pt', | |
"Energía total del mercado Ibérico (MWh)": 'energy_es_pt', | |
"Exportación de España a Portugal (MWh)": 'energy_export_es_to_pt', | |
"Importación de España desde Portugal (MWh)": 'energy_import_es_from_pt', | |
"Precio marginal en el sistema español (EUR/MWh)": 'spot_price_es', | |
"Precio marginal en el sistema portugués (EUR/MWh)": 'spot_price_pt', | |
}) | |
def ajuste_price(fetch_date): | |
source = ajuste_url(fetch_date.year, str.zfill(str(fetch_date.month), 2), str.zfill(str(fetch_date.day), 2)) | |
return to_dict(source, fetch_date, { | |
"Precio de ajuste en el sistema español (EUR/MWh)": 'ajuste_price_es', | |
"Precio de ajuste en el sistema portugués (EUR/MWh)": 'ajuste_price_pt', | |
"Energía horaria sujeta al MAJ a los consumidores MIBEL (MWh)": 'ajuste_energy', | |
"Energía horaria sujeta al mecanismo de ajuste a los consumidores MIBEL (MWh)": 'ajuste_energy', | |
"Cuantía unitaria del ajuste (EUR/MWh)": 'ajuste_quantity', | |
}) | |
if __name__ == '__main__': | |
if len(sys.argv) not in [2, 3] or not sys.argv[1] in ['spot', 'ajuste']: | |
print('usage: omie.py <spot|ajuste> [ISO date]', file=sys.stderr) | |
sys.exit(1) | |
fetch_date = date.today() if len(sys.argv) == 2 else date.fromisoformat(sys.argv[2]) | |
if sys.argv[1] == 'spot': | |
spot = spot_price(fetch_date) | |
if spot is not None: | |
print(json.dumps(spot)) | |
if sys.argv[1] == 'ajuste': | |
ajuste = ajuste_price(fetch_date) | |
if ajuste is not None: | |
print(json.dumps(ajuste)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Pode-se fazer isso @jonferreira, o problema é que não há forma de garantir que ele actualiza atempadamente à meia noite. Como podes ver aqui em casa actualizou às 00:00:59, com esse
scan_interval
abres a possibilidade de ele actualizar à 1 da manhã.Pode ser que no futuro eu dedique uns tempos a fazer disto uma integração que só actualiza uma vez por dia mas para já não me importo de gastar uns bytes uma vez por minuto e estes ficheiros estão com certeza "cached" no OMIE.
Pode fazer sentido consoante a necessidade de cada um. Se reparares já actualizei os exemplos hoje de manhã e estão lá os sensores da média diária
omie_daily_spot_avg_pt
e o horárioomie_daily_spot_hourly_pt
. Com o https://github.com/RomRider/apexcharts-card por exemplo já consegue fazer gráficos com o valor horário até ao fim do dia usando somente os atributos doomie_daily_spot_avg_pt
porque tem os valores futuros também.Já para o HA gravar os dados no histórico e estatísticas necessitamos do sensor
omie_daily_spot_hourly_pt
com o valor horário . 👍