Skip to content
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

Improve toiletlid various parameters #579

Merged
merged 4 commits into from
Nov 28, 2019
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
75 changes: 69 additions & 6 deletions miio/tests/test_toiletlid.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,29 +30,65 @@ def __init__(self, *args, **kwargs):
self.state = {
"is_on": False,
"work_state": 1,
"work_mode": "Vacant",
"ambient_light": "Yellow",
"filter_use_flux": "100",
"filter_use_time": "180",
}
self.users = {}

self.return_values = {
"get_prop": self._get_state,
"nozzle_clean": lambda x: self._set_state("work_state", [97]),
"set_aled_v_of_uid": self.set_aled_v_of_uid,
"get_aled_v_of_uid": self.get_aled_v_of_uid,
"uid_mac_op": self.uid_mac_op,
"get_all_user_info": self.get_all_user_info,
}
super().__init__(args, kwargs)

def set_aled_v_of_uid(self, x):
uid, color = x
return self._set_state("ambient_light", [AmbientLightColor(color).name])

def get_aled_v_of_uid(self, uid):
color = self._get_state(["ambient_light"])
def set_aled_v_of_uid(self, args):
uid, color = args
if uid:
if uid in self.users:
self.users.setdefault("ambient_light", AmbientLightColor(color).name)
else:
raise ValueError("This user is not bind.")
else:
return self._set_state("ambient_light", [AmbientLightColor(color).name])

def get_aled_v_of_uid(self, args):
uid = args[0]
if uid:
if uid in self.users:
color = self.users.get("ambient_light")
else:
raise ValueError("This user is not bind.")
else:
color = self._get_state(["ambient_light"])
if not AmbientLightColor._member_map_.get(color[0]):
raise ValueError(color)
return AmbientLightColor._member_map_.get(color[0]).value

def uid_mac_op(self, args):
xiaomi_id, band_mac, alias, operating = args
if operating == "bind":
info = self.users.setdefault(
xiaomi_id, {"rssi": -50, "set": "3-0-2-2-0-0-5-5"}
)
info.update(mac=band_mac, name=alias)
elif operating == "unbind":
self.users.pop(xiaomi_id)
else:
raise ValueError("operating error")

def get_all_user_info(self):
users = {}
for index, (xiaomi_id, info) in enumerate(self.users.items(), start=1):
user_id = "user%s" % index
users[user_id] = {"uid": xiaomi_id, **info}
return users


@pytest.fixture(scope="class")
def toiletlidv1(request):
Expand All @@ -62,6 +98,15 @@ def toiletlidv1(request):

@pytest.mark.usefixtures("toiletlidv1")
class TestToiletlidV1(TestCase):
MOCK_USER = {
"11111111": {
"mac": "ff:ff:ff:ff:ff:ff",
"name": "myband",
"rssi": -50,
"set": "3-0-2-2-0-0-5-5",
}
}

def is_on(self):
return self.device.status().is_on

Expand Down Expand Up @@ -94,3 +139,21 @@ def test_nozzle_clean(self):
self.device.nozzle_clean()
assert self.is_on() is True
self.device._reset_state()

def test_get_all_user_info(self):
users = self.device.get_all_user_info()
for name, info in users.items():
assert info["uid"] in self.MOCK_USER
data = self.MOCK_USER[info["uid"]]
assert info["name"] == data["name"]
assert info["mac"] == data["mac"]

def test_bind_xiaomi_band(self):
for xiaomi_id, info in self.MOCK_USER.items():
self.device.bind_xiaomi_band(xiaomi_id, info["mac"], info["name"])
assert self.device.users == self.MOCK_USER

def test_unbind_xiaomi_band(self):
for xiaomi_id, info in self.MOCK_USER.items():
self.device.unbind_xiaomi_band(xiaomi_id, info["mac"])
assert self.device.users == {}
58 changes: 52 additions & 6 deletions miio/toiletlid.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import enum
import logging
from typing import Any, Dict
from typing import Any, Dict, List

import click

