refactor(utils): create utils package and consolidate constants

Reorganized utility modules into structured package:
- average_utils.py → utils/average.py
- price_utils.py → utils/price.py
- Created utils/__init__.py with clean exports

Moved MINUTES_PER_INTERVAL to const.py (centralized constant
management), with re-exports in utils modules for backward
compatibility during migration.

Added comprehensive package docstring explaining scope:
- Pure data transformation functions (stateless)
- No HA entity/coordinator dependencies
- Clear separation from entity_utils/ (entity-specific logic)

Impact: Cleaner module structure, easier navigation. Follows
file organization policy from AGENTS.md (keep root clean).
This commit is contained in:
Julian Pawlowski 2025-11-18 20:06:46 +00:00
parent d828f754be
commit d52eb6b788
3 changed files with 67 additions and 5 deletions

View file

@ -0,0 +1,63 @@
"""
Pure data transformation utilities for Tibber Prices integration.
This package contains stateless, pure functions for data processing:
- Time-window calculations (trailing/leading averages, min/max)
- Price enrichment (differences, volatility, rating levels)
- Statistical analysis (aggregation, trends)
These functions operate on raw data structures (dicts, lists) and do NOT depend on:
- Home Assistant entities or state management
- Configuration entries or coordinators
- Translation systems or UI-specific logic
For entity-specific utilities (icons, colors, attributes), see entity_utils/ package.
"""
from __future__ import annotations
from .average import (
calculate_current_leading_avg,
calculate_current_leading_max,
calculate_current_leading_min,
calculate_current_trailing_avg,
calculate_current_trailing_max,
calculate_current_trailing_min,
calculate_next_n_hours_avg,
round_to_nearest_quarter_hour,
)
from .price import (
aggregate_period_levels,
aggregate_period_ratings,
aggregate_price_levels,
aggregate_price_rating,
calculate_difference_percentage,
calculate_price_trend,
calculate_rating_level,
calculate_trailing_average_for_interval,
calculate_volatility_level,
enrich_price_info_with_differences,
find_price_data_for_interval,
)
__all__ = [
"aggregate_period_levels",
"aggregate_period_ratings",
"aggregate_price_levels",
"aggregate_price_rating",
"calculate_current_leading_avg",
"calculate_current_leading_max",
"calculate_current_leading_min",
"calculate_current_trailing_avg",
"calculate_current_trailing_max",
"calculate_current_trailing_min",
"calculate_difference_percentage",
"calculate_next_n_hours_avg",
"calculate_price_trend",
"calculate_rating_level",
"calculate_trailing_average_for_interval",
"calculate_volatility_level",
"enrich_price_info_with_differences",
"find_price_data_for_interval",
"round_to_nearest_quarter_hour",
]

View file

@ -7,10 +7,7 @@ import statistics
from datetime import datetime, timedelta
from typing import Any
from homeassistant.util import dt as dt_util
from .average_utils import round_to_nearest_quarter_hour
from .const import (
from custom_components.tibber_prices.const import (
DEFAULT_VOLATILITY_THRESHOLD_HIGH,
DEFAULT_VOLATILITY_THRESHOLD_MODERATE,
DEFAULT_VOLATILITY_THRESHOLD_VERY_HIGH,
@ -22,10 +19,12 @@ from .const import (
VOLATILITY_MODERATE,
VOLATILITY_VERY_HIGH,
)
from homeassistant.util import dt as dt_util
from .average import round_to_nearest_quarter_hour
_LOGGER = logging.getLogger(__name__)
MINUTES_PER_INTERVAL = 15
MIN_PRICES_FOR_VOLATILITY = 2 # Minimum number of price values needed for volatility calculation
# Volatility factors for adaptive trend thresholds