-
-
Notifications
You must be signed in to change notification settings - Fork 567
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
Tests for the Xiaomi Air Conditioning Companion #182
Changes from 4 commits
5a272b5
cee9fef
c909f26
b5b1e77
f761f6c
36abfa5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,7 +48,7 @@ class Power(enum.Enum): | |
}, | ||
'0100010727': { | ||
'deviceType': 'gree_2', | ||
'base': '[po][mo][wi][sw][tt]1100190[tt1]205002102000t7t0190[tt1]207002000000[tt4]0', | ||
'base': '[po][mo][wi][sw][tt]1100190[tt1]205002102000[tt7]0190[tt1]207002000000[tt4]0', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. line too long (95 > 79 characters) |
||
'off': '01011101004000205002112000D04000207002000000A0' | ||
}, | ||
'0100004795': { | ||
|
@@ -101,9 +101,12 @@ def is_on(self) -> bool: | |
return self.power == 'on' | ||
|
||
@property | ||
def temperature(self) -> int: | ||
def temperature(self) -> Optional[int]: | ||
"""Current temperature.""" | ||
return int(self.data[1][6:8], 16) | ||
try: | ||
return int(self.data[1][6:8], 16) | ||
except TypeError: | ||
return None | ||
|
||
@property | ||
def swing_mode(self) -> bool: | ||
|
@@ -113,20 +116,20 @@ def swing_mode(self) -> bool: | |
@property | ||
def fan_speed(self) -> Optional[FanSpeed]: | ||
"""Current fan speed.""" | ||
speed = int(self.data[1][4:5]) | ||
if speed is not None: | ||
try: | ||
speed = int(self.data[1][4:5]) | ||
return FanSpeed(speed) | ||
|
||
return None | ||
except TypeError: | ||
return None | ||
|
||
@property | ||
def mode(self) -> Optional[OperationMode]: | ||
"""Current operation mode.""" | ||
mode = int(self.data[1][3:4]) | ||
if mode is not None: | ||
try: | ||
mode = int(self.data[1][3:4]) | ||
return OperationMode(mode) | ||
|
||
return None | ||
except TypeError: | ||
return None | ||
|
||
|
||
class AirConditioningCompanion(Device): | ||
|
@@ -137,17 +140,17 @@ def status(self) -> AirConditioningCompanionStatus: | |
status = self.send("get_model_and_state", []) | ||
return AirConditioningCompanionStatus(status) | ||
|
||
def learn(self): | ||
def learn(self, slot: int=STORAGE_SLOT_ID): | ||
"""Learn an infrared command.""" | ||
return self.send("start_ir_learn", [STORAGE_SLOT_ID]) | ||
return self.send("start_ir_learn", [slot]) | ||
|
||
def learn_result(self): | ||
"""Read the learned command.""" | ||
return self.send("get_ir_learn_result", []) | ||
|
||
def learn_stop(self): | ||
def learn_stop(self, slot: int=STORAGE_SLOT_ID): | ||
"""Stop learning of a infrared command.""" | ||
return self.send("end_ir_learn", [STORAGE_SLOT_ID]) | ||
return self.send("end_ir_learn", [slot]) | ||
|
||
def send_ir_code(self, command: str): | ||
"""Play a captured command. | ||
|
@@ -175,18 +178,19 @@ def send_configuration(self, model: str, power: Power, | |
if model in DEVICE_COMMAND_TEMPLATES: | ||
configuration = model + DEVICE_COMMAND_TEMPLATES[model]['base'] | ||
else: | ||
configuration = model + DEVICE_COMMAND_TEMPLATES['fallback']['base'] | ||
configuration = \ | ||
model + DEVICE_COMMAND_TEMPLATES['fallback']['base'] | ||
|
||
configuration = configuration.replace('[po]', power.value) | ||
configuration = configuration.replace('[mo]', operation_mode.value) | ||
configuration = configuration.replace('[wi]', fan_speed.value) | ||
configuration = configuration.replace('[sw]', swing_mode.value) | ||
configuration = configuration.replace('[po]', str(power.value)) | ||
configuration = configuration.replace('[mo]', str(operation_mode.value)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. line too long (80 > 79 characters) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. line too long (80 > 79 characters) |
||
configuration = configuration.replace('[wi]', str(fan_speed.value)) | ||
configuration = configuration.replace('[sw]', str(swing_mode.value)) | ||
configuration = configuration.replace( | ||
'[tt]', hex(int(target_temperature))[2:]) | ||
|
||
temperature = (1 + int(target_temperature) - 17) % 16 | ||
temperature = hex(temperature)[2:].upper() | ||
configuration = configuration.replace('[[tt1]]', temperature) | ||
configuration = configuration.replace('[tt1]', temperature) | ||
|
||
temperature = (4 + int(target_temperature) - 17) % 16 | ||
temperature = hex(temperature)[2:].upper() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
import string | ||
from unittest import TestCase | ||
from miio import AirConditioningCompanion | ||
from miio.airconditioningcompanion import OperationMode, FanSpeed | ||
from miio.airconditioningcompanion import OperationMode, FanSpeed, Power, \ | ||
SwingMode, STORAGE_SLOT_ID | ||
import pytest | ||
|
||
|
||
|
@@ -9,7 +11,12 @@ def __init__(self, *args, **kwargs): | |
self.state = ['010500978022222102', '010201190280222221', '2'] | ||
|
||
self.return_values = { | ||
'get_model_and_state': self._get_state | ||
'get_model_and_state': self._get_state, | ||
'start_ir_learn': lambda x: True, | ||
'end_ir_learn': lambda x: True, | ||
'get_ir_learn_result': lambda x: True, | ||
'send_ir_code': lambda x: True, | ||
'send_cmd': self._send_cmd_input_validation, | ||
} | ||
self.start_state = self.state.copy() | ||
|
||
|
@@ -25,6 +32,9 @@ def _get_state(self, props): | |
"""Return the requested data""" | ||
return self.state | ||
|
||
def _send_cmd_input_validation(self, props): | ||
return all(c in string.hexdigits for c in props[0]) | ||
|
||
|
||
@pytest.fixture(scope="class") | ||
def airconditioningcompanion(request): | ||
|
@@ -50,3 +60,47 @@ def test_status(self): | |
assert self.state().swing_mode is False | ||
assert self.state().fan_speed == FanSpeed.Low | ||
assert self.state().mode == OperationMode.Auto | ||
|
||
def test_status_without_temperature(self): | ||
self.device._reset_state() | ||
self.device.state[1] = None | ||
assert self.state().temperature is None | ||
|
||
def test_status_without_mode(self): | ||
self.device._reset_state() | ||
self.device.state[1] = None | ||
assert self.state().mode is None | ||
|
||
def test_status_without_fan_speed(self): | ||
self.device._reset_state() | ||
self.device.state[1] = None | ||
assert self.state().fan_speed is None | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line at end of file |
||
def test_learn(self): | ||
assert self.device.learn(STORAGE_SLOT_ID) is True | ||
assert self.device.learn() is True | ||
|
||
def test_learn_result(self): | ||
assert self.device.learn_result() is True | ||
|
||
def test_learn_stop(self): | ||
assert self.device.learn(STORAGE_SLOT_ID) is True | ||
assert self.device.learn() is True | ||
|
||
def test_send_ir_code(self): | ||
assert self.device.send_ir_code('0000000') is True | ||
|
||
def test_send_command(self): | ||
assert self.device.send_command('0000000') is True | ||
|
||
def test_send_configuration(self): | ||
def send_configuration(): | ||
return self.device.send_configuration( | ||
'0100010727', | ||
Power.On, | ||
OperationMode.Auto, | ||
22.5, | ||
FanSpeed.Low, | ||
SwingMode.On) | ||
|
||
assert send_configuration() is True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
line too long (95 > 79 characters)