Expand All @@ -27,6 +27,14 @@ class AmbientLightColor(enum.Enum):
Red = "7"


class ToiletlidOperatingMode(enum.Enum):
Vacant = 0
Occupied = 1
RearCleanse = 2
FrontCleanse = 3
NozzleClean = 6


class ToiletlidStatus:
def __init__(self, data: Dict[str, Any]) -> None:
# {"work_state": 1,"filter_use_flux": 100,"filter_use_time": 180, "ambient_light": "Red"}
Expand All @@ -37,6 +45,11 @@ def work_state(self) -> int:
"""Device state code"""
return self.data["work_state"]

@property
def work_mode(self) -> ToiletlidOperatingMode:
"""Device working mode"""
return ToiletlidOperatingMode((self.work_state - 1) // 16)

@property
def is_on(self) -> bool:
return self.work_state != 1
Expand All @@ -60,12 +73,14 @@ def __repr__(self) -> str:
return (
"<ToiletlidStatus work=%s, "
"state=%s, "
"work_mode=%s, "
"ambient_light=%s, "
"filter_use_percentage=%s, "
"filter_remaining_time=%s>"
% (
self.is_on,
self.work_state,
self.work_mode,
self.ambient_light,
self.filter_use_percentage,
self.filter_remaining_time,
Expand Down Expand Up @@ -95,6 +110,7 @@ def __init__(
"",
"Work: {result.is_on}\n"
"State: {result.work_state}\n"
"Work Mode: {result.work_mode}\n"
"Ambient Light: {result.ambient_light}\n"
"Filter remaining: {result.filter_use_percentage}\n"
"Filter remaining time: {result.filter_remaining_time}\n",
Expand Down Expand Up @@ -123,22 +139,52 @@ def nozzle_clean(self):

@command(
click.argument("color", type=EnumType(AmbientLightColor, False)),
click.argument("xiaomi_id", type=str, default=""),
default_output=format_output(
"Set the ambient light to {color} color the next time you start it."
),
)
def set_ambient_light(self, color: AmbientLightColor):
def set_ambient_light(self, color: AmbientLightColor, xiaomi_id: str = ""):
rytilahti marked this conversation as resolved.
Show resolved Hide resolved
"""Set Ambient light color."""
return self.send("set_aled_v_of_uid", ["", color.value])
return self.send("set_aled_v_of_uid", [xiaomi_id, color.value])

@command(default_output=format_output("Get the Ambient light color."))
def get_ambient_light(self) -> str:
@command(
click.argument("xiaomi_id", type=str, default=""),
default_output=format_output("Get the Ambient light color."),
)
def get_ambient_light(self, xiaomi_id: str = "") -> str:
"""Get Ambient light color."""
color = self.send("get_aled_v_of_uid", [""])
color = self.send("get_aled_v_of_uid", [xiaomi_id])
try:
return AmbientLightColor(color[0]).name
except ValueError:
_LOGGER.warning(
"Get ambient light response error, return unknown value: %s.", color[0]
)
return "Unknown"

@command(default_output=format_output("Get user list."))
def get_all_user_info(self) -> List[Dict]:
"""Get All bind user."""
users = self.send("get_all_user_info")
return users

@command(
click.argument("xiaomi_id", type=str),
click.argument("band_mac", type=str),
click.argument("alias", type=str),
default_output=format_output("Bind xiaomi band to xiaomi id."),
)
def bind_xiaomi_band(self, xiaomi_id: str, band_mac: str, alias: str):

"""Bind xiaomi band to xiaomi id."""
return self.send("uid_mac_op", [xiaomi_id, band_mac, alias, "bind"])

@command(
click.argument("xiaomi_id", type=str),
click.argument("band_mac", type=str),
default_output=format_output("Unbind xiaomi band to xiaomi id."),
)
def unbind_xiaomi_band(self, xiaomi_id: str, band_mac: str):
"""Unbind xiaomi band to xiaomi id."""
return self.send("uid_mac_op", [xiaomi_id, band_mac, "", "unbind"])