From b72c9de19c7a87ac260dd34f8350caaa0ff019f4 Mon Sep 17 00:00:00 2001 From: YogevBokobza Date: Mon, 11 Nov 2024 22:26:30 +0200 Subject: [PATCH 1/2] feat: make a single switcherapi class --- README.md | 10 +- docs/usage.md | 8 +- scripts/control_device.py | 50 +++---- src/aioswitcher/api/__init__.py | 250 +------------------------------- tests/test_api_tcp_client.py | 99 +------------ 5 files changed, 38 insertions(+), 379 deletions(-) diff --git a/README.md b/README.md index eebda341..4c9dad21 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ asyncio.run(print_devices(60)) ```python async def control_power_plug(device_type, device_ip, device_id, device_key) : # for connecting to a device we need its type, id, login key and ip address - async with SwitcherType1Api(device_type, device_ip, device_id, device_key) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key) as api: # get the device current state await api.get_state() # turn the device on @@ -62,7 +62,7 @@ asyncio.run(print_devices(60)) ```python async def control_water_heater(device_type, device_ip, device_id, device_key) : # for connecting to a device we need its type, id, login key and ip address - async with SwitcherType1Api(device_type, device_ip, device_id, device_key) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key) as api: # get the device current state await api.get_state() # turn the device on for 15 minutes @@ -96,7 +96,7 @@ asyncio.run(print_devices(60)) ```python async def control_runner(device_type, device_ip, device_id, device_key, token) : # for connecting to a device we need its type, id, login key and ip address - async with SwitcherType2Api(device_type, device_ip, device_id, device_key, token) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key, token) as api: # get the shutter current state, circuit number is 0 await api.get_shutter_state(0) # open the shutter to 30%, circuit number is 0 @@ -122,7 +122,7 @@ asyncio.run(print_devices(60)) ```python async def control_breeze(device_type, device_ip, device_id, device_key, remote_manager, remote_id) : # for connecting to a device we need its type, id, login key and ip address - async with SwitcherType2Api(device_type, device_ip, device_id, device_key) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key) as api: # get the device current state await api.get_breeze_state() # initialize the Breeze RemoteManager and get the remote @@ -152,7 +152,7 @@ asyncio.run(print_devices(60)) ```python async def control_light(device_type, device_ip, device_id, device_key, token) : # for connecting to a device we need its type, id, login key and ip address - async with SwitcherType2Api(device_type, device_ip, device_id, device_key, token) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key, token) as api: # get the light current state, circuit number is 0 await api.get_light_state(0) # turn on the light, circuit number is 0 (Only for Runner S11, Runner S12 and Lights) diff --git a/docs/usage.md b/docs/usage.md index c51f1d2f..e355f80f 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -42,7 +42,7 @@ We can use the Type1 API to gain the following capabilities: ```python async def control_device(device_type, device_ip, device_id, device_key) : # for connecting to a device we need its type, id, login key and ip address - async with SwitcherType1Api(device_type, device_ip, device_id, device_key) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key) as api: # get the device current state (1) await api.get_state() # turn the device on for 15 minutes (2) @@ -102,7 +102,7 @@ We can use the Type2 API to gain the following capabilities on Switcher Breeze, ```python async def control_runner(device_type, device_ip, device_id, device_key, token) : # for connecting to a device we need its type, id, login key, token and ip address - async with SwitcherType2Api(device_type, device_ip, device_id, device_key, token) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key, token) as api: # get the shutter current state, circuit number is 0 await api.get_shutter_state(0) # open the shutter to 30%, circuit number is 0 @@ -135,7 +135,7 @@ asyncio.run( ```python async def control_light(device_type, device_ip, device_id, device_key, token) : # for connecting to a device we need its type, id, login key and ip address - async with SwitcherType2Api(device_type, device_ip, device_id, device_key, token) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key, token) as api: # get the light current state, circuit number is 0 await api.get_light_state(0) # turn on the light, circuit number is 0 (Only for Runner S11, Runner S12 and Lights) @@ -155,7 +155,7 @@ asyncio.run( ```python async def control_breeze(device_type, device_ip, device_id, device_key, remote_manager, remote_id) : # for connecting to a device we need its type, id, login key and ip address - async with SwitcherType2Api(device_type, device_ip, device_id, device_key) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key) as api: # get the device current state (1) await api.get_breeze_state() # initialize the Breeze RemoteManager and get the remote (2) diff --git a/scripts/control_device.py b/scripts/control_device.py index 58e56fbd..e5d3f39f 100755 --- a/scripts/control_device.py +++ b/scripts/control_device.py @@ -22,7 +22,7 @@ from pprint import PrettyPrinter from typing import Any, Dict, List, Union -from aioswitcher.api import Command, SwitcherType1Api, SwitcherType2Api +from aioswitcher.api import Command, SwitcherApi from aioswitcher.api.remotes import SwitcherBreezeRemoteManager from aioswitcher.device import ( DeviceState, @@ -442,9 +442,7 @@ async def get_thermostat_state( token: Union[str, None] = None, ) -> None: """Use to launch a get_breeze_state request.""" - async with SwitcherType2Api( - device_type, device_ip, device_id, device_key, token - ) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key, token) as api: printer.pprint(asdict(await api.get_breeze_state(), verbose)) @@ -458,9 +456,7 @@ async def get_shutter_state( token: Union[str, None] = None, ) -> None: """Use to launch a get_shutter_state request.""" - async with SwitcherType2Api( - device_type, device_ip, device_id, device_key, token - ) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key, token) as api: printer.pprint(asdict(await api.get_shutter_state(index), verbose)) @@ -472,7 +468,7 @@ async def get_state( verbose: bool, ) -> None: """Use to launch a get_state request.""" - async with SwitcherType1Api(device_type, device_ip, device_id, device_key) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key) as api: printer.pprint(asdict(await api.get_state(), verbose)) @@ -492,9 +488,7 @@ async def control_thermostat( token: Union[str, None] = None, ) -> None: """Control Breeze device.""" - async with SwitcherType2Api( - device_type, device_ip, device_id, device_key, token - ) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key, token) as api: printer.pprint( asdict( await api.control_breeze_device( @@ -520,7 +514,7 @@ async def turn_on( verbose: bool, ) -> None: """Use to launch a turn_on request.""" - async with SwitcherType1Api(device_type, device_ip, device_id, device_key) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key) as api: printer.pprint(asdict(await api.control_device(Command.ON, timer), verbose)) @@ -532,7 +526,7 @@ async def turn_off( verbose: bool, ) -> None: """Use to launch a turn_off request.""" - async with SwitcherType1Api(device_type, device_ip, device_id, device_key) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key) as api: printer.pprint(asdict(await api.control_device(Command.OFF), verbose)) @@ -545,7 +539,7 @@ async def set_name( verbose: bool, ) -> None: """Use to launch a set_name request.""" - async with SwitcherType1Api(device_type, device_ip, device_id, device_key) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key) as api: printer.pprint(asdict(await api.set_device_name(name), verbose)) @@ -560,7 +554,7 @@ async def set_auto_shutdown( ) -> None: """Use to launch a set_auto_shutdown request.""" td_val = timedelta(hours=hours, minutes=minutes) - async with SwitcherType1Api(device_type, device_ip, device_id, device_key) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key) as api: printer.pprint(asdict(await api.set_auto_shutdown(td_val), verbose)) @@ -572,7 +566,7 @@ async def get_schedules( verbose: bool, ) -> None: """Use to launch a get_schedules request.""" - async with SwitcherType1Api(device_type, device_ip, device_id, device_key) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key) as api: response = await api.get_schedules() if verbose: printer.pprint({"unparsed_response": response.unparsed_response}) @@ -591,7 +585,7 @@ async def delete_schedule( verbose: bool, ) -> None: """Use to launch a delete_schedule request.""" - async with SwitcherType1Api(device_type, device_ip, device_id, device_key) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key) as api: printer.pprint(asdict(await api.delete_schedule(schedule_id), verbose)) @@ -606,7 +600,7 @@ async def create_schedule( verbose: bool, ) -> None: """Use to launch a create_schedule request.""" - async with SwitcherType1Api(device_type, device_ip, device_id, device_key) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key) as api: printer.pprint( asdict( await api.create_schedule( @@ -629,9 +623,7 @@ async def stop_shutter( token: Union[str, None] = None, ) -> None: """Stop shutter.""" - async with SwitcherType2Api( - device_type, device_ip, device_id, device_key, token - ) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key, token) as api: printer.pprint( asdict( await api.stop_shutter(index), @@ -651,9 +643,7 @@ async def set_shutter_position( token: Union[str, None] = None, ) -> None: """Use to set the shutter position.""" - async with SwitcherType2Api( - device_type, device_ip, device_id, device_key, token - ) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key, token) as api: printer.pprint( asdict( await api.set_position(position, index), @@ -672,9 +662,7 @@ async def get_light_state( token: Union[str, None] = None, ) -> None: """Use to launch a get_light_state request.""" - async with SwitcherType2Api( - device_type, device_ip, device_id, device_key, token - ) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key, token) as api: printer.pprint(asdict(await api.get_light_state(index), verbose)) @@ -688,9 +676,7 @@ async def turn_on_light( token: Union[str, None] = None, ) -> None: """Use for turn on light.""" - async with SwitcherType2Api( - device_type, device_ip, device_id, device_key, token - ) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key, token) as api: printer.pprint(asdict(await api.set_light(DeviceState.ON, index), verbose)) @@ -704,9 +690,7 @@ async def turn_off_light( token: Union[str, None] = None, ) -> None: """Use for turn off light.""" - async with SwitcherType2Api( - device_type, device_ip, device_id, device_key, token - ) as api: + async with SwitcherApi(device_type, device_ip, device_id, device_key, token) as api: printer.pprint(asdict(await api.set_light(DeviceState.OFF, index), verbose)) diff --git a/src/aioswitcher/api/__init__.py b/src/aioswitcher/api/__init__.py index 4602099c..959125e4 100644 --- a/src/aioswitcher/api/__init__.py +++ b/src/aioswitcher/api/__init__.py @@ -14,7 +14,6 @@ """Switcher integration TCP socket API module.""" -from abc import ABC from asyncio import open_connection from binascii import unhexlify from datetime import timedelta @@ -83,7 +82,8 @@ class Command(Enum): OFF = "0" -class SwitcherApi(ABC): +@final +class SwitcherApi: """Switcher TCP based API. Args: @@ -101,7 +101,6 @@ def __init__( ip_address: str, device_id: str, device_key: str, - port: int = SWITCHER_TCP_PORT_TYPE1, token: Union[str, None] = None, ) -> None: """Initialize the Switcher TCP connection API.""" @@ -109,7 +108,10 @@ def __init__( self._ip_address = ip_address self._device_id = device_id self._device_key = device_key - self._port = port + if self._device_type.protocol_type == 1: + self._port = SWITCHER_TCP_PORT_TYPE1 + else: + self._port = SWITCHER_TCP_PORT_TYPE2 self._connected = False self._token = None if self._device_type.token_needed: @@ -203,216 +205,6 @@ async def _login(self) -> Tuple[str, SwitcherLoginResponse]: response = await self._reader.read(1024) return timestamp, SwitcherLoginResponse(response) - async def get_state(self) -> SwitcherStateResponse: - """Use for sending the get state packet to the device. - - Returns: - An instance of ``SwitcherStateResponse``. - - """ - raise NotImplementedError - - async def get_breeze_state(self) -> SwitcherThermostatStateResponse: - """Use for sending the get state packet to the Breeze device. - - Returns: - An instance of ``SwitcherThermostatStateResponse``. - - """ - raise NotImplementedError - - async def control_device( - self, command: Command, minutes: int = 0 - ) -> SwitcherBaseResponse: - """Use for sending the control packet to the device. - - Args: - command: use the ``aioswitcher.api.Command`` enum. - minutes: if turning-on optionally incorporate a timer. - - Returns: - An instance of ``SwitcherBaseResponse``. - - """ - raise NotImplementedError - - async def control_breeze_device( - self, - remote: SwitcherBreezeRemote, - state: Union[DeviceState, None] = None, - mode: Union[ThermostatMode, None] = None, - target_temp: int = 0, - fan_level: Union[ThermostatFanLevel, None] = None, - swing: Union[ThermostatSwing, None] = None, - update_state: bool = False, - ) -> SwitcherBaseResponse: - """Use for sending the control packet to the Breeze device. - - Args: - remote: the remote for the breeze device - state: the desired state of the device - mode: the desired mode of the device - target_temp: the target temperature - fan_level: the desired fan level - swing: the desired swing state - update_state: update the device state without controlling the device - - Returns: - An instance of ``SwitcherBaseResponse``. - - """ - raise NotImplementedError - - async def stop_shutter(self, index: int = 0) -> SwitcherBaseResponse: - """Use for stopping the shutter. - - Args: - index: which runner to stop position, default to 0. - - Returns: - An instance of ``SwitcherBaseResponse``. - - """ - raise NotImplementedError - - async def set_position( - self, position: int = 0, index: int = 0 - ) -> SwitcherBaseResponse: - """Use for setting the shutter position of the Runners devices. - - Args: - position: the position to set the device to, default to 0. - index: which runner to set position, default to 0. - - Returns: - An instance of ``SwitcherBaseResponse``. - - """ - raise NotImplementedError - - async def get_shutter_state(self, index: int = 0) -> SwitcherBaseResponse: - """Use for sending the get state packet to the Runners devices. - - Args: - index: which runner to set get state, default to 0. - - Returns: - An instance of ``SwitcherShutterStateResponse``. - - """ - raise NotImplementedError - - async def set_device_name(self, name: str) -> SwitcherBaseResponse: - """Use for sending the set name packet to the device. - - Args: - name: string name with the length of 2 >= x >= 32. - - Returns: - An instance of ``SwitcherBaseResponse``. - - """ - raise NotImplementedError - - async def set_auto_shutdown(self, full_time: timedelta) -> SwitcherBaseResponse: - """Use for sending the set auto-off packet to the device. - - Args: - full_time: timedelta value containing the configuration value for - auto-shutdown. - - Returns: - An instance of ``SwitcherBaseResponse``. - - """ - raise NotImplementedError - - async def get_schedules(self) -> SwitcherGetSchedulesResponse: - """Use for retrieval of the schedules from the device. - - Returns: - An instance of ``SwitcherGetSchedulesResponse``. - - """ - raise NotImplementedError - - async def delete_schedule(self, schedule_id: str) -> SwitcherBaseResponse: - """Use for deleting a schedule from the device. - - Use ``get_schedules`` to retrieve the schedule instance. - - Args: - schedule_id: the identification of the schedule for deletion. - - Returns: - An instance of ``SwitcherBaseResponse``. - - """ - raise NotImplementedError - - async def create_schedule( - self, start_time: str, end_time: str, days: Set[Days] = set() - ) -> SwitcherBaseResponse: - """Use for creating a new schedule in the next empty schedule slot. - - Args: - start_time: a string start time in %H:%M format. e.g. 13:00. - end_time: a string start time in %H:%M format. e.g. 13:00. - days: for recurring schedules, add ``Days``. - - Returns: - An instance of ``SwitcherBaseResponse``. - - """ - raise NotImplementedError - - async def get_light_state(self, index: int = 0) -> SwitcherBaseResponse: - """Use for sending the get state packet to the Light devices. - - Args: - index: which light to set get state, default to 0. - - Returns: - An instance of ``SwitcherLightStateResponse``. - - """ - raise NotImplementedError - - async def set_light( - self, command: DeviceState, index: int = 0 - ) -> SwitcherBaseResponse: - """Use for turn on/off light. - - Args: - command: use the ``aioswitcher.api.DeviceState`` enum. - index: which light to turn on/off, default to 0. - - Returns: - An instance of ``SwitcherBaseResponse``. - - """ - raise NotImplementedError - - -@final -class SwitcherType1Api(SwitcherApi): - """Switcher Type1 devices (Plug, V2, Touch, V4) TCP based API. - - Args: - device_type: the type of the device. - ip_address: the ip address assigned to the device. - device_id: the id of the desired device. - device_key: the login key of the device. - """ - - def __init__( - self, device_type: DeviceType, ip_address: str, device_id: str, device_key: str - ) -> None: - """Initialize the Switcher TCP connection API.""" - super().__init__( - device_type, ip_address, device_id, device_key, SWITCHER_TCP_PORT_TYPE1 - ) - async def get_state(self) -> SwitcherStateResponse: """Use for sending the get state packet to the device. @@ -604,36 +396,6 @@ async def create_schedule( response = await self._reader.read(1024) return SwitcherBaseResponse(response) - -@final -class SwitcherType2Api(SwitcherApi): - """Switcher Type2 devices (Breeze, Runners) TCP based API. - - Args: - device_type: the type of the device. - ip_address: the ip address assigned to the device. - device_id: the id of the desired device. - device_key: the login key of the device. - """ - - def __init__( - self, - device_type: DeviceType, - ip_address: str, - device_id: str, - device_key: str, - token: Union[str, None] = None, - ) -> None: - """Initialize the Switcher TCP connection API.""" - super().__init__( - device_type, - ip_address, - device_id, - device_key, - SWITCHER_TCP_PORT_TYPE2, - token, - ) - async def control_breeze_device( self, remote: SwitcherBreezeRemote, diff --git a/tests/test_api_tcp_client.py b/tests/test_api_tcp_client.py index 526687b1..ac2cf3fc 100644 --- a/tests/test_api_tcp_client.py +++ b/tests/test_api_tcp_client.py @@ -30,8 +30,6 @@ SWITCHER_TCP_PORT_TYPE2, Command, SwitcherApi, - SwitcherType1Api, - SwitcherType2Api, ) from aioswitcher.api.messages import ( SwitcherBaseResponse, @@ -94,7 +92,7 @@ def writer_mock(writer_write): @pytest_asyncio.fixture async def connected_api_type1(reader_mock, writer_mock): with patch("aioswitcher.api.open_connection", return_value=(reader_mock, writer_mock)): - api = SwitcherType1Api(device_type_api1, device_ip, device_id, device_key) + api = SwitcherApi(device_type_api1, device_ip, device_id, device_key) await api.connect() yield api await api.disconnect() @@ -103,7 +101,7 @@ async def connected_api_type1(reader_mock, writer_mock): @pytest_asyncio.fixture async def connected_api_type2(reader_mock, writer_mock): with patch("aioswitcher.api.open_connection", return_value=(reader_mock, writer_mock)): - api = SwitcherType2Api(device_type_api2, device_ip, device_id, device_key, token_empty) + api = SwitcherApi(device_type_api2, device_ip, device_id, device_key, token_empty) await api.connect() yield api await api.disconnect() @@ -112,7 +110,7 @@ async def connected_api_type2(reader_mock, writer_mock): @pytest_asyncio.fixture async def connected_api_token_type2(reader_mock, writer_mock): with patch("aioswitcher.api.open_connection", return_value=(reader_mock, writer_mock)): - api = SwitcherType2Api(device_type_token_api2, device_ip, device_id, device_key, token_not_empty) + api = SwitcherApi(device_type_token_api2, device_ip, device_id, device_key, token_not_empty) await api.connect() yield api await api.disconnect() @@ -120,7 +118,7 @@ async def connected_api_token_type2(reader_mock, writer_mock): @patch("logging.Logger.info") async def test_stopping_before_started_and_connected_should_write_to_the_info_output(mock_info): - api = SwitcherType1Api(device_type_api1, device_ip, device_id, device_key) + api = SwitcherApi(device_type_api1, device_ip, device_id, device_key) assert_that(api.connected).is_false() await api.disconnect() mock_info.assert_called_with("switcher device not connected") @@ -128,14 +126,14 @@ async def test_stopping_before_started_and_connected_should_write_to_the_info_ou async def test_api_as_a_context_manager(reader_mock, writer_mock): with patch("aioswitcher.api.open_connection", return_value=(reader_mock, writer_mock)): - async with SwitcherType1Api(device_type_api1, device_ip, device_id, device_key) as api: + async with SwitcherApi(device_type_api1, device_ip, device_id, device_key) as api: assert_that(api.connected).is_true() async def test_api_with_token_needed_but_missing_should_raise_error(): with raises(RuntimeError, match="A token is needed but is missing"): with patch("aioswitcher.api.open_connection", return_value=b''): - await SwitcherType2Api(device_type_token_api2, device_ip, device_id, device_key, token_empty) + await SwitcherApi(device_type_token_api2, device_ip, device_id, device_key, token_empty) async def test_login_function(reader_mock, writer_write, connected_api_type1, resource_path_root): @@ -190,12 +188,6 @@ async def test_get_state_function_with_valid_packets(reader_mock, writer_write, assert_that(response.unparsed_response).is_equal_to(get_state_response_packet) -async def test_get_state_function_not_implemented(reader_mock, writer_mock): - with raises(NotImplementedError): - with patch("aioswitcher.api.open_connection", return_value=(reader_mock, writer_mock)): - await SwitcherApi(device_type_api1, device_ip, device_id, device_key, device_port).get_state() - - async def test_get_breeze_state_function_with_valid_packets(reader_mock, writer_write, connected_api_type2, resource_path_root): login_response_packet = _load_dummy_packet(resource_path_root, "login2_response") get_breeze_state_response_packet = _load_dummy_packet(resource_path_root, "get_breeze_state") @@ -230,12 +222,6 @@ async def test_get_breeze_state_function_with_a_faulty_get_state_response_should assert_that(writer_write.call_count).is_equal_to(2) -async def test_get_breeze_state_function_not_implemented(reader_mock, writer_mock): - with raises(NotImplementedError): - with patch("aioswitcher.api.open_connection", return_value=(reader_mock, writer_mock)): - await SwitcherApi(device_type_api2, device_ip, device_id, device_key, device_port2).get_breeze_state() - - async def test_control_breeze_device_function_with_valid_packets(reader_mock, writer_write, connected_api_type2, resource_path_root): four_packets = _get_dummy_packets(resource_path_root, "login2_response", "get_breeze_state", "control_breeze_response", "control_breeze_swing_response") with patch.object(reader_mock, "read", side_effect=four_packets): @@ -246,13 +232,6 @@ async def test_control_breeze_device_function_with_valid_packets(reader_mock, wr assert_that(response.unparsed_response).is_equal_to(four_packets[-1]) -async def test_control_breeze_device_function_not_implemented(reader_mock, writer_mock): - with raises(NotImplementedError): - with patch("aioswitcher.api.open_connection", return_value=(reader_mock, writer_mock)): - remote = SwitcherBreezeRemoteManager().get_remote('ELEC7022') - await SwitcherApi(device_type_api2, device_ip, device_id, device_key, device_port2).control_breeze_device(remote, DeviceState.ON, ThermostatMode.COOL, 24, ThermostatFanLevel.HIGH, ThermostatSwing.ON) - - async def test_control_breeze_device_update_state_with_valid_packets(reader_mock, writer_write, connected_api_type2, resource_path_root): three_packets = _get_dummy_packets(resource_path_root, "login2_response", "get_breeze_state", "control_breeze_response") with patch.object(reader_mock, "read", side_effect=three_packets): @@ -395,12 +374,6 @@ async def test_turn_off_function_with_valid_packets(reader_mock, writer_write, c assert_that(response.unparsed_response).is_equal_to(two_packets[-1]) -async def test_control_device_function_not_implemented(reader_mock, writer_mock): - with raises(NotImplementedError): - with patch("aioswitcher.api.open_connection", return_value=(reader_mock, writer_mock)): - await SwitcherApi(device_type_api1, device_ip, device_id, device_key, device_port).control_device(Command.ON, 0) - - async def test_set_name_function_with_valid_packets(reader_mock, writer_write, connected_api_type1, resource_path_root): two_packets = _get_dummy_packets(resource_path_root, "login_response", "set_name_response") with patch.object(reader_mock, "read", side_effect=two_packets): @@ -410,12 +383,6 @@ async def test_set_name_function_with_valid_packets(reader_mock, writer_write, c assert_that(response.unparsed_response).is_equal_to(two_packets[-1]) -async def test_set_name_function_not_implemented(reader_mock, writer_mock): - with raises(NotImplementedError): - with patch("aioswitcher.api.open_connection", return_value=(reader_mock, writer_mock)): - await SwitcherApi(device_type_api1, device_ip, device_id, device_key, device_port).set_device_name("my boiler") - - async def test_set_auto_shutdown_function_with_valid_packets(reader_mock, writer_write, connected_api_type1, resource_path_root): two_packets = _get_dummy_packets(resource_path_root, "login_response", "set_auto_shutdown_response") with patch.object(reader_mock, "read", side_effect=two_packets): @@ -425,12 +392,6 @@ async def test_set_auto_shutdown_function_with_valid_packets(reader_mock, writer assert_that(response.unparsed_response).is_equal_to(two_packets[-1]) -async def test_set_auto_shutdown_function_not_implemented(reader_mock, writer_mock): - with raises(NotImplementedError): - with patch("aioswitcher.api.open_connection", return_value=(reader_mock, writer_mock)): - await SwitcherApi(device_type_api1, device_ip, device_id, device_key, device_port).set_auto_shutdown(timedelta(hours=2, minutes=30)) - - async def test_get_schedules_function_with_valid_packets(reader_mock, writer_write, connected_api_type1, resource_path_root): two_packets = _get_dummy_packets(resource_path_root, "login_response", "get_schedules_response") with patch.object(reader_mock, "read", side_effect=two_packets): @@ -440,12 +401,6 @@ async def test_get_schedules_function_with_valid_packets(reader_mock, writer_wri assert_that(response.unparsed_response).is_equal_to(two_packets[-1]) -async def test_get_schedules_function_not_implemented(reader_mock, writer_mock): - with raises(NotImplementedError): - with patch("aioswitcher.api.open_connection", return_value=(reader_mock, writer_mock)): - await SwitcherApi(device_type_api1, device_ip, device_id, device_key, device_port).get_schedules() - - async def test_delete_schedule_function_with_valid_packets(reader_mock, writer_write, connected_api_type1, resource_path_root): two_packets = _get_dummy_packets(resource_path_root, "login_response", "delete_schedule_response") with patch.object(reader_mock, "read", side_effect=two_packets): @@ -455,12 +410,6 @@ async def test_delete_schedule_function_with_valid_packets(reader_mock, writer_w assert_that(response.unparsed_response).is_equal_to(two_packets[-1]) -async def test_delete_schedule_function_not_implemented(reader_mock, writer_mock): - with raises(NotImplementedError): - with patch("aioswitcher.api.open_connection", return_value=(reader_mock, writer_mock)): - await SwitcherApi(device_type_api1, device_ip, device_id, device_key, device_port).delete_schedule("0") - - async def test_create_schedule_function_with_valid_packets(reader_mock, writer_write, connected_api_type1, resource_path_root): two_packets = _get_dummy_packets(resource_path_root, "login_response", "create_schedule_response") with patch.object(reader_mock, "read", side_effect=two_packets): @@ -470,12 +419,6 @@ async def test_create_schedule_function_with_valid_packets(reader_mock, writer_w assert_that(response.unparsed_response).is_equal_to(two_packets[-1]) -async def test_create_schedule_function_not_implemented(reader_mock, writer_mock): - with raises(NotImplementedError): - with patch("aioswitcher.api.open_connection", return_value=(reader_mock, writer_mock)): - await SwitcherApi(device_type_api1, device_ip, device_id, device_key, device_port).create_schedule("18:00", "19:00") - - async def test_stop_shutter_device_function_with_valid_packets(reader_mock, writer_write, connected_api_type2, resource_path_root): two_packets = _get_dummy_packets(resource_path_root, "login_response", "stop_shutter_response") with patch.object(reader_mock, "read", side_effect=two_packets): @@ -494,12 +437,6 @@ async def test_stop_shutter_token_device_function_with_valid_packets(reader_mock assert_that(response.unparsed_response).is_equal_to(three_packets[-1]) -async def test_stop_shutter_function_not_implemented(reader_mock, writer_mock): - with raises(NotImplementedError): - with patch("aioswitcher.api.open_connection", return_value=(reader_mock, writer_mock)): - await SwitcherApi(device_type_api2, device_ip, device_id, device_key, device_port2).stop_shutter(0) - - async def test_set_shutter_position_device_function_with_valid_packets(reader_mock, writer_write, connected_api_type2, resource_path_root): two_packets = _get_dummy_packets(resource_path_root, "login_response", "set_shutter_position_response") with patch.object(reader_mock, "read", side_effect=two_packets): @@ -551,12 +488,6 @@ async def test_get_light_state_function_with_a_faulty_get_state_response_should_ assert_that(writer_write.call_count).is_equal_to(2) -async def test_get_light_state_function_not_implemented(reader_mock, writer_mock): - with raises(NotImplementedError): - with patch("aioswitcher.api.open_connection", return_value=(reader_mock, writer_mock)): - await SwitcherApi(device_type_token_api2, device_ip, device_id, device_key, device_port2, token_not_empty).get_light_state() - - async def test_set_light_function_with_valid_packets(reader_mock, writer_write, connected_api_token_type2, resource_path_root): three_packets = _get_dummy_packets(resource_path_root, "login_response", "login2_response", "set_light_response") with patch.object(reader_mock, "read", side_effect=three_packets): @@ -575,12 +506,6 @@ async def test_set_light_function_with_valid_packets_second_light(reader_mock, w assert_that(response.unparsed_response).is_equal_to(three_packets[-1]) -async def test_set_light_function_not_implemented(reader_mock, writer_mock): - with raises(NotImplementedError): - with patch("aioswitcher.api.open_connection", return_value=(reader_mock, writer_mock)): - await SwitcherApi(device_type_token_api2, device_ip, device_id, device_key, device_port2, token_not_empty).set_light(Command.ON, device_index2) - - async def test_get_shutter_state_function_with_valid_packets(reader_mock, writer_write, connected_api_type2, resource_path_root): login_response_packet = _load_dummy_packet(resource_path_root, "login2_response") get_state_response_packet = _load_dummy_packet(resource_path_root, "get_shutter_state_response") @@ -606,12 +531,6 @@ async def test_get_shutter_state_function_with_a_faulty_get_state_response_shoul assert_that(writer_write.call_count).is_equal_to(2) -async def test_get_shutter_state_function_not_implemented(reader_mock, writer_mock): - with raises(NotImplementedError): - with patch("aioswitcher.api.open_connection", return_value=(reader_mock, writer_mock)): - await SwitcherApi(device_type_api2, device_ip, device_id, device_key, device_port2).get_shutter_state() - - async def test_set_position_function_with_a_faulty_get_state_response_should_raise_error(reader_mock, writer_write, connected_api_type2): with raises(RuntimeError, match="login request was not successful"): with patch.object(reader_mock, "read", return_value=b''): @@ -626,12 +545,6 @@ async def test_stop_position_function_with_a_faulty_get_state_response_should_ra writer_write.assert_called_once() -async def test_set_position_function_not_implemented(reader_mock, writer_mock): - with raises(NotImplementedError): - with patch("aioswitcher.api.open_connection", return_value=(reader_mock, writer_mock)): - await SwitcherApi(device_type_api2, device_ip, device_id, device_key, device_port2).set_position(50) - - def _get_dummy_packets(resource_path_root, *packets): return [_load_dummy_packet(resource_path_root, packet) for packet in packets] From 279b39ac398f697e5c513c01c5e5316a87199d25 Mon Sep 17 00:00:00 2001 From: YogevBokobza Date: Tue, 12 Nov 2024 08:27:07 +0200 Subject: [PATCH 2/2] fix based on requested changes --- src/aioswitcher/api/__init__.py | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/aioswitcher/api/__init__.py b/src/aioswitcher/api/__init__.py index 959125e4..a23e0f14 100644 --- a/src/aioswitcher/api/__init__.py +++ b/src/aioswitcher/api/__init__.py @@ -24,7 +24,6 @@ from typing import Optional, Set, Tuple, Type, Union, final from ..device import ( - DeviceCategory, DeviceState, DeviceType, ThermostatFanLevel, @@ -63,16 +62,6 @@ # Type 2 devices: Breeze, Runners SWITCHER_TCP_PORT_TYPE2 = 10000 -SWITCHER_DEVICE_TO_TCP_PORT = { - DeviceCategory.THERMOSTAT: SWITCHER_TCP_PORT_TYPE2, - DeviceCategory.SHUTTER: SWITCHER_TCP_PORT_TYPE2, - DeviceCategory.SINGLE_SHUTTER_DUAL_LIGHT: SWITCHER_TCP_PORT_TYPE2, - DeviceCategory.DUAL_SHUTTER_SINGLE_LIGHT: SWITCHER_TCP_PORT_TYPE2, - DeviceCategory.LIGHT: SWITCHER_TCP_PORT_TYPE2, - DeviceCategory.WATER_HEATER: SWITCHER_TCP_PORT_TYPE1, - DeviceCategory.POWER_PLUG: SWITCHER_TCP_PORT_TYPE1, -} - @unique class Command(Enum): @@ -91,7 +80,6 @@ class SwitcherApi: ip_address: the ip address assigned to the device. device_id: the id of the desired device. device_key: the login key of the device. - port: the port of the device, default is 9957. """ @@ -108,9 +96,8 @@ def __init__( self._ip_address = ip_address self._device_id = device_id self._device_key = device_key - if self._device_type.protocol_type == 1: - self._port = SWITCHER_TCP_PORT_TYPE1 - else: + self._port = SWITCHER_TCP_PORT_TYPE1 + if device_type.protocol_type == 2: self._port = SWITCHER_TCP_PORT_TYPE2 self._connected = False self._token = None