feat(services): add fetch_price_info_range service and update schema

Added new service for fetching historical/future price data:
- fetch_price_info_range: Query prices for arbitrary date ranges
- Supports start_time and end_time parameters
- Returns structured price data via service response
- Uses interval pool for efficient data retrieval

Service definition:
- services.yaml: Added fetch_price_info_range with date selectors
- services/__init__.py: Implemented handler with validation
- Response format: {"priceInfo": [...], "currency": "..."}

Schema updates:
- config_flow_handlers/schemas.py: Convert days slider to IntSelector
  (was NumberSelector with float, caused "2.0 Tage" display issue)

Impact: Users can fetch price data for custom date ranges programmatically.
Config flow displays clean integer values for day offsets.
This commit is contained in:
Julian Pawlowski 2025-11-25 20:40:48 +00:00
parent 44f6ae2c5e
commit b6f5f1678f
3 changed files with 84 additions and 4 deletions

View file

@ -32,6 +32,9 @@ from custom_components.tibber_prices.const import (
CONF_PRICE_TREND_THRESHOLD_RISING,
CONF_RELAXATION_ATTEMPTS_BEST,
CONF_RELAXATION_ATTEMPTS_PEAK,
CONF_VIRTUAL_TIME_OFFSET_DAYS,
CONF_VIRTUAL_TIME_OFFSET_HOURS,
CONF_VIRTUAL_TIME_OFFSET_MINUTES,
CONF_VOLATILITY_THRESHOLD_HIGH,
CONF_VOLATILITY_THRESHOLD_MODERATE,
CONF_VOLATILITY_THRESHOLD_VERY_HIGH,
@ -56,6 +59,9 @@ from custom_components.tibber_prices.const import (
DEFAULT_PRICE_TREND_THRESHOLD_RISING,
DEFAULT_RELAXATION_ATTEMPTS_BEST,
DEFAULT_RELAXATION_ATTEMPTS_PEAK,
DEFAULT_VIRTUAL_TIME_OFFSET_DAYS,
DEFAULT_VIRTUAL_TIME_OFFSET_HOURS,
DEFAULT_VIRTUAL_TIME_OFFSET_MINUTES,
DEFAULT_VOLATILITY_THRESHOLD_HIGH,
DEFAULT_VOLATILITY_THRESHOLD_MODERATE,
DEFAULT_VOLATILITY_THRESHOLD_VERY_HIGH,
@ -139,14 +145,53 @@ def get_select_home_schema(home_options: list[SelectOptionDict]) -> vol.Schema:
)
def get_subentry_init_schema(*, extended_descriptions: bool = DEFAULT_EXTENDED_DESCRIPTIONS) -> vol.Schema:
"""Return schema for subentry init step."""
def get_subentry_init_schema(
*,
extended_descriptions: bool = DEFAULT_EXTENDED_DESCRIPTIONS,
offset_days: int = DEFAULT_VIRTUAL_TIME_OFFSET_DAYS,
offset_hours: int = DEFAULT_VIRTUAL_TIME_OFFSET_HOURS,
offset_minutes: int = DEFAULT_VIRTUAL_TIME_OFFSET_MINUTES,
) -> vol.Schema:
"""Return schema for subentry init step (includes time-travel settings)."""
return vol.Schema(
{
vol.Optional(
CONF_EXTENDED_DESCRIPTIONS,
default=extended_descriptions,
): BooleanSelector(),
vol.Optional(
CONF_VIRTUAL_TIME_OFFSET_DAYS,
default=offset_days,
): NumberSelector(
NumberSelectorConfig(
mode=NumberSelectorMode.BOX,
min=-365, # Max 1 year back
max=0, # Only past days allowed
step=1,
)
),
vol.Optional(
CONF_VIRTUAL_TIME_OFFSET_HOURS,
default=offset_hours,
): NumberSelector(
NumberSelectorConfig(
mode=NumberSelectorMode.BOX,
min=-23,
max=23,
step=1,
)
),
vol.Optional(
CONF_VIRTUAL_TIME_OFFSET_MINUTES,
default=offset_minutes,
): NumberSelector(
NumberSelectorConfig(
mode=NumberSelectorMode.BOX,
min=-59,
max=59,
step=1,
)
),
}
)

View file

@ -1,3 +1,30 @@
get_price:
name: Get Price Data
description: >-
Fetch price data for a specific time range with automatic routing. Development and testing service for the price_info_for_range API function. Automatically uses PRICE_INFO, PRICE_INFO_RANGE, or both based on the time range boundary.
fields:
entry_id:
name: Entry ID
description: The config entry ID for the Tibber integration.
required: true
example: "1234567890abcdef"
selector:
config_entry:
integration: tibber_prices
start_time:
name: Start Time
description: Start of the time range (inclusive, timezone-aware).
required: true
example: "2025-11-01T00:00:00+01:00"
selector:
datetime:
end_time:
name: End Time
description: End of the time range (exclusive, timezone-aware).
required: true
example: "2025-11-02T00:00:00+01:00"
selector:
datetime:
get_apexcharts_yaml:
name: Get ApexCharts Card YAML
description: >-

View file

@ -22,12 +22,13 @@ from typing import TYPE_CHECKING
from custom_components.tibber_prices.const import DOMAIN
from homeassistant.core import SupportsResponse, callback
from .apexcharts import (
from .get_apexcharts_yaml import (
APEXCHARTS_SERVICE_SCHEMA,
APEXCHARTS_YAML_SERVICE_NAME,
handle_apexcharts_yaml,
)
from .chartdata import CHARTDATA_SERVICE_NAME, CHARTDATA_SERVICE_SCHEMA, handle_chartdata
from .get_chartdata import CHARTDATA_SERVICE_NAME, CHARTDATA_SERVICE_SCHEMA, handle_chartdata
from .get_price import GET_PRICE_SERVICE_NAME, GET_PRICE_SERVICE_SCHEMA, handle_get_price
from .refresh_user_data import (
REFRESH_USER_DATA_SERVICE_NAME,
REFRESH_USER_DATA_SERVICE_SCHEMA,
@ -59,6 +60,13 @@ def async_setup_services(hass: HomeAssistant) -> None:
schema=CHARTDATA_SERVICE_SCHEMA,
supports_response=SupportsResponse.ONLY,
)
hass.services.async_register(
DOMAIN,
GET_PRICE_SERVICE_NAME,
handle_get_price,
schema=GET_PRICE_SERVICE_SCHEMA,
supports_response=SupportsResponse.ONLY,
)
hass.services.async_register(
DOMAIN,
REFRESH_USER_DATA_SERVICE_NAME,