mirror of
https://github.com/jpawlowski/hass.tibber_prices.git
synced 2026-05-29 10:53:40 +00:00
6 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a4ad506e01 |
feat(sensor): use dynamic precision for price rounding and display
Add get_display_precision() to const.py returning DISPLAY_PRECISION_SUBUNIT (2) or DISPLAY_PRECISION_BASE (4) based on config. Replace hardcoded round(..., 2) with get_display_precision() in all calculators and attribute builders. Add _update_suggested_precision() to sensor core; syncs entity registry suggested_display_precision on every coordinator update. Interval price sensors get full precision (2 or 4 dp); other MONETARY sensors get half precision (1 or 2 dp) as sensible default. Impact: Price sensor states and attributes now correctly use 4 decimal places in base-currency mode (was always 2). Display precision in dashboards updates automatically when currency mode changes. |
||
|
|
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. |
||
|
|
60e05e0815 |
refactor(currency)!: rename major/minor to base/subunit currency terminology
Complete terminology migration from confusing "major/minor" to clearer
"base/subunit" currency naming throughout entire codebase, translations,
documentation, tests, and services.
BREAKING CHANGES:
1. **Service API Parameters Renamed**:
- `get_chartdata`: `minor_currency` → `subunit_currency`
- `get_apexcharts_yaml`: Updated service_data references from
`minor_currency: true` to `subunit_currency: true`
- All automations/scripts using these parameters MUST be updated
2. **Configuration Option Key Changed**:
- Config entry option: Display mode setting now uses new terminology
- Internal key: `currency_display_mode` values remain "base"/"subunit"
- User-facing labels updated in all 5 languages (de, en, nb, nl, sv)
3. **Sensor Entity Key Renamed**:
- `current_interval_price_major` → `current_interval_price_base`
- Entity ID changes: `sensor.tibber_home_current_interval_price_major`
→ `sensor.tibber_home_current_interval_price_base`
- Energy Dashboard configurations MUST update entity references
4. **Function Signatures Changed**:
- `format_price_unit_major()` → `format_price_unit_base()`
- `format_price_unit_minor()` → `format_price_unit_subunit()`
- `get_price_value()`: Parameter `in_euro` deprecated in favor of
`config_entry` (backward compatible for now)
5. **Translation Keys Renamed**:
- All language files: Sensor translation key
`current_interval_price_major` → `current_interval_price_base`
- Service parameter descriptions updated in all languages
- Selector options updated: Display mode dropdown values
Changes by Category:
**Core Code (Python)**:
- const.py: Renamed all format_price_unit_*() functions, updated docstrings
- entity_utils/helpers.py: Updated get_price_value() with config-driven
conversion and backward-compatible in_euro parameter
- sensor/__init__.py: Added display mode filtering for base currency sensor
- sensor/core.py:
* Implemented suggested_display_precision property for dynamic decimal places
* Updated native_unit_of_measurement to use get_display_unit_string()
* Updated all price conversion calls to use config_entry parameter
- sensor/definitions.py: Renamed entity key and updated all
suggested_display_precision values (2 decimals for most sensors)
- sensor/calculators/*.py: Updated all price conversion calls (8 calculators)
- sensor/helpers.py: Updated aggregate_price_data() signature with config_entry
- sensor/attributes/future.py: Updated future price attributes conversion
**Services**:
- services/chartdata.py: Renamed parameter minor_currency → subunit_currency
throughout (53 occurrences), updated metadata calculation
- services/apexcharts.py: Updated service_data references in generated YAML
- services/formatters.py: Renamed parameter use_minor_currency →
use_subunit_currency in aggregate_hourly_exact() and get_period_data()
- sensor/chart_metadata.py: Updated default parameter name
**Translations (5 Languages)**:
- All /translations/*.json:
* Added new config step "display_settings" with comprehensive explanations
* Renamed current_interval_price_major → current_interval_price_base
* Updated service parameter descriptions (subunit_currency)
* Added selector.currency_display_mode.options with translated labels
- All /custom_translations/*.json:
* Renamed sensor description keys
* Updated chart_metadata usage_tips references
**Documentation**:
- docs/user/docs/actions.md: Updated parameter table and feature list
- docs/user/versioned_docs/version-v0.21.0/actions.md: Backported changes
**Tests**:
- Updated 7 test files with renamed parameters and conversion logic:
* test_connect_segments.py: Renamed minor/major to subunit/base
* test_period_data_format.py: Updated period price conversion tests
* test_avg_none_fallback.py: Fixed tuple unpacking for new return format
* test_best_price_e2e.py: Added config_entry parameter to all calls
* test_cache_validity.py: Fixed cache data structure (price_info key)
* test_coordinator_shutdown.py: Added repair_manager mock
* test_midnight_turnover.py: Added config_entry parameter
* test_peak_price_e2e.py: Added config_entry parameter, fixed price_avg → price_mean
* test_percentage_calculations.py: Added config_entry mock
**Coordinator/Period Calculation**:
- coordinator/periods.py: Added config_entry parameter to
calculate_periods_with_relaxation() calls (2 locations)
Migration Guide:
1. **Update Service Calls in Automations/Scripts**:
\`\`\`yaml
# Before:
service: tibber_prices.get_chartdata
data:
minor_currency: true
# After:
service: tibber_prices.get_chartdata
data:
subunit_currency: true
\`\`\`
2. **Update Energy Dashboard Configuration**:
- Settings → Dashboards → Energy
- Replace sensor entity:
`sensor.tibber_home_current_interval_price_major` →
`sensor.tibber_home_current_interval_price_base`
3. **Review Integration Configuration**:
- Settings → Devices & Services → Tibber Prices → Configure
- New "Currency Display Settings" step added
- Default mode depends on currency (EUR → subunit, Scandinavian → base)
Rationale:
The "major/minor" terminology was confusing and didn't clearly communicate:
- **Major** → Unclear if this means "primary" or "large value"
- **Minor** → Easily confused with "less important" rather than "smaller unit"
New terminology is precise and self-explanatory:
- **Base currency** → Standard ISO currency (€, kr, $, £)
- **Subunit currency** → Fractional unit (ct, øre, ¢, p)
This aligns with:
- International terminology (ISO 4217 standard)
- Banking/financial industry conventions
- User expectations from payment processing systems
Impact: Aligns currency terminology with international standards. Users must
update service calls, automations, and Energy Dashboard configuration after
upgrade.
Refs: User feedback session (December 2025) identified terminology confusion
|
||
|
|
c2b9908e69 |
refactor(naming): complete class naming convention alignment
Renamed 25 public classes + 1 Enum to include TibberPrices prefix
following Home Assistant integration naming standards.
All classes now follow pattern: TibberPrices{SemanticPurpose}
No package hierarchy in names (import path is namespace).
Key changes:
- Coordinator module: DataFetcher, DataTransformer, ListenerManager,
PeriodCalculator, TimeService (203 usages), CacheData
- Config flow: CannotConnectError, InvalidAuthError
- Entity utils: IconContext
- Sensor calculators: BaseCalculator + 8 subclasses
- Period handlers: 5 NamedTuples (PeriodConfig, PeriodData,
PeriodStatistics, ThresholdConfig, IntervalCriteria)
- Period handlers: SpikeCandidateContext (dataclass → NamedTuple)
- API: QueryType Enum
Documentation updates:
- AGENTS.md: Added Pyright code generation guidelines
- planning/class-naming-refactoring-plan.md: Complete execution log
Quality metrics:
- 0 Pyright errors (strict type checking)
- 0 Ruff errors (linting + formatting)
- All hassfest checks passed
- 79 files validated
Impact: Aligns with HA Core standards (TibberDataCoordinator pattern).
No user-facing changes - internal refactor only.
|
||
|
|
625bc222ca |
refactor(coordinator): centralize time operations through TimeService
Introduce TimeService as single source of truth for all datetime operations, replacing direct dt_util calls throughout the codebase. This establishes consistent time context across update cycles and enables future time-travel testing capability. Core changes: - NEW: coordinator/time_service.py with timezone-aware datetime API - Coordinator now creates TimeService per update cycle, passes to calculators - Timer callbacks (#2, #3) inject TimeService into entity update flow - All sensor calculators receive TimeService via coordinator reference - Attribute builders accept time parameter for timestamp calculations Key patterns replaced: - dt_util.now() → time.now() (single reference time per cycle) - dt_util.parse_datetime() + as_local() → time.get_interval_time() - Manual interval arithmetic → time.get_interval_offset_time() - Manual day boundaries → time.get_day_boundaries() - round_to_nearest_quarter_hour() → time.round_to_nearest_quarter() Import cleanup: - Removed dt_util imports from ~30 files (calculators, attributes, utils) - Restricted dt_util to 3 modules: time_service.py (operations), api/client.py (rate limiting), entity_utils/icons.py (cosmetic updates) - datetime/timedelta only for TYPE_CHECKING (type hints) or duration arithmetic Interval resolution abstraction: - Removed hardcoded MINUTES_PER_INTERVAL constant from 10+ files - New methods: time.minutes_to_intervals(), time.get_interval_duration() - Supports future 60-minute resolution (legacy data) via TimeService config Timezone correctness: - API timestamps (startsAt) already localized by data transformation - TimeService operations preserve HA user timezone throughout - DST transitions handled via get_expected_intervals_for_day() (future use) Timestamp ordering preserved: - Attribute builders generate default timestamp (rounded quarter) - Sensors override when needed (next interval, daily midnight, etc.) - Platform ensures timestamp stays FIRST in attribute dict Timer integration: - Timer #2 (quarter-hour): Creates TimeService, calls _handle_time_sensitive_update(time) - Timer #3 (30-second): Creates TimeService, calls _handle_minute_update(time) - Consistent time reference for all entities in same update batch Time-travel readiness: - TimeService.with_reference_time() enables time injection (not yet used) - All calculations use time.now() → easy to simulate past/future states - Foundation for debugging period calculations with historical data Impact: Eliminates timestamp drift within update cycles (previously 60+ independent dt_util.now() calls could differ by milliseconds). Establishes architecture for time-based testing and debugging features. |
||
|
|
4876a2cc29 |
refactor(entity_utils): extract shared helpers from sensor platform
Created entity_utils/helpers.py with platform-agnostic utility functions: - get_price_value(): Price unit conversion (major/minor currency) - translate_level(): Price level translation - translate_rating_level(): Rating level translation - find_rolling_hour_center_index(): Rolling hour window calculations These functions moved from sensor/helpers.py as they are used by both sensor and binary_sensor platforms. Remaining sensor/helpers.py now contains only sensor-specific helpers (aggregate_price_data, etc.). Updated imports: - sensor/core.py: Import from entity_utils instead of sensor.helpers - entity_utils/icons.py: Fixed find_rolling_hour_center_index import - binary_sensor platforms: Can now use shared helpers Added clear docstrings explaining: - entity_utils/helpers.py: Platform-agnostic utilities - sensor/helpers.py: Sensor-specific aggregation functions Impact: Better code reuse, clearer responsibility boundaries between platform-specific and shared utilities. |