Skip to content

Split washer and dryer class #96

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Jun 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
import aiohttp

from cli_ac_menu import show_aircon_menu
from cli_dryer_menu import show_dryer_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 cli_washer_menu import show_washer_menu
from whirlpool.appliancesmanager import AppliancesManager
from whirlpool.auth import Auth
from whirlpool.backendselector import BackendSelector, Brand, Region
Expand Down Expand Up @@ -69,8 +70,11 @@ async def start():
if appliance_manager.aircons:
print("\n".join(map(str, appliance_manager.aircons)))

if appliance_manager.washer_dryers:
print("\n".join(map(str, appliance_manager.washer_dryers)))
if appliance_manager.dryers:
print("\n".join(map(str, appliance_manager.dryers)))

if appliance_manager.washers:
print("\n".join(map(str, appliance_manager.washers)))

if appliance_manager.ovens:
print("\n".join(map(str, appliance_manager.ovens)))
Expand Down Expand Up @@ -99,9 +103,14 @@ async def __aexit__(self, *args) -> None:
await show_aircon_menu(ac_data)
return

for wd_data in appliance_manager.washer_dryers:
if wd_data.said == args.said:
await show_washerdryer_menu(wd_data)
for dr_data in appliance_manager.dryers:
if dr_data.said == args.said:
await show_dryer_menu(dr_data)
return

for wr_data in appliance_manager.washers:
if wr_data.said == args.said:
await show_washer_menu(wr_data)
return

for mo_data in appliance_manager.ovens:
Expand Down
74 changes: 74 additions & 0 deletions cli_dryer_menu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import json

import aioconsole

from whirlpool.dryer import Dryer


async def show_dryer_menu(dr: Dryer) -> None:
def print_menu():
print("\n")
print(30 * "-", "MENU", 30 * "-")
print("u. Update status from server")
print("p. Print status")
print("v. Print raw status")
print("c. Custom command")
print("q. Exit")
print(67 * "-")

def print_status(dr: Dryer):
print(f"online: {dr.get_online()}")
print(f"state: {dr.get_machine_state()}")
print(f"door open: {dr.get_door_open()}")
print(f"est time remaining: {dr.get_est_time_remaining()}")
print(f"extra power changeable: {dr.get_extra_power_changeable()}")
print(f"steam changeable: {dr.get_steam_changeable()}")
print(f"cycle select: {dr.get_cycle_changeable()}")
print(f"dryness: {dr.get_dryness_changeable()}")
print(f"manual dry time: {dr.get_manual_dry_time_changeable()}")
print(f"static guard: {dr.get_static_guard_changeable()}")
print(f"temperature: {dr.get_temperature_changeable()}")
print(f"wrinkle shield: {dr.get_wrinkle_shield_changeable()}")
print(f"airflow status: {dr.get_cycle_status_airflow_status()}")
print(f"cool down: {dr.get_cycle_status_cool_down()}")
print(f"damp: {dr.get_cycle_status_damp()}")
print(f"drying: {dr.get_cycle_status_drying()}")
print(f"limited cycle: {dr.get_cycle_status_limited_cycle()}")
print(f"sensing: {dr.get_cycle_status_sensing()}")
print(f"static reduce: {dr.get_cycle_status_static_reduce()}")
print(f"steaming: {dr.get_cycle_status_steaming()}")
print(f"wet: {dr.get_cycle_status_wet()}")
print(f"cycle count: {dr.get_cycle_count()}")

print(f"set dryness: {dr.get_dryness()}")
print(f"set manual dry time: {dr.get_manual_dry_time()}")
print(f"set cycle select: {dr.get_cycle()}")
print(f"set temperature: {dr.get_temperature()}")
print(f"set wrinkle shield: {dr.get_wrinkle_shield()}")

def attr_upd():
print("Attributes updated")

dr.register_attr_callback(attr_upd)

loop = True
while loop:
print_menu()
choice = await aioconsole.ainput("Enter your choice: ")

if choice == "p":
print_status(dr)
elif choice == "u":
await dr.fetch_data()
print_status(dr)
elif choice == "v":
print(json.dumps(dr._data_dict, indent=4))
elif choice == "c":
cmd = await aioconsole.ainput("Command: ")
val = await aioconsole.ainput("Value: ")
await dr.send_attributes({cmd: val})
elif choice == "q":
print("Bye")
loop = False
else:
print("Wrong option selection. Enter any key to try again..")
34 changes: 17 additions & 17 deletions cli_washerdryer_menu.py → cli_washer_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

