diff --git a/custom_components/tibber_prices/config_flow_handlers/schemas.py b/custom_components/tibber_prices/config_flow_handlers/schemas.py index 73dec8d..2925b0d 100644 --- a/custom_components/tibber_prices/config_flow_handlers/schemas.py +++ b/custom_components/tibber_prices/config_flow_handlers/schemas.py @@ -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, + ) + ), } ) diff --git a/custom_components/tibber_prices/services.yaml b/custom_components/tibber_prices/services.yaml index 9c99365..f6eeb3e 100644 --- a/custom_components/tibber_prices/services.yaml +++ b/custom_components/tibber_prices/services.yaml @@ -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: >- diff --git a/custom_components/tibber_prices/services/__init__.py b/custom_components/tibber_prices/services/__init__.py index 9e8ca37..d3506a7 100644 --- a/custom_components/tibber_prices/services/__init__.py +++ b/custom_components/tibber_prices/services/__init__.py @@ -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,