diff --git a/cli.py b/cli.py index 0a8ff6a..8e7d5bf 100644 --- a/cli.py +++ b/cli.py @@ -6,6 +6,7 @@ from cli_ac_menu import show_aircon_menu from cli_oven_menu import show_oven_menu +from cli_refrigerator_menu import show_refrigerator_menu from cli_washerdryer_menu import show_washerdryer_menu from whirlpool.appliancesmanager import AppliancesManager from whirlpool.auth import Auth @@ -22,7 +23,10 @@ parser.add_argument("-e", "--email", help="Email address") parser.add_argument("-p", "--password", help="Password") parser.add_argument( - "-b", "--brand", help="Brand (whirlpool/maytag/kitchenaid)", default="whirlpool" + "-b", + "--brand", + help="Brand (whirlpool/maytag/kitchenaid/consul)", + default="whirlpool", ) parser.add_argument("-r", "--region", help="Region (EU/US)", default="EU") parser.add_argument("-l", "--list", help="List appliances", action="store_true") @@ -40,6 +44,8 @@ def attr_upd(): selected_brand = Brand.Maytag elif args.brand == "kitchenaid": selected_brand = Brand.KitchenAid + elif args.brand == "consul": + selected_brand = Brand.Consul else: logger.error("Invalid brand argument") return @@ -66,6 +72,7 @@ def attr_upd(): print(appliance_manager.aircons) print(appliance_manager.washer_dryers) print(appliance_manager.ovens) + print(appliance_manager.refrigerators) return if not args.said: @@ -87,5 +94,10 @@ def attr_upd(): await show_oven_menu(backend_selector, auth, args.said, session) return + for rf_data in appliance_manager.refrigerators: + if rf_data["SAID"] == args.said: + await show_refrigerator_menu(backend_selector, auth, args.said, session) + return + asyncio.run(start()) diff --git a/cli_refrigerator_menu.py b/cli_refrigerator_menu.py new file mode 100644 index 0000000..95e5684 --- /dev/null +++ b/cli_refrigerator_menu.py @@ -0,0 +1,72 @@ +import aioconsole + +from whirlpool.refrigerator import Refrigerator + + +async def show_refrigerator_menu(backend_selector, auth, said, session): + def print_menu(): + print("\n") + print(30 * "-", "MENU", 30 * "-") + print("+. Temp up") + print("-. Temp down") + print("-4. Set -4°C") + print("-2. Set -2°C") + print("0. Set 0°C") + print("3. Set 3°C") + print("5. Set 5°C") + print("t. Turbo toggle") + print("l. Display lock toggle") + print("u. Update status from server") + print("p. Print status") + print("r. Print raw status") + print("c. Custom command") + print("q. Exit") + print(67 * "-") + + def print_status(bc: Refrigerator): + print("current_temp: " + str(rf.get_offset_temp()) + "°C") + print("turbo_mode: " + str(rf.get_turbo_mode())) + print("display_locked: " + str(rf.get_display_lock())) + + def attr_upd(): + print("Attributes updated") + + rf = Refrigerator(backend_selector, auth, said, session) + rf.register_attr_callback(attr_upd) + await rf.connect() + + loop = True + while loop: + print_menu() + choice = await aioconsole.ainput("Enter your choice: ") + + if choice == "+": + temp = rf.get_temp() - 1 + await rf.set_temp(temp) + elif choice == "-": + temp = rf.get_temp() + 1 + await rf.set_temp(temp) + elif choice in ["-4", "-2", "0", "3", "5"]: + temp = int(choice) + await rf.set_offset_temp(temp) + elif choice == "t": + await rf.set_turbo_mode(not rf.get_turbo_mode()) + elif choice == "l": + await rf.set_display_lock(not rf.get_display_lock()) + elif choice == "p": + print_status(rf) + elif choice == "u": + await rf.fetch_data() + print_status(rf) + elif choice == "r": + print(rf._data_dict) + elif choice == "c": + cmd = await aioconsole.ainput("Command: ") + val = await aioconsole.ainput("Value: ") + await rf.send_attributes({cmd: val}) + elif choice == "q": + await rf.disconnect() + print("Bye") + loop = False + else: + print("Wrong option selection. Enter any key to try again..") diff --git a/tests/conftest.py b/tests/conftest.py index 524586b..858150d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -13,6 +13,7 @@ from whirlpool.appliancesmanager import AppliancesManager from whirlpool.auth import Auth from whirlpool.oven import Oven +from whirlpool.refrigerator import Refrigerator from whirlpool.washerdryer import WasherDryer SAID = "WPR1XYZABC123" @@ -67,6 +68,15 @@ def aircon_fixture(backend_selector_mock, auth_fixture, client_session_fixture): yield aircon +@pytest.fixture(name="refrigerator") +def refrigerator_fixture(backend_selector_mock, auth_fixture, client_session_fixture): + with patch("whirlpool.appliance.Appliance._create_headers", return_value={}): + refrigerator = Refrigerator( + backend_selector_mock, auth_fixture, SAID, client_session_fixture + ) + yield refrigerator + + @pytest.fixture(name="appliances_manager") def appliances_manager_fixture( backend_selector_mock, auth_fixture, client_session_fixture diff --git a/tests/data/refrigerator_data.json b/tests/data/refrigerator_data.json new file mode 100644 index 0000000..9e053c0 --- /dev/null +++ b/tests/data/refrigerator_data.json @@ -0,0 +1,466 @@ +{ + "DATA1": { + "_id": "WPR43R8FNDJ4C", + "applianceId": "WPR43R8FNDJ4C", + "lastFullSyncTime": 1663677597931, + "lastModified": 1736031905504, + "attributes": { + "XCat_ApplianceInfoSetSerialNumber": { + "value": "TED2018", + "updateTime": 1735714437212 + }, + "Sys_OpSetCalibrationOn": { + "value": "0", + "updateTime": 1735714437212 + }, + "Sys_AlertStatusCustomerFaultCode": { + "value": "0", + "updateTime": 1562028497470 + }, + "lkCans": { + "value": "14", + "updateTime": 1736007173422 + }, + "XCat_WifiSetDeprovisionWifiCommModule": { + "value": "0", + "updateTime": 1735714437212 + }, + "Pantry_OpStatusDoorOpen": { + "value": "0", + "updateTime": 1735714437212 + }, + "ModelNumber": { + "value": "CZE12", + "updateTime": 1735714435000 + }, + "ISP_PART_NUMBER": { + "value": "W00000000", + "updateTime": 1735714435000 + }, + "Freezer_OpStatusContentsWeight": { + "value": "3", + "updateTime": 1736031905314 + }, + "XCat_OdometerStatusRunningHours": { + "value": "553", + "updateTime": 1736030707778 + }, + "ApplianceVersionNumber": { + "value": "0", + "updateTime": 1735714435000 + }, + "ProjectReleaseNumber": { + "value": "W11224365", + "updateTime": 1570702737991 + }, + "ccuri": { + "value": "API144_FRIG_V12", + "updateTime": 1735714435000 + }, + "version": { + "value": "1", + "updateTime": 1735714436056 + }, + "lkLongneck": { + "value": "59", + "updateTime": 1736007173422 + }, + "XCat_PersistentInfoVersion": { + "value": "12", + "updateTime": 1735714437212 + }, + "lkVolume": { + "value": "27.045", + "updateTime": 1736007173422 + }, + "lkBottles": { + "value": "2", + "updateTime": 1736007173422 + }, + "SerialNumber": { + "value": "ED2018", + "updateTime": 1735714435000 + }, + "Refrigerator_OpStatusDoorOpen": { + "value": "0", + "updateTime": 1736007170085 + }, + "Sys_DisplaySetCavityBrightness": { + "value": "0", + "updateTime": 1736007170085 + }, + "lkWeight": { + "value": "39785.0", + "updateTime": 1736007173422 + }, + "Refrigerator_OpSetTempPreset": { + "value": "10", + "updateTime": 1736030932627 + }, + "XCat_WifiStatusRssiAntennaDiversity": { + "value": "-31", + "updateTime": 1735714437212 + }, + "Sys_AlertStatusDoorOpenAlarm": { + "value": "0", + "updateTime": 1735714437212 + }, + "XCat_PowerStatusPowerOutage": { + "value": "1", + "updateTime": 1734307490309 + }, + "Sys_OpStatusState": { + "value": "1", + "updateTime": 1736030847546 + }, + "XCat_OdometerStatusTotalHours": { + "value": "553", + "updateTime": 1736030707778 + }, + "applianceId": { + "value": "72698", + "updateTime": 1736007173422 + }, + "Sys_OpSetMaxCool": { + "value": "0", + "updateTime": 1735714437212 + }, + "TimezoneId": { + "value": "America/New_York", + "updateTime": 1580769838547 + }, + "XCat_PersistentInfoSaid": { + "value": "WPR43R8FNDJ4C", + "updateTime": 1735714437212 + }, + "XCat_WifiSetPublishApplianceState": { + "value": "0", + "updateTime": 1735714437212 + }, + "orgId": { + "value": "NAR", + "updateTime": 1592607815213 + }, + "SAID": { + "value": "WPR43R8FNDJ4C", + "updateTime": 1735714435000 + }, + "Sys_OpSetControlLock": { + "value": "0", + "updateTime": 1735714437212 + }, + "UtcOffset": { + "value": "-18000", + "updateTime": 1580769838547 + }, + "DstOffset": { + "value": "0", + "updateTime": 1580769838547 + }, + "XCat_WifiStatusIspCheck": { + "value": "1", + "updateTime": 1735714437212 + }, + "CC_URI": { + "value": "API144_FRIG_V12", + "updateTime": 1593115050140 + }, + "lkDelta": { + "value": "-551.0", + "updateTime": 1736007173422 + }, + "DateTimeMode": { + "value": "2", + "updateTime": 1580769838547 + }, + "XCat_ApplianceInfoSetModelNumber": { + "value": "CZE12", + "updateTime": 1735714437212 + }, + "Refrigerator_OpStatusContentsWeight": { + "value": "39785", + "updateTime": 1736007173422 + }, + "XCat_WifiSetRebootWifiCommModule": { + "value": "0", + "updateTime": 1735714437212 + }, + "XCat_ConfigSetApplianceCapability": { + "value": "0", + "updateTime": 1562028497470 + }, + "ISP_WIFI_VERSION": { + "value": "9.0.0", + "updateTime": 1735714435000 + }, + "SubscribeClaimstate": { + "value": "1", + "updateTime": 1592607815750 + }, + "XCat_PersistentInfoMacAddress": { + "value": "88:E7:12:0F:E3:9A", + "updateTime": 1735714437212 + }, + "Sys_OpSetVacationMode": { + "value": "0", + "updateTime": 1648382747876 + }, + "XCat_DateTimeSetDateTimeSet": { + "value": "2024-12-30T02:44:23-03:00", + "updateTime": 1735537463798 + }, + "createdDate": { + "value": "1736007174451", + "updateTime": 1736007173422 + }, + "TimeZoneId": { + "value": "America/Sao_Paulo", + "updateTime": 1735714436058 + }, + "ISP_WIFI_PART_NUMBER": { + "value": "W11224365", + "updateTime": 1735714435000 + }, + "Online": { + "value": "0", + "updateTime": 1735714435238 + }, + "MAC_Address": { + "value": "88:e7:12:0f:e3:9a", + "updateTime": 1735714435000 + } + } + }, + "DATA2": { + "_id": "WPR43R8FNDJ4C", + "applianceId": "WPR43R8FNDJ4C", + "lastFullSyncTime": 1663677597931, + "lastModified": 1736031905504, + "attributes": { + "XCat_ApplianceInfoSetSerialNumber": { + "value": "TED2018", + "updateTime": 1735714437212 + }, + "Sys_OpSetCalibrationOn": { + "value": "0", + "updateTime": 1735714437212 + }, + "Sys_AlertStatusCustomerFaultCode": { + "value": "0", + "updateTime": 1562028497470 + }, + "lkCans": { + "value": "14", + "updateTime": 1736007173422 + }, + "XCat_WifiSetDeprovisionWifiCommModule": { + "value": "0", + "updateTime": 1735714437212 + }, + "Pantry_OpStatusDoorOpen": { + "value": "0", + "updateTime": 1735714437212 + }, + "ModelNumber": { + "value": "CZE12", + "updateTime": 1735714435000 + }, + "ISP_PART_NUMBER": { + "value": "W00000000", + "updateTime": 1735714435000 + }, + "Freezer_OpStatusContentsWeight": { + "value": "3", + "updateTime": 1736031905314 + }, + "XCat_OdometerStatusRunningHours": { + "value": "553", + "updateTime": 1736030707778 + }, + "ApplianceVersionNumber": { + "value": "0", + "updateTime": 1735714435000 + }, + "ProjectReleaseNumber": { + "value": "W11224365", + "updateTime": 1570702737991 + }, + "ccuri": { + "value": "API144_FRIG_V12", + "updateTime": 1735714435000 + }, + "version": { + "value": "1", + "updateTime": 1735714436056 + }, + "lkLongneck": { + "value": "59", + "updateTime": 1736007173422 + }, + "XCat_PersistentInfoVersion": { + "value": "12", + "updateTime": 1735714437212 + }, + "lkVolume": { + "value": "27.045", + "updateTime": 1736007173422 + }, + "lkBottles": { + "value": "2", + "updateTime": 1736007173422 + }, + "SerialNumber": { + "value": "ED2018", + "updateTime": 1735714435000 + }, + "Refrigerator_OpStatusDoorOpen": { + "value": "0", + "updateTime": 1736007170085 + }, + "Sys_DisplaySetCavityBrightness": { + "value": "0", + "updateTime": 1736007170085 + }, + "lkWeight": { + "value": "39785.0", + "updateTime": 1736007173422 + }, + "Refrigerator_OpSetTempPreset": { + "value": "8", + "updateTime": 1736030932627 + }, + "XCat_WifiStatusRssiAntennaDiversity": { + "value": "-31", + "updateTime": 1735714437212 + }, + "Sys_AlertStatusDoorOpenAlarm": { + "value": "0", + "updateTime": 1735714437212 + }, + "XCat_PowerStatusPowerOutage": { + "value": "1", + "updateTime": 1734307490309 + }, + "Sys_OpStatusState": { + "value": "1", + "updateTime": 1736030847546 + }, + "XCat_OdometerStatusTotalHours": { + "value": "553", + "updateTime": 1736030707778 + }, + "applianceId": { + "value": "72698", + "updateTime": 1736007173422 + }, + "Sys_OpSetMaxCool": { + "value": "1", + "updateTime": 1735714437212 + }, + "TimezoneId": { + "value": "America/New_York", + "updateTime": 1580769838547 + }, + "XCat_PersistentInfoSaid": { + "value": "WPR43R8FNDJ4C", + "updateTime": 1735714437212 + }, + "XCat_WifiSetPublishApplianceState": { + "value": "0", + "updateTime": 1735714437212 + }, + "orgId": { + "value": "NAR", + "updateTime": 1592607815213 + }, + "SAID": { + "value": "WPR43R8FNDJ4C", + "updateTime": 1735714435000 + }, + "Sys_OpSetControlLock": { + "value": "1", + "updateTime": 1735714437212 + }, + "UtcOffset": { + "value": "-18000", + "updateTime": 1580769838547 + }, + "DstOffset": { + "value": "0", + "updateTime": 1580769838547 + }, + "XCat_WifiStatusIspCheck": { + "value": "1", + "updateTime": 1735714437212 + }, + "CC_URI": { + "value": "API144_FRIG_V12", + "updateTime": 1593115050140 + }, + "lkDelta": { + "value": "-551.0", + "updateTime": 1736007173422 + }, + "DateTimeMode": { + "value": "2", + "updateTime": 1580769838547 + }, + "XCat_ApplianceInfoSetModelNumber": { + "value": "CZE12", + "updateTime": 1735714437212 + }, + "Refrigerator_OpStatusContentsWeight": { + "value": "39785", + "updateTime": 1736007173422 + }, + "XCat_WifiSetRebootWifiCommModule": { + "value": "0", + "updateTime": 1735714437212 + }, + "XCat_ConfigSetApplianceCapability": { + "value": "0", + "updateTime": 1562028497470 + }, + "ISP_WIFI_VERSION": { + "value": "9.0.0", + "updateTime": 1735714435000 + }, + "SubscribeClaimstate": { + "value": "1", + "updateTime": 1592607815750 + }, + "XCat_PersistentInfoMacAddress": { + "value": "88:E7:12:0F:E3:9A", + "updateTime": 1735714437212 + }, + "Sys_OpSetVacationMode": { + "value": "0", + "updateTime": 1648382747876 + }, + "XCat_DateTimeSetDateTimeSet": { + "value": "2024-12-30T02:44:23-03:00", + "updateTime": 1735537463798 + }, + "createdDate": { + "value": "1736007174451", + "updateTime": 1736007173422 + }, + "TimeZoneId": { + "value": "America/Sao_Paulo", + "updateTime": 1735714436058 + }, + "ISP_WIFI_PART_NUMBER": { + "value": "W11224365", + "updateTime": 1735714435000 + }, + "Online": { + "value": "1", + "updateTime": 1735714435238 + }, + "MAC_Address": { + "value": "88:e7:12:0f:e3:9a", + "updateTime": 1735714435000 + } + } + } +} diff --git a/tests/test_refrigerator.py b/tests/test_refrigerator.py new file mode 100644 index 0000000..cfcb729 --- /dev/null +++ b/tests/test_refrigerator.py @@ -0,0 +1,116 @@ +import json +from collections.abc import Callable +from pathlib import Path +from typing import Any + +import pytest +from yarl import URL + +from whirlpool.backendselector import BackendSelector +from whirlpool.refrigerator import Refrigerator + +ACCOUNT_ID = 111222333 + + +CURR_DIR = Path(__file__).parent +DATA_DIR = CURR_DIR / "data" + +REFRIGERATOR_DATA = json.loads((DATA_DIR / "refrigerator_data.json").read_text()) + +DATA1 = REFRIGERATOR_DATA["DATA1"] +DATA2 = REFRIGERATOR_DATA["DATA2"] + + +async def test_attributes( + refrigerator: Refrigerator, + backend_selector_mock: BackendSelector, + aioresponses_mock, +): + aioresponses_mock.get( + backend_selector_mock.websocket_url, + payload={"url": "wss://something"}, + repeat=True, + ) + aioresponses_mock.get( + backend_selector_mock.get_appliance_data_url(refrigerator.said), payload=DATA1 + ) + + await refrigerator.connect() + assert refrigerator.get_online() is False + assert refrigerator.get_offset_temp() == "0" + assert refrigerator.get_turbo_mode() is False + assert refrigerator.get_display_lock() is False + await refrigerator.disconnect() + + aioresponses_mock.get( + backend_selector_mock.get_appliance_data_url(refrigerator.said), payload=DATA2 + ) + + await refrigerator.connect() + assert refrigerator.get_online() is True + assert refrigerator.get_turbo_mode() is True + assert refrigerator.get_display_lock() is True + assert refrigerator.get_offset_temp() == "5" + await refrigerator.disconnect() + + +@pytest.mark.parametrize( + ["method", "argument", "expected_json"], + [ + (Refrigerator.set_offset_temp, -4, {"Refrigerator_OpSetTempPreset": "12"}), + (Refrigerator.set_offset_temp, -2, {"Refrigerator_OpSetTempPreset": "11"}), + (Refrigerator.set_offset_temp, 0, {"Refrigerator_OpSetTempPreset": "10"}), + (Refrigerator.set_offset_temp, 3, {"Refrigerator_OpSetTempPreset": "9"}), + (Refrigerator.set_offset_temp, 5, {"Refrigerator_OpSetTempPreset": "8"}), + (Refrigerator.set_temp, 8, {"Refrigerator_OpSetTempPreset": "8"}), + (Refrigerator.set_temp, 12, {"Refrigerator_OpSetTempPreset": "12"}), + (Refrigerator.set_turbo_mode, True, {"Sys_OpSetMaxCool": "1"}), + (Refrigerator.set_turbo_mode, False, {"Sys_OpSetMaxCool": "0"}), + (Refrigerator.set_display_lock, True, {"Sys_OpSetControlLock": "1"}), + (Refrigerator.set_display_lock, False, {"Sys_OpSetControlLock": "0"}), + ], +) +async def test_setters( + refrigerator: Refrigerator, + backend_selector_mock: BackendSelector, + aioresponses_mock, + method: Callable, + argument: Any, + expected_json: dict, +): + expected_payload = { + "json": { + "body": expected_json, + "header": {"said": refrigerator.said, "command": "setAttributes"}, + } + } + + post_request_call_kwargs = { + "url": backend_selector_mock.appliance_command_url, + "method": "POST", + "data": None, + "json": expected_payload["json"], + "allow_redirects": True, + "headers": {}, + } + + url = backend_selector_mock.appliance_command_url + + aioresponses_mock.get( + backend_selector_mock.websocket_url, payload={"url": "wss://something"} + ) + aioresponses_mock.get( + backend_selector_mock.get_appliance_data_url(refrigerator.said), payload=DATA1 + ) + + await refrigerator.connect() + + # add call, call method + aioresponses_mock.post(url, payload=expected_payload) + await method(refrigerator, argument) + + # assert args and length + aioresponses_mock.assert_called_with(**post_request_call_kwargs) + assert len(aioresponses_mock.requests[("POST", URL(url))]) == 1 + + await refrigerator.disconnect() diff --git a/whirlpool/appliancesmanager.py b/whirlpool/appliancesmanager.py index 08151d8..39b40d8 100644 --- a/whirlpool/appliancesmanager.py +++ b/whirlpool/appliancesmanager.py @@ -20,6 +20,7 @@ def __init__( self._auth = auth self._aircons: list[dict[str, Any]] = [] self._washer_dryers: list[dict[str, Any]] = [] + self._refrigerators: list[dict[str, Any]] = [] self._ovens: list[dict[str, Any]] = [] self._session: aiohttp.ClientSession = session @@ -61,10 +62,15 @@ def _add_appliance(self, appliance: dict[str, Any]) -> None: "cooking_u2", "ddm_cooking_bio_self_clean_tourmaline_v2", ] + if any(model in data_model for model in oven_models): self._ovens.append(appliance_data) return + if "ddm_ted_refrigerator_v12" in data_model: + self._refrigerators.append(appliance_data) + return + LOGGER.warning("Unsupported appliance data model %s", data_model) async def _get_owned_appliances(self, account_id: str) -> bool: @@ -115,6 +121,10 @@ async def fetch_appliances(self): def aircons(self): return self._aircons + @property + def refrigerators(self): + return self._refrigerators + @property def washer_dryers(self): return self._washer_dryers diff --git a/whirlpool/backendselector.py b/whirlpool/backendselector.py index cb54a0f..cad1fd8 100644 --- a/whirlpool/backendselector.py +++ b/whirlpool/backendselector.py @@ -31,6 +31,12 @@ "client_secret": "T5j9T4ZAMnC6EMVpPAwZyKsRykXGfKOMDqikPHYpCKEMYjssPtJtuJtMYEc30g56", # noqa: E501 }, ], + Brand.Consul: [ + { + "client_id": "consul_lar_android_v1", + "client_secret": "xfPIj2fqhHXlK4bz2oPToDX5E0zHZ409ZLY6ZHiU3p_jh4wv_Ycg8haUhnB6yXuA", + } + ], } URLS: dict[Region, str] = { diff --git a/whirlpool/refrigerator.py b/whirlpool/refrigerator.py new file mode 100644 index 0000000..8d21cc8 --- /dev/null +++ b/whirlpool/refrigerator.py @@ -0,0 +1,61 @@ +import logging + +import aiohttp + +from .appliance import Appliance + +LOGGER = logging.getLogger(__name__) + +SETTING_TEMP = "Refrigerator_OpSetTempPreset" +SETTING_DISPLAY_LOCK = "Sys_OpSetControlLock" +SETTING_TURBO_MODE = "Sys_OpSetMaxCool" + +TEMP_MAP = { + -4: 12, + -2: 11, + 0: 10, + 3: 9, + 5: 8, +} + + +class Refrigerator(Appliance): + def __init__(self, backend_selector, auth, said, session: aiohttp.ClientSession): + Appliance.__init__(self, backend_selector, auth, said, session) + + def get_offset_temp(self): + reversed_temp_map = {v: k for k, v in TEMP_MAP.items()} + return str(reversed_temp_map[int(self.get_attribute(SETTING_TEMP))]) + + async def set_offset_temp(self, temp): + if temp in TEMP_MAP.keys(): + await self.send_attributes({SETTING_TEMP: str(TEMP_MAP[temp])}) + else: + LOGGER.error( + f"Invalid temperature: {temp}. Allowed values are {TEMP_MAP.keys()}." + ) + + def get_temp(self): + return int(self.get_attribute(SETTING_TEMP)) + + async def set_temp(self, temp: int): + if temp in TEMP_MAP.values(): + await self.send_attributes({SETTING_TEMP: str(temp)}) + else: + LOGGER.error( + f"Invalid temperature: {temp}. Allowed values are {TEMP_MAP.values()}." + ) + + def get_turbo_mode(self): + return self.attr_value_to_bool(self.get_attribute(SETTING_TURBO_MODE)) + + async def set_turbo_mode(self, turbo: bool): + await self.send_attributes({SETTING_TURBO_MODE: self.bool_to_attr_value(turbo)}) + + def get_display_lock(self): + return self.attr_value_to_bool(self.get_attribute(SETTING_DISPLAY_LOCK)) + + async def set_display_lock(self, display: bool): + await self.send_attributes( + {SETTING_DISPLAY_LOCK: self.bool_to_attr_value(display)} + ) diff --git a/whirlpool/types.py b/whirlpool/types.py index 3a89891..b46ff8a 100644 --- a/whirlpool/types.py +++ b/whirlpool/types.py @@ -5,6 +5,7 @@ class Brand(Enum): Whirlpool = 0 Maytag = 1 KitchenAid = 2 + Consul = 3 class Region(Enum):