hass.tibber_prices/custom_components/tibber_prices/sensor/helpers.py
Julian Pawlowski 2f704a35a3 refactor: remove dead code across integration
Remove unused functions, constants, and entity definitions that were
left over from previous refactorings. All removed code was either
superseded by better implementations or never actually called.

Removed functions:
- entity_utils/helpers.py: translate_level(), translate_rating_level()
  (HA handles ENUM translation automatically via translations/*.json)
- entity_utils/attributes.py: build_timestamp_attribute(),
  build_period_attributes() (superseded by inline implementations)
- sensor/helpers.py: get_hourly_price_value(), aggregate_window_data()
  (replaced by Calculator Pattern in sensor/calculators/)

Removed constants and definitions:
- const.py: CONF_CHART_DATA_CONFIG (DATA_CHART_CONFIG is the active one),
  PRICE_LEVEL_OPTIONS, PRICE_RATING_OPTIONS, VOLATILITY_OPTIONS,
  PRICE_TREND_OPTIONS (never imported; options defined inline in
  definitions.py due to HA import timing constraints),
  async_get_home_type_translation() (sync version used instead)
- coordinator/core.py: FRESH_TO_CACHED_SECONDS (leftover from old
  caching strategy, never referenced)
- switch/definitions.py: BEST_PRICE_SWITCH_ENTITIES (duplicate of
  BEST_PRICE_SWITCH_ENTITY_DESCRIPTIONS using base class instead of
  custom TibberPricesSwitchEntityDescription subclass)

Cleanup:
- entity_utils/__init__.py: Remove exports for deleted functions
- sensor/helpers.py: Remove now-unused imports (timedelta,
  get_intervals_for_day_offsets, get_price_value, Callable)
- entity_utils/helpers.py: Remove unused get_price_level_translation
  import after translate_level() removal
- sensor/definitions.py: Update 7x "Keep in sync with *_OPTIONS"
  comments to reference individual PRICE_LEVEL_*/PRICE_RATING_*/
  VOLATILITY_* constants instead

Impact: No user-visible changes. Reduces codebase by ~130 lines.
Improves maintainability by eliminating misleading dead code.
2026-04-11 12:13:26 +00:00

97 lines
3.1 KiB
Python

"""
Sensor platform-specific helper functions.
This module contains helper functions specific to the sensor platform:
- aggregate_price_data: Calculate average price from window data
- aggregate_level_data: Aggregate price levels from intervals
- aggregate_rating_data: Aggregate price ratings from intervals
For shared helper functions (used by both sensor and binary_sensor platforms),
see entity_utils/helpers.py:
- get_price_value: Price unit conversion
- find_rolling_hour_center_index: Rolling hour window calculations
"""
from __future__ import annotations
from typing import TYPE_CHECKING
from custom_components.tibber_prices.const import get_display_unit_factor
from custom_components.tibber_prices.utils.average import calculate_mean, calculate_median
from custom_components.tibber_prices.utils.price import (
aggregate_price_levels,
aggregate_price_rating,
)
if TYPE_CHECKING:
from homeassistant.config_entries import ConfigEntry
def aggregate_average_data(
window_data: list[dict],
config_entry: ConfigEntry,
) -> tuple[float | None, float | None]:
"""
Calculate average and median price from window data.
Args:
window_data: List of price interval dictionaries with 'total' key.
config_entry: Config entry to get display unit configuration.
Returns:
Tuple of (average price, median price) in display currency units,
or (None, None) if no prices.
"""
prices = [float(i["total"]) for i in window_data if "total" in i]
if not prices:
return None, None
# Calculate both mean and median
mean = calculate_mean(prices)
median = calculate_median(prices)
# Convert to display currency unit based on configuration
factor = get_display_unit_factor(config_entry)
return round(mean * factor, 2), round(median * factor, 2) if median is not None else None
def aggregate_level_data(window_data: list[dict]) -> str | None:
"""
Aggregate price levels from window data.
Args:
window_data: List of price interval dictionaries with 'level' key
Returns:
Aggregated price level (lowercase), or None if no levels
"""
levels = [i["level"] for i in window_data if "level" in i]
if not levels:
return None
aggregated = aggregate_price_levels(levels)
return aggregated.lower() if aggregated else None
def aggregate_rating_data(
window_data: list[dict],
threshold_low: float,
threshold_high: float,
) -> str | None:
"""
Aggregate price ratings from window data.
Args:
window_data: List of price interval dictionaries with 'difference' and 'rating_level'
threshold_low: Low threshold for rating calculation
threshold_high: High threshold for rating calculation
Returns:
Aggregated price rating (lowercase), or None if no ratings
"""
differences = [i["difference"] for i in window_data if "difference" in i and "rating_level" in i]
if not differences:
return None
aggregated, _ = aggregate_price_rating(differences, threshold_low, threshold_high)
return aggregated.lower() if aggregated else None