mirror of
https://github.com/jpawlowski/hass.tibber_prices.git
synced 2026-03-29 21:03:40 +00:00
refactor(calculators): consolidate duplicate data access patterns
Refactored Trend, Timing, and Lifecycle calculators to use BaseCalculator helper methods instead of duplicating data access logic. Changes: - TrendCalculator: Simplified 12 lines of repeated price_info access to 3-4 clean property calls (intervals_today/tomorrow, get_all_intervals) - TimingCalculator: Replaced direct coordinator.data checks with has_data() - LifecycleCalculator: Replaced 5 lines of nested gets with 2 helper calls Benefits: - Eliminated 10+ duplicate data access patterns - Consistent None-handling across all calculators - Single source of truth for coordinator data access - Easier to maintain (changes propagate automatically) BaseCalculator helpers used: - has_data(): Replaces 'if not self.coordinator.data:' checks - intervals_today/tomorrow: Direct property access to day intervals - get_intervals(day): Safe day-specific interval retrieval - get_all_intervals(): Combined yesterday+today+tomorrow - coordinator_data: Property for coordinator.data access Validation: - Type checker: 0 errors, 0 warnings - Tests: 347 passed, 2 skipped (no behavior change) - Net: 19 deletions, 14 insertions (5 lines removed, patterns simplified) Impact: Cleaner code, reduced duplication, consistent error handling. Future calculator additions will automatically benefit from centralized data access patterns.
This commit is contained in:
parent
ed08bc29da
commit
ea21b229ee
3 changed files with 14 additions and 19 deletions
|
|
@ -201,12 +201,10 @@ class TibberPricesLifecycleCalculator(TibberPricesBaseCalculator):
|
||||||
True if data exists and is not empty
|
True if data exists and is not empty
|
||||||
|
|
||||||
"""
|
"""
|
||||||
coordinator = self.coordinator
|
if not self.has_data():
|
||||||
if not coordinator.data:
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
price_info = coordinator.data.get("priceInfo", {})
|
day_data = self.get_intervals(day)
|
||||||
day_data = price_info.get(day, [])
|
|
||||||
return bool(day_data)
|
return bool(day_data)
|
||||||
|
|
||||||
def get_data_completeness_status(self) -> str:
|
def get_data_completeness_status(self) -> str:
|
||||||
|
|
@ -248,7 +246,7 @@ class TibberPricesLifecycleCalculator(TibberPricesBaseCalculator):
|
||||||
"""
|
"""
|
||||||
coordinator = self.coordinator
|
coordinator = self.coordinator
|
||||||
# Check if coordinator has data (transformed, ready for entities)
|
# Check if coordinator has data (transformed, ready for entities)
|
||||||
if not coordinator.data:
|
if not self.has_data():
|
||||||
return "empty"
|
return "empty"
|
||||||
|
|
||||||
# Check if we have price update timestamp
|
# Check if we have price update timestamp
|
||||||
|
|
|
||||||
|
|
@ -65,11 +65,11 @@ class TibberPricesTimingCalculator(TibberPricesBaseCalculator):
|
||||||
- None if no relevant period data available
|
- None if no relevant period data available
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if not self.coordinator.data:
|
if not self.has_data():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Get period data from coordinator
|
# Get period data from coordinator
|
||||||
periods_data = self.coordinator.data.get("periods", {})
|
periods_data = self.coordinator_data.get("periods", {})
|
||||||
period_data = periods_data.get(period_type)
|
period_data = periods_data.get(period_type)
|
||||||
|
|
||||||
if not period_data or not period_data.get("periods"):
|
if not period_data or not period_data.get("periods"):
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ class TibberPricesTrendCalculator(TibberPricesBaseCalculator):
|
||||||
if self._cached_trend_value is not None and self._trend_attributes:
|
if self._cached_trend_value is not None and self._trend_attributes:
|
||||||
return self._cached_trend_value
|
return self._cached_trend_value
|
||||||
|
|
||||||
if not self.coordinator.data:
|
if not self.has_data():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Get current interval price and timestamp
|
# Get current interval price and timestamp
|
||||||
|
|
@ -107,9 +107,8 @@ class TibberPricesTrendCalculator(TibberPricesBaseCalculator):
|
||||||
volatility_threshold_high = self.config.get("volatility_threshold_high", 30.0)
|
volatility_threshold_high = self.config.get("volatility_threshold_high", 30.0)
|
||||||
|
|
||||||
# Prepare data for volatility-adaptive thresholds
|
# Prepare data for volatility-adaptive thresholds
|
||||||
price_info = self.coordinator.data.get("priceInfo", {})
|
today_prices = self.intervals_today
|
||||||
today_prices = price_info.get("today", [])
|
tomorrow_prices = self.intervals_tomorrow
|
||||||
tomorrow_prices = price_info.get("tomorrow", [])
|
|
||||||
all_intervals = today_prices + tomorrow_prices
|
all_intervals = today_prices + tomorrow_prices
|
||||||
lookahead_intervals = self.coordinator.time.minutes_to_intervals(hours * 60)
|
lookahead_intervals = self.coordinator.time.minutes_to_intervals(hours * 60)
|
||||||
|
|
||||||
|
|
@ -247,12 +246,11 @@ class TibberPricesTrendCalculator(TibberPricesBaseCalculator):
|
||||||
Average price for the later half intervals, or None if insufficient data
|
Average price for the later half intervals, or None if insufficient data
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if not self.coordinator.data:
|
if not self.has_data():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
price_info = self.coordinator.data.get("priceInfo", {})
|
today_prices = self.intervals_today
|
||||||
today_prices = price_info.get("today", [])
|
tomorrow_prices = self.intervals_tomorrow
|
||||||
tomorrow_prices = price_info.get("tomorrow", [])
|
|
||||||
all_prices = today_prices + tomorrow_prices
|
all_prices = today_prices + tomorrow_prices
|
||||||
|
|
||||||
if not all_prices:
|
if not all_prices:
|
||||||
|
|
@ -307,12 +305,11 @@ class TibberPricesTrendCalculator(TibberPricesBaseCalculator):
|
||||||
return self._trend_calculation_cache
|
return self._trend_calculation_cache
|
||||||
|
|
||||||
# Validate coordinator data
|
# Validate coordinator data
|
||||||
if not self.coordinator.data:
|
if not self.has_data():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
price_info = self.coordinator.data.get("priceInfo", {})
|
all_intervals = self.get_all_intervals()
|
||||||
all_intervals = price_info.get("today", []) + price_info.get("tomorrow", [])
|
current_interval = find_price_data_for_interval(self.price_info, now, time=time)
|
||||||
current_interval = find_price_data_for_interval(price_info, now, time=time)
|
|
||||||
|
|
||||||
if not all_intervals or not current_interval:
|
if not all_intervals or not current_interval:
|
||||||
return None
|
return None
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue