thinqconnect 0.9.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. tests/__init__.py +0 -0
  2. tests/conftest.py +195 -0
  3. tests/device_test_base.py +145 -0
  4. tests/test_air_conditioner.py +29 -0
  5. tests/test_air_purifier.py +23 -0
  6. tests/test_air_purifier_fan.py +32 -0
  7. tests/test_ceiling_fan.py +23 -0
  8. tests/test_cooktop.py +22 -0
  9. tests/test_dehumidifier.py +20 -0
  10. tests/test_dish_washer.py +19 -0
  11. tests/test_dryer.py +18 -0
  12. tests/test_home_brew.py +15 -0
  13. tests/test_hood.py +19 -0
  14. tests/test_humidifier.py +23 -0
  15. tests/test_kimchi_refrigerator.py +15 -0
  16. tests/test_microwave_oven.py +19 -0
  17. tests/test_mqtt_client.py +136 -0
  18. tests/test_oven.py +21 -0
  19. tests/test_plant_cultivator.py +15 -0
  20. tests/test_refrigerator.py +25 -0
  21. tests/test_robot_cleaner.py +19 -0
  22. tests/test_stick_cleaner.py +15 -0
  23. tests/test_styler.py +19 -0
  24. tests/test_system_boiler.py +25 -0
  25. tests/test_thinq_device_api.py +87 -0
  26. tests/test_washcomnbo_main.py +19 -0
  27. tests/test_washcomnbo_mini.py +19 -0
  28. tests/test_washer.py +19 -0
  29. tests/test_washtower.py +23 -0
  30. tests/test_washtower_dryer.py +15 -0
  31. tests/test_washtower_washer.py +20 -0
  32. tests/test_water_heater.py +22 -0
  33. tests/test_water_purifier.py +15 -0
  34. tests/test_wine_cellar.py +24 -0
  35. thinqconnect/__init__.py +74 -0
  36. thinqconnect/const.py +41 -0
  37. thinqconnect/country.py +358 -0
  38. thinqconnect/device.py +67 -0
  39. thinqconnect/devices/__init__.py +0 -0
  40. thinqconnect/devices/air_conditioner.py +207 -0
  41. thinqconnect/devices/air_purifier.py +99 -0
  42. thinqconnect/devices/air_purifier_fan.py +125 -0
  43. thinqconnect/devices/ceiling_fan.py +51 -0
  44. thinqconnect/devices/connect_device.py +484 -0
  45. thinqconnect/devices/cooktop.py +183 -0
  46. thinqconnect/devices/dehumidifier.py +53 -0
  47. thinqconnect/devices/dish_washer.py +79 -0
  48. thinqconnect/devices/dryer.py +72 -0
  49. thinqconnect/devices/home_brew.py +56 -0
  50. thinqconnect/devices/hood.py +86 -0
  51. thinqconnect/devices/humidifier.py +152 -0
  52. thinqconnect/devices/kimchi_refrigerator.py +140 -0
  53. thinqconnect/devices/microwave_oven.py +75 -0
  54. thinqconnect/devices/oven.py +248 -0
  55. thinqconnect/devices/plant_cultivator.py +121 -0
  56. thinqconnect/devices/refrigerator.py +207 -0
  57. thinqconnect/devices/robot_cleaner.py +75 -0
  58. thinqconnect/devices/stick_cleaner.py +52 -0
  59. thinqconnect/devices/styler.py +65 -0
  60. thinqconnect/devices/system_boiler.py +77 -0
  61. thinqconnect/devices/washcombo.py +60 -0
  62. thinqconnect/devices/washcombo_main.py +29 -0
  63. thinqconnect/devices/washcombo_mini.py +29 -0
  64. thinqconnect/devices/washer.py +172 -0
  65. thinqconnect/devices/washtower.py +114 -0
  66. thinqconnect/devices/washtower_dryer.py +36 -0
  67. thinqconnect/devices/washtower_washer.py +36 -0
  68. thinqconnect/devices/water_heater.py +59 -0
  69. thinqconnect/devices/water_purifier.py +45 -0
  70. thinqconnect/devices/wine_cellar.py +167 -0
  71. thinqconnect/mqtt_client.py +282 -0
  72. thinqconnect/thinq_api.py +327 -0
  73. thinqconnect-0.9.0.dist-info/LICENSE +201 -0
  74. thinqconnect-0.9.0.dist-info/METADATA +606 -0
  75. thinqconnect-0.9.0.dist-info/RECORD +77 -0
  76. thinqconnect-0.9.0.dist-info/WHEEL +5 -0
  77. thinqconnect-0.9.0.dist-info/top_level.txt +2 -0
