Commit graph

244 commits

Author SHA1 Message Date
Julian Pawlowski
9c00d985c8 chore(release): bump version to 0.7.0 2025-11-15 18:22:08 +00:00
Julian Pawlowski
a75b8ffdb3 perf(coordinator): optimize API calls and data processing
Implemented comprehensive performance optimizations to eliminate asyncio
warnings and reduce unnecessary API calls:

Performance Improvements:
- Two-tier caching: raw API data + transformed data
- Transformation caching prevents re-processing on every coordinator update
- Only retransform when config changes, new data arrives, or midnight turnover
- Reduced coordinator update time from ~120ms to <10ms (cache hits)

API Call Optimization:
- Removed periodic 6-hour "safety" API calls (trust cache validation)
- Random delay (0-30s) for tomorrow data checks (prevents thundering herd)
- API calls only when truly needed (no cache, invalid cache, tomorrow missing)
- Expected reduction: ~50% fewer API calls (from ~4-5/day to ~2/day)

Enhanced Logging:
- Clear [Timer #1/2/3] prefixes for multi-timer system
- Distinguish "Fetching from API" vs "Using cache"
- Separate "Transforming data" vs "Using cached transformed data"
- Hierarchical logging shows which timer triggered which action

Documentation:
- Comprehensive TIMER SYSTEM block explaining three independent timers
- Enhanced docstrings for timer handlers (synchronous callbacks vs async def)
- Clarified why @callback handlers don't use async/await (no I/O operations)
- Updated UPDATE_INTERVAL documentation (removed periodic check reference)

Technical Details:
- _get_current_transformation_config(): Captures all config affecting transformation
- _should_retransform_data(): Intelligent cache invalidation logic
- _should_update_price_data(): Returns bool|"tomorrow_check" to signal delay needed
- Timer handlers use @callback decorator (synchronous, no I/O, fast execution)

Impact: Eliminates asyncio warnings (tasks >0.1s), reduces API load by 50%,
maintains data accuracy through robust cache validation. No user-visible changes.
2025-11-15 18:21:50 +00:00
Julian Pawlowski
503075c443 refactor(config_flow): restructure package to satisfy hassfest validation
Home Assistant's hassfest validation requires config flows to be defined
in a file named config_flow.py (not a package directory).

Changes:
- Renamed custom_components/tibber_prices/config_flow/ → config_flow_handlers/
- Created config_flow.py as bridge file re-exporting from config_flow_handlers/
- Updated all import paths across 5 files (user_flow, options_flow, subentry_flow, etc.)
- Added ./scripts/hassfest for local validation (JSON/Python syntax, required files)
- Added ./scripts/clean with three modes (--minimal, normal, --deep)
- Refactored develop/lint/lint-check to use centralized cleanup (DRY principle)
- Updated documentation in AGENTS.md and docs/development/

Technical details:
- Bridge file uses __all__ exports to maintain clean public API
- hassfest script uses ast.parse() for syntax validation (no disk artifacts)
- clean --minimal removes .egg-info only (silent, for automated scripts)
- Dual pip/uv pip compatibility for package uninstallation

Impact: Integration now passes hassfest validation. Local validation available
via ./scripts/hassfest before pushing to GitHub. Cleanup logic centralized and
DRY across all development scripts.
2025-11-15 17:40:53 +00:00
Julian Pawlowski
decca432df feat(sensors): add timing sensors for best_price and peak_price periods
Added 10 new timing sensors (5 for best_price, 5 for peak_price) to track
period timing and progress:

Timestamp sensors (quarter-hour updates):
- best_price_end_time / peak_price_end_time
  Shows when current/next period ends (always useful reference time)
- best_price_next_start_time / peak_price_next_start_time
  Shows when next period starts (even during active periods)

Countdown sensors (minute updates):
- best_price_remaining_minutes / peak_price_remaining_minutes
  Minutes left in current period (0 when inactive)
- best_price_next_in_minutes / peak_price_next_in_minutes
  Minutes until next period starts
- best_price_progress / peak_price_progress
  Progress percentage through current period (0-100%)

Smart fallback behavior:
- Sensors always show useful values (no 'Unknown' during normal operation)
- Timestamp sensors show current OR next period end/start times
- Countdown sensors return 0 when no period is active
- Grace period: Progress stays at 100% for 60 seconds after period ends

Dynamic visual feedback:
- Progress icons differentiate 3 states at 0%:
  * No data: mdi:help-circle-outline (gray)
  * Waiting for next period: mdi:timer-pause-outline
  * Period just started: mdi:circle-outline
- Progress 1-99%: mdi:circle-slice-1 to mdi:circle-slice-8 (pie chart)
- Timer icons based on urgency (alert/timer/timer-sand/timer-outline)
- Dynamic colors: green (best_price), orange/red (peak_price), gray (disabled)
- icon_color attribute for UI styling

Implementation details:
- Dual update mechanism: quarter-hour (timestamps) + minute (countdowns)
- Period state callbacks: Check if period is currently active
- IconContext dataclass: Reduced function parameters from 6 to 3
- Unit constants: UnitOfTime.MINUTES, PERCENTAGE from homeassistant.const
- Complete translations for 5 languages (de, en, nb, nl, sv)

Impact: Users can now build sophisticated automations based on period timing
('start dishwasher if remaining_minutes > 60'), display countdowns in
dashboards, and get clear visual feedback about period states. All sensors
provide meaningful values at all times, making automation logic simpler.
2025-11-15 17:12:55 +00:00
Julian Pawlowski
22165d038d feat(sensors): add timestamp attributes and enhance icon system
Added timestamp attributes to all sensors and enhanced the dynamic icon
system for comprehensive price sensor coverage with rolling hour support.

TIMESTAMP ATTRIBUTES:

Core Changes:
- sensor/attributes.py:
  * Enhanced add_average_price_attributes() to track extreme intervals
    for min/max sensors and add appropriate timestamps
  * Added _update_extreme_interval() helper to reduce complexity
  * Extended add_volatility_type_attributes() with timestamp logic for
    all 4 volatility types (today/tomorrow/today_tomorrow/next_24h)
  * Fixed current_interval_price timestamp assignment (use interval_data)

Timestamp Logic:
- Interval-based sensors: Use startsAt of specific 15-minute interval
- Min/Max sensors: Use startsAt of interval with extreme price
- Average sensors: Use startsAt of first interval in window
- Volatility sensors: Use midnight (00:00) for calendar day sensors,
  current time for rolling 24h window
- Daily sensors: Already used fallback to midnight (verified)

ICON SYSTEM ENHANCEMENTS:

Major Extensions:
- entity_utils/icons.py:
  * Created get_rolling_hour_price_level_for_icon() implementing
    5-interval window aggregation matching sensor calculation logic
  * Extended get_price_sensor_icon() coverage from 1 to 4 sensors:
    - current_interval_price (existing)
    - next_interval_price (NEW - dynamic instead of static)
    - current_hour_average_price (NEW - uses rolling hour aggregation)
    - next_hour_average_price (NEW - uses rolling hour aggregation)
  * Added imports for aggregate_level_data and find_rolling_hour_center_index

Documentation:
- sensor/definitions.py:
  * Updated 30+ sensor descriptions with detailed icon behavior comments
  * Changed next_interval_price from static to dynamic icon
  * Documented dynamic vs static icons for all sensor types
  * Added clear icon mapping source documentation

SENSOR KEY RENAMING:

Renamed for clarity (current_hour_average → current_hour_average_price):
- sensor/core.py: Updated value getters and cached data lookup
- sensor/definitions.py: Updated entity descriptions
- sensor/attributes.py: Updated key references in attribute builders
- coordinator.py: Updated TIME_SENSITIVE_ENTITY_KEYS set
- const.py: Updated comment documentation

Translation Updates:
- custom_translations/*.json (5 files): Updated sensor keys
- translations/*.json (5 files): Updated sensor keys

Impact:
- All sensors now have timestamp attribute showing applicable time/interval
- Icon system provides richer visual feedback for more sensor types
- Consistent sensor naming improves code readability
- Users get temporal context for all sensor values
- Dynamic icons adapt to price conditions across more sensors
2025-11-15 15:31:43 +00:00
Julian Pawlowski
b32679ba75 feat(translations): add price level and rating states for multiple languages 2025-11-15 14:18:41 +00:00
Julian Pawlowski
e18d653233 feat(sensors): add daily aggregated price level and rating sensors
Added 6 new sensors for yesterday/today/tomorrow aggregated price
levels and ratings, following the same calculation logic as existing
current/next interval sensors.

New sensors:
- yesterday_price_level, today_price_level, tomorrow_price_level
- yesterday_price_rating, today_price_rating, tomorrow_price_rating

Implementation details:
- Added DAILY_LEVEL_SENSORS and DAILY_RATING_SENSORS in sensor/definitions.py
- Implemented _get_daily_aggregated_value() in sensor/core.py using
  existing aggregate_level_data() and aggregate_rating_data() helpers
- Extended icon support in entity_utils/icons.py for dynamic icons
- Added icon_color attributes in sensor/attributes.py with helper
  functions _get_day_key_from_sensor_key() and _add_fallback_timestamp()
- Complete translations in all 5 languages (de, en, nb, nl, sv):
  * Standard translations: sensor names
  * Custom translations: description, long_description, usage_tips

Impact: Users can now see aggregated daily price levels and ratings
for yesterday, today, and tomorrow at a glance, making it easier to
compare overall price situations across days and plan energy consumption
accordingly. Sensors use same aggregation logic as hourly sensors for
consistency.
2025-11-15 13:31:44 +00:00
Julian Pawlowski
1e51b0485b refactor(const): update icon for 'off_no_future' state in BINARY_SENSOR_ICON_MAPPING 2025-11-15 13:08:54 +00:00
Julian Pawlowski
e35970dfcb refactor(const): update icon for 'off_no_future' state in BINARY_SENSOR_ICON_MAPPING 2025-11-15 13:07:04 +00:00
Julian Pawlowski
d90266e1ad refactor(config_flow): split monolithic file into modular package structure
Refactored config_flow.py (995 lines) into focused modules within config_flow/
package to improve maintainability and code organization.

Changes:
- Created config_flow/ package with 6 specialized modules (1,260 lines total)
- Extracted validators to validators.py (95 lines) - pure, testable functions
- Extracted schemas to schemas.py (577 lines) - centralized vol.Schema definitions
- Split flow handlers into separate files:
  * user_flow.py (274 lines) - Main config flow (setup + reauth)
  * subentry_flow.py (124 lines) - Subentry flow (add homes)
  * options_flow.py (160 lines) - Options flow (6-step configuration wizard)
- Package exports via __init__.py (50 lines) for backward compatibility
- Deleted config_flow_legacy.py (no longer needed)

Technical improvements:
- Used Mapping[str, Any] for config_entry.options compatibility
- Proper TYPE_CHECKING imports for circular dependency management
- All 10 inline vol.Schema definitions replaced with reusable functions
- Validators are pure functions (no side effects, easily testable)
- Clear separation of concerns (validation, schemas, flows)

Documentation:
- Updated AGENTS.md with new package structure
- Updated config flow patterns and examples
- Added "Add a new config flow step" guide to Common Tasks
- Marked refactoring plan as COMPLETED with lessons learned

Verification:
- All linting checks pass (./scripts/lint-check)
- All flow handlers import successfully
- Home Assistant loads integration without errors
- All flow types functional (user, subentry, options, reauth)
- No user-facing changes (backward compatible)

Impact: Improves code maintainability by organizing 995 lines into 6 focused
modules (avg 210 lines/module). Enables easier testing, future modifications,
and onboarding of new contributors.
2025-11-15 13:03:13 +00:00
Julian Pawlowski
efda22f7ad refactor(binary_sensor): split into package matching sensor/ structure
Split binary_sensor.py (645 lines) into binary_sensor/ package with
4 modules following the established sensor/ pattern for consistency
and maintainability.

Package structure:
- binary_sensor/__init__.py (32 lines): Platform setup
- binary_sensor/definitions.py (46 lines): ENTITY_DESCRIPTIONS, constants
- binary_sensor/attributes.py (443 lines): Attribute builder functions
- binary_sensor/core.py (282 lines): TibberPricesBinarySensor class

Changes:
- Created binary_sensor/ package with __init__.py importing from .core
- Extracted ENTITY_DESCRIPTIONS and constants to definitions.py
- Moved 13 attribute builders to attributes.py (get_price_intervals_attributes,
  build_async/sync_extra_state_attributes, add_* helpers)
- Moved TibberPricesBinarySensor class to core.py with state logic and
  icon handling
- Used keyword-only parameters to satisfy Ruff PLR0913 (too many args)
- Applied absolute imports (custom_components.tibber_prices.*) in modules

All 4 binary sensors tested and working:
- peak_price_period
- best_price_period
- connection
- tomorrow_data_available

Documentation updated:
- AGENTS.md: Architecture Overview, Component Structure, Common Tasks
- binary-sensor-refactoring-plan.md: Marked  COMPLETED with summary

Impact: Symmetric platform structure (sensor/ ↔ binary_sensor/). Easier
to add new binary sensors following documented pattern. No user-visible
changes.
2025-11-15 12:35:02 +00:00
Copilot
78498a9aec
Fix AttributeError when homes lack active subscriptions (#28)
* Initial plan

* Fix AttributeError for homes without active subscription

Co-authored-by: jpawlowski <75446+jpawlowski@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jpawlowski <75446+jpawlowski@users.noreply.github.com>
2025-11-15 13:08:15 +01:00
Julian Pawlowski
fa40c00f67 refactor(sensors): Transform sensor platform into package 2025-11-15 11:46:54 +00:00
Julian Pawlowski
d2d07d5e16 refactor(sensors): Refactor price sensor calculations and remove unused methods
- Removed the `calculate_current_rolling_5interval_avg` and `calculate_next_hour_rolling_5interval_avg` functions from `average_utils.py` to streamline the codebase.
- Introduced unified methods for retrieving interval values and rolling hour calculations in `sensor.py`, enhancing code reusability and readability.
- Organized sensor definitions into categories based on calculation methods for better maintainability.
- Updated handler methods to utilize the new unified methods, ensuring consistent data retrieval across different sensor types.
- Improved documentation and comments throughout the code to clarify the purpose and functionality of various methods.
2025-11-15 09:29:33 +00:00
Julian Pawlowski
7737dccd49 refactor(sensors): rename current price sensors for clarity
Renamed internal sensor keys to be more explicit about their temporal scope:
- current_price → current_interval_price
- price_level → current_interval_price_level
- price_rating → current_interval_price_rating

This naming makes it clearer that these sensors represent the current
15-minute interval, distinguishing them from hourly averages and other
time-based calculations.

Updated across all components:
- Sensor entity descriptions and handlers (sensor.py)
- Time-sensitive entity keys list (coordinator.py)
- Config flow step IDs (config_flow.py)
- Translation keys in all 5 languages (de, en, nb, nl, sv)
- Custom translations (entity descriptions, usage tips)
- Price level/rating lookups (const.py, sensor.py)
- Documentation examples (AGENTS.md, README.md)

Impact: Sensor entity IDs remain unchanged due to translation_key system.
Existing automations continue to work. Only internal code references and
translation structures updated for consistency.
2025-11-15 08:30:25 +00:00
Julian Pawlowski
c4f36d04de feat(icons): add dynamic icons and colors for all sensor types
Implemented comprehensive dynamic icon and color system across all sensor types:

Price Sensors (5 sensors):
- Current/hour prices: Dynamic cash-family icons based on price level
  (cash-multiple/plus/cash/minus/remove)
- Next/previous: Static contextual icons (cash-fast, cash-refund, clock-fast)
- All have icon_color attribute for card-mod styling

Price Level Sensors (5 sensors):
- Dynamic gauge-family icons: gauge-empty → gauge-low → gauge → gauge-full → alert
- icon_color attribute with CSS variables (green/gray/orange/red)

Price Rating Sensors (5 sensors):
- Dynamic thumb-family icons: thumb-up → thumbs-up-down → thumb-down
- icon_color attribute for LOW/NORMAL/HIGH ratings

Volatility Sensors (4 sensors):
- Dynamic chart-family icons: chart-line-variant → chart-timeline-variant →
  chart-bar → chart-scatter-plot
- icon_color attribute for LOW/MODERATE/HIGH/VERY_HIGH levels

Trend Sensors (8 sensors):
- Dynamic trend icons: trending-up/down/neutral based on price movement
- icon_color attribute (red=rising, green=falling, gray=stable)

Binary Sensors (2 sensors):
- Best Price Period: piggy-bank (ON) / timer-sand or timer-sand-complete (OFF)
- Peak Price Period: alert-circle (ON) / shield-check or shield-check-outline (OFF)
- 6-hour lookahead window for intelligent OFF state icons
- icon_color attribute for all states

Technical implementation:
- PRICE_LEVEL_CASH_ICON_MAPPING in const.py for price sensor icons
- PRICE_SENSOR_ICON_MAPPING removed (static icons now in entity descriptions)
- Centralized icon logic in sensor.py icon property
- All color mappings use CSS variables for theme compatibility
- Binary sensors detect future periods within 6-hour window

Impact: Users now have visual indicators for all price-related states without
requiring card-mod. Optional card-mod styling available via icon_color attribute
for advanced customization. Icons update dynamically as price levels, ratings,
volatility, and trends change throughout the day.
2025-11-14 11:31:25 +00:00
Julian Pawlowski
fe5af68f8e feat(sensor): add icon color determination based on price trend state 2025-11-14 09:52:28 +00:00
Julian Pawlowski
6521aa7bdd feat(sensor): add dynamic icon support for price trend sensors 2025-11-14 09:39:37 +00:00
Julian Pawlowski
3a9234ffbf chore(release): bump version to 0.6.1 2025-11-14 01:14:05 +00:00
Julian Pawlowski
07517660e3 refactor(volatility): migrate to coefficient of variation calculation
Replaced absolute volatility thresholds (ct/øre) with relative coefficient
of variation (CV = std_dev / mean * 100%) for scale-independent volatility
measurement that works across all price levels.

Changes to volatility calculation:
- price_utils.py: Rewrote calculate_volatility_level() to accept price list
  instead of spread value, using statistics.mean() and statistics.stdev()
- sensor.py: Updated volatility sensors to pass price lists (not spread)
- services.py: Modified _get_price_stats() to calculate CV from prices
- period_statistics.py: Extract prices for CV calculation in period summaries
- const.py: Updated default thresholds to 15%/30%/50% (was 5/15/30 ct)
  with comprehensive documentation explaining CV-based approach

Dead code removal:
- period_utils/core.py: Removed filter_periods_by_volatility() function
  (86 lines of code that was never actually called)
- period_utils/__init__.py: Removed dead function export
- period_utils/relaxation.py: Simplified callback signature from
  Callable[[str|None, str|None], bool] to Callable[[str|None], bool]
- coordinator.py: Updated lambda callbacks to match new signature
- const.py: Replaced RELAXATION_VOLATILITY_ANY with RELAXATION_LEVEL_ANY

Bug fix:
- relaxation.py: Added int() conversion for max_relaxation_attempts
  (line 435: attempts = max(1, int(max_relaxation_attempts)))
  Fixes TypeError when config value arrives as float

Configuration UI:
- config_flow.py: Changed volatility threshold unit display from "ct" to "%"

Translations (all 5 languages):
- Updated volatility descriptions to explain coefficient of variation
- Changed threshold labels from "spread ≥ value" to "CV ≥ percentage"
- Languages: de, en, nb, nl, sv

Documentation:
- period-calculation.md: Removed volatility filter section (dead feature)

Impact: Breaking change for users with custom volatility thresholds.
Old absolute values (e.g., 5 ct) will be interpreted as percentages (5%).
However, new defaults (15%/30%/50%) are more conservative and work
universally across all currencies and price levels. No data migration
needed - existing configs continue to work with new interpretation.
2025-11-14 01:12:47 +00:00
Julian Pawlowski
6dc49becb1 chore(release): bump version to 0.6.0 2025-11-14 00:18:32 +00:00
Julian Pawlowski
67270d8fe2 chore(release): bump version to 0.5.1 2025-11-14 00:07:50 +00:00
Julian Pawlowski
5a5c8ca3cc feat(relaxation): make tail handling smarter and attempts configurable
- Skip asymmetry/zigzag rejection near the data tail and refactor spike
  validation so legitimate end-of-day spikes stop breaking periods.
- Expose relaxation attempt sliders for both Best/Peak flows, wire the values
  through the coordinator, and extend the relaxation engine to honor the new
  max-attempt cap with richer logging & metadata.
- Raise the default attempt count to eight flex levels so the 25% increment
  pattern can stretch much further before stopping, keeping translations and
  docs (including the matrix explanation) in sync across all locales.

Impact: Tail spikes no longer get thrown out incorrectly, users can tune how
aggressively the period search relaxes, and the defaults now find more viable
periods on volatile days.
2025-11-14 00:07:12 +00:00
Julian Pawlowski
d3c02568ee fix(build_periods): improve comment clarity for smoothing impact on interval qualification 2025-11-13 23:00:26 +00:00
Julian Pawlowski
a39eb66f49 fix(const): clarify comments on peak price flexibility threshold 2025-11-13 23:00:18 +00:00
Julian Pawlowski
2e7dd64db0 chore(release): bump version to 0.5.0 2025-11-13 22:53:48 +00:00
Julian Pawlowski
383b495545
Feature/adaptive defaults (#22)
* feat(period-calc): adaptive defaults + remove volatility filter

Major improvements to period calculation with smarter defaults and
simplified configuration:

**Adaptive Defaults:**
- ENABLE_MIN_PERIODS: true (was false) - Always try to find periods
- MIN_PERIODS target: 2 periods/day (ensures coverage)
- BEST_PRICE_MAX_LEVEL: "cheap" (was "any") - Prefer genuinely cheap
- PEAK_PRICE_MIN_LEVEL: "expensive" (was "any") - Prefer genuinely expensive
- GAP_TOLERANCE: 1 (was 0) - Allow 1-level deviations in sequences
- MIN_DISTANCE_FROM_AVG: 5% (was 2%) - Ensure significance
- PEAK_PRICE_MIN_PERIOD_LENGTH: 30min (was 60min) - More responsive
- PEAK_PRICE_FLEX: -20% (was -15%) - Better peak detection

**Volatility Filter Removal:**
- Removed CONF_BEST_PRICE_MIN_VOLATILITY from const.py
- Removed CONF_PEAK_PRICE_MIN_VOLATILITY from const.py
- Removed volatility filter UI controls from config_flow.py
- Removed filter_periods_by_volatility() calls from coordinator.py
- Updated all 5 translations (de, en, nb, nl, sv)

**Period Calculation Logic:**
- Level filter now integrated into _build_periods() (applied during
  interval qualification, not as post-filter)
- Gap tolerance implemented via _check_level_with_gap_tolerance()
- Short periods (<1.5h) use strict filtering (no gap tolerance)
- Relaxation now passes level_filter + gap_count directly to
  PeriodConfig
- show_periods check skipped when relaxation enabled (relaxation
  tries "any" as fallback)

**Documentation:**
- Complete rewrite of docs/user/period-calculation.md:
  * Visual examples with timelines
  * Step-by-step explanation of 4-step process
  * Configuration scenarios (5 common use cases)
  * Troubleshooting section with specific fixes
  * Advanced topics (per-day independence, early stop, etc.)
- Updated README.md: "volatility" → "distance from average"

Impact: Periods now reliably appear on most days with meaningful
quality filters. Users get warned about expensive periods and notified
about cheap opportunities without manual tuning. Relaxation ensures
coverage while keeping filters as strict as possible.

Breaking change: Volatility filter removed (was never a critical
feature, often confused users). Existing configs continue to work
(removed keys are simply ignored).

* feat(periods): modularize period_utils and add statistical outlier filtering

Refactored monolithic period_utils.py (1800 lines) into focused modules
for better maintainability and added advanced outlier filtering with
smart impact tracking.

Modular structure:
- types.py: Type definitions and constants (89 lines)
- level_filtering.py: Level filtering with gap tolerance (121 lines)
- period_building.py: Period construction from intervals (238 lines)
- period_statistics.py: Statistics and summaries (318 lines)
- period_merging.py: Overlap resolution (382 lines)
- relaxation.py: Per-day relaxation strategy (547 lines)
- core.py: Main API orchestration (251 lines)
- outlier_filtering.py: Statistical spike detection (294 lines)
- __init__.py: Public API exports (62 lines)

New statistical outlier filtering:
- Linear regression for trend-based spike detection
- 2 standard deviation confidence intervals (95%)
- Symmetry checking to preserve legitimate price shifts
- Enhanced zigzag detection with relative volatility (catches clusters)
- Replaces simple average smoothing with trend-based predictions

Smart impact tracking:
- Tests if original price would have passed criteria
- Only counts smoothed intervals that actually changed period formation
- Tracks level gap tolerance usage separately
- Both attributes only appear when > 0 (clean UI)

New period attributes:
- period_interval_smoothed_count: Intervals kept via outlier smoothing
- period_interval_level_gap_count: Intervals kept via gap tolerance

Impact: Statistical outlier filtering prevents isolated price spikes from
breaking continuous periods while preserving data integrity. All statistics
use original prices. Smart tracking shows only meaningful interventions,
making it clear when tolerance mechanisms actually influenced results.

Backwards compatible: All public APIs re-exported from period_utils package.

* Update docs/user/period-calculation.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update custom_components/tibber_prices/const.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update custom_components/tibber_prices/coordinator.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update custom_components/tibber_prices/const.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* docs(periods): fix corrupted period-calculation.md and add outlier filtering documentation

Completely rewrote period-calculation.md after severe corruption (massive text
duplication throughout the file made it 2489 lines).

Changes:
- Fixed formatting: Removed all duplicate text and headers
- Reduced file size: 2594 lines down to 516 lines (clean, readable structure)
- Added section 5: "Statistical Outlier Filtering (NEW)" explaining:
  - Linear regression-based spike detection (95% confidence intervals)
  - Symmetry checking to preserve legitimate price shifts
  - Enhanced zigzag detection with relative volatility
  - Data integrity guarantees (original prices always used)
  - New period attributes: period_interval_smoothed_count
- Added troubleshooting: "Price spikes breaking periods" section
- Added technical details: Algorithm constants and implementation notes

Impact: Users can now understand how outlier filtering prevents isolated
price spikes from breaking continuous periods. Documentation is readable
again with no duplicate content.

* fix(const): improve clarity in comments regarding period lengths for price alerts

* docs(periods): improve formatting and clarity in period-calculation.md

* Initial plan

* refactor: convert flexibility_pct to ratio once at function entry

Co-authored-by: jpawlowski <75446+jpawlowski@users.noreply.github.com>

* Update custom_components/tibber_prices/const.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update custom_components/tibber_prices/period_utils/period_building.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update custom_components/tibber_prices/period_utils/relaxation.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Julian Pawlowski <jpawlowski@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2025-11-13 23:51:29 +01:00
Julian Pawlowski
3f43bb4bc0 chore(release): bump version to 0.4.1 2025-11-11 21:22:36 +00:00
Julian Pawlowski
aa58c6718f refactor(period_utils): implement per-day relaxation with 4×4 matrix strategy
Restructured relaxation mechanism to process each day independently instead
of globally, enabling different days to relax at different levels.

Key changes:
- Added hierarchical logging with INDENT_L0-L5 constants
- Replaced global relaxation loop with per-day relaxation (_relax_single_day)
- Implemented 4×4 matrix strategy (4 flex levels × 4 filter combinations)
- Enhanced _resolve_period_overlaps with replacement and extension logic
- Added helper functions: _group_periods_by_day, _group_prices_by_day,
  _check_min_periods_per_day

Relaxation strategy:
- Each flex level tries 4 filter combinations before increasing flex
- Early exit after EACH successful combination (minimal relaxation)
- Extensions preserve baseline metadata, replacements use relaxed metadata
- Only standalone periods count toward min_periods requirement

Impact: Users get more accurate period detection per day. Days with clear
cheap/expensive patterns use strict filters while difficult days relax as
needed. Reduces over-relaxation - finds 'good enough' solutions faster.
2025-11-11 21:21:56 +00:00
Julian Pawlowski
7605e88b96 refactor(period_utils): simplify period qualification logic by removing average boundary check 2025-11-10 14:58:16 +00:00
Julian Pawlowski
6a77572f4e refactor(docs): update references from copilot-instructions.md to AGENTS.md across documentation 2025-11-10 14:09:40 +00:00
Julian Pawlowski
6e1a3e37c5 chore(release): bump version to 0.4.0 2025-11-10 12:15:58 +00:00
Julian Pawlowski
817658f230 feat(periods): add gap tolerance for price level filters with intelligent period splitting
Implemented configurable gap tolerance (0-8 intervals) for best price and peak price
level filters to prevent periods from being split by occasional level deviations.

Key features:
- Gap tolerance only applies to periods ≥ MIN_INTERVALS_FOR_GAP_TOLERANCE (1.5h)
- Short periods (< 1.5h) use strict filtering (zero tolerance)
- Dynamic minimum distance between gaps: max(2, (interval_count // max_gap_count) // 2)
- 25% maximum cap on total gaps to prevent excessive outliers in long periods
- Intelligent period splitting at gap clusters (2+ consecutive non-qualifying intervals)
- Each sub-period independently validated with same gap tolerance rules

Technical implementation:
- Added CONF_BEST_PRICE_MAX_LEVEL_GAP_COUNT and CONF_PEAK_PRICE_MAX_LEVEL_GAP_COUNT constants
- Added MIN_INTERVALS_FOR_GAP_TOLERANCE = 6 (1.5h minimum for gap tolerance)
- Implemented _split_at_gap_clusters() for period recovery
- Implemented _check_short_period_strict() for strict short-period filtering
- Implemented _check_level_filter_with_gaps() with fallback splitting logic
- Extracted _check_sequence_with_gap_tolerance() for reusable core validation
- Enhanced _check_level_filter() to use gap-tolerant validation

Configuration UI:
- Added NumberSelector (0-8, slider mode) for gap count in config flow
- Added translations for all 5 languages (de, en, nb, nl, sv)
- Default: 0 (strict filtering, backwards compatible)

Impact: Users can now configure how many occasional level deviations are acceptable
within qualifying price periods. This reduces period fragmentation while maintaining
meaningful price-based filtering. Long periods are protected by the 25% cap, and
gap clusters trigger intelligent splitting to recover usable sub-periods.
2025-11-10 04:38:44 +00:00
Julian Pawlowski
40a335dabe feat(periods): add adaptive filter relaxation for minimum period guarantee
Implemented multi-phase filter relaxation system to ensure minimum number
of best-price and peak-price periods are found, even on days with unusual
price patterns.

New configuration options per period type (best/peak):
- enable_min_periods_{best|peak}: Toggle feature on/off
- min_periods_{best|peak}: Target number of periods (default: 2)
- relaxation_step_{best|peak}: Step size for threshold increase (default: 25%)

Relaxation phases (applied sequentially until target reached):
1. Flex threshold increase (up to 4 steps, e.g., 15% → 18.75% → 22.5% → ...)
2. Volatility filter bypass + continued flex increase
3. All filters off + continued flex increase

Changes to period calculation:
- New calculate_periods_with_relaxation() wrapper function
- filter_periods_by_volatility() now applies post-calculation filtering
- _resolve_period_overlaps() merges baseline + relaxed periods intelligently
- Relaxed periods marked with relaxation_level, relaxation_threshold_* attributes
- Overlap detection prevents double-counting same intervals

Binary sensor attribute ordering improvements:
- Added helper methods for consistent attribute priority
- Relaxation info grouped in priority 6 (after detail attributes)
- Only shown when period was actually relaxed (relaxation_active=true)

Translation updates:
- Added UI labels + descriptions for 6 new config options (all 5 languages)
- Explained relaxation concept with examples in data_description fields
- Clarified volatility filter now applies per-period, not per-day

Impact: Users can configure integration to guarantee minimum number of
periods per day. System automatically relaxes filters when needed while
preserving baseline periods found with strict filters. Particularly useful
for automation reliability on days with flat pricing or unusual patterns.

Fixes edge case where no periods were found despite prices varying enough
for meaningful optimization decisions.
2025-11-10 03:34:09 +00:00
Julian Pawlowski
9640b041e0 refactor(periods): move all period logic to coordinator and refactor period_utils
Moved filter logic and all period attribute calculations from binary_sensor.py
to coordinator.py and period_utils.py, following Home Assistant best practices
for data flow architecture.

ARCHITECTURE CHANGES:

Binary Sensor Simplification (~225 lines removed):
- Removed _build_periods_summary, _add_price_diff_for_period (calculation logic)
- Removed _get_period_intervals_from_price_info (107 lines, interval reconstruction)
- Removed _should_show_periods, _check_volatility_filter, _check_level_filter
- Removed _build_empty_periods_result (filtering result builder)
- Removed _get_price_hours_attributes (24 lines, dead code)
- Removed datetime import (unused after cleanup)
- New: _build_final_attributes_simple (~20 lines, timestamp-only)
- Result: Pure display-only logic, reads pre-calculated data from coordinator

Coordinator Enhancement (+160 lines):
- Added _should_show_periods(): UND-Verknüpfung of volatility and level filters
- Added _check_volatility_filter(): Checks min_volatility threshold
- Added _check_level_filter(): Checks min/max level bounds
- Enhanced _calculate_periods_for_price_info(): Applies filters before period calculation
- Returns empty periods when filters don't match (instead of calculating unnecessarily)
- Passes volatility thresholds (moderate/high/very_high) to PeriodConfig

Period Utils Refactoring (+110 lines):
- Extended PeriodConfig with threshold_volatility_moderate/high/very_high
- Added PeriodData NamedTuple: Groups timing data (start, end, length, position)
- Added PeriodStatistics NamedTuple: Groups calculated stats (prices, volatility, ratings)
- Added ThresholdConfig NamedTuple: Groups all thresholds + reverse_sort flag
- New _calculate_period_price_statistics(): Extracts price_avg/min/max/spread calculation
- New _build_period_summary_dict(): Builds final dict with correct attribute ordering
- Enhanced _extract_period_summaries(): Now calculates ALL attributes (no longer lightweight):
  * price_avg, price_min, price_max, price_spread (in minor units: ct/øre)
  * volatility (low/moderate/high/very_high based on absolute thresholds)
  * rating_difference_% (average of interval differences)
  * period_price_diff_from_daily_min/max (period avg vs daily reference)
  * aggregated level and rating_level
  * period_interval_count (renamed from interval_count for clarity)
- Removed interval_starts array (redundant - start/end/count sufficient)
- Function signature refactored from 9→4 parameters using NamedTuples

Code Organization (HA Best Practice):
- Moved calculate_volatility_level() from const.py to price_utils.py
- Rule: const.py should contain only constants, no functions
- Removed duplicate VOLATILITY_THRESHOLD_* constants from const.py
- Updated imports in sensor.py, services.py, period_utils.py

DATA FLOW:

Before:
API → Coordinator (basic enrichment) → Binary Sensor (calculate everything on each access)

After:
API → Coordinator (enrichment + filtering + period calculation with ALL attributes) →
      Cached Data → Binary Sensor (display + timestamp only)

ATTRIBUTE STRUCTURE:

Period summaries now contain (following copilot-instructions.md ordering):
1. Time: start, end, duration_minutes
2. Decision: level, rating_level, rating_difference_%
3. Prices: price_avg, price_min, price_max, price_spread, volatility
4. Differences: period_price_diff_from_daily_min/max (conditional)
5. Details: period_interval_count, period_position
6. Meta: periods_total, periods_remaining

BREAKING CHANGES: None
- Period data structure enhanced but backwards compatible
- Binary sensor API unchanged (state + attributes)

Impact: Binary sensors now display pre-calculated data from coordinator instead
of calculating on every access. Reduces complexity, improves performance, and
centralizes business logic following Home Assistant coordinator pattern. All
period filtering (volatility + level) now happens in coordinator before caching.
2025-11-09 23:46:48 +00:00
Julian Pawlowski
b36a94d53b feat(translations): update language style and tone for user instructions across multiple languages 2025-11-09 19:27:42 +00:00
Julian Pawlowski
900e77203a chore(release): bump version to 0.3.0 2025-11-09 16:06:34 +00:00
Julian Pawlowski
ae82e4637c fix: handle missing entry_id in reauth flow and ensure integration version is a string 2025-11-09 16:04:18 +00:00
Julian Pawlowski
da5a723777 fix: update return type annotation for API request method and ensure exceptions are raised 2025-11-09 16:04:12 +00:00
Julian Pawlowski
12fbe33bb9 fix: handle unknown integration version in setup entry 2025-11-09 16:04:04 +00:00
Julian Pawlowski
7e57facf50 fix(translations): restore corrupted Norwegian and Dutch translations
Restored valid Norwegian (nb) and Dutch (nl) translations from git
commit 5e0a297 after corruption caused JSON parsing errors.

Added 4 missing volatility sensor translations to both languages:
- today_volatility
- tomorrow_volatility
- next_24h_volatility
- today_tomorrow_volatility

All translations include complete description, long_description, and
usage_tips fields.

Impact: Norwegian and Dutch users now see complete, properly translated
sensor descriptions. JSON validation passes without errors.
2025-11-09 15:31:56 +00:00
Julian Pawlowski
532a91be58 fix(translations): resolve hassfest selector key validation errors
Changed all selector option keys from uppercase to lowercase to comply
with Home Assistant's hassfest validation pattern [a-z0-9-_]+.

Fixed inconsistency in PEAK_PRICE_MIN_LEVEL_OPTIONS where some values
were uppercase while others were lowercase.

Changes:
- translations/*.json: All selector keys now lowercase (volatility, price_level)
- const.py: Added .lower() to all PEAK_PRICE_MIN_LEVEL_OPTIONS values
- binary_sensor.py: Added .upper() conversion when looking up price levels
  in PRICE_LEVEL_MAPPING to handle lowercase config values

Impact: Config flow now works correctly with translated selector options.
Hassfest validation passes without selector key errors.
2025-11-09 15:31:37 +00:00
Julian Pawlowski
f4568be34e feat(sensors): add price volatility analysis and period filters
Added comprehensive volatility analysis system:
- 4 new volatility sensors (today, tomorrow, next_24h, today+tomorrow)
- Volatility classification (LOW/MODERATE/HIGH/VERY HIGH) based on price spread
- Configurable thresholds in options flow (step 6 of 6)
- Best/Peak price period filters using volatility and price level
- Price spread calculation in get_price service

Volatility sensors help users decide if price-based optimization is worthwhile.
For example, battery optimization only makes sense when volatility ≥ MODERATE.

Period filters allow AND-logic combinations:
- best_price_min_volatility: Only show cheap periods on volatile days
- best_price_max_level: Only show periods when prices reach desired level
- peak_price_min_volatility: Only show peaks on volatile days
- peak_price_min_level: Only show peaks when expensive levels occur

All 5 language files updated (de, en, nb, nl, sv) with:
- Volatility sensor translations (name, states, descriptions)
- Config flow step 6 "Volatility" with threshold settings
- Step progress indicators added to all config steps
- Period filter translations with usage tips

Impact: Users can now assess daily price volatility and configure period
sensors to only activate when conditions justify battery cycling or load
shifting. Reduces unnecessary battery wear on low-volatility days.
2025-11-09 14:24:34 +00:00
Julian Pawlowski
32e429624e refactor: Adjust suggested display precision for future average price sensors and add timestamp attributes for next average calculations 2025-11-08 17:06:19 +00:00
Julian Pawlowski
ac100216ee refactor: Update attribute naming and ordering for clarity and consistency 2025-11-08 16:50:55 +00:00
Julian Pawlowski
db0d65a939 feat: Add price trend thresholds configuration and update related calculations 2025-11-08 16:02:21 +00:00
Julian Pawlowski
5ba0633d15 refactor: Store trend attributes in a sensor-specific dictionary for better organization 2025-11-08 15:30:55 +00:00
Julian Pawlowski
f9f4908748 refactor: Enhance period calculations with aggregated levels and ratings 2025-11-08 15:01:25 +00:00
Julian Pawlowski
db3299b7a7 Add period calculation for best and peak prices
- Introduced a new utility module `period_utils.py` for calculating price periods.
- Implemented `_get_period_config` method to retrieve configuration for best and peak price calculations.
- Added `_calculate_periods_for_price_info` method to compute best and peak price periods based on price data.
- Enhanced `TibberPricesDataUpdateCoordinator` to include calculated periods in the data transformation methods.
- Updated configuration constants for best and peak price settings.
2025-11-08 14:26:46 +00:00
Julian Pawlowski
3f3edd8a28 refactor: Update price level and rating options to inline definitions for sensor initialization 2025-11-08 09:24:28 +00:00
Julian Pawlowski
9c6ebc45ec chore: Bump version to 0.2.0 2025-11-07 23:45:28 +00:00
Julian Pawlowski
df9fb37fe4 refactor: Update integration version handling in TibberPrices components 2025-11-07 23:43:39 +00:00
Julian Pawlowski
3df68db20b refactor: Update interval attribute keys and improve period merging logic in TibberPricesBinarySensor 2025-11-07 23:31:29 +00:00
Julian Pawlowski
ca88f136c3 feat: Implement time-sensitive updates for Tibber price sensors and binary sensors 2025-11-07 21:02:11 +00:00
Julian Pawlowski
1ed2c08f34 feat: Add minimum period length configuration for best and peak price sensors 2025-11-07 15:16:16 +00:00
Julian Pawlowski
f4ae8422f2 fix: Update trend percentage attribute key format in TibberPricesSensor 2025-11-07 14:49:36 +00:00
Julian Pawlowski
19063daa72 fix: Remove unused model_id attribute from TibberPricesEntity 2025-11-07 14:45:33 +00:00
Julian Pawlowski
40852b7d84 fix: Update reauthentication titles for Tibber Price integration in multiple languages 2025-11-07 11:13:42 +00:00
Julian Pawlowski
5e0a297a8f Update Dutch and Swedish translations for Tibber Prices integration
- Revised various phrases for clarity and consistency in Dutch (nl.json) and Swedish (sv.json) translations.
- Changed terms from "woning" to "huis" in Dutch for better contextual accuracy.
- Improved readability and grammatical correctness in both languages.
- Ensured all user-facing strings are updated to reflect the latest terminology and phrasing.
2025-11-06 22:53:20 +00:00
Julian Pawlowski
ef1a81ccc1 Refactor translations for electricity prices in multiple languages
- Updated keys from "cents" to more user-friendly terms for current, next, and previous prices.
- Added state descriptions for price levels and ratings, including categories like "very cheap," "cheap," "normal," "expensive," and "very expensive."
- Introduced new average price sensors for the next 1 to 12 hours.
- Added price trend sensors for 1 to 12 hours with states indicating rising, falling, or stable trends.
- Ensured consistency in naming conventions across English, Norwegian, Dutch, and Swedish translations.
2025-11-06 22:36:12 +00:00
Julian Pawlowski
76e5a0fc58 feat: Add function to calculate average price for the next N hours 2025-11-06 22:35:53 +00:00
Julian Pawlowski
4d77d6d824 fix: Change integration type from service to hub in manifest.json 2025-11-06 17:04:10 +00:00
Julian Pawlowski
433558f60b feat: Implement reauthentication flow 2025-11-06 16:59:41 +00:00
Julian Pawlowski
3ef588b1f4 fix: Update German translations for peak and best price period labels 2025-11-06 16:01:41 +00:00
Julian Pawlowski
96df4882e0 Add Norwegian, Dutch, and Swedish translations for Tibber Prices integration 2025-11-06 12:03:03 +00:00
Julian Pawlowski
63904fff39 feat: Enhance Tibber Prices integration with new configuration options and improved data handling
- Added new configuration options for minimum distance from average price for best and peak prices.
- Updated default values for best and peak price flexibility.
- Improved coordinator to handle midnight turnover and data rotation more effectively.
- Refactored entity initialization to streamline device information retrieval.
- Updated sensor attributes to use more descriptive names for price values.
- Enhanced translations for new configuration options in English and German.
- Improved unit tests for coordinator functionality, ensuring proper cleanup and async handling.
2025-11-06 11:43:22 +00:00
Julian Pawlowski
f7991ae71c fix 2025-11-03 22:26:51 +00:00
Julian Pawlowski
af3e112c99 update translations 2025-11-03 22:11:19 +00:00
Julian Pawlowski
17a20fbb39 update default values 2025-11-03 22:04:14 +00:00
Julian Pawlowski
2f7b48e177 update currency 2025-11-03 21:31:38 +00:00
Julian Pawlowski
8790ac8a41 fix 2025-11-03 21:13:50 +00:00
Julian Pawlowski
bba5f180b0 add lots of new sensors 2025-11-03 20:55:28 +00:00
Julian Pawlowski
6040a19136 update dev environment 2025-11-03 15:54:01 +00:00
Julian Pawlowski
5ee780da87 update translations 2025-11-03 09:53:19 +00:00
Julian Pawlowski
02adf47faf fix translations 2025-11-03 00:47:50 +00:00
Julian Pawlowski
a4a8fc5707 fix manifest order 2025-11-03 00:47:45 +00:00
Julian Pawlowski
d749016f3a fix sorting order 2025-11-03 00:44:25 +00:00
Julian Pawlowski
a0700790ed fix manifest 2025-11-03 00:38:19 +00:00
Julian Pawlowski
79556768cc fix linting errors 2025-11-03 00:32:27 +00:00
Julian Pawlowski
d3c91e162a fix 2025-11-03 00:15:03 +00:00
Julian Pawlowski
1f5c8fead8 fix 2025-11-03 00:07:46 +00:00
Julian Pawlowski
65e8bdbd15 fix 2025-11-03 00:03:58 +00:00
Julian Pawlowski
3b87cc67e5 fix reload 2025-11-02 23:53:16 +00:00
Julian Pawlowski
54d0359be8 fix 2025-11-02 23:45:05 +00:00
Julian Pawlowski
097c3c63c0 fix 2025-11-02 23:37:19 +00:00
Julian Pawlowski
1b452b72fb fix midnight turnover 2025-11-02 23:27:44 +00:00
Julian Pawlowski
ef05929247 fix entity update 2025-11-02 23:14:26 +00:00
Julian Pawlowski
9fd196948c remove priceRating API relations 2025-11-02 22:30:01 +00:00
Julian Pawlowski
4f6d429132 refactoring for QUARTER_HOURLY prices 2025-11-02 20:22:29 +00:00
Julian Pawlowski
8c61292acf refactoring for QUARTER_HOURLY prices 2025-11-02 19:33:19 +00:00
Julian Pawlowski
70b5a0acd1 fix services 2025-11-02 17:50:50 +00:00
Julian Pawlowski
0eaeaaf708 fix rating data 2025-11-02 17:38:06 +00:00
Julian Pawlowski
6b3d299d3d fix options flow 2025-11-02 17:27:37 +00:00
Julian Pawlowski
e02630440a fix options flow 2025-11-02 16:58:47 +00:00
Julian Pawlowski
0ffa17679b fix config flow 2025-11-02 15:46:13 +00:00
Julian Pawlowski
88ed07c4c0 fix 2025-11-02 12:13:20 +00:00
Julian Pawlowski
f57fdfde6b update 2025-05-25 22:15:25 +00:00
Julian Pawlowski
bd33fc7367 config 2025-05-24 20:50:17 +00:00
Julian Pawlowski
b5c278920c refactoring config flow 2025-05-24 20:50:07 +00:00
Julian Pawlowski
5bb8af942e fix 2025-05-24 17:35:55 +00:00
Julian Pawlowski
86c8073a51 fix 2025-05-24 13:59:46 +00:00
Julian Pawlowski
130b51f5b6 fix 2025-05-24 12:07:54 +00:00
Julian Pawlowski
862dfcb158 fix 2025-05-21 15:14:55 +00:00
Julian Pawlowski
defd6ad92c fix 2025-05-21 11:54:49 +00:00
Julian Pawlowski
8c43f2750f fix 2025-05-21 11:29:50 +00:00
Julian Pawlowski
b23697036a fix 2025-05-21 02:37:41 +00:00
Julian Pawlowski
2ef3217518 fix 2025-05-20 23:35:56 +00:00
Julian Pawlowski
dd65f0efad fix 2025-05-20 23:19:45 +00:00
Julian Pawlowski
0a11f38a1b fix 2025-05-20 20:44:35 +00:00
Julian Pawlowski
a375026e07 refactoring 2025-05-20 20:28:35 +00:00
Julian Pawlowski
1d1f6ec3ca fix 2025-05-20 19:25:10 +00:00
Julian Pawlowski
069490d8cd fix 2025-05-20 18:55:10 +00:00
Julian Pawlowski
76d2e2bb2b fix 2025-05-20 17:57:49 +00:00
Julian Pawlowski
3d37ace85e refactoring 2025-05-20 12:43:12 +00:00
Julian Pawlowski
adc11b0e4d refactoring 2025-05-20 10:41:01 +00:00
Julian Pawlowski
da4ef5675a fix 2025-05-19 10:05:17 +00:00
Julian Pawlowski
1f8158ecea fix 2025-05-19 09:51:52 +00:00
Julian Pawlowski
71b81a9812 refactoring 2025-05-18 14:11:27 +00:00
Julian Pawlowski
1dc2457564 fix rotation 2025-05-17 22:30:49 +00:00
Julian Pawlowski
0116d5ad62 refactoring 2025-05-17 21:59:04 +00:00
Julian Pawlowski
7c4ae98417 refactoring 2025-05-17 20:01:39 +00:00
Julian Pawlowski
52cfc4a87f refactoring 2025-05-17 17:39:06 +00:00
Julian Pawlowski
a4859a9d2e
refactoring 2025-05-11 13:21:22 +02:00
Julian Pawlowski
94ef6ed4a6 add friendly name 2025-04-23 23:53:11 +00:00
Julian Pawlowski
02a226819a refactoring 2025-04-23 23:07:30 +00:00
Julian Pawlowski
3d33d8d6bc add descriptions 2025-04-23 21:13:57 +00:00
Julian Pawlowski
51b028e9b7 add descriptions 2025-04-23 20:18:35 +00:00
Julian Pawlowski
ed779f03f0 refactoring 2025-04-23 20:00:17 +00:00
Julian Pawlowski
c67ec09c9a refactoring 2025-04-23 18:51:40 +00:00
Julian Pawlowski
59cd48977b add copilot instructions 2025-04-23 17:46:12 +00:00
Julian Pawlowski
dd94351278 refactoring 2025-04-23 16:42:31 +00:00
Julian Pawlowski
eeff264ae7 commit changes 2025-04-21 19:59:03 +00:00
Julian Pawlowski
23a46faecc add some entities 2025-04-21 19:36:32 +00:00
Julian Pawlowski
5150ae3f48 refactoring 2025-04-21 18:07:50 +00:00
Julian Pawlowski
385ea6c1de expose config_entry 2025-04-18 22:30:39 +00:00
Julian Pawlowski
aa92de42da add update schedule 2025-04-18 22:10:52 +00:00
Julian Pawlowski
f06b9ff0cf add cleanup 2025-04-18 21:37:48 +00:00
Julian Pawlowski
f092ad2839 add data retrieving 2025-04-18 21:14:36 +00:00
Julian Pawlowski
5f8abf3a63 refactoring 2025-04-18 17:08:08 +00:00
Julian Pawlowski
73fa6c18a7 add authentication 2025-04-18 16:10:14 +00:00
Julian Pawlowski
ef38bf75b5 rename functions 2025-04-18 14:12:10 +00:00
Julian Pawlowski
8123285489 rename directory 2025-04-18 13:16:59 +00:00
Julian Pawlowski
dea7cfee43 Rename component 2025-04-18 12:51:32 +00:00
Julian Pawlowski
131a4eb148
Initial commit 2025-04-18 14:32:54 +02:00