mirror of
https://github.com/jpawlowski/hass.tibber_prices.git
synced 2026-03-30 05:13:40 +00:00
Best Price min_distance now uses negative values (-50 to 0) to match semantic meaning "below average". Peak Price continues using positive values (0 to 50) for "above average". Uniform formula: avg * (1 + distance/100) works for both period types. Sign indicates direction: negative = toward MIN (cheap), positive = toward MAX (expensive). Changes: - const.py: DEFAULT_BEST_PRICE_MIN_DISTANCE_FROM_AVG = -5 (was 5) - schemas.py: Best Price range -50 to 0, Peak Price range 0 to 50 - validators.py: Separate validate_best_price_distance_percentage() - level_filtering.py: Simplified to uniform formula (removed conditionals) - translations: Separate error messages for Best/Peak distance validation - tests: 37 comprehensive validator tests (100% coverage) Impact: Configuration UI now visually represents direction relative to average. Users see intuitive negative values for "below average" pricing.
920 lines
No EOL
48 KiB
JSON
920 lines
No EOL
48 KiB
JSON
{
|
||
"config": {
|
||
"step": {
|
||
"user": {
|
||
"description": "Set up Tibber Price Information & Ratings.\n\nTo generate an API access token, visit https://developer.tibber.com.",
|
||
"data": {
|
||
"access_token": "API access token"
|
||
},
|
||
"submit": "Validate Token"
|
||
},
|
||
"select_home": {
|
||
"description": "Select a home to fetch price information and ratings.",
|
||
"data": {
|
||
"home_id": "Home"
|
||
},
|
||
"title": "Pick a Home",
|
||
"submit": "Select Home"
|
||
},
|
||
"finish": {
|
||
"description": "Select a home to fetch price information and ratings.",
|
||
"data": {
|
||
"home_id": "Home ID"
|
||
},
|
||
"title": "Pick a home",
|
||
"submit": "Select Home"
|
||
},
|
||
"reauth_confirm": {
|
||
"title": "Reauthenticate Tibber Price Integration",
|
||
"description": "The access token for Tibber is no longer valid. Please enter a new API access token to continue using this integration.\n\nTo generate a new API access token, visit https://developer.tibber.com.",
|
||
"data": {
|
||
"access_token": "API access token"
|
||
},
|
||
"submit": "Update Token"
|
||
}
|
||
},
|
||
"error": {
|
||
"auth": "The Tibber Access Token is invalid.",
|
||
"connection": "Unable to connect to Tibber. Please check your internet connection.",
|
||
"unknown": "Unexpected error",
|
||
"cannot_connect": "Failed to connect",
|
||
"invalid_access_token": "Invalid access token",
|
||
"missing_homes": "The new access token does not have access to all configured homes. Please use an access token that has access to the same Tibber homes.",
|
||
"invalid_yaml_syntax": "Invalid YAML syntax. Please check indentation, colons, and special characters.",
|
||
"invalid_yaml_structure": "YAML must be a dictionary/object (key: value pairs), not a list or plain text.",
|
||
"service_call_failed": "Service call validation failed: {error_detail}"
|
||
},
|
||
"abort": {
|
||
"already_configured": "Integration is already configured",
|
||
"entry_not_found": "Tibber configuration entry not found.",
|
||
"setup_complete": "Setup complete! You can change additional options for Tibber Prices in the integration's options after closing this dialog.",
|
||
"reauth_successful": "Reauthentication successful. The integration has been updated with the new access token."
|
||
}
|
||
},
|
||
"common": {
|
||
"step_progress": "{step_num} / {total_steps}"
|
||
},
|
||
"config_subentries": {
|
||
"home": {
|
||
"initiate_flow": {
|
||
"user": "Add Tibber Home"
|
||
},
|
||
"title": "Add Tibber Home",
|
||
"step": {
|
||
"user": {
|
||
"title": "Add Tibber Home",
|
||
"description": "Select a home to add to your Tibber integration.\n\n**Note:** After adding this home, you can add additional homes from the integration's context menu by selecting \"Add Tibber Home\".",
|
||
"data": {
|
||
"home_id": "Home"
|
||
}
|
||
}
|
||
},
|
||
"error": {
|
||
"api_error": "Failed to fetch homes from Tibber API"
|
||
},
|
||
"abort": {
|
||
"no_parent_entry": "Parent entry not found",
|
||
"no_access_token": "No access token available",
|
||
"home_not_found": "Selected home not found",
|
||
"api_error": "Failed to fetch homes from Tibber API",
|
||
"no_available_homes": "No additional homes available to add. All homes from your Tibber account have already been added."
|
||
}
|
||
}
|
||
},
|
||
"options": {
|
||
"step": {
|
||
"init": {
|
||
"title": "⚙️ General Settings",
|
||
"description": "_{step_progress}_\n\n**Configure general settings for Tibber Price Information & Ratings.**\n\n---\n\n**User:** {user_login}",
|
||
"data": {
|
||
"extended_descriptions": "Extended Descriptions"
|
||
},
|
||
"data_description": {
|
||
"extended_descriptions": "Controls whether entity attributes include detailed explanations and usage tips.\n\n• Disabled (default): Brief description only\n• Enabled: Detailed explanation + practical usage examples\n\nExample:\nDisabled = 1 attribute\nEnabled = 2 additional attributes"
|
||
},
|
||
"submit": "Continue →"
|
||
},
|
||
"current_interval_price_rating": {
|
||
"title": "📊 Price Rating Thresholds",
|
||
"description": "_{step_progress}_\n\n**Configure thresholds for price rating levels (low/normal/high) based on comparison with trailing 24-hour average.**\n\n---",
|
||
"data": {
|
||
"price_rating_threshold_low": "Low Threshold",
|
||
"price_rating_threshold_high": "High Threshold"
|
||
},
|
||
"data_description": {
|
||
"price_rating_threshold_low": "Percentage below the trailing 24-hour average that the current price must be to qualify as 'low' rating. Example: 5 means at least 5% below average. Sensors with this rating indicate favorable time windows. Default: 5%",
|
||
"price_rating_threshold_high": "Percentage above the trailing 24-hour average that the current price must be to qualify as 'high' rating. Example: 10 means at least 10% above average. Sensors with this rating warn about expensive time windows. Default: 10%"
|
||
},
|
||
"submit": "Continue →"
|
||
},
|
||
"best_price": {
|
||
"title": "💚 Best Price Period Settings",
|
||
"description": "_{step_progress}_\n\n**Configure settings for the Best Price Period binary sensor. This sensor is active during periods with the lowest electricity prices.**\n\n---",
|
||
"data": {
|
||
"best_price_min_period_length": "Minimum Period Length",
|
||
"best_price_flex": "Flexibility",
|
||
"best_price_min_distance_from_avg": "Minimum Distance",
|
||
"best_price_max_level": "Price Level Filter",
|
||
"best_price_max_level_gap_count": "Gap Tolerance",
|
||
"enable_min_periods_best": "Achieve Minimum Count",
|
||
"min_periods_best": "Minimum Periods",
|
||
"relaxation_attempts_best": "Relaxation Attempts"
|
||
},
|
||
"data_description": {
|
||
"best_price_min_period_length": "Minimum duration for a period to be considered as 'best price'. Longer periods are more practical for running appliances like dishwashers or heat pumps. Best price periods require 60 minutes minimum (vs. 30 minutes for peak price warnings) because they should provide meaningful time windows for consumption planning, not just brief opportunities.",
|
||
"best_price_flex": "Maximum above the daily minimum price that intervals can be and still qualify as 'best price'. Recommended: 15-20 with relaxation enabled (default), or 25-35 without relaxation. Maximum: 50 (hard cap for reliable period detection).",
|
||
"best_price_min_distance_from_avg": "Ensures periods are significantly cheaper than the daily average, not just marginally below it. This filters out noise and prevents marking slightly-below-average periods as 'best price' on days with flat prices. Higher values = stricter filtering (only truly cheap periods qualify). Default: 5 means periods must be at least 5% below the daily average.",
|
||
"best_price_max_level": "Only show best price periods if they contain intervals with price levels ≤ selected value. For example, selecting 'Cheap' means the period must have at least one 'VERY_CHEAP' or 'CHEAP' interval. This ensures 'best price' periods are not just relatively cheap for the day, but actually cheap in absolute terms. Select 'Any' to show best prices regardless of their absolute price level.",
|
||
"best_price_max_level_gap_count": "Maximum number of consecutive intervals allowed that deviate by exactly one level step from the required level. For example: with 'Cheap' filter and gap count 1, a sequence 'CHEAP, CHEAP, NORMAL, CHEAP' is accepted (NORMAL is one step above CHEAP). This prevents periods from being split by occasional level deviations. **Note:** Gap tolerance requires periods ≥90 minutes (6 intervals) to detect outliers effectively. Default: 0 (strict filtering, no tolerance).",
|
||
"enable_min_periods_best": "When enabled, filters will be gradually relaxed if not enough periods are found. This attempts to reach the desired minimum number of periods, which may include less optimal time windows as best-price periods.",
|
||
"min_periods_best": "Minimum number of best price periods to aim for per day. Filters will be relaxed step-by-step to try achieving this count. Only active when 'Try to Achieve Minimum Period Count' is enabled. Default: 1",
|
||
"relaxation_attempts_best": "How many flex levels (attempts) to try before giving up. Each attempt runs all filter combinations at the new flex level. More attempts increase the chance of finding additional periods at the cost of longer processing time."
|
||
},
|
||
"submit": "Continue →"
|
||
},
|
||
"peak_price": {
|
||
"title": "🔴 Peak Price Period Settings",
|
||
"description": "_{step_progress}_\n\n**Configure settings for the Peak Price Period binary sensor. This sensor is active during periods with the highest electricity prices.**\n\n---",
|
||
"data": {
|
||
"peak_price_min_period_length": "Minimum Period Length",
|
||
"peak_price_flex": "Flexibility",
|
||
"peak_price_min_distance_from_avg": "Minimum Distance",
|
||
"peak_price_min_level": "Price Level Filter",
|
||
"peak_price_max_level_gap_count": "Gap Tolerance",
|
||
"enable_min_periods_peak": "Achieve Minimum Count",
|
||
"min_periods_peak": "Minimum Periods",
|
||
"relaxation_attempts_peak": "Relaxation Attempts"
|
||
},
|
||
"data_description": {
|
||
"peak_price_min_period_length": "Minimum duration for a period to be considered as 'peak price'. Peak price warnings are allowed for shorter periods (30 minutes minimum vs. 60 minutes for best price) because brief expensive spikes are worth alerting about, even if they're too short for consumption planning.",
|
||
"peak_price_flex": "Maximum below the daily maximum price that intervals can be and still qualify as 'peak price'. Recommended: -15 to -20 with relaxation enabled (default), or -25 to -35 without relaxation. Maximum: -50 (hard cap for reliable period detection). Note: Negative values indicate distance below maximum.",
|
||
"peak_price_min_distance_from_avg": "Ensures periods are significantly more expensive than the daily average, not just marginally above it. This filters out noise and prevents marking slightly-above-average periods as 'peak price' on days with flat prices. Higher values = stricter filtering (only truly expensive periods qualify). Default: 5 means periods must be at least 5% above the daily average.",
|
||
"peak_price_min_level": "Only show peak price periods if they contain intervals with price levels ≥ selected value. For example, selecting 'Expensive' means the period must have at least one 'EXPENSIVE' or 'VERY_EXPENSIVE' interval. This ensures 'peak price' periods are not just relatively expensive for the day, but actually expensive in absolute terms. Select 'Any' to show peak prices regardless of their absolute price level.",
|
||
"peak_price_max_level_gap_count": "Maximum number of consecutive intervals allowed that deviate by exactly one level step from the required level. For example: with 'Expensive' filter and gap count 2, a sequence 'EXPENSIVE, NORMAL, NORMAL, EXPENSIVE' is accepted (NORMAL is one step below EXPENSIVE). This prevents periods from being split by occasional level deviations. **Note:** Gap tolerance requires periods ≥90 minutes (6 intervals) to detect outliers effectively. Default: 0 (strict filtering, no tolerance).",
|
||
"enable_min_periods_peak": "When enabled, filters will be gradually relaxed if not enough periods are found. This attempts to reach the desired minimum number of periods to ensure you're warned about expensive periods even on days with unusual price patterns.",
|
||
"min_periods_peak": "Minimum number of peak price periods to aim for per day. Filters will be relaxed step-by-step to try achieving this count. Only active when 'Try to Achieve Minimum Period Count' is enabled. Default: 1",
|
||
"relaxation_attempts_peak": "How many flex levels (attempts) to try before giving up. Each attempt runs all filter combinations at the new flex level. More attempts increase the chance of finding additional peak periods at the cost of longer processing time."
|
||
},
|
||
"submit": "Continue →"
|
||
},
|
||
"price_trend": {
|
||
"title": "📈 Price Trend Thresholds",
|
||
"description": "_{step_progress}_\n\n**Configure thresholds for price trend sensors. These sensors compare current price with the average of the next N hours to determine if prices are rising, falling, or stable.**\n\n---",
|
||
"data": {
|
||
"price_trend_threshold_rising": "Rising Threshold",
|
||
"price_trend_threshold_falling": "Falling Threshold"
|
||
},
|
||
"data_description": {
|
||
"price_trend_threshold_rising": "Percentage that the average of the next N hours must be above the current price to qualify as 'rising' trend. Example: 5 means average is at least 5% higher → prices will rise. Typical values: 5-15%. Default: 5%",
|
||
"price_trend_threshold_falling": "Percentage (negative) that the average of the next N hours must be below the current price to qualify as 'falling' trend. Example: -5 means average is at least 5% lower → prices will fall. Typical values: -5 to -15%. Default: -5%"
|
||
},
|
||
"submit": "Continue →"
|
||
},
|
||
"chart_data_export": {
|
||
"title": "📊 Chart Data Export Sensor",
|
||
"description": "_{step_progress}_\n\nThe Chart Data Export Sensor provides price data as sensor attributes.\n\n⚠️ **Note:** This sensor is a legacy feature for compatibility with older tools.\n\n**Recommended for new setups:** Use the `tibber_prices.get_chartdata` **service directly** - it's more flexible, efficient, and the modern Home Assistant approach.\n\n**When this sensor makes sense:**\n\n✅ Your dashboard tool can **only** read attributes (no service calls)\n✅ You need static data that updates automatically\n❌ **Not for automations:** Use `tibber_prices.get_chartdata` directly there - more flexible and efficient!\n\n---\n\n**Enable the sensor:**\n\n1. Open **Settings → Devices & Services → Tibber Prices**\n2. Select your home → Find **'Chart Data Export'** (Diagnostic section)\n3. **Enable the sensor** (disabled by default)\n\n**Configuration (optional):**\n\nDefault settings work out-of-the-box (today+tomorrow, 15-minute intervals, prices only).\n\nFor customization, add to **`configuration.yaml`**:\n\n```yaml\ntibber_prices:\n chart_export:\n day:\n - today\n - tomorrow\n include_level: true\n include_rating_level: true\n```\n\n**All parameters:** See `tibber_prices.get_chartdata` service documentation",
|
||
"submit": "Complete ✓"
|
||
},
|
||
"volatility": {
|
||
"title": "💨 Price Volatility Thresholds",
|
||
"description": "_{step_progress}_\n\n**Configure thresholds for volatility classification.** Volatility measures relative price variation using the coefficient of variation (CV = standard deviation / mean × 100%). These thresholds are percentage values that work across all price levels.\n\nUsed by:\n• Volatility sensors (classification)\n• Trend sensors (adaptive threshold adjustment: <moderate = more sensitive, ≥high = less sensitive)\n\n---",
|
||
"data": {
|
||
"volatility_threshold_moderate": "Moderate Threshold",
|
||
"volatility_threshold_high": "High Threshold",
|
||
"volatility_threshold_very_high": "Very High Threshold"
|
||
},
|
||
"data_description": {
|
||
"volatility_threshold_moderate": "Coefficient of Variation (CV) at which prices are considered 'moderately volatile'. CV = (standard deviation / mean) × 100%. Example: 15 means price fluctuations of ±15% around average. Sensors show this classification, trend sensors become more sensitive. Default: 15%",
|
||
"volatility_threshold_high": "Coefficient of Variation (CV) at which prices are considered 'highly volatile'. Example: 30 means price fluctuations of ±30% around average. Larger price jumps expected, trend sensors become less sensitive. Default: 30%",
|
||
"volatility_threshold_very_high": "Coefficient of Variation (CV) at which prices are considered 'very highly volatile'. Example: 50 means extreme price fluctuations of ±50% around average. On such days, strong price spikes are likely. Default: 50%"
|
||
},
|
||
"submit": "Next to Step 4"
|
||
}
|
||
},
|
||
"error": {
|
||
"auth": "The Tibber Access Token is invalid.",
|
||
"connection": "Unable to connect to Tibber. Please check your internet connection.",
|
||
"unknown": "An unexpected error occurred. Please check the logs for details.",
|
||
"cannot_connect": "Failed to connect",
|
||
"invalid_access_token": "Invalid access token",
|
||
"different_home": "The access token is not valid for the home ID this integration is configured for.",
|
||
"invalid_period_length": "Period length must be at least 15 minutes (multiples of 15).",
|
||
"invalid_flex": "Flexibility percentage must be between -50% and +50%",
|
||
"invalid_best_price_distance": "Distance percentage must be between -50% and 0% (negative = below average)",
|
||
"invalid_peak_price_distance": "Distance percentage must be between 0% and 50% (positive = above average)",
|
||
"invalid_min_periods": "Minimum periods count must be between 1 and 10",
|
||
"invalid_gap_count": "Gap count must be between 0 and 8",
|
||
"invalid_relaxation_attempts": "Relaxation attempts must be between 1 and 12",
|
||
"invalid_price_rating_low": "Low price rating threshold must be between -50% and -5%",
|
||
"invalid_price_rating_high": "High price rating threshold must be between 5% and 50%",
|
||
"invalid_price_rating_thresholds": "Low threshold must be less than high threshold",
|
||
"invalid_volatility_threshold_moderate": "Moderate volatility threshold must be between 5% and 25%",
|
||
"invalid_volatility_threshold_high": "High volatility threshold must be between 20% and 40%",
|
||
"invalid_volatility_threshold_very_high": "Very high volatility threshold must be between 35% and 80%",
|
||
"invalid_volatility_thresholds": "Thresholds must be in ascending order: moderate < high < very high",
|
||
"invalid_price_trend_rising": "Rising trend threshold must be between 1% and 50%",
|
||
"invalid_price_trend_falling": "Falling trend threshold must be between -50% and -1%"
|
||
},
|
||
"abort": {
|
||
"entry_not_found": "Tibber configuration entry not found."
|
||
}
|
||
},
|
||
"entity": {
|
||
"sensor": {
|
||
"current_interval_price": {
|
||
"name": "Current Electricity Price"
|
||
},
|
||
"current_interval_price_major": {
|
||
"name": "Current Electricity Price (Energy Dashboard)"
|
||
},
|
||
"next_interval_price": {
|
||
"name": "Next Electricity Price"
|
||
},
|
||
"previous_interval_price": {
|
||
"name": "Previous Electricity Price"
|
||
},
|
||
"current_hour_average_price": {
|
||
"name": "⌀ Hourly Price Current"
|
||
},
|
||
"next_hour_average_price": {
|
||
"name": "⌀ Hourly Price Next"
|
||
},
|
||
"current_interval_price_level": {
|
||
"name": "Current Price Level",
|
||
"state": {
|
||
"very_cheap": "Very Cheap",
|
||
"cheap": "Cheap",
|
||
"normal": "Normal",
|
||
"expensive": "Expensive",
|
||
"very_expensive": "Very Expensive"
|
||
}
|
||
},
|
||
"next_interval_price_level": {
|
||
"name": "Next Price Level",
|
||
"state": {
|
||
"very_cheap": "Very Cheap",
|
||
"cheap": "Cheap",
|
||
"normal": "Normal",
|
||
"expensive": "Expensive",
|
||
"very_expensive": "Very Expensive"
|
||
}
|
||
},
|
||
"previous_interval_price_level": {
|
||
"name": "Previous Price Level",
|
||
"state": {
|
||
"very_cheap": "Very Cheap",
|
||
"cheap": "Cheap",
|
||
"normal": "Normal",
|
||
"expensive": "Expensive",
|
||
"very_expensive": "Very Expensive"
|
||
}
|
||
},
|
||
"current_hour_price_level": {
|
||
"name": "Current Hour Price Level",
|
||
"state": {
|
||
"very_cheap": "Very Cheap",
|
||
"cheap": "Cheap",
|
||
"normal": "Normal",
|
||
"expensive": "Expensive",
|
||
"very_expensive": "Very Expensive"
|
||
}
|
||
},
|
||
"next_hour_price_level": {
|
||
"name": "Next Hour Price Level",
|
||
"state": {
|
||
"very_cheap": "Very Cheap",
|
||
"cheap": "Cheap",
|
||
"normal": "Normal",
|
||
"expensive": "Expensive",
|
||
"very_expensive": "Very Expensive"
|
||
}
|
||
},
|
||
"lowest_price_today": {
|
||
"name": "Today's Lowest Price"
|
||
},
|
||
"highest_price_today": {
|
||
"name": "Today's Highest Price"
|
||
},
|
||
"average_price_today": {
|
||
"name": "⌀ Price Today"
|
||
},
|
||
"lowest_price_tomorrow": {
|
||
"name": "Tomorrow's Lowest Price"
|
||
},
|
||
"highest_price_tomorrow": {
|
||
"name": "Tomorrow's Highest Price"
|
||
},
|
||
"average_price_tomorrow": {
|
||
"name": "⌀ Price Tomorrow"
|
||
},
|
||
"yesterday_price_level": {
|
||
"name": "Yesterday's Price Level",
|
||
"state": {
|
||
"very_cheap": "Very Cheap",
|
||
"cheap": "Cheap",
|
||
"normal": "Normal",
|
||
"expensive": "Expensive",
|
||
"very_expensive": "Very Expensive"
|
||
}
|
||
},
|
||
"today_price_level": {
|
||
"name": "Today's Price Level",
|
||
"state": {
|
||
"very_cheap": "Very Cheap",
|
||
"cheap": "Cheap",
|
||
"normal": "Normal",
|
||
"expensive": "Expensive",
|
||
"very_expensive": "Very Expensive"
|
||
}
|
||
},
|
||
"tomorrow_price_level": {
|
||
"name": "Tomorrow's Price Level",
|
||
"state": {
|
||
"very_cheap": "Very Cheap",
|
||
"cheap": "Cheap",
|
||
"normal": "Normal",
|
||
"expensive": "Expensive",
|
||
"very_expensive": "Very Expensive"
|
||
}
|
||
},
|
||
"yesterday_price_rating": {
|
||
"name": "Yesterday's Price Rating",
|
||
"state": {
|
||
"low": "Low",
|
||
"normal": "Normal",
|
||
"high": "High"
|
||
}
|
||
},
|
||
"today_price_rating": {
|
||
"name": "Today's Price Rating",
|
||
"state": {
|
||
"low": "Low",
|
||
"normal": "Normal",
|
||
"high": "High"
|
||
}
|
||
},
|
||
"tomorrow_price_rating": {
|
||
"name": "Tomorrow's Price Rating",
|
||
"state": {
|
||
"low": "Low",
|
||
"normal": "Normal",
|
||
"high": "High"
|
||
}
|
||
},
|
||
"trailing_price_average": {
|
||
"name": "⌀ Price Trailing 24h"
|
||
},
|
||
"leading_price_average": {
|
||
"name": "⌀ Price Leading 24h"
|
||
},
|
||
"trailing_price_min": {
|
||
"name": "Trailing 24h Minimum Price"
|
||
},
|
||
"trailing_price_max": {
|
||
"name": "Trailing 24h Maximum Price"
|
||
},
|
||
"leading_price_min": {
|
||
"name": "Leading 24h Minimum Price"
|
||
},
|
||
"leading_price_max": {
|
||
"name": "Leading 24h Maximum Price"
|
||
},
|
||
"current_interval_price_rating": {
|
||
"name": "Current Price Rating",
|
||
"state": {
|
||
"low": "Low",
|
||
"normal": "Normal",
|
||
"high": "High"
|
||
}
|
||
},
|
||
"next_interval_price_rating": {
|
||
"name": "Next Price Rating",
|
||
"state": {
|
||
"low": "Low",
|
||
"normal": "Normal",
|
||
"high": "High"
|
||
}
|
||
},
|
||
"previous_interval_price_rating": {
|
||
"name": "Previous Price Rating",
|
||
"state": {
|
||
"low": "Low",
|
||
"normal": "Normal",
|
||
"high": "High"
|
||
}
|
||
},
|
||
"current_hour_price_rating": {
|
||
"name": "Current Hour Price Rating",
|
||
"state": {
|
||
"low": "Low",
|
||
"normal": "Normal",
|
||
"high": "High"
|
||
}
|
||
},
|
||
"next_hour_price_rating": {
|
||
"name": "Next Hour Price Rating",
|
||
"state": {
|
||
"low": "Low",
|
||
"normal": "Normal",
|
||
"high": "High"
|
||
}
|
||
},
|
||
"next_avg_1h": {
|
||
"name": "⌀ Price Next 1h"
|
||
},
|
||
"next_avg_2h": {
|
||
"name": "⌀ Price Next 2h"
|
||
},
|
||
"next_avg_3h": {
|
||
"name": "⌀ Price Next 3h"
|
||
},
|
||
"next_avg_4h": {
|
||
"name": "⌀ Price Next 4h"
|
||
},
|
||
"next_avg_5h": {
|
||
"name": "⌀ Price Next 5h"
|
||
},
|
||
"next_avg_6h": {
|
||
"name": "⌀ Price Next 6h"
|
||
},
|
||
"next_avg_8h": {
|
||
"name": "⌀ Price Next 8h"
|
||
},
|
||
"next_avg_12h": {
|
||
"name": "⌀ Price Next 12h"
|
||
},
|
||
"price_trend_1h": {
|
||
"name": "Price Trend (1h)",
|
||
"state": {
|
||
"rising": "Rising",
|
||
"falling": "Falling",
|
||
"stable": "Stable"
|
||
}
|
||
},
|
||
"price_trend_2h": {
|
||
"name": "Price Trend (2h)",
|
||
"state": {
|
||
"rising": "Rising",
|
||
"falling": "Falling",
|
||
"stable": "Stable"
|
||
}
|
||
},
|
||
"price_trend_3h": {
|
||
"name": "Price Trend (3h)",
|
||
"state": {
|
||
"rising": "Rising",
|
||
"falling": "Falling",
|
||
"stable": "Stable"
|
||
}
|
||
},
|
||
"price_trend_4h": {
|
||
"name": "Price Trend (4h)",
|
||
"state": {
|
||
"rising": "Rising",
|
||
"falling": "Falling",
|
||
"stable": "Stable"
|
||
}
|
||
},
|
||
"price_trend_5h": {
|
||
"name": "Price Trend (5h)",
|
||
"state": {
|
||
"rising": "Rising",
|
||
"falling": "Falling",
|
||
"stable": "Stable"
|
||
}
|
||
},
|
||
"price_trend_6h": {
|
||
"name": "Price Trend (6h)",
|
||
"state": {
|
||
"rising": "Rising",
|
||
"falling": "Falling",
|
||
"stable": "Stable"
|
||
}
|
||
},
|
||
"price_trend_8h": {
|
||
"name": "Price Trend (8h)",
|
||
"state": {
|
||
"rising": "Rising",
|
||
"falling": "Falling",
|
||
"stable": "Stable"
|
||
}
|
||
},
|
||
"price_trend_12h": {
|
||
"name": "Price Trend (12h)",
|
||
"state": {
|
||
"rising": "Rising",
|
||
"falling": "Falling",
|
||
"stable": "Stable"
|
||
}
|
||
},
|
||
"current_price_trend": {
|
||
"name": "Current Price Trend",
|
||
"state": {
|
||
"rising": "Rising",
|
||
"falling": "Falling",
|
||
"stable": "Stable"
|
||
}
|
||
},
|
||
"next_price_trend_change": {
|
||
"name": "Next Price Trend Change"
|
||
},
|
||
"daily_rating": {
|
||
"name": "Daily Price Rating"
|
||
},
|
||
"monthly_rating": {
|
||
"name": "Monthly Price Rating"
|
||
},
|
||
"data_lifecycle_status": {
|
||
"name": "Data Lifecycle Status",
|
||
"state": {
|
||
"cached": "Cached",
|
||
"fresh": "Fresh",
|
||
"refreshing": "Refreshing",
|
||
"searching_tomorrow": "Searching Tomorrow",
|
||
"turnover_pending": "Turnover Pending",
|
||
"error": "Error"
|
||
}
|
||
},
|
||
"today_volatility": {
|
||
"name": "Today's Price Volatility",
|
||
"state": {
|
||
"low": "Low",
|
||
"moderate": "Moderate",
|
||
"high": "High",
|
||
"very_high": "Very High"
|
||
}
|
||
},
|
||
"tomorrow_volatility": {
|
||
"name": "Tomorrow's Price Volatility",
|
||
"state": {
|
||
"low": "Low",
|
||
"moderate": "Moderate",
|
||
"high": "High",
|
||
"very_high": "Very High"
|
||
}
|
||
},
|
||
"next_24h_volatility": {
|
||
"name": "Next 24h Price Volatility",
|
||
"state": {
|
||
"low": "Low",
|
||
"moderate": "Moderate",
|
||
"high": "High",
|
||
"very_high": "Very High"
|
||
}
|
||
},
|
||
"today_tomorrow_volatility": {
|
||
"name": "Today+Tomorrow Price Volatility",
|
||
"state": {
|
||
"low": "Low",
|
||
"moderate": "Moderate",
|
||
"high": "High",
|
||
"very_high": "Very High"
|
||
}
|
||
},
|
||
"best_price_end_time": {
|
||
"name": "Best Price End"
|
||
},
|
||
"best_price_period_duration": {
|
||
"name": "Best Price Duration"
|
||
},
|
||
"best_price_remaining_minutes": {
|
||
"name": "Best Price Remaining Time"
|
||
},
|
||
"best_price_progress": {
|
||
"name": "Best Price Progress"
|
||
},
|
||
"best_price_next_start_time": {
|
||
"name": "Best Price Start"
|
||
},
|
||
"best_price_next_in_minutes": {
|
||
"name": "Best Price Starts In"
|
||
},
|
||
"peak_price_end_time": {
|
||
"name": "Peak Price End"
|
||
},
|
||
"peak_price_period_duration": {
|
||
"name": "Peak Price Duration"
|
||
},
|
||
"peak_price_remaining_minutes": {
|
||
"name": "Peak Price Remaining Time"
|
||
},
|
||
"peak_price_progress": {
|
||
"name": "Peak Price Progress"
|
||
},
|
||
"peak_price_next_start_time": {
|
||
"name": "Peak Price Start"
|
||
},
|
||
"peak_price_next_in_minutes": {
|
||
"name": "Peak Price Starts In"
|
||
},
|
||
"home_type": {
|
||
"name": "Home Type",
|
||
"state": {
|
||
"apartment": "Apartment",
|
||
"rowhouse": "Rowhouse",
|
||
"house": "House",
|
||
"cottage": "Cottage"
|
||
}
|
||
},
|
||
"home_size": {
|
||
"name": "Home Size"
|
||
},
|
||
"main_fuse_size": {
|
||
"name": "Main Fuse Size"
|
||
},
|
||
"number_of_residents": {
|
||
"name": "Number of Residents"
|
||
},
|
||
"primary_heating_source": {
|
||
"name": "Primary Heating Source",
|
||
"state": {
|
||
"air2air_heatpump": "Air-to-Air Heat Pump",
|
||
"air2water_heatpump": "Air-to-Water Heat Pump",
|
||
"boiler": "Boiler",
|
||
"central_heating": "Central Heating",
|
||
"district_heating": "District Heating",
|
||
"district": "District Heating",
|
||
"electric_boiler": "Electric Boiler",
|
||
"electricity": "Electricity",
|
||
"floor": "Floor Heating",
|
||
"gas": "Gas",
|
||
"ground_heatpump": "Ground Heat Pump",
|
||
"ground": "Ground Heat Pump",
|
||
"oil": "Oil",
|
||
"other": "Other",
|
||
"waste": "Waste Heat"
|
||
}
|
||
},
|
||
"grid_company": {
|
||
"name": "Grid Company"
|
||
},
|
||
"grid_area_code": {
|
||
"name": "Grid Area Code"
|
||
},
|
||
"price_area_code": {
|
||
"name": "Price Area Code"
|
||
},
|
||
"consumption_ean": {
|
||
"name": "Consumption EAN"
|
||
},
|
||
"production_ean": {
|
||
"name": "Production EAN"
|
||
},
|
||
"energy_tax_type": {
|
||
"name": "Energy Tax Type"
|
||
},
|
||
"vat_type": {
|
||
"name": "VAT Type"
|
||
},
|
||
"estimated_annual_consumption": {
|
||
"name": "Estimated Annual Consumption"
|
||
},
|
||
"subscription_status": {
|
||
"name": "Subscription Status",
|
||
"state": {
|
||
"running": "Running",
|
||
"ended": "Ended",
|
||
"pending": "Pending",
|
||
"unknown": "Unknown"
|
||
}
|
||
},
|
||
"chart_data_export": {
|
||
"name": "Chart Data Export",
|
||
"state": {
|
||
"pending": "Pending",
|
||
"ready": "Ready",
|
||
"error": "Error"
|
||
}
|
||
}
|
||
},
|
||
"binary_sensor": {
|
||
"peak_price_period": {
|
||
"name": "Peak Price Period"
|
||
},
|
||
"best_price_period": {
|
||
"name": "Best Price Period"
|
||
},
|
||
"connection": {
|
||
"name": "Tibber API Connection"
|
||
},
|
||
"tomorrow_data_available": {
|
||
"name": "Tomorrow's Data Available"
|
||
},
|
||
"has_ventilation_system": {
|
||
"name": "Has Ventilation System"
|
||
},
|
||
"realtime_consumption_enabled": {
|
||
"name": "Realtime Consumption Enabled"
|
||
}
|
||
}
|
||
},
|
||
"issues": {
|
||
"new_homes_available": {
|
||
"title": "New Tibber homes detected",
|
||
"description": "We detected {count} new home(s) on your Tibber account: {homes}. You can add them to Home Assistant through the Tibber integration configuration."
|
||
},
|
||
"homes_removed": {
|
||
"title": "Tibber homes removed",
|
||
"description": "We detected that {count} home(s) have been removed from your Tibber account: {homes}. Please review your Tibber integration configuration."
|
||
}
|
||
},
|
||
"services": {
|
||
"get_apexcharts_yaml": {
|
||
"name": "Get ApexCharts Card YAML",
|
||
"description": "Returns a ready-to-copy YAML snippet for an ApexCharts card visualizing Tibber Prices for the selected day. Use this to easily add a pre-configured chart to your dashboard. The YAML will use the get_chartdata service for data.",
|
||
"fields": {
|
||
"entry_id": {
|
||
"name": "Entry ID",
|
||
"description": "The config entry ID for the Tibber integration."
|
||
},
|
||
"day": {
|
||
"name": "Day",
|
||
"description": "Which day to visualize (yesterday, today, or tomorrow)."
|
||
},
|
||
"level_type": {
|
||
"name": "Level Type",
|
||
"description": "Select which price level classification to visualize: 'rating_level' (low/normal/high based on your configured thresholds) or 'level' (Tibber API levels: very cheap/cheap/normal/expensive/very expensive)."
|
||
}
|
||
}
|
||
},
|
||
"get_chartdata": {
|
||
"name": "Get Chart Data",
|
||
"description": "Returns price data in a simple chart-friendly format compatible with the Tibber Core integration output structure. Perfect for use with popular chart cards like ha-price-timeline-card, ApexCharts Card, Plotly Graph Card, Mini Graph Card, or the built-in History Graph Card. Field names and data structure can be customized to match your specific chart requirements.",
|
||
"fields": {
|
||
"entry_id": {
|
||
"name": "Entry ID",
|
||
"description": "The config entry ID for the Tibber integration."
|
||
},
|
||
"day": {
|
||
"name": "Day",
|
||
"description": "Which day(s) to fetch prices for. You can select multiple days. If not specified, returns all available data (today + tomorrow if available)."
|
||
},
|
||
"resolution": {
|
||
"name": "Resolution",
|
||
"description": "Time resolution for the returned data. Options: 'interval' (default, 15-minute intervals, 96 points per day), 'hourly' (hourly averages, 24 points per day)."
|
||
},
|
||
"output_format": {
|
||
"name": "Output Format",
|
||
"description": "Output format for the returned data. Options: 'array_of_objects' (default, array of objects with customizable field names), 'array_of_arrays' (array of [timestamp, price] arrays with trailing null point for stepline charts)."
|
||
},
|
||
"array_fields": {
|
||
"name": "Array Fields (Array of Arrays only)",
|
||
"description": "[ONLY FOR Array of Arrays FORMAT] Define which fields to include. Use field names in curly braces, separated by commas. Available fields: start_time, price_per_kwh, level, rating_level, average. Fields will be automatically enabled even if include_* options are not set. Leave empty for default (timestamp and price only)."
|
||
},
|
||
"minor_currency": {
|
||
"name": "Minor Currency",
|
||
"description": "Return prices in minor currency units (cents for EUR, øre for NOK/SEK) instead of major currency units. Disabled by default."
|
||
},
|
||
"round_decimals": {
|
||
"name": "Round Decimals",
|
||
"description": "Number of decimal places to round prices to (0-10). If not specified, uses default precision (4 decimals for major currency, 2 for minor currency)."
|
||
},
|
||
"include_level": {
|
||
"name": "Include Level (Array of Objects only)",
|
||
"description": "[ONLY FOR Array of Objects FORMAT] Include the Tibber price level field (VERY_CHEAP, CHEAP, NORMAL, EXPENSIVE, VERY_EXPENSIVE) in each data point."
|
||
},
|
||
"include_rating_level": {
|
||
"name": "Include Rating Level (Array of Objects only)",
|
||
"description": "[ONLY FOR Array of Objects FORMAT] Include the calculated rating level field (LOW, NORMAL, HIGH) based on your configured thresholds in each data point."
|
||
},
|
||
"include_average": {
|
||
"name": "Include Average (Array of Objects only)",
|
||
"description": "[ONLY FOR Array of Objects FORMAT] Include the daily average price in each data point for comparison."
|
||
},
|
||
"level_filter": {
|
||
"name": "Level Filter",
|
||
"description": "Filter intervals to include only specific Tibber price levels (VERY_CHEAP, CHEAP, NORMAL, EXPENSIVE, VERY_EXPENSIVE). If not specified, all levels are included."
|
||
},
|
||
"rating_level_filter": {
|
||
"name": "Rating Level Filter",
|
||
"description": "Filter intervals to include only specific rating levels (LOW, NORMAL, HIGH). If not specified, all rating levels are included."
|
||
},
|
||
"period_filter": {
|
||
"name": "Period Filter",
|
||
"description": "Filter intervals to include only those within Best Price or Peak Price periods. Options: 'best_price' (only intervals in Best Price periods), 'peak_price' (only intervals in Peak Price periods). If not specified, all intervals are included. This uses the precomputed period data from binary sensors."
|
||
},
|
||
"insert_nulls": {
|
||
"name": "Insert NULL Values",
|
||
"description": "Control NULL value insertion for filtered data. 'none' (default): No NULL values, only matching intervals. 'segments': Add NULL points at segment boundaries for clean gaps in charts (recommended for stepline charts). 'all': Insert NULL for all timestamps where filter doesn't match (useful for continuous time series visualization)."
|
||
},
|
||
"add_trailing_null": {
|
||
"name": "Add Trailing Null Point",
|
||
"description": "[BOTH FORMATS] Add a final data point with null values (except timestamp) at the end. Some chart libraries need this to prevent extrapolation/interpolation to the viewport edge when using stepline rendering. Leave disabled unless your chart requires it."
|
||
},
|
||
"start_time_field": {
|
||
"name": "Start Time Field Name (Array of Objects only)",
|
||
"description": "[ONLY FOR Array of Objects FORMAT] Custom name for the start time field in the output. Defaults to 'start_time' if not specified."
|
||
},
|
||
"end_time_field": {
|
||
"name": "End Time Field Name (Array of Objects only)",
|
||
"description": "[ONLY FOR Array of Objects FORMAT] Custom name for the end time field in the output. Defaults to 'end_time' if not specified. Only used with period_filter."
|
||
},
|
||
"price_field": {
|
||
"name": "Price Field Name (Array of Objects only)",
|
||
"description": "[ONLY FOR Array of Objects FORMAT] Custom name for the price field in the output. Defaults to 'price_per_kwh' if not specified."
|
||
},
|
||
"level_field": {
|
||
"name": "Level Field Name (Array of Objects only)",
|
||
"description": "[ONLY FOR Array of Objects FORMAT] Custom name for the level field in the output. Defaults to 'level' if not specified. Only used when include_level is enabled."
|
||
},
|
||
"rating_level_field": {
|
||
"name": "Rating Level Field Name (Array of Objects only)",
|
||
"description": "[ONLY FOR Array of Objects FORMAT] Custom name for the rating_level field in the output. Defaults to 'rating_level' if not specified. Only used when include_rating_level is enabled."
|
||
},
|
||
"average_field": {
|
||
"name": "Average Field Name (Array of Objects only)",
|
||
"description": "[ONLY FOR Array of Objects FORMAT] Custom name for the average field in the output. Defaults to 'average' if not specified. Only used when include_average is enabled."
|
||
},
|
||
"data_key": {
|
||
"name": "Data Key (both formats)",
|
||
"description": "[BOTH FORMATS] Custom name for the top-level data key in the response. Defaults to 'data' if not specified. For ApexCharts compatibility with Array of Arrays, use 'points'."
|
||
}
|
||
}
|
||
},
|
||
"refresh_user_data": {
|
||
"name": "Refresh User Data",
|
||
"description": "Forces a refresh of the user data (homes, profile information) from the Tibber API. This can be useful after making changes to your Tibber account or when troubleshooting connectivity issues.",
|
||
"fields": {
|
||
"entry_id": {
|
||
"name": "Entry ID",
|
||
"description": "The config entry ID for the Tibber integration."
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"selector": {
|
||
"day": {
|
||
"options": {
|
||
"yesterday": "Yesterday",
|
||
"today": "Today",
|
||
"tomorrow": "Tomorrow"
|
||
}
|
||
},
|
||
"resolution": {
|
||
"options": {
|
||
"interval": "Interval (15 min)",
|
||
"hourly": "Hourly"
|
||
}
|
||
},
|
||
"output_format": {
|
||
"options": {
|
||
"array_of_objects": "Array of Objects",
|
||
"array_of_arrays": "Array of Arrays"
|
||
}
|
||
},
|
||
"level_type": {
|
||
"options": {
|
||
"rating_level": "Rating Level (low/normal/high)",
|
||
"level": "Tibber Level (very cheap to very expensive)"
|
||
}
|
||
},
|
||
"level_filter": {
|
||
"options": {
|
||
"very_cheap": "Very cheap",
|
||
"cheap": "Cheap",
|
||
"normal": "Normal",
|
||
"expensive": "Expensive",
|
||
"very_expensive": "Very expensive"
|
||
}
|
||
},
|
||
"rating_level_filter": {
|
||
"options": {
|
||
"low": "Low",
|
||
"normal": "Normal",
|
||
"high": "High"
|
||
}
|
||
},
|
||
"insert_nulls": {
|
||
"options": {
|
||
"none": "None",
|
||
"segments": "Segments",
|
||
"all": "All"
|
||
}
|
||
},
|
||
"period_filter": {
|
||
"options": {
|
||
"best_price": "Best Price Periods",
|
||
"peak_price": "Peak Price Periods"
|
||
}
|
||
},
|
||
"volatility": {
|
||
"options": {
|
||
"low": "Low",
|
||
"moderate": "Moderate",
|
||
"high": "High",
|
||
"very_high": "Very high"
|
||
}
|
||
},
|
||
"current_interval_price_level": {
|
||
"options": {
|
||
"any": "Any",
|
||
"very_cheap": "Very cheap",
|
||
"cheap": "Cheap",
|
||
"normal": "Normal",
|
||
"expensive": "Expensive",
|
||
"very_expensive": "Very expensive"
|
||
}
|
||
}
|
||
},
|
||
"title": "Tibber Price Information & Ratings"
|
||
} |