strompreis/collectors/smard.py

58 lines
1.8 KiB
Python

"""
Collector for SMARD (Electricity Market Data) API.
"""
import time
import logging
import polars as pl
from utils import request_utils
from utils.config_loader import settings
logger = logging.getLogger(__name__)
def fetch_smard_data(filter_id: int, region: str = None) -> pl.DataFrame:
"""
Fetches time-series data from the SMARD API for a specific filter.
Args:
filter_id: The SMARD data identifier (e.g., 4169 for price).
region: The region code (defaults to config value).
Returns:
A Polars DataFrame with 'timestamp' (ms) and 'value'.
"""
region = region or settings.smard.region
base_url = settings.smard.base_url
now_ms = int(time.time()) * 1000
index_url = f"{base_url}/{filter_id}/{region}/index_hour.json"
try:
index_data = request_utils.make_requests(index_url)
if not index_data or "timestamps" not in index_data:
logger.warning(f"No index data for filter {filter_id}")
return pl.DataFrame()
closest_ts = min(index_data["timestamps"], key=lambda x: abs(x - now_ms))
data_url = (
f"{base_url}/{filter_id}/{region}/"
f"{filter_id}_{region}_hour_{closest_ts}.json"
)
payload = request_utils.make_requests(data_url)
series = payload.get("series", [])
clean_series = [row for row in series if row[1] is not None]
if not clean_series:
return pl.DataFrame()
return pl.DataFrame(
{
"timestamp": [row[0] for row in clean_series],
"value": [row[1] for row in clean_series],
},
schema={"timestamp": pl.Int64, "value": pl.Float64}
)
except Exception as e:
logger.error(f"Failed to fetch SMARD filter {filter_id}: {e}")
return pl.DataFrame()