diff --git a/aioesphomeapi/client.py b/aioesphomeapi/client.py index a7230dbf..bcdcd882 100644 --- a/aioesphomeapi/client.py +++ b/aioesphomeapi/client.py @@ -134,7 +134,6 @@ BluetoothGATTServices, BluetoothLEAdvertisement, BluetoothLERawAdvertisement, - BluetoothLERawAdvertisements, BluetoothProxyFeature, BluetoothProxySubscriptionFlag, ButtonInfo, @@ -183,6 +182,7 @@ UserServiceArgType, VoiceAssistantCommand, VoiceAssistantEventType, + make_ble_raw_advertisement_processor, ) _LOGGER = logging.getLogger(__name__) @@ -409,7 +409,7 @@ async def subscribe_states(self, on_state: Callable[[EntityState], None]) -> Non } msg_types = (*response_types, CameraImageResponse) - def on_msg(msg: message.Message) -> None: + def _on_state_msg(msg: message.Message) -> None: msg_type = type(msg) cls = response_types.get(msg_type) if cls: @@ -432,7 +432,7 @@ def on_msg(msg: message.Message) -> None: assert self._connection is not None self._connection.send_message_callback_response( - SubscribeStatesRequest(), on_msg, msg_types + SubscribeStatesRequest(), _on_state_msg, msg_types ) async def subscribe_logs( @@ -457,13 +457,15 @@ async def subscribe_service_calls( ) -> None: self._check_authenticated() - def on_msg(msg: HomeassistantServiceResponse) -> None: + def _on_home_assistant_service_response( + msg: HomeassistantServiceResponse, + ) -> None: on_service_call(HomeassistantServiceCall.from_pb(msg)) assert self._connection is not None self._connection.send_message_callback_response( SubscribeHomeassistantServicesRequest(), - on_msg, + _on_home_assistant_service_response, (HomeassistantServiceResponse,), ) @@ -501,19 +503,23 @@ async def subscribe_bluetooth_le_advertisements( self._check_authenticated() msg_types = (BluetoothLEAdvertisementResponse,) - def on_msg(msg: BluetoothLEAdvertisementResponse) -> None: + def _on_bluetooth_le_advertising_response( + msg: BluetoothLEAdvertisementResponse, + ) -> None: on_bluetooth_le_advertisement(BluetoothLEAdvertisement.from_pb(msg)) # type: ignore[misc] assert self._connection is not None self._connection.send_message_callback_response( SubscribeBluetoothLEAdvertisementsRequest(flags=0), - on_msg, + _on_bluetooth_le_advertising_response, msg_types, ) def unsub() -> None: if self._connection is not None: - self._connection.remove_message_callback(on_msg, msg_types) + self._connection.remove_message_callback( + _on_bluetooth_le_advertising_response, msg_types + ) self._connection.send_message( UnsubscribeBluetoothLEAdvertisementsRequest() ) @@ -526,10 +532,8 @@ async def subscribe_bluetooth_le_raw_advertisements( self._check_authenticated() msg_types = (BluetoothLERawAdvertisementsResponse,) - def on_msg(msg: BluetoothLERawAdvertisementsResponse) -> None: - on_advertisements(BluetoothLERawAdvertisements.from_pb(msg).advertisements) # type: ignore[misc] - assert self._connection is not None + on_msg = make_ble_raw_advertisement_processor(on_advertisements) self._connection.send_message_callback_response( SubscribeBluetoothLEAdvertisementsRequest( flags=BluetoothProxySubscriptionFlag.RAW_ADVERTISEMENTS @@ -553,18 +557,24 @@ async def subscribe_bluetooth_connections_free( self._check_authenticated() msg_types = (BluetoothConnectionsFreeResponse,) - def on_msg(msg: BluetoothConnectionsFreeResponse) -> None: + def _on_bluetooth_connections_free_response( + msg: BluetoothConnectionsFreeResponse, + ) -> None: resp = BluetoothConnectionsFree.from_pb(msg) on_bluetooth_connections_free_update(resp.free, resp.limit) assert self._connection is not None self._connection.send_message_callback_response( - SubscribeBluetoothConnectionsFreeRequest(), on_msg, msg_types + SubscribeBluetoothConnectionsFreeRequest(), + _on_bluetooth_connections_free_response, + msg_types, ) def unsub() -> None: if self._connection is not None: - self._connection.remove_message_callback(on_msg, msg_types) + self._connection.remove_message_callback( + _on_bluetooth_connections_free_response, msg_types + ) return unsub @@ -583,7 +593,9 @@ async def bluetooth_device_connect( # pylint: disable=too-many-locals event = asyncio.Event() - def on_msg(msg: BluetoothDeviceConnectionResponse) -> None: + def _on_bluetooth_device_connection_response( + msg: BluetoothDeviceConnectionResponse, + ) -> None: resp = BluetoothDeviceConnection.from_pb(msg) if address == resp.address: on_bluetooth_connection_state(resp.connected, resp.mtu, resp.error) @@ -614,13 +626,15 @@ def on_msg(msg: BluetoothDeviceConnectionResponse) -> None: has_address_type=address_type is not None, address_type=address_type or 0, ), - on_msg, + _on_bluetooth_device_connection_response, msg_types, ) def unsub() -> None: if self._connection is not None: - self._connection.remove_message_callback(on_msg, msg_types) + self._connection.remove_message_callback( + _on_bluetooth_device_connection_response, msg_types + ) try: try: @@ -930,14 +944,16 @@ async def bluetooth_gatt_start_notify( BluetoothGATTNotifyResponse, ) - def on_msg(msg: BluetoothGATTNotifyDataResponse) -> None: + def _on_bluetooth_gatt_notify_data_response( + msg: BluetoothGATTNotifyDataResponse, + ) -> None: notify = BluetoothGATTRead.from_pb(msg) if address == notify.address and handle == notify.handle: on_bluetooth_gatt_notify(handle, bytearray(notify.data)) assert self._connection is not None remove_callback = self._connection.add_message_callback( - on_msg, (BluetoothGATTNotifyDataResponse,) + _on_bluetooth_gatt_notify_data_response, (BluetoothGATTNotifyDataResponse,) ) async def stop_notify() -> None: @@ -959,13 +975,15 @@ async def subscribe_home_assistant_states( ) -> None: self._check_authenticated() - def on_msg(msg: SubscribeHomeAssistantStateResponse) -> None: + def _on_subscribe_home_assistant_state_response( + msg: SubscribeHomeAssistantStateResponse, + ) -> None: on_state_sub(msg.entity_id, msg.attribute) assert self._connection is not None self._connection.send_message_callback_response( SubscribeHomeAssistantStatesRequest(), - on_msg, + _on_subscribe_home_assistant_state_response, (SubscribeHomeAssistantStateResponse,), ) @@ -1349,7 +1367,7 @@ def _started(fut: asyncio.Task[Optional[int]]) -> None: _LOGGER.error("Server could not be started") self._connection.send_message(VoiceAssistantResponse(error=True)) - def on_msg(msg: VoiceAssistantRequest) -> None: + def _on_voice_assistant_request(msg: VoiceAssistantRequest) -> None: command = VoiceAssistantCommand.from_pb(msg) if command.start: start_task = asyncio.create_task( @@ -1368,7 +1386,7 @@ def on_msg(msg: VoiceAssistantRequest) -> None: self._connection.send_message(SubscribeVoiceAssistantRequest(subscribe=True)) remove_callback = self._connection.add_message_callback( - on_msg, (VoiceAssistantRequest,) + _on_voice_assistant_request, (VoiceAssistantRequest,) ) def unsub() -> None: diff --git a/aioesphomeapi/model.py b/aioesphomeapi/model.py index 121640b4..f2e576e0 100644 --- a/aioesphomeapi/model.py +++ b/aioesphomeapi/model.py @@ -935,17 +935,16 @@ class BluetoothLERawAdvertisement: data: bytes = field(default_factory=bytes) -@_dataclass_decorator -class BluetoothLERawAdvertisements: - advertisements: List[BluetoothLERawAdvertisement] +def make_ble_raw_advertisement_processor( + on_advertisements: Callable[[List[BluetoothLERawAdvertisement]], None] +) -> Callable[["BluetoothLERawAdvertisementsResponse"], None]: + """Make a processor for BluetoothLERawAdvertisementResponse.""" - @classmethod - def from_pb( # type: ignore[misc] - cls: "BluetoothLERawAdvertisements", + def _on_ble_raw_advertisement_response( data: "BluetoothLERawAdvertisementsResponse", - ) -> "BluetoothLERawAdvertisements": - return cls( # type: ignore[operator, no-any-return] - advertisements=[ + ) -> None: + on_advertisements( + [ BluetoothLERawAdvertisement( # type: ignore[call-arg] adv.address, adv.rssi, adv.address_type, adv.data ) @@ -953,6 +952,8 @@ def from_pb( # type: ignore[misc] ] ) + return _on_ble_raw_advertisement_response + @dataclass(frozen=True) class BluetoothDeviceConnection(APIModelBase):