-
-
Notifications
You must be signed in to change notification settings - Fork 35.8k
Add OMIE integration #150399
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Add OMIE integration #150399
Conversation
* Port code over from luuuis/hass_omie and adapt to use pyomie client library
Co-authored-by: Abílio Costa <[email protected]>
|
@luuuis I think this should still go ahead, but have a look at #145848 (comment) |
|
Marking as draft until #150399 (comment) is sorted out. |
|
By the way, I just tried running this and got an error: |
|
Last changes:
|
|
|
||
| return { | ||
| dt.datetime.fromisoformat(dt_str).astimezone(CET): v | ||
| for dt_str, v in localize_quarter_hourly_data(market_date, series_data).items() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
v is the price? if so, lets rename it to price
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
v contains the series values depending on the series. There are series for prices, import/export power and so forth, although in practice we are only reading the price-related series into the sensors.
series_value would be an accurate and descriptive variable name, if somewhat verbose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
series_values (plural) then?
anything that tells what the variable is fine, because v is too opaque.
| from __future__ import annotations | ||
|
|
||
| from collections.abc import Mapping | ||
| import datetime as dt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if possible, lets use now from homeassistant.util.dt instead of datetime.datetime
|
It seems that this is fetching data 1 hour ahead. Currently at 19:00 UTC / 20:00 CET, it shows 0.1572 €/kWh which is the price for H21Q1 on the website. |
| for date in {d for d in market_dates if d not in data}: | ||
| _LOGGER.debug("Fetching OMIE data for %s", date) | ||
| if results := await pyomie.spot_price(self._client_session, date): | ||
| _LOGGER.debug("pyomie.spot_price returned: %s", results) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this prints a very big and ugly unformulated message 😅
can we remove it and maybe have logs in the library instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh it's big for sure, especially since the transition to 15-minute pricing. I'm not sure what you mean by ugly here and it seems like that would be highly subjective anyway–it's a JSON payload returned by an external lib. 🤷
The rationale to have it is that DEBUG logs on this component would be used for troubleshooting only and it's normally only logged every 24 hours anyway. It feels like by removing it we would hamper our ability to troubleshoot potential future issues for I'm not sure what benefit?
Since pyomie's only function is to print the fetched data formatted as JSON to stdout, it would be silly to also duplicate that into logs. Having said that, I could imagine a separate logger in HA for this that doesn't propagate messages to the parent logger and therefore has to be set explicitly. Something like:
_LOGGER = logging.getLogger(__name__)
# Separate logger for pyomie payloads that doesn't inherit
_PYOMIE_LOGGER = logging.getLogger(f'{__name__}.pyomie')
_PYOMIE_LOGGER.propagate = False
_PYOMIE_LOGGER.setLevel(logging.WARNING)I haven't seen this pattern used in HA elsewhere, however. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I said ugly because it is not just json, it is printing data structs/classes:
2025-11-04 19:40:59.554 DEBUG (MainThread) [homeassistant.components.omie.coordinator] pyomie.spot_price returned: OMIEResults(updated_at=datetime.datetime(2025, 11, 4, 19, 40, 59, 554411, tzinfo=datetime.timezone.utc), market_date=datetime.date(2025, 11, 4), contents=SpotData(url='https://www.omie.es/sites/default/files/dados/AGNO_2025/MES_11/TXT/INT_PBC_EV_H_1_04_11_2025_04_11_2025.TXT', market_date='2025-11-04', header='OMIE - Mercado de electricidad;Fecha Emisión :03/11/2025 - 14:14;;04/11/2025;Precio del mercado diario (EUR/MWh);;;;', es_pt_total_power=[29418.9, 29014.8, 28514.6, 28036.4, 27595.0, 27341.3, 27035.9, 27004.3, 26461.1, 26251.3, 26126.3, 26082.7, 26046.5, 26007.4, 26039.5, 26068.4, 26007.5, 26072.9, 26137.7, 26182.7, 26385.2, 26551.6, 26687.7, 26923.3, 28743.2, 28930.3, 29519.9, 30033.6, 31538.1, 32463.2, 33191.8
It also has things like this, with \r\n for example:
raw='OMIE - Mercado de electricidad;Fecha Emisión :03/11/2025 - 14:14;;04/11/2025;Precio del mercado diario (EUR/MWh);;;;\r\n\r\n;H1Q1;H1Q2;H1Q3;H1Q4;H2Q1;H2Q2;H2Q3;H2Q4;H3Q1;H3Q2;H3Q3;H3Q4;H4Q1;H4Q2;H4Q3;H4Q4;H5Q1;H5Q2;H5Q3;H5Q4;H6Q1;H6Q2;H6Q3;H6Q4;H7Q1;H7Q2;H7Q3;H7Q4;H8Q1;H8Q2;H8Q3;H8Q4;H9Q1;H9Q2;H9Q3;H9Q4;H10Q1;H10Q2;H10Q3;H10Q4;H11Q1;H11Q2;H11Q3;H11Q4;H12Q1;H12Q2;H12Q3;H12Q4;H13Q1;H13Q2;H13Q3;H13Q4;H14Q1;H14Q2;H14Q3;H14Q4;H15Q1;H15Q2;H15Q3;H15Q4;H16Q1;H16Q2;H16Q3;H16Q4;H17Q1;H17Q2;H17Q3;H17Q4;H18Q1;H18Q2;H18Q3;H18Q4;H19Q1;H19Q2;H19Q3;H19Q4;H20Q1;H20Q2;H20Q3;H20Q4;H21Q1;H21Q2;H21Q3;H21Q4;H22Q1;H22Q2;H22Q3;H22Q4;H23Q1;H23Q2;H23Q3;H23Q4;H24Q1;H24Q2;H24Q3;H24Q4;\r\nPrecio marginal en el sistema español (EUR/MWh);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since pyomie's only function is to print the fetched data formatted as JSON to stdout, it would be silly to also duplicate that into logs.
You can make it a debug log, and set the library log level to info or warning by default. Would that work for you?
Co-authored-by: Abílio Costa <[email protected]>
Co-authored-by: Abílio Costa <[email protected]>
0.1572 is the correct price for 2025-11-03 at 19:00 in Portugal. OMIE hours are 1-based, you can read all about it in Interpretação OMIE mercado diário (not updated for quarter-hourly prices but the same logic applies). Full results for 2025-11-03~ ❯❯❯ pipx run pyomie 2025-11-03 | jq '.pt_spot_price | to_entries | map({
key: (
(.key * 15 / 60 | floor | tostring) as $hour |
(.key * 15 % 60 | tostring) as $min |
(if ($hour | length) == 1 then "0" + $hour else $hour end) + ":" +
(if ($min | length) == 1 then "0" + $min else $min end)
),
value: (.value*10|round/10000)
}) | from_entries'
{
"00:00": 0.0921,
"00:15": 0.0901,
"00:30": 0.0875,
"00:45": 0.0861,
"01:00": 0.0846,
"01:15": 0.0837,
"01:30": 0.0836,
"01:45": 0.0834,
"02:00": 0.0832,
"02:15": 0.083,
"02:30": 0.0829,
"02:45": 0.0829,
"03:00": 0.0827,
"03:15": 0.0824,
"03:30": 0.0824,
"03:45": 0.0827,
"04:00": 0.0824,
"04:15": 0.0827,
"04:30": 0.083,
"04:45": 0.0832,
"05:00": 0.0836,
"05:15": 0.0837,
"05:30": 0.0854,
"05:45": 0.0913,
"06:00": 0.095,
"06:15": 0.1028,
"06:30": 0.105,
"06:45": 0.1101,
"07:00": 0.1187,
"07:15": 0.1239,
"07:30": 0.1404,
"07:45": 0.1494,
"08:00": 0.1432,
"08:15": 0.1187,
"08:30": 0.1056,
"08:45": 0.0875,
"09:00": 0.0905,
"09:15": 0.0827,
"09:30": 0.065,
"09:45": 0.0454,
"10:00": 0.05,
"10:15": 0.0378,
"10:30": 0.0301,
"10:45": 0.0187,
"11:00": 0.0285,
"11:15": 0.0191,
"11:30": 0.0167,
"11:45": 0.0155,
"12:00": 0.0168,
"12:15": 0.0167,
"12:30": 0.0168,
"12:45": 0.0157,
"13:00": 0.0152,
"13:15": 0.0129,
"13:30": 0.0129,
"13:45": 0.014,
"14:00": 0.0143,
"14:15": 0.0167,
"14:30": 0.0197,
"14:45": 0.0238,
"15:00": 0.019,
"15:15": 0.0359,
"15:30": 0.0397,
"15:45": 0.0506,
"16:00": 0.045,
"16:15": 0.0511,
"16:30": 0.0725,
"16:45": 0.0834,
"17:00": 0.0854,
"17:15": 0.1039,
"17:30": 0.1118,
"17:45": 0.1404,
"18:00": 0.1187,
"18:15": 0.1233,
"18:30": 0.129,
"18:45": 0.1292,
"19:00": 0.1404,
"19:15": 0.15,
"19:30": 0.15,
"19:45": 0.15,
"20:00": 0.1572,
"20:15": 0.1553,
"20:30": 0.15,
"20:45": 0.1432,
"21:00": 0.15,
"21:15": 0.135,
"21:30": 0.1217,
"21:45": 0.1153,
"22:00": 0.1105,
"22:15": 0.105,
"22:30": 0.1002,
"22:45": 0.0934,
"23:00": 0.0967,
"23:15": 0.0945,
"23:30": 0.09,
"23:45": 0.0861
} |
Proposed change
Add an integration for retrieving Iberian Peninsula energy price data from OMIE. The integration retrieves data from the daily market run and then updates the sensors accordingly on an hourly basis.
This is (simplified) port of https://github.com/luuuis/hass_omie/, also developed by myself, which has proven itself stable over the last years.
Type of change
Additional information
Follow-up of #108045 (stale)
Checklist
ruff format homeassistant tests)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest.requirements_all.txt.Updated by running
python3 -m script.gen_requirements_all.To help with the load of incoming pull requests: