22
33from __future__ import annotations
44
5+ from collections .abc import Callable
56from datetime import date , datetime
7+ from functools import partial
68import logging
79from typing import TYPE_CHECKING
810
911from pynordpool import (
1012 AREAS ,
1113 Currency ,
14+ DeliveryPeriodData ,
1215 NordPoolAuthenticationError ,
16+ NordPoolClient ,
1317 NordPoolEmptyResponseError ,
1418 NordPoolError ,
19+ PriceIndicesData ,
1520)
1621import voluptuous as vol
1722
3237
3338if TYPE_CHECKING :
3439 from . import NordPoolConfigEntry
35- from .const import DOMAIN
40+ from .const import ATTR_RESOLUTION , DOMAIN
3641
3742_LOGGER = logging .getLogger (__name__ )
3843ATTR_CONFIG_ENTRY = "config_entry"
3944ATTR_AREAS = "areas"
4045ATTR_CURRENCY = "currency"
4146
4247SERVICE_GET_PRICES_FOR_DATE = "get_prices_for_date"
48+ SERVICE_GET_PRICE_INDICES_FOR_DATE = "get_price_indices_for_date"
4349SERVICE_GET_PRICES_SCHEMA = vol .Schema (
4450 {
4551 vol .Required (ATTR_CONFIG_ENTRY ): ConfigEntrySelector ({"integration" : DOMAIN }),
5056 ),
5157 }
5258)
59+ SERVICE_GET_PRICE_INDICES_SCHEMA = SERVICE_GET_PRICES_SCHEMA .extend (
60+ {
61+ vol .Optional (ATTR_RESOLUTION , default = 60 ): vol .All (
62+ cv .positive_int , vol .All (vol .Coerce (int ), vol .In ((15 , 30 , 60 )))
63+ ),
64+ }
65+ )
5366
5467
5568def get_config_entry (hass : HomeAssistant , entry_id : str ) -> NordPoolConfigEntry :
@@ -71,11 +84,13 @@ def get_config_entry(hass: HomeAssistant, entry_id: str) -> NordPoolConfigEntry:
7184def async_setup_services (hass : HomeAssistant ) -> None :
7285 """Set up services for Nord Pool integration."""
7386
74- async def get_prices_for_date (call : ServiceCall ) -> ServiceResponse :
75- """Get price service."""
87+ def get_service_params (
88+ call : ServiceCall ,
89+ ) -> tuple [NordPoolClient , date , str , list [str ], int ]:
90+ """Return the parameters for the service."""
7691 entry = get_config_entry (hass , call .data [ATTR_CONFIG_ENTRY ])
77- asked_date : date = call .data [ATTR_DATE ]
7892 client = entry .runtime_data .client
93+ asked_date : date = call .data [ATTR_DATE ]
7994
8095 areas : list [str ] = entry .data [ATTR_AREAS ]
8196 if _areas := call .data .get (ATTR_AREAS ):
@@ -85,14 +100,55 @@ async def get_prices_for_date(call: ServiceCall) -> ServiceResponse:
85100 if _currency := call .data .get (ATTR_CURRENCY ):
86101 currency = _currency
87102
103+ resolution : int = 60
104+ if _resolution := call .data .get (ATTR_RESOLUTION ):
105+ resolution = _resolution
106+
88107 areas = [area .upper () for area in areas ]
89108 currency = currency .upper ()
90109
110+ return (client , asked_date , currency , areas , resolution )
111+
112+ async def get_prices_for_date (
113+ client : NordPoolClient ,
114+ asked_date : date ,
115+ currency : str ,
116+ areas : list [str ],
117+ resolution : int ,
118+ ) -> DeliveryPeriodData :
119+ """Get prices."""
120+ return await client .async_get_delivery_period (
121+ datetime .combine (asked_date , dt_util .utcnow ().time ()),
122+ Currency (currency ),
123+ areas ,
124+ )
125+
126+ async def get_price_indices_for_date (
127+ client : NordPoolClient ,
128+ asked_date : date ,
129+ currency : str ,
130+ areas : list [str ],
131+ resolution : int ,
132+ ) -> PriceIndicesData :
133+ """Get prices."""
134+ return await client .async_get_price_indices (
135+ datetime .combine (asked_date , dt_util .utcnow ().time ()),
136+ Currency (currency ),
137+ areas ,
138+ resolution = resolution ,
139+ )
140+
141+ async def get_prices (func : Callable , call : ServiceCall ) -> ServiceResponse :
142+ """Get price service."""
143+ client , asked_date , currency , areas , resolution = get_service_params (call )
144+
91145 try :
92- price_data = await client .async_get_delivery_period (
93- datetime .combine (asked_date , dt_util .utcnow ().time ()),
94- Currency (currency ),
146+ price_data = await func (
147+ client ,
148+ asked_date ,
149+ currency ,
95150 areas ,
151+ resolution ,
96152 )
97153 except NordPoolAuthenticationError as error :
98154 raise ServiceValidationError (
@@ -122,7 +178,14 @@ async def get_prices_for_date(call: ServiceCall) -> ServiceResponse:
122178 hass .services .async_register (
123179 DOMAIN ,
124180 SERVICE_GET_PRICES_FOR_DATE ,
125- get_prices_for_date ,
181+ partial ( get_prices , get_prices_for_date ) ,
126182 schema = SERVICE_GET_PRICES_SCHEMA ,
127183 supports_response = SupportsResponse .ONLY ,
128184 )
185+ hass .services .async_register (
186+ DOMAIN ,
187+ SERVICE_GET_PRICE_INDICES_FOR_DATE ,
188+ partial (get_prices , get_price_indices_for_date ),
189+ schema = SERVICE_GET_PRICE_INDICES_SCHEMA ,
190+ supports_response = SupportsResponse .ONLY ,
191+ )
0 commit comments