tests/__init__.py ADDED
File without changes
tests/conftest.py ADDED
@@ -0,0 +1,195 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import logging
5
+ from pathlib import Path
6
+ from typing import Callable
7
+
8
+ import pytest
9
+
10
+ from thinqconnect.const import DeviceType
11
+ from thinqconnect.devices.connect_device import ConnectBaseDevice
12
+ from thinqconnect.thinq_api import ThinQApi
13
+
14
+ logger = logging.getLogger("test")
15
+
16
+
17
+ def pytest_generate_tests(metafunc):
18
+ if "model_name" in metafunc.fixturenames:
19
+ device_type = metafunc.cls.get_device_type()
20
+ model_list = get_model_list(device_type)
21
+ metafunc.parametrize("model_name", model_list)
22
+
23
+
24
+ def get_model_list(device_type: str) -> list[str]:
25
+ base_path = Path.cwd() / "tests" / "devices" / device_type.split("DEVICE_")[1].lower()
26
+ return [d.name for d in base_path.iterdir() if d.is_dir()]
27
+
28
+
29
+ @pytest.fixture
30
+ def generate_device() -> Callable[[type[ConnectBaseDevice], ThinQApi, dict, str, str, str | None], ConnectBaseDevice]:
31
+ def _device(
32
+ device_class: type[ConnectBaseDevice],
33
+ thinq_api: ThinQApi,
34
+ profile: dict,
35
+ device_type: str,
36
+ model_name: str,
37
+ reportable: bool = False,
38
+ group_id: str | None = None,
39
+ ) -> ConnectBaseDevice:
40
+ if device_type in [
41
+ DeviceType.WASHCOMBO_MAIN,
42
+ DeviceType.WASHCOMBO_MINI,
43
+ DeviceType.WASHTOWER_DRYER,
44
+ DeviceType.WASHTOWER_WASHER,
45
+ ]:
46
+ return device_class(
47
+ thinq_api=thinq_api,
48
+ device_id=profile["deviceId"],
49
+ device_type=device_type,
50
+ model_name=model_name,
51
+ alias=f"TEST_{device_type}",
52
+ reportable=reportable,
53
+ profile=profile["response"],
54
+ group_id=group_id,
55
+ )
56
+ else:
57
+ return device_class(
58
+ thinq_api=thinq_api,
59
+ device_id=profile["deviceId"],
60
+ device_type=device_type,
61
+ model_name=model_name,
62
+ alias=f"TEST_{device_type}",
63
+ reportable=reportable,
64
+ profile=profile["response"],
65
+ )
66
+
67
+ return _device
68
+
69
+
70
+ @pytest.fixture
71
+ def json_object() -> Callable[[str], dict]:
72
+ def _json_object(file_path: str):
73
+ return read_file(file_path)
74
+
75
+ return _json_object
76
+
77
+
78
+ def read_file(file_path: str) -> dict:
79
+ default_dict = {}
80
+ try:
81
+ with open(file_path, "r", encoding="utf-8") as f:
82
+ sample_set = f.read()
83
+ return json.loads(sample_set)
84
+ except Exception as e:
85
+ logger.error(f"read file error: {e}")
86
+ return default_dict
87
+
88
+
89
+ @pytest.fixture
90
+ def test_device_profile() -> Callable[[str, ConnectBaseDevice], dict]:
91
+ def _device_profile(device_name: str, device: ConnectBaseDevice) -> dict:
92
+ profile_attr: dict[str, dict | list | None] = {
93
+ "properties": device.profiles.properties,
94
+ "writable_properties": device.profiles.writable_properties,
95
+ "location_properties": device.profiles.location_properties,
96
+ "notification": device.profiles.notification,
97
+ "errors": device.profiles.errors,
98
+ }
99
+ for key, value in profile_attr.items():
100
+ logger.info(f"test {device_name}.profiles.{key}: {value}")
101
+
102
+ test_result = dict.copy(profile_attr)
103
+ for properties in profile_attr["properties"].values():
104
+ for prop in properties:
105
+ test_result[prop] = device.profiles.get_property(prop)
106
+ logger.info(f"test {device_name}.profiles.{prop}: {test_result[prop]}")
107
+
108
+ for location, resources in profile_attr["location_properties"].items():
109
+ location_profiles = device.profiles.get_sub_profile(location)
110
+ sub_profile_attr: dict[str, dict | list | None] = {
111
+ "writable_properties": location_profiles.writable_properties,
112
+ **(
113
+ {"notification": location_profiles.notification, "errors": location_profiles.errors}
114
+ if location_profiles.notification or location_profiles.errors
115
+ else {}
116
+ ),
117
+ }
118
+ for key, value in sub_profile_attr.items():
119
+ logger.info(f"test {device_name}.profiles.{location}.{key}: {value}")
120
+
121
+ test_result[location] = dict.copy(sub_profile_attr)
122
+ for properties in resources.values():
123
+ for prop in properties:
124
+ test_result[location][prop] = location_profiles.get_property(prop)
125
+ logger.info(f"test {device_name}.profiles.{location}.{prop}: {test_result[location][prop]}")
126
+
127
+ return test_result
128
+
129
+ return _device_profile
130
+
131
+
132
+ @pytest.fixture
133
+ def test_device_status() -> Callable[[str, ConnectBaseDevice, dict, bool], dict]:
134
+ def _device_status(device_name: str, device: ConnectBaseDevice, status: dict, is_update: bool = False) -> dict:
135
+ device_properties = device.profiles.properties
136
+ location_properties = device.profiles.location_properties
137
+ if is_update:
138
+ device.update_status(status=status["response"])
139
+ else:
140
+ device.set_status(status=status["response"])
141
+
142
+ test_result = {}
143
+ if device.profiles.errors:
144
+ test_result["error"] = device.get_status("error")
145
+ logger.info(f"test {device_name}.error: {test_result['error']}")
146
+
147
+ for properties in device_properties.values():
148
+ for prop in properties:
149
+ test_result[prop] = device.get_status(prop)
150
+ logger.info(f"test {device_name}.{prop}: {test_result[prop]}")
151
+
152
+ for location, resources in location_properties.items():
153
+ sub_device = device.get_sub_device(location)
154
+ test_result[location] = {}
155
+ if device.profiles.get_sub_profile(location).errors:
156
+ test_result[location]["error"] = sub_device.get_status("error")
157
+ logger.info(f"test {device_name}.{location}.error: {test_result[location]['error']}")
158
+
159
+ for properties in resources.values():
160
+ for prop in properties:
161
+ test_result[location][prop] = sub_device.get_status(prop)
162
+ logger.info(f"test {device_name}.{location}.{prop}: {test_result[location][prop]}")
163
+ return test_result
164
+
165
+ return _device_status
166
+
167
+
168
+ @pytest.fixture
169
+ def check_device_control() -> Callable[[str, ConnectBaseDevice], None]:
170
+ def _check_result(fn_name: str | None, prop_name: str) -> str:
171
+ if fn_name == f"set_{prop_name}":
172
+ return "Exist"
173
+ elif fn_name:
174
+ return f"Exist with custom name '{fn_name}'"
175
+ return "Not Exist"
176
+
177
+ def _check_control(device_name: str, device: ConnectBaseDevice):
178
+ location_properties = device.profiles.location_properties
179
+ writable_props = device.profiles.writable_properties
180
+ logger.info(f"test {device_name}.profiles.writable_properties: {device.profiles.writable_properties}")
181
+ for prop in writable_props:
182
+ logger.info(f"check {device_name}.set_{prop}: {_check_result(device.get_property_set_fn(prop), prop)}")
183
+
184
+ for location in location_properties.keys():
185
+ sub_device = device.get_sub_device(location)
186
+ writable_props = sub_device.profiles.writable_properties
187
+ logger.info(
188
+ f"test {device_name}.profiles.{location}.writable_properties: {sub_device.profiles.writable_properties}"
189
+ )
190
+ for prop in writable_props:
191
+ logger.info(
192
+ f"check {device_name}.{location}.set_{prop}: {_check_result(sub_device.get_property_set_fn(prop), prop)}"
193
+ )
194
+
195
+ return _check_control
@@ -0,0 +1,145 @@
1
+ import abc
2
+ import json
3
+ import logging
4
+ import os
5
+ from glob import glob
6
+ from typing import Callable
7
+
8
+ import pytest
9
+ from aiohttp import ClientSession
10
+ from deepdiff import DeepDiff
11
+
12
+ from thinqconnect.devices.connect_device import ConnectBaseDevice
13
+ from thinqconnect.thinq_api import ThinQApi
14
+
15
+ logger = logging.getLogger("test")
16
+
17
+
18
+ class DeviceTestBase(abc.ABC):
19
+ @pytest.mark.asyncio
20
+ async def test_device(
21
+ self,
22
+ model_name: str,
23
+ generate_device: Callable[[type[ConnectBaseDevice], ThinQApi, dict, str, str, str | None], ConnectBaseDevice],
24
+ json_object: Callable[[str], dict],
25
+ test_device_profile: Callable[[str, ConnectBaseDevice], dict],
26
+ test_device_status: Callable[[str, ConnectBaseDevice, dict, bool], dict],
27
+ check_device_control: Callable[[str, ConnectBaseDevice], None],
28
+ ):
29
+ async with ClientSession() as session:
30
+ access_token, client_id = self.get_credentials()
31
+ thinq_api = ThinQApi(
32
+ session=session,
33
+ access_token=access_token,
34
+ country_code="KR",
35
+ client_id=client_id,
36
+ )
37
+ device = generate_device(
38
+ self.get_device_class(),
39
+ thinq_api,
40
+ json_object(self.get_profile_file_path(self.get_device_type(), model_name)),
41
+ self.get_device_type(),
42
+ model_name,
43
+ )
44
+
45
+ await self.run_device_test(
46
+ device,
47
+ json_object,
48
+ test_device_profile,
49
+ test_device_status,
50
+ check_device_control,
51
+ )
52
+
53
+ @classmethod
54
+ def get_credentials(cls) -> tuple[str, str]:
55
+ access_token = "ab3f3fa8443d91d48a2e331c6489ae0c1133acd441e539035ac1"
56
+ client_id = "test_client_id"
57
+ return (access_token, client_id)
58
+
59
+ @classmethod
60
+ def get_device_type_path(cls, device_type: str) -> str:
61
+ short_device_type = cls.get_short_device_type(device_type)
62
+ return f"tests/devices/{short_device_type}/"
63
+
64
+ @classmethod
65
+ def get_profile_file_path(cls, device_type: str, model_name: str) -> str:
66
+ return f"{cls.get_device_type_path(device_type)}{model_name}/profile.json"
67
+
68
+ @classmethod
69
+ def get_result_file_path(cls, device_type: str, model_name: str) -> str:
70
+ return f"{cls.get_device_type_path(device_type)}result_{model_name}.json"
71
+
72
+ @classmethod
73
+ def get_short_device_type(cls, device_type: str) -> str:
74
+ return device_type.split("DEVICE_")[1].lower()
75
+
76
+ @classmethod
77
+ def write_test_result(cls, device_type: str, model_name: str, test_result: dict) -> str:
78
+ try:
79
+ file_path = cls.get_result_file_path(device_type, model_name)
80
+ if file_exist := os.path.exists(file_path):
81
+ with open(file_path) as file:
82
+ if file:
83
+ prev_result = json.load(file)
84
+ if not DeepDiff(prev_result, test_result, ignore_order=True):
85
+ logger.info("Test Result is not Changed.")
86
+ return
87
+
88
+ with open(file_path, "w") as file:
89
+ json.dump(test_result, file, indent=4)
90
+
91
+ except Exception as e:
92
+ logger.info(f"An error occurred: {e}")
93
+
94
+ if not file_exist:
95
+ logger.info(f"Test Result is Created to {file_path}")
96
+ else:
97
+ logger.info(f"Test Result is Updated to {file_path}")
98
+ assert False
99
+
100
+ @classmethod
101
+ async def run_device_test(
102
+ cls,
103
+ device: ConnectBaseDevice,
104
+ json_object: Callable[[str], dict],
105
+ test_device_profile: Callable[[str, ConnectBaseDevice], dict],
106
+ test_device_status: Callable[[str, ConnectBaseDevice, dict, bool], dict],
107
+ check_device_control: Callable[[str, ConnectBaseDevice], None],
108
+ ):
109
+ device_type = device.device_type
110
+ short_device_type = cls.get_short_device_type(device_type)
111
+ model_name = device.model_name
112
+ test_result = {"profile": None, "status": {}, "event": {}}
113
+
114
+ logger.info(f"{device_type} Test with model : {model_name}")
115
+
116
+ test_result["profile"] = test_device_profile(device_type, device)
117
+
118
+ status_files = glob(f"tests/devices/{short_device_type}/{model_name}/status/*.json")
119
+ for status_file in status_files:
120
+ status = json_object(status_file)
121
+ test_result["status"][status_file.split("/")[-1]] = test_device_status(device_type, device, status)
122
+
123
+ event_files = glob(f"tests/devices/{short_device_type}/{model_name}/event/*.json")
124
+
125
+ for event_file in sorted(event_files):
126
+ print(event_file.split("/")[-1])
127
+ event = json_object(event_file)
128
+ test_result["event"][event_file.split("/")[-1]] = test_device_status(
129
+ device_type, device, event, is_update=True
130
+ )
131
+
132
+ check_device_control(device_type, device)
133
+
134
+ logger.info(f"{device_type} Test with model : {model_name} is done.")
135
+ cls.write_test_result(device_type, model_name, test_result)
136
+
137
+ @classmethod
138
+ @abc.abstractmethod
139
+ def get_device_class(cls) -> type[ConnectBaseDevice]:
140
+ pass
141
+
142
+ @classmethod
143
+ @abc.abstractmethod
144
+ def get_device_type(cls) -> str:
145
+ pass
@@ -0,0 +1,29 @@
1
+ from __future__ import annotations
2
+
3
+ from tests.device_test_base import DeviceTestBase
4
+ from thinqconnect.const import DeviceType
5
+ from thinqconnect.devices.air_conditioner import AirConditionerDevice
6
+
7
+
8
+ class TestAirConditioner(DeviceTestBase):
9
+ @classmethod
10
+ def get_device_class(cls) -> type[AirConditionerDevice]:
11
+ return AirConditionerDevice
12
+
13
+ @classmethod
14
+ def get_device_type(cls) -> str:
15
+ return DeviceType.AIR_CONDITIONER
16
+
17
+ async def check_control(self, device: AirConditionerDevice):
18
+ await device.set_current_job_mode("COOL")
19
+ await device.set_air_con_operation_mode("POWER_ON")
20
+ await device.set_air_con_operation_mode("POWER_OFF")
21
+ await device.set_current_job_mode("AIR_DRY")
22
+ await device.set_air_clean_operation_mode("START")
23
+ await device.set_monitoring_enabled("ON_WORKING")
24
+ await device.set_wind_strength("MID")
25
+ await device.set_relative_time_to_stop(1, 10)
26
+ await device.set_sleep_timer_relative_time_to_stop(1, 10)
27
+ await device.set_target_temperature(20)
28
+ await device.set_cool_target_temperature(24)
29
+ await device.set_power_save_enabled(False)
@@ -0,0 +1,23 @@
1
+ from __future__ import annotations
2
+
3
+ from tests.device_test_base import DeviceTestBase
4
+ from thinqconnect.const import DeviceType
5
+ from thinqconnect.devices.air_purifier import AirPurifierDevice
6
+
7
+
8
+ class TestAirPurifier(DeviceTestBase):
9
+ @classmethod
10
+ def get_device_class(cls) -> type[AirPurifierDevice]:
11
+ return AirPurifierDevice
12
+
13
+ @classmethod
14
+ def get_device_type(cls) -> str:
15
+ return DeviceType.AIR_PURIFIER
16
+
17
+ async def check_control(self, device: AirPurifierDevice):
18
+ # NOTE: AIR_910604_WW 제어 테스트이고, 시뮬레이터 기기로 테스트 시 전원 켠 후 Mode를 Single로 변경하고 Speed를 Turbo로 변경 필요
19
+ await device.set_wind_strength("LOW")
20
+ await device.set_absolute_time_to_stop(13, 30)
21
+ await device.set_air_purifier_operation_mode("POWER_OFF")
22
+ await device.set_absolute_time_to_start(12, 30)
23
+ await device.set_air_purifier_operation_mode("POWER_ON")
@@ -0,0 +1,32 @@
1
+ from __future__ import annotations
2
+
3
+ from tests.device_test_base import DeviceTestBase
4
+ from thinqconnect.const import DeviceType
5
+ from thinqconnect.devices.air_purifier_fan import AirPurifierFanDevice
6
+
7
+
8
+ class TestAirPurifierFan(DeviceTestBase):
9
+ @classmethod
10
+ def get_device_class(cls) -> type[AirPurifierFanDevice]:
11
+ return AirPurifierFanDevice
12
+
13
+ @classmethod
14
+ def get_device_type(cls) -> str:
15
+ return DeviceType.AIR_PURIFIER_FAN
16
+
17
+ async def check_control(self, device: AirPurifierFanDevice):
18
+ # NOTE: 밀웜 동작 확인 불가
19
+ # await device.set_current_job_mode("DIRECT_CLEAN")
20
+ # await device.set_relative_time_to_stop(5)
21
+ # await device.set_wind_angle("ANGLE_45")
22
+ # await device.set_warm_mode("WARM_ON")
23
+ # await device.set_wind_temperature(35)
24
+
25
+ # NOTE: 밀웜 테스트 완료
26
+ await device.set_air_fan_operation_mode("POWER_ON")
27
+ await device.set_absolute_time_to_stop(13, 30)
28
+ await device.set_display_light("LEVEL_2")
29
+ await device.set_wind_strength("AUTO")
30
+ await device.set_uv_nano("ON")
31
+ await device.set_air_fan_operation_mode("POWER_OFF")
32
+ await device.set_absolute_time_to_start(12, 30)
@@ -0,0 +1,23 @@
1
+ from __future__ import annotations
2
+
3
+ from tests.device_test_base import DeviceTestBase
4
+ from thinqconnect.const import DeviceType
5
+ from thinqconnect.devices.ceiling_fan import CeilingFanDevice
6
+
7
+
8
+ class TestCeilingFan(DeviceTestBase):
9
+ @classmethod
10
+ def get_device_class(cls) -> type[CeilingFanDevice]:
11
+ return CeilingFanDevice
12
+
13
+ @classmethod
14
+ def get_device_type(cls) -> str:
15
+ return DeviceType.CEILING_FAN
16
+
17
+ async def check_control(self, device: CeilingFanDevice):
18
+ await device.set_ceiling_fan_operation_mode("POWER_ON")
19
+ await device.set_ceiling_fan_operation_mode("POWER_OFF")
20
+ await device.set_wind_strength("TURBO")
21
+ await device.set_wind_strength("HIGH")
22
+ await device.set_wind_strength("LOW")
23
+ await device.set_wind_strength("MID")
tests/test_cooktop.py ADDED
@@ -0,0 +1,22 @@
1
+ from __future__ import annotations
2
+
3
+ from tests.device_test_base import DeviceTestBase
4
+ from thinqconnect.const import DeviceType
5
+ from thinqconnect.devices.cooktop import CooktopDevice
6
+
7
+
8
+ class TestCooktop(DeviceTestBase):
9
+ @classmethod
10
+ def get_device_class(cls) -> type[CooktopDevice]:
11
+ return CooktopDevice
12
+
13
+ @classmethod
14
+ def get_device_type(cls) -> str:
15
+ return DeviceType.COOKTOP
16
+
17
+ async def check_control(self, device: CooktopDevice):
18
+ await device.set_operation_mode("POWER_OFF")
19
+ await device.set_power_level("left_rear", 1)
20
+ # await device.set_power_level("left_rear", 15) # negative
21
+ await device.set_remain_hour("right_front", 1)
22
+ await device.set_remain_minute("left_rear", 5)
@@ -0,0 +1,20 @@
1
+ from __future__ import annotations
2
+
3
+ from tests.device_test_base import DeviceTestBase
4
+ from thinqconnect.const import DeviceType
5
+ from thinqconnect.devices.dehumidifier import DehumidifierDevice
6
+
7
+
8
+ class TestDehumidifier(DeviceTestBase):
9
+ @classmethod
10
+ def get_device_class(cls) -> type[DehumidifierDevice]:
11
+ return DehumidifierDevice
12
+
13
+ @classmethod
14
+ def get_device_type(cls) -> str:
15
+ return DeviceType.DEHUMIDIFIER
16
+
17
+ async def check_control(self, device: DehumidifierDevice):
18
+ await device.set_dehumidifier_operation_mode("POWER_ON")
19
+ await device.set_wind_strength("LOW")
20
+ await device.set_dehumidifier_operation_mode("POWER_OFF")
@@ -0,0 +1,19 @@
1
+ from __future__ import annotations
2
+
3
+ from tests.device_test_base import DeviceTestBase
4
+ from thinqconnect.const import DeviceType
5
+ from thinqconnect.devices.dish_washer import DishWasherDevice
6
+
7
+
8
+ class TestDishWasher(DeviceTestBase):
9
+ @classmethod
10
+ def get_device_class(cls) -> type[DishWasherDevice]:
11
+ return DishWasherDevice
12
+
13
+ @classmethod
14
+ def get_device_type(cls) -> str:
15
+ return DeviceType.DISH_WASHER
16
+
17
+ async def check_control(self, device: DishWasherDevice):
18
+ await device.set_dish_washer_operation_mode("START")
19
+ await device.set_relative_hour_to_start(1)
tests/test_dryer.py ADDED
@@ -0,0 +1,18 @@
1
+ from __future__ import annotations
2
+
3
+ from tests.device_test_base import DeviceTestBase
4
+ from thinqconnect.const import DeviceType
5
+ from thinqconnect.devices.dryer import DryerDevice
6
+
7
+
8
+ class TestDryer(DeviceTestBase):
9
+ @classmethod
10
+ def get_device_class(cls) -> type[DryerDevice]:
11
+ return DryerDevice
12
+
13
+ @classmethod
14
+ def get_device_type(cls) -> str:
15
+ return DeviceType.DRYER
16
+
17
+ async def check_control(self, device: DryerDevice):
18
+ await device.set_dryer_operation_mode("POWER_OFF")
@@ -0,0 +1,15 @@
1
+ from __future__ import annotations
2
+
3
+ from tests.device_test_base import DeviceTestBase
4
+ from thinqconnect.const import DeviceType
5
+ from thinqconnect.devices.home_brew import HomeBrewDevice
6
+
7
+
8
+ class TestHomeBrew(DeviceTestBase):
9
+ @classmethod
10
+ def get_device_class(cls) -> type[HomeBrewDevice]:
11
+ return HomeBrewDevice
12
+
13
+ @classmethod
14
+ def get_device_type(cls) -> str:
15
+ return DeviceType.HOME_BREW
tests/test_hood.py ADDED
@@ -0,0 +1,19 @@
1
+ from __future__ import annotations
2
+
3
+ from tests.device_test_base import DeviceTestBase
4
+ from thinqconnect.const import DeviceType
5
+ from thinqconnect.devices.hood import HoodDevice
6
+
7
+
8
+ class TestHood(DeviceTestBase):
9
+ @classmethod
10
+ def get_device_class(cls) -> type[HoodDevice]:
11
+ return HoodDevice
12
+
13
+ @classmethod
14
+ def get_device_type(cls) -> str:
15
+ return DeviceType.HOOD
16
+
17
+ async def check_control(self, device: HoodDevice):
18
+ await device.set_fan_speed(2)
19
+ await device.set_lamp_brightness(1)
@@ -0,0 +1,23 @@
1
+ from __future__ import annotations
2
+
3
+ from tests.device_test_base import DeviceTestBase
4
+ from thinqconnect.const import DeviceType
5
+ from thinqconnect.devices.humidifier import HumidifierDevice
6
+
7
+
8
+ class TestHumidifier(DeviceTestBase):
9
+ @classmethod
10
+ def get_device_class(cls) -> type[HumidifierDevice]:
11
+ return HumidifierDevice
12
+
13
+ @classmethod
14
+ def get_device_type(cls) -> str:
15
+ return DeviceType.HUMIDIFIER
16
+
17
+ async def check_control(self, device: HumidifierDevice):
18
+ # NOTE: 실기기 테스트 필요
19
+ await device.set_current_job_mode("AIR_CLEAN")
20
+ await device.set_humidifier_operation_mode("POWER_OFF")
21
+ await device.set_humidifier_operation_mode("POWER_ON")
22
+ await device.set_sleep_mode("SLEEP_OFF")
23
+ await device.set_sleep_mode("SLEEP_ON")
@@ -0,0 +1,15 @@
1
+ from __future__ import annotations
2
+
3
+ from tests.device_test_base import DeviceTestBase
4
+ from thinqconnect.const import DeviceType
5
+ from thinqconnect.devices.kimchi_refrigerator import KimchiRefrigeratorDevice
6
+
7
+
8
+ class TestKimchiRefrigerator(DeviceTestBase):
9
+ @classmethod
10
+ def get_device_class(cls) -> type[KimchiRefrigeratorDevice]:
11
+ return KimchiRefrigeratorDevice
12
+
13
+ @classmethod
14
+ def get_device_type(cls) -> str:
15
+ return DeviceType.KIMCHI_REFRIGERATOR
@@ -0,0 +1,19 @@
1
+ from __future__ import annotations
2
+
3
+ from tests.device_test_base import DeviceTestBase
4
+ from thinqconnect.const import DeviceType
5
+ from thinqconnect.devices.microwave_oven import MicrowaveOvenDevice
6
+
7
+
8
+ class TestMicrowaveOven(DeviceTestBase):
9
+ @classmethod
10
+ def get_device_class(cls) -> type[MicrowaveOvenDevice]:
11
+ return MicrowaveOvenDevice
12
+
13
+ @classmethod
14
+ def get_device_type(cls) -> str:
15
+ return DeviceType.MICROWAVE_OVEN
16
+
17
+ async def check_control(self, device: MicrowaveOvenDevice):
18
+ await device.set_fan_speed(2)
19
+ await device.set_lamp_brightness(1)