fix(periods): rename periods_remaining to period_count_remaining

Consistent naming with the period_count_* family introduced in the
previous commit (period_count_total, period_count_today,
period_count_tomorrow).

periods_remaining was the last attribute in the navigation triplet
using the old plural form. Renamed to period_count_remaining to follow
the established pattern: all countable period metrics use the
period_count_* prefix.

BREAKING CHANGE: periods_remaining renamed to period_count_remaining.

Impact: All four period count attributes now share the same prefix
(period_count_total, period_count_today, period_count_tomorrow,
period_count_remaining), making automation templates more predictable.
This commit is contained in:
Julian Pawlowski 2026-04-12 10:05:21 +00:00
parent 779e22a84e
commit 1d3c55097d
7 changed files with 14 additions and 14 deletions

View file

@ -127,7 +127,7 @@ def get_price_intervals_attributes(
| { | {
"period_position": i, "period_position": i,
"period_count_total": total_filtered, "period_count_total": total_filtered,
"periods_remaining": total_filtered - i, "period_count_remaining": total_filtered - i,
} }
for i, period in enumerate(filtered_periods, 1) for i, period in enumerate(filtered_periods, 1)
] ]
@ -266,8 +266,8 @@ def add_detail_attributes(attributes: dict, current_period: dict) -> None:
attributes["period_position"] = current_period["period_position"] attributes["period_position"] = current_period["period_position"]
if "period_count_total" in current_period: if "period_count_total" in current_period:
attributes["period_count_total"] = current_period["period_count_total"] attributes["period_count_total"] = current_period["period_count_total"]
if "periods_remaining" in current_period: if "period_count_remaining" in current_period:
attributes["periods_remaining"] = current_period["periods_remaining"] attributes["period_count_remaining"] = current_period["period_count_remaining"]
def add_period_count_attributes( def add_period_count_attributes(
@ -421,7 +421,7 @@ def build_final_attributes_simple(
2. Core decision attributes (level, rating_level, rating_difference_%) 2. Core decision attributes (level, rating_level, rating_difference_%)
3. Price statistics (price_mean, price_median, price_min, price_max, price_spread, volatility) 3. Price statistics (price_mean, price_median, price_min, price_max, price_spread, volatility)
4. Price differences (period_price_diff_from_daily_min, period_price_diff_from_daily_min_%) 4. Price differences (period_price_diff_from_daily_min, period_price_diff_from_daily_min_%)
5. Detail information (period_interval_count, period_position, period_count_total, periods_remaining) 5. Detail information (period_interval_count, period_position, period_count_total, period_count_remaining)
6. Relaxation information (relaxation_active, relaxation_level, relaxation_threshold_original_%, 6. Relaxation information (relaxation_active, relaxation_level, relaxation_threshold_original_%,
relaxation_threshold_applied_%) - only if current period was relaxed relaxation_threshold_applied_%) - only if current period was relaxed
7. Calculation summary (min_periods_configured, flat_days_detected, 7. Calculation summary (min_periods_configured, flat_days_detected,

View file

@ -73,7 +73,7 @@ class TibberPricesBinarySensor(TibberPricesEntity, BinarySensorEntity, RestoreEn
"period_price_diff_from_daily_min", "period_price_diff_from_daily_min",
"period_price_diff_from_daily_min_%", "period_price_diff_from_daily_min_%",
"period_count_total", "period_count_total",
"periods_remaining", "period_count_remaining",
} }
) )

View file

@ -105,7 +105,7 @@ class PeriodSummary(TypedDict, total=False):
period_interval_count: int # Number of intervals in period period_interval_count: int # Number of intervals in period
period_position: int # Period position (1-based) period_position: int # Period position (1-based)
period_count_total: int # Total number of periods period_count_total: int # Total number of periods
periods_remaining: int # Remaining periods after this one period_count_remaining: int # Remaining periods after this one
# Relaxation information (priority 6 - only if period was relaxed) # Relaxation information (priority 6 - only if period was relaxed)
relaxation_active: bool # Whether this period was found via relaxation relaxation_active: bool # Whether this period was found via relaxation
@ -125,7 +125,7 @@ class PeriodAttributes(BaseAttributes, total=False):
2. Core decision attributes (level, rating_level, rating_difference_%) 2. Core decision attributes (level, rating_level, rating_difference_%)
3. Price statistics (price_mean, price_median, price_min, price_max, price_spread, volatility) 3. Price statistics (price_mean, price_median, price_min, price_max, price_spread, volatility)
4. Price comparison (period_price_diff_from_daily_min, period_price_diff_from_daily_min_%) 4. Price comparison (period_price_diff_from_daily_min, period_price_diff_from_daily_min_%)
5. Detail information (period_interval_count, period_position, period_count_total, periods_remaining) 5. Detail information (period_interval_count, period_position, period_count_total, period_count_remaining)
6. Relaxation information (only if period was relaxed) 6. Relaxation information (only if period was relaxed)
7. Meta information (periods list) 7. Meta information (periods list)
""" """
@ -156,7 +156,7 @@ class PeriodAttributes(BaseAttributes, total=False):
period_interval_count: int # Number of intervals in current/next period period_interval_count: int # Number of intervals in current/next period
period_position: int # Period position (1-based) period_position: int # Period position (1-based)
period_count_total: int # Total number of periods found period_count_total: int # Total number of periods found
periods_remaining: int # Remaining periods after current/next one period_count_remaining: int # Remaining periods after current/next one
# Relaxation information (priority 6 - only if period was relaxed) # Relaxation information (priority 6 - only if period was relaxed)
relaxation_active: bool # Whether current/next period was found via relaxation relaxation_active: bool # Whether current/next period was found via relaxation

View file

@ -56,7 +56,7 @@ def recalculate_period_metadata(periods: list[dict], *, time: TibberPricesTimeSe
""" """
Recalculate period metadata after merging periods. Recalculate period metadata after merging periods.
Updates period_position, period_count_total, and periods_remaining for all periods Updates period_position, period_count_total, and period_count_remaining for all periods
based on chronological order. based on chronological order.
This must be called after resolve_period_overlaps() to ensure metadata This must be called after resolve_period_overlaps() to ensure metadata
@ -79,7 +79,7 @@ def recalculate_period_metadata(periods: list[dict], *, time: TibberPricesTimeSe
for position, period in enumerate(periods, 1): for position, period in enumerate(periods, 1):
period["period_position"] = position period["period_position"] = position
period["period_count_total"] = total_periods period["period_count_total"] = total_periods
period["periods_remaining"] = total_periods - position period["period_count_remaining"] = total_periods - position
def merge_adjacent_periods(period1: dict, period2: dict) -> dict: def merge_adjacent_periods(period1: dict, period2: dict) -> dict:

View file

@ -179,7 +179,7 @@ def build_period_summary_dict(
"period_interval_count": period_data.period_length, "period_interval_count": period_data.period_length,
"period_position": period_data.period_idx, "period_position": period_data.period_idx,
"period_count_total": period_data.total_periods, "period_count_total": period_data.total_periods,
"periods_remaining": period_data.total_periods - period_data.period_idx, "period_count_remaining": period_data.total_periods - period_data.period_idx,
} }
# Add period price difference attributes based on sensor type (step 4) # Add period price difference attributes based on sensor type (step 4)

View file

@ -173,7 +173,7 @@ class TibberPricesSensor(TibberPricesEntity, RestoreSensor):
"period_price_diff_from_daily_min", "period_price_diff_from_daily_min",
"period_price_diff_from_daily_min_%", "period_price_diff_from_daily_min_%",
"period_count_total", "period_count_total",
"periods_remaining", "period_count_remaining",
} }
) )

