1313 RequestLimitReached ,
1414 WebsocketError ,
1515)
16-
17- from homeassistant .config_entries import ConfigEntry
18- from homeassistant .const import CONF_API_TOKEN , Platform
19- from homeassistant .core import HomeAssistant
20- from homeassistant .exceptions import ConfigEntryAuthFailed , ConfigEntryNotReady
16+ import voluptuous as vol
17+
18+ from homeassistant .config_entries import ConfigEntry , ConfigEntryState
19+ from homeassistant .const import CONF_API_TOKEN , CONF_DEVICE_ID , Platform
20+ from homeassistant .core import HomeAssistant , ServiceCall
21+ from homeassistant .exceptions import (
22+ ConfigEntryAuthFailed ,
23+ ConfigEntryNotReady ,
24+ ServiceValidationError ,
25+ )
26+ from homeassistant .helpers import config_validation as cv , device_registry as dr
2127from homeassistant .helpers .dispatcher import async_dispatcher_send
28+ from homeassistant .helpers .typing import ConfigType
2229
2330from .const import (
31+ BCU_APP ,
2432 CHARGEPOINT_SETTINGS ,
2533 CHARGEPOINT_STATUS ,
34+ CHARGING_CARD_ID ,
2635 DOMAIN ,
2736 EVSE_ID ,
2837 LOGGER ,
2938 PLUG_AND_CHARGE ,
39+ SERVICE_START_CHARGE_SESSION ,
3040 VALUE ,
3141)
3242
3343type BlueCurrentConfigEntry = ConfigEntry [Connector ]
3444
3545PLATFORMS = [Platform .BUTTON , Platform .SENSOR , Platform .SWITCH ]
3646CHARGE_POINTS = "CHARGE_POINTS"
47+ CHARGE_CARDS = "CHARGE_CARDS"
3748DATA = "data"
3849DELAY = 5
3950
4051GRID = "GRID"
4152OBJECT = "object"
4253VALUE_TYPES = [CHARGEPOINT_STATUS , CHARGEPOINT_SETTINGS ]
4354
55+ CONFIG_SCHEMA = cv .config_entry_only_config_schema (DOMAIN )
56+
57+ SERVICE_START_CHARGE_SESSION_SCHEMA = vol .Schema (
58+ {
59+ vol .Required (CONF_DEVICE_ID ): cv .string ,
60+ # When no charging card is provided, use no charging card (BCU_APP = no charging card).
61+ vol .Optional (CHARGING_CARD_ID , default = BCU_APP ): cv .string ,
62+ }
63+ )
64+
4465
4566async def async_setup_entry (
4667 hass : HomeAssistant , config_entry : BlueCurrentConfigEntry
@@ -67,6 +88,66 @@ async def async_setup_entry(
6788 return True
6889
6990
91+ async def async_setup (hass : HomeAssistant , config : ConfigType ) -> bool :
92+ """Set up Blue Current."""
93+
94+ async def start_charge_session (service_call : ServiceCall ) -> None :
95+ """Start a charge session with the provided device and charge card ID."""
96+ # When no charge card is provided, use the default charge card set in the config flow.
97+ charging_card_id = service_call .data [CHARGING_CARD_ID ]
98+ device_id = service_call .data [CONF_DEVICE_ID ]
99+
100+ # Get the device based on the given device ID.
101+ device = dr .async_get (hass ).devices .get (device_id )
102+
103+ if device is None :
104+ raise ServiceValidationError (
105+ translation_domain = DOMAIN , translation_key = "invalid_device_id"
106+ )
107+
108+ blue_current_config_entry : ConfigEntry | None = None
109+
110+ for config_entry_id in device .config_entries :
111+ config_entry = hass .config_entries .async_get_entry (config_entry_id )
112+ if not config_entry or config_entry .domain != DOMAIN :
113+ # Not the blue_current config entry.
114+ continue
115+
116+ if config_entry .state is not ConfigEntryState .LOADED :
117+ raise ServiceValidationError (
118+ translation_domain = DOMAIN , translation_key = "config_entry_not_loaded"
119+ )
120+
121+ blue_current_config_entry = config_entry
122+ break
123+
124+ if not blue_current_config_entry :
125+ # The device is not connected to a valid blue_current config entry.
126+ raise ServiceValidationError (
127+ translation_domain = DOMAIN , translation_key = "no_config_entry"
128+ )
129+
130+ connector = blue_current_config_entry .runtime_data
131+
132+ # Get the evse_id from the identifier of the device.
133+ evse_id = next (
134+ identifier [1 ]
135+ for identifier in device .identifiers
136+ if identifier [0 ] == DOMAIN
137+ )
138+
139+ await connector .client .start_session (evse_id , charging_card_id )
140+
141+ hass .services .async_register (
142+ DOMAIN ,
143+ SERVICE_START_CHARGE_SESSION ,
144+ start_charge_session ,
145+ SERVICE_START_CHARGE_SESSION_SCHEMA ,
146+ )
147+
148+ return True
149+
150+
70151async def async_unload_entry (
71152 hass : HomeAssistant , config_entry : BlueCurrentConfigEntry
72153) -> bool :
@@ -87,6 +168,7 @@ def __init__(
87168 self .client = client
88169 self .charge_points : dict [str , dict ] = {}
89170 self .grid : dict [str , Any ] = {}
171+ self .charge_cards : dict [str , dict [str , Any ]] = {}
90172
91173 async def on_data (self , message : dict ) -> None :
92174 """Handle received data."""
0 commit comments