import aioconsole

from whirlpool.washerdryer import WasherDryer
from whirlpool.washer import Washer


async def show_washerdryer_menu(wd: WasherDryer) -> None:
async def show_washer_menu(wr: Washer) -> None:
def print_menu():
print("\n")
print(30 * "-", "MENU", 30 * "-")
Expand All @@ -16,37 +16,37 @@ def print_menu():
print("q. Exit")
print(67 * "-")

def print_status(wd: WasherDryer):
print("online: " + str(wd.get_online()))
print("state: " + str(wd.get_machine_state()))
print("sensing: " + str(wd.get_cycle_status_sensing()))
print("filling: " + str(wd.get_cycle_status_filling()))
print("soaking: " + str(wd.get_cycle_status_soaking()))
print("washing: " + str(wd.get_cycle_status_washing()))
print("rinsing: " + str(wd.get_cycle_status_rinsing()))
print("spinning: " + str(wd.get_cycle_status_spinning()))
def print_status(wr: Washer):
print("online: " + str(wr.get_online()))
print("state: " + str(wr.get_machine_state()))
print("sensing: " + str(wr.get_cycle_status_sensing()))
print("filling: " + str(wr.get_cycle_status_filling()))
print("soaking: " + str(wr.get_cycle_status_soaking()))
print("washing: " + str(wr.get_cycle_status_washing()))
print("rinsing: " + str(wr.get_cycle_status_rinsing()))
print("spinning: " + str(wr.get_cycle_status_spinning()))

def attr_upd():
print("Attributes updated")

wd.register_attr_callback(attr_upd)
wr.register_attr_callback(attr_upd)

loop = True
while loop:
print_menu()
choice = await aioconsole.ainput("Enter your choice: ")

if choice == "p":
print_status(wd)
print_status(wr)
elif choice == "u":
await wd.fetch_data()
print_status(wd)
await wr.fetch_data()
print_status(wr)
elif choice == "v":
print(json.dumps(wd._data_dict, indent=4))
print(json.dumps(wr._data_dict, indent=4))
elif choice == "c":
cmd = await aioconsole.ainput("Command: ")
val = await aioconsole.ainput("Value: ")
await wd.send_attributes({cmd: val})
await wr.send_attributes({cmd: val})
elif choice == "q":
print("Bye")
loop = False
Expand Down
33 changes: 33 additions & 0 deletions tests/data/owned_appliances.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,39 @@
"CATEGORY_NAME": "Climate",
"MODEL_NO": "CoolMyBeer",
"SERIAL": "FR12345678"
},
{
"DATA_MODEL_KEY": "DDM_LAUNDRY_VMAX20_MAYTAG_DRYER_6_V1",
"CATEGORY_NAME": "FabricCare",
"MODEL_NO": "MGD6230HW3",
"REPLENISHMENT_DEVICE_MODEL": null,
"IMAGE_PATH": null,
"APPLIANCE_ID": 999,
"APPLIANCE_MASTER_ID": 3703,
"MODEL_SKU_ID": null,
"CREATED_AT": 1693943005000,
"UPDATED_AT": 1693943005000,
"APPLIANCE_NAME": "Dryer",
"SAID": "SAIDDRYER1",
"NEST_AWAY": 0,
"CYCLE_HANDOFF": 0,
"NEST_THERMOSTAT_ID": 0,
"THERMOSTAT_INFLUENCE_THRESHOLD": null,
"THERMOSTAT_DESIRED_OFFSET": null,
"THERMOSTAT_OFFSET_NEEDED": null,
"DELETE_FLAG": 0,
"DISPLAY_POSITION": null,
"SERIAL": "MC1234567",
"LOCATION_ID": 999,
"MACHINE_ID": null,
"MACHINE_POSITION": 0,
"ISVOICEDEFAULT": 1,
"DEVICE_ID": "9d83427a-b994-4859-a2b9-2472c5dcbc26",
"IS_ENROLLED": null,
"STATUS": "CLAIMED",
"APPLIANCE_TYPE_ID": null,
"MACHINE_STATUS": null,
"APPLIANCE_MODE": 2
}
]
}
39 changes: 39 additions & 0 deletions tests/test_dryer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from whirlpool.appliancesmanager import AppliancesManager
from whirlpool.dryer import (
Cycle,
Dryness,
MachineState,
Temperature,
WrinkleShield,
)