View file

@ -137,7 +137,7 @@ class TibberPricesSensor(TibberPricesEntity, SensorEntity):
### 7. Redundant/Derived Data ### 7. Redundant/Derived Data
**Attributes:** `price_spread`, `volatility`, `diff_%`, `rating_difference_%`, `period_price_diff_from_daily_min`, `period_price_diff_from_daily_min_%`, `period_count_total`, `periods_remaining` **Attributes:** `price_spread`, `volatility`, `diff_%`, `rating_difference_%`, `period_price_diff_from_daily_min`, `period_price_diff_from_daily_min_%`, `period_count_total`, `period_count_remaining`
**Reason:** **Reason:**
- Can be calculated from other attributes - Can be calculated from other attributes
@ -146,7 +146,7 @@ class TibberPricesSensor(TibberPricesEntity, SensorEntity):
**Impact:** ~100-200 bytes saved per state change **Impact:** ~100-200 bytes saved per state change
**Example:** `price_spread = price_max - price_min` (both are recorded, so spread can be calculated). `periods_remaining = period_count_total - period_position` (both components are recorded). **Example:** `price_spread = price_max - price_min` (both are recorded, so spread can be calculated). `period_count_remaining = period_count_total - period_position` (both components are recorded).
## Attributes That ARE Recorded ## Attributes That ARE Recorded