Refactor connection checks to return APIConnection to avoid many asserts (#660)

This commit is contained in:
J. Nick Koston 2023-11-22 22:22:10 +01:00 committed by GitHub
parent 3fb5f322b5
commit ac43747196
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -411,7 +411,7 @@ class APIClient:
else: else:
await self._connection.disconnect() await self._connection.disconnect()
def _check_authenticated(self) -> None: def _get_authenticated_connection(self) -> APIConnection:
connection = self._connection connection = self._connection
if not connection: if not connection:
raise APIConnectionError(f"Not connected to {self.log_name}!") raise APIConnectionError(f"Not connected to {self.log_name}!")
@ -420,13 +420,10 @@ class APIClient:
f"Authenticated connection not ready yet for {self.log_name}; " f"Authenticated connection not ready yet for {self.log_name}; "
f"current state is {connection.connection_state}!" f"current state is {connection.connection_state}!"
) )
return connection
async def device_info(self) -> DeviceInfo: async def device_info(self) -> DeviceInfo:
self._check_authenticated() resp = await self._get_authenticated_connection().send_message_await_response(
connection = self._connection
if TYPE_CHECKING:
assert connection is not None
resp = await connection.send_message_await_response(
DeviceInfoRequest(), DeviceInfoResponse DeviceInfoRequest(), DeviceInfoResponse
) )
info = DeviceInfo.from_pb(resp) info = DeviceInfo.from_pb(resp)
@ -441,7 +438,6 @@ class APIClient:
async def list_entities_services( async def list_entities_services(
self, self,
) -> tuple[list[EntityInfo], list[UserService]]: ) -> tuple[list[EntityInfo], list[UserService]]:
self._check_authenticated()
response_types = LIST_ENTITIES_SERVICES_RESPONSE_TYPES response_types = LIST_ENTITIES_SERVICES_RESPONSE_TYPES
msg_types = LIST_ENTITIES_MSG_TYPES msg_types = LIST_ENTITIES_MSG_TYPES
@ -451,9 +447,7 @@ class APIClient:
def do_stop(msg: message.Message) -> bool: def do_stop(msg: message.Message) -> bool:
return isinstance(msg, ListEntitiesDoneResponse) return isinstance(msg, ListEntitiesDoneResponse)
if TYPE_CHECKING: resp = await self._get_authenticated_connection().send_messages_await_response_complex(
assert self._connection is not None
resp = await self._connection.send_messages_await_response_complex(
(ListEntitiesRequest(),), do_append, do_stop, msg_types, 60 (ListEntitiesRequest(),), do_append, do_stop, msg_types, 60
) )
entities: list[EntityInfo] = [] entities: list[EntityInfo] = []
@ -468,7 +462,6 @@ class APIClient:
return entities, services return entities, services
async def subscribe_states(self, on_state: Callable[[EntityState], None]) -> None: async def subscribe_states(self, on_state: Callable[[EntityState], None]) -> None:
self._check_authenticated()
image_stream: dict[int, list[bytes]] = {} image_stream: dict[int, list[bytes]] = {}
response_types = SUBSCRIBE_STATES_RESPONSE_TYPES response_types = SUBSCRIBE_STATES_RESPONSE_TYPES
msg_types = SUBSCRIBE_STATES_MSG_TYPES msg_types = SUBSCRIBE_STATES_MSG_TYPES
@ -494,9 +487,7 @@ class APIClient:
del image_stream[msg_key] del image_stream[msg_key]
on_state(CameraState(key=msg.key, data=image_data)) # type: ignore[call-arg] on_state(CameraState(key=msg.key, data=image_data)) # type: ignore[call-arg]
if TYPE_CHECKING: self._get_authenticated_connection().send_message_callback_response(
assert self._connection is not None
self._connection.send_message_callback_response(
SubscribeStatesRequest(), _on_state_msg, msg_types SubscribeStatesRequest(), _on_state_msg, msg_types
) )
@ -506,31 +497,24 @@ class APIClient:
log_level: LogLevel | None = None, log_level: LogLevel | None = None,
dump_config: bool | None = None, dump_config: bool | None = None,
) -> None: ) -> None:
self._check_authenticated()
req = SubscribeLogsRequest() req = SubscribeLogsRequest()
if log_level is not None: if log_level is not None:
req.level = log_level req.level = log_level
if dump_config is not None: if dump_config is not None:
req.dump_config = dump_config req.dump_config = dump_config
if TYPE_CHECKING: self._get_authenticated_connection().send_message_callback_response(
assert self._connection is not None
self._connection.send_message_callback_response(
req, on_log, (SubscribeLogsResponse,) req, on_log, (SubscribeLogsResponse,)
) )
async def subscribe_service_calls( async def subscribe_service_calls(
self, on_service_call: Callable[[HomeassistantServiceCall], None] self, on_service_call: Callable[[HomeassistantServiceCall], None]
) -> None: ) -> None:
self._check_authenticated()
def _on_home_assistant_service_response( def _on_home_assistant_service_response(
msg: HomeassistantServiceResponse, msg: HomeassistantServiceResponse,
) -> None: ) -> None:
on_service_call(HomeassistantServiceCall.from_pb(msg)) on_service_call(HomeassistantServiceCall.from_pb(msg))
if TYPE_CHECKING: self._get_authenticated_connection().send_message_callback_response(
assert self._connection is not None
self._connection.send_message_callback_response(
SubscribeHomeassistantServicesRequest(), SubscribeHomeassistantServicesRequest(),
_on_home_assistant_service_response, _on_home_assistant_service_response,
(HomeassistantServiceResponse,), (HomeassistantServiceResponse,),
@ -567,13 +551,10 @@ class APIClient:
), ),
timeout: float = 10.0, timeout: float = 10.0,
) -> message.Message: ) -> message.Message:
self._check_authenticated()
msg_types = (response_type, BluetoothGATTErrorResponse) msg_types = (response_type, BluetoothGATTErrorResponse)
if TYPE_CHECKING:
assert self._connection is not None
message_filter = partial(self._filter_bluetooth_message, address, handle) message_filter = partial(self._filter_bluetooth_message, address, handle)
resp = await self._connection.send_messages_await_response_complex( resp = await self._get_authenticated_connection().send_messages_await_response_complex(
(request,), message_filter, message_filter, msg_types, timeout (request,), message_filter, message_filter, msg_types, timeout
) )
@ -585,7 +566,6 @@ class APIClient:
async def subscribe_bluetooth_le_advertisements( async def subscribe_bluetooth_le_advertisements(
self, on_bluetooth_le_advertisement: Callable[[BluetoothLEAdvertisement], None] self, on_bluetooth_le_advertisement: Callable[[BluetoothLEAdvertisement], None]
) -> Callable[[], None]: ) -> Callable[[], None]:
self._check_authenticated()
msg_types = (BluetoothLEAdvertisementResponse,) msg_types = (BluetoothLEAdvertisementResponse,)
def _on_bluetooth_le_advertising_response( def _on_bluetooth_le_advertising_response(
@ -593,13 +573,13 @@ class APIClient:
) -> None: ) -> None:
on_bluetooth_le_advertisement(BluetoothLEAdvertisement.from_pb(msg)) # type: ignore[misc] on_bluetooth_le_advertisement(BluetoothLEAdvertisement.from_pb(msg)) # type: ignore[misc]
if TYPE_CHECKING: unsub_callback = (
assert self._connection is not None self._get_authenticated_connection().send_message_callback_response(
unsub_callback = self._connection.send_message_callback_response(
SubscribeBluetoothLEAdvertisementsRequest(flags=0), SubscribeBluetoothLEAdvertisementsRequest(flags=0),
_on_bluetooth_le_advertising_response, _on_bluetooth_le_advertising_response,
msg_types, msg_types,
) )
)
def unsub() -> None: def unsub() -> None:
if self._connection is not None: if self._connection is not None:
@ -613,24 +593,22 @@ class APIClient:
async def subscribe_bluetooth_le_raw_advertisements( async def subscribe_bluetooth_le_raw_advertisements(
self, on_advertisements: Callable[[list[BluetoothLERawAdvertisement]], None] self, on_advertisements: Callable[[list[BluetoothLERawAdvertisement]], None]
) -> Callable[[], None]: ) -> Callable[[], None]:
self._check_authenticated()
msg_types = (BluetoothLERawAdvertisementsResponse,) msg_types = (BluetoothLERawAdvertisementsResponse,)
if TYPE_CHECKING:
assert self._connection is not None
def _on_ble_raw_advertisement_response( def _on_ble_raw_advertisement_response(
data: BluetoothLERawAdvertisementsResponse, data: BluetoothLERawAdvertisementsResponse,
) -> None: ) -> None:
on_advertisements(data.advertisements) on_advertisements(data.advertisements)
unsub_callback = self._connection.send_message_callback_response( unsub_callback = (
self._get_authenticated_connection().send_message_callback_response(
SubscribeBluetoothLEAdvertisementsRequest( SubscribeBluetoothLEAdvertisementsRequest(
flags=BluetoothProxySubscriptionFlag.RAW_ADVERTISEMENTS flags=BluetoothProxySubscriptionFlag.RAW_ADVERTISEMENTS
), ),
_on_ble_raw_advertisement_response, _on_ble_raw_advertisement_response,
msg_types, msg_types,
) )
)
def unsub() -> None: def unsub() -> None:
if self._connection is not None: if self._connection is not None:
@ -644,7 +622,6 @@ class APIClient:
async def subscribe_bluetooth_connections_free( async def subscribe_bluetooth_connections_free(
self, on_bluetooth_connections_free_update: Callable[[int, int], None] self, on_bluetooth_connections_free_update: Callable[[int, int], None]
) -> Callable[[], None]: ) -> Callable[[], None]:
self._check_authenticated()
msg_types = (BluetoothConnectionsFreeResponse,) msg_types = (BluetoothConnectionsFreeResponse,)
def _on_bluetooth_connections_free_response( def _on_bluetooth_connections_free_response(
@ -652,9 +629,7 @@ class APIClient:
) -> None: ) -> None:
on_bluetooth_connections_free_update(msg.free, msg.limit) on_bluetooth_connections_free_update(msg.free, msg.limit)
if TYPE_CHECKING: return self._get_authenticated_connection().send_message_callback_response(
assert self._connection is not None
return self._connection.send_message_callback_response(
SubscribeBluetoothConnectionsFreeRequest(), SubscribeBluetoothConnectionsFreeRequest(),
_on_bluetooth_connections_free_response, _on_bluetooth_connections_free_response,
msg_types, msg_types,
@ -692,14 +667,10 @@ class APIClient:
has_cache: bool = False, has_cache: bool = False,
address_type: int | None = None, address_type: int | None = None,
) -> Callable[[], None]: ) -> Callable[[], None]:
self._check_authenticated()
msg_types = (BluetoothDeviceConnectionResponse,) msg_types = (BluetoothDeviceConnectionResponse,)
debug = _LOGGER.isEnabledFor(logging.DEBUG) debug = _LOGGER.isEnabledFor(logging.DEBUG)
connect_future: asyncio.Future[None] = self._loop.create_future() connect_future: asyncio.Future[None] = self._loop.create_future()
if TYPE_CHECKING:
assert self._connection is not None
if has_cache: if has_cache:
# REMOTE_CACHING feature with cache: requestor has services and mtu cached # REMOTE_CACHING feature with cache: requestor has services and mtu cached
request_type = BluetoothDeviceRequestType.CONNECT_V3_WITH_CACHE request_type = BluetoothDeviceRequestType.CONNECT_V3_WITH_CACHE
@ -714,7 +685,7 @@ class APIClient:
if debug: if debug:
_LOGGER.debug("%s: Using connection version %s", address, request_type) _LOGGER.debug("%s: Using connection version %s", address, request_type)
unsub = self._connection.send_message_callback_response( unsub = self._get_authenticated_connection().send_message_callback_response(
BluetoothDeviceRequest( BluetoothDeviceRequest(
address=address, address=address,
request_type=request_type, request_type=request_type,
@ -865,10 +836,9 @@ class APIClient:
msg_types: tuple[type[message.Message], ...], msg_types: tuple[type[message.Message], ...],
timeout: float, timeout: float,
) -> message.Message: ) -> message.Message:
self._check_authenticated() [
if TYPE_CHECKING: response
assert self._connection is not None ] = await self._get_authenticated_connection().send_messages_await_response_complex(
[response] = await self._connection.send_messages_await_response_complex(
( (
BluetoothDeviceRequest( BluetoothDeviceRequest(
address=address, address=address,
@ -885,7 +855,6 @@ class APIClient:
async def bluetooth_gatt_get_services( async def bluetooth_gatt_get_services(
self, address: int self, address: int
) -> ESPHomeBluetoothGATTServices: ) -> ESPHomeBluetoothGATTServices:
self._check_authenticated()
msg_types = ( msg_types = (
BluetoothGATTGetServicesResponse, BluetoothGATTGetServicesResponse,
BluetoothGATTGetServicesDoneResponse, BluetoothGATTGetServicesDoneResponse,
@ -900,9 +869,7 @@ class APIClient:
def do_stop(msg: message.Message) -> bool: def do_stop(msg: message.Message) -> bool:
return isinstance(msg, stop_types) and msg.address == address return isinstance(msg, stop_types) and msg.address == address
if TYPE_CHECKING: resp = await self._get_authenticated_connection().send_messages_await_response_complex(
assert self._connection is not None
resp = await self._connection.send_messages_await_response_complex(
(BluetoothGATTGetServicesRequest(address=address),), (BluetoothGATTGetServicesRequest(address=address),),
do_append, do_append,
do_stop, do_stop,
@ -946,9 +913,7 @@ class APIClient:
req.data = data req.data = data
if not response: if not response:
if TYPE_CHECKING: self._get_authenticated_connection().send_message(req)
assert self._connection is not None
self._connection.send_message(req)
return return
await self._send_bluetooth_message_await_response( await self._send_bluetooth_message_await_response(
@ -1008,9 +973,7 @@ class APIClient:
req.data = data req.data = data
if not wait_for_response: if not wait_for_response:
if TYPE_CHECKING: self._get_authenticated_connection().send_message(req)
assert self._connection is not None
self._connection.send_message(req)
return return
await self._send_bluetooth_message_await_response( await self._send_bluetooth_message_await_response(
@ -1037,7 +1000,6 @@ class APIClient:
callbacks without stopping the notify session on the remote device, which callbacks without stopping the notify session on the remote device, which
should be used when the connection is lost. should be used when the connection is lost.
""" """
await self._send_bluetooth_message_await_response( await self._send_bluetooth_message_await_response(
address, address,
handle, handle,
@ -1051,9 +1013,7 @@ class APIClient:
if address == msg.address and handle == msg.handle: if address == msg.address and handle == msg.handle:
on_bluetooth_gatt_notify(handle, bytearray(msg.data)) on_bluetooth_gatt_notify(handle, bytearray(msg.data))
if TYPE_CHECKING: remove_callback = self._get_authenticated_connection().add_message_callback(
assert self._connection is not None
remove_callback = self._connection.add_message_callback(
_on_bluetooth_gatt_notify_data_response, (BluetoothGATTNotifyDataResponse,) _on_bluetooth_gatt_notify_data_response, (BluetoothGATTNotifyDataResponse,)
) )
@ -1063,8 +1023,6 @@ class APIClient:
remove_callback() remove_callback()
self._check_authenticated()
self._connection.send_message( self._connection.send_message(
BluetoothGATTNotifyRequest(address=address, handle=handle, enable=False) BluetoothGATTNotifyRequest(address=address, handle=handle, enable=False)
) )
@ -1074,16 +1032,12 @@ class APIClient:
async def subscribe_home_assistant_states( async def subscribe_home_assistant_states(
self, on_state_sub: Callable[[str, str | None], None] self, on_state_sub: Callable[[str, str | None], None]
) -> None: ) -> None:
self._check_authenticated()
def _on_subscribe_home_assistant_state_response( def _on_subscribe_home_assistant_state_response(
msg: SubscribeHomeAssistantStateResponse, msg: SubscribeHomeAssistantStateResponse,
) -> None: ) -> None:
on_state_sub(msg.entity_id, msg.attribute) on_state_sub(msg.entity_id, msg.attribute)
if TYPE_CHECKING: self._get_authenticated_connection().send_message_callback_response(
assert self._connection is not None
self._connection.send_message_callback_response(
SubscribeHomeAssistantStatesRequest(), SubscribeHomeAssistantStatesRequest(),
_on_subscribe_home_assistant_state_response, _on_subscribe_home_assistant_state_response,
(SubscribeHomeAssistantStateResponse,), (SubscribeHomeAssistantStateResponse,),
@ -1092,11 +1046,7 @@ class APIClient:
async def send_home_assistant_state( async def send_home_assistant_state(
self, entity_id: str, attribute: str | None, state: str self, entity_id: str, attribute: str | None, state: str
) -> None: ) -> None:
self._check_authenticated() self._get_authenticated_connection().send_message(
if TYPE_CHECKING:
assert self._connection is not None
self._connection.send_message(
HomeAssistantStateResponse( HomeAssistantStateResponse(
entity_id=entity_id, entity_id=entity_id,
state=state, state=state,
@ -1111,8 +1061,6 @@ class APIClient:
tilt: float | None = None, tilt: float | None = None,
stop: bool = False, stop: bool = False,
) -> None: ) -> None:
self._check_authenticated()
req = CoverCommandRequest() req = CoverCommandRequest()
req.key = key req.key = key
apiv = cast(APIVersion, self.api_version) apiv = cast(APIVersion, self.api_version)
@ -1135,9 +1083,8 @@ class APIClient:
elif position == 0.0: elif position == 0.0:
req.legacy_command = LegacyCoverCommand.CLOSE req.legacy_command = LegacyCoverCommand.CLOSE
req.has_legacy_command = True req.has_legacy_command = True
if TYPE_CHECKING:
assert self._connection is not None self._get_authenticated_connection().send_message(req)
self._connection.send_message(req)
async def fan_command( async def fan_command(
self, self,
@ -1148,8 +1095,6 @@ class APIClient:
oscillating: bool | None = None, oscillating: bool | None = None,
direction: FanDirection | None = None, direction: FanDirection | None = None,
) -> None: ) -> None:
self._check_authenticated()
req = FanCommandRequest() req = FanCommandRequest()
req.key = key req.key = key
if state is not None: if state is not None:
@ -1167,9 +1112,8 @@ class APIClient:
if direction is not None: if direction is not None:
req.has_direction = True req.has_direction = True
req.direction = direction req.direction = direction
if TYPE_CHECKING:
assert self._connection is not None self._get_authenticated_connection().send_message(req)
self._connection.send_message(req)
async def light_command( # pylint: disable=too-many-branches async def light_command( # pylint: disable=too-many-branches
self, self,
@ -1187,8 +1131,6 @@ class APIClient:
flash_length: float | None = None, flash_length: float | None = None,
effect: str | None = None, effect: str | None = None,
) -> None: ) -> None:
self._check_authenticated()
req = LightCommandRequest() req = LightCommandRequest()
req.key = key req.key = key
if state is not None: if state is not None:
@ -1229,19 +1171,15 @@ class APIClient:
if effect is not None: if effect is not None:
req.has_effect = True req.has_effect = True
req.effect = effect req.effect = effect
if TYPE_CHECKING:
assert self._connection is not None self._get_authenticated_connection().send_message(req)
self._connection.send_message(req)
async def switch_command(self, key: int, state: bool) -> None: async def switch_command(self, key: int, state: bool) -> None:
self._check_authenticated()
req = SwitchCommandRequest() req = SwitchCommandRequest()
req.key = key req.key = key
req.state = state req.state = state
if TYPE_CHECKING:
assert self._connection is not None self._get_authenticated_connection().send_message(req)
self._connection.send_message(req)
async def climate_command( async def climate_command(
self, self,
@ -1256,8 +1194,6 @@ class APIClient:
preset: ClimatePreset | None = None, preset: ClimatePreset | None = None,
custom_preset: str | None = None, custom_preset: str | None = None,
) -> None: ) -> None:
self._check_authenticated()
req = ClimateCommandRequest() req = ClimateCommandRequest()
req.key = key req.key = key
if mode is not None: if mode is not None:
@ -1292,29 +1228,22 @@ class APIClient:
if custom_preset is not None: if custom_preset is not None:
req.has_custom_preset = True req.has_custom_preset = True
req.custom_preset = custom_preset req.custom_preset = custom_preset
if TYPE_CHECKING:
assert self._connection is not None self._get_authenticated_connection().send_message(req)
self._connection.send_message(req)
async def number_command(self, key: int, state: float) -> None: async def number_command(self, key: int, state: float) -> None:
self._check_authenticated()
req = NumberCommandRequest() req = NumberCommandRequest()
req.key = key req.key = key
req.state = state req.state = state
if TYPE_CHECKING:
assert self._connection is not None self._get_authenticated_connection().send_message(req)
self._connection.send_message(req)
async def select_command(self, key: int, state: str) -> None: async def select_command(self, key: int, state: str) -> None:
self._check_authenticated()
req = SelectCommandRequest() req = SelectCommandRequest()
req.key = key req.key = key
req.state = state req.state = state
if TYPE_CHECKING:
assert self._connection is not None self._get_authenticated_connection().send_message(req)
self._connection.send_message(req)
async def siren_command( async def siren_command(
self, self,
@ -1324,8 +1253,6 @@ class APIClient:
volume: float | None = None, volume: float | None = None,
duration: int | None = None, duration: int | None = None,
) -> None: ) -> None:
self._check_authenticated()
req = SirenCommandRequest() req = SirenCommandRequest()
req.key = key req.key = key
if state is not None: if state is not None:
@ -1340,18 +1267,14 @@ class APIClient:
if duration is not None: if duration is not None:
req.duration = duration req.duration = duration
req.has_duration = True req.has_duration = True
if TYPE_CHECKING:
assert self._connection is not None self._get_authenticated_connection().send_message(req)
self._connection.send_message(req)
async def button_command(self, key: int) -> None: async def button_command(self, key: int) -> None:
self._check_authenticated()
req = ButtonCommandRequest() req = ButtonCommandRequest()
req.key = key req.key = key
if TYPE_CHECKING:
assert self._connection is not None self._get_authenticated_connection().send_message(req)
self._connection.send_message(req)
async def lock_command( async def lock_command(
self, self,
@ -1359,16 +1282,13 @@ class APIClient:
command: LockCommand, command: LockCommand,
code: str | None = None, code: str | None = None,
) -> None: ) -> None:
self._check_authenticated()
req = LockCommandRequest() req = LockCommandRequest()
req.key = key req.key = key
req.command = command req.command = command
if code is not None: if code is not None:
req.code = code req.code = code
if TYPE_CHECKING:
assert self._connection is not None self._get_authenticated_connection().send_message(req)
self._connection.send_message(req)
async def media_player_command( async def media_player_command(
self, self,
@ -1378,8 +1298,6 @@ class APIClient:
volume: float | None = None, volume: float | None = None,
media_url: str | None = None, media_url: str | None = None,
) -> None: ) -> None:
self._check_authenticated()
req = MediaPlayerCommandRequest() req = MediaPlayerCommandRequest()
req.key = key req.key = key
if command is not None: if command is not None:
@ -1391,25 +1309,19 @@ class APIClient:
if media_url is not None: if media_url is not None:
req.media_url = media_url req.media_url = media_url
req.has_media_url = True req.has_media_url = True
if TYPE_CHECKING:
assert self._connection is not None self._get_authenticated_connection().send_message(req)
self._connection.send_message(req)
async def text_command(self, key: int, state: str) -> None: async def text_command(self, key: int, state: str) -> None:
self._check_authenticated()
req = TextCommandRequest() req = TextCommandRequest()
req.key = key req.key = key
req.state = state req.state = state
if TYPE_CHECKING:
assert self._connection is not None self._get_authenticated_connection().send_message(req)
self._connection.send_message(req)
async def execute_service( async def execute_service(
self, service: UserService, data: ExecuteServiceDataType self, service: UserService, data: ExecuteServiceDataType
) -> None: ) -> None:
self._check_authenticated()
req = ExecuteServiceRequest() req = ExecuteServiceRequest()
req.key = service.key req.key = service.key
args = [] args = []
@ -1440,9 +1352,8 @@ class APIClient:
args.append(arg) args.append(arg)
# pylint: disable=no-member # pylint: disable=no-member
req.args.extend(args) req.args.extend(args)
if TYPE_CHECKING:
assert self._connection is not None self._get_authenticated_connection().send_message(req)
self._connection.send_message(req)
async def _request_image( async def _request_image(
self, *, single: bool = False, stream: bool = False self, *, single: bool = False, stream: bool = False
@ -1450,9 +1361,8 @@ class APIClient:
req = CameraImageRequest() req = CameraImageRequest()
req.single = single req.single = single
req.stream = stream req.stream = stream
if TYPE_CHECKING:
assert self._connection is not None self._get_authenticated_connection().send_message(req)
self._connection.send_message(req)
async def request_single_image(self) -> None: async def request_single_image(self) -> None:
await self._request_image(single=True) await self._request_image(single=True)
@ -1482,7 +1392,7 @@ class APIClient:
Returns a callback to unsubscribe. Returns a callback to unsubscribe.
""" """
self._check_authenticated() connection = self._get_authenticated_connection()
start_task: asyncio.Task[int | None] | None = None start_task: asyncio.Task[int | None] | None = None
@ -1511,12 +1421,9 @@ class APIClient:
self._background_tasks.add(stop_task) self._background_tasks.add(stop_task)
stop_task.add_done_callback(self._background_tasks.discard) stop_task.add_done_callback(self._background_tasks.discard)
if TYPE_CHECKING: connection.send_message(SubscribeVoiceAssistantRequest(subscribe=True))
assert self._connection is not None
self._connection.send_message(SubscribeVoiceAssistantRequest(subscribe=True)) remove_callback = connection.add_message_callback(
remove_callback = self._connection.add_message_callback(
_on_voice_assistant_request, (VoiceAssistantRequest,) _on_voice_assistant_request, (VoiceAssistantRequest,)
) )
@ -1535,8 +1442,6 @@ class APIClient:
def send_voice_assistant_event( def send_voice_assistant_event(
self, event_type: VoiceAssistantEventType, data: dict[str, str] | None self, event_type: VoiceAssistantEventType, data: dict[str, str] | None
) -> None: ) -> None:
self._check_authenticated()
req = VoiceAssistantEventResponse() req = VoiceAssistantEventResponse()
req.event_type = event_type req.event_type = event_type
@ -1551,9 +1456,7 @@ class APIClient:
# pylint: disable=no-member # pylint: disable=no-member
req.data.extend(data_args) req.data.extend(data_args)
if TYPE_CHECKING: self._get_authenticated_connection().send_message(req)
assert self._connection is not None
self._connection.send_message(req)
async def alarm_control_panel_command( async def alarm_control_panel_command(
self, self,
@ -1561,13 +1464,10 @@ class APIClient:
command: AlarmControlPanelCommand, command: AlarmControlPanelCommand,
code: str | None = None, code: str | None = None,
) -> None: ) -> None:
self._check_authenticated()
req = AlarmControlPanelCommandRequest() req = AlarmControlPanelCommandRequest()
req.key = key req.key = key
req.command = command req.command = command
if code is not None: if code is not None:
req.code = code req.code = code
if TYPE_CHECKING:
assert self._connection is not None self._get_authenticated_connection().send_message(req)
self._connection.send_message(req)