async def test_attributes(appliances_manager: AppliancesManager):
dryer = appliances_manager.dryers[0]
assert dryer.get_machine_state() == MachineState.Standby
assert not dryer.get_door_open()
assert dryer.get_est_time_remaining() == 1800
assert not dryer.get_drum_light_on()
assert dryer.get_steam_changeable()
assert not dryer.get_cycle_changeable()
assert dryer.get_dryness_changeable()
assert dryer.get_manual_dry_time_changeable()
assert dryer.get_steam_changeable()
assert dryer.get_wrinkle_shield_changeable()
assert dryer.get_dryness() == Dryness.High
assert dryer.get_manual_dry_time() == 1800
assert dryer.get_cycle() == Cycle.TimedDry
assert not dryer.get_cycle_status_airflow_status()
assert not dryer.get_cycle_status_cool_down()
assert not dryer.get_cycle_status_damp()
assert not dryer.get_cycle_status_drying()
assert not dryer.get_cycle_status_limited_cycle()
assert not dryer.get_cycle_status_sensing()
assert not dryer.get_cycle_status_static_reduce()
assert not dryer.get_cycle_status_steaming()
assert not dryer.get_cycle_status_wet()
assert dryer.get_cycle_count() == 195
assert dryer.get_damp_notification_tone_volume() == 0
assert dryer.get_alert_tone_volume() == 0
assert dryer.get_temperature() == Temperature.Cool
assert dryer.get_wrinkle_shield() == WrinkleShield.Off
19 changes: 19 additions & 0 deletions tests/test_washer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from whirlpool.appliancesmanager import AppliancesManager
from whirlpool.washer import MachineState


async def test_attributes(appliances_manager: AppliancesManager):
washer = appliances_manager.washers[0]

assert washer.get_machine_state() == MachineState.Standby
assert washer.get_cycle_status_sensing() is False
assert washer.get_cycle_status_filling() is False
assert washer.get_cycle_status_soaking() is False
assert washer.get_cycle_status_washing() is False
assert washer.get_cycle_status_rinsing() is False
assert washer.get_cycle_status_spinning() is False
assert washer.get_dispense_1_level() == 4
assert washer.get_door_open() is True
assert washer.get_time_remaining() == 4080


25 changes: 18 additions & 7 deletions whirlpool/appliancesmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
from .appliance import Appliance
from .auth import Auth
from .backendselector import BackendSelector
from .dryer import Dryer
from .oven import Oven
from .refrigerator import Refrigerator
from .types import ApplianceInfo
from .washerdryer import WasherDryer
from .washer import Washer

LOGGER = logging.getLogger(__name__)

Expand All @@ -31,15 +32,17 @@ def __init__(
self._session: aiohttp.ClientSession = session
self._event_socket: EventSocket | None = None
self._aircons: dict[str, Any] = {}
self._washerdryers: dict[str, Any] = {}
self._dryers: dict[str, Any] = {}
self._washers: dict[str, Any] = {}
self._ovens: dict[str, Any] = {}
self._refrigerators: dict[str, Any] = {}

@cached_property
def all_appliances(self) -> dict[str, Appliance]:
return {
**self._aircons,
**self._washerdryers,
**self._dryers,
**self._washers,
**self._ovens,
**self._refrigerators,
}
Expand All @@ -49,8 +52,12 @@ def aircons(self) -> list[Aircon]:
return list(self._aircons.values())

@property
def washer_dryers(self) -> list[WasherDryer]:
return list(self._washerdryers.values())
def dryers(self) -> list[Dryer]:
return list(self._dryers.values())

@property
def washers(self) -> list[Washer]:
return list(self._washers.values())

@property
def ovens(self) -> list[Oven]:
Expand Down Expand Up @@ -85,8 +92,12 @@ def _add_appliance(self, appliance: dict[str, Any]) -> None:
self._aircons[appliance_data.said] = Aircon(
self._backend_selector, self._auth, self._session, appliance_data
)
elif "dryer" in data_model or "washer" in data_model:
self._washerdryers[appliance_data.said] = WasherDryer(
elif "dryer" in data_model:
self._dryers[appliance_data.said] = Dryer(
self._backend_selector, self._auth, self._session, appliance_data
)
elif "washer" in data_model:
self._washers[appliance_data.said] = Washer(
self._backend_selector, self._auth, self._session, appliance_data
)
elif any(model in data_model for model in oven_models):
Expand Down
Loading
Loading