From aec957ff0609417dc355af718366ad86441d7abe Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Wed, 20 Jan 2021 18:27:18 +0100 Subject: [PATCH 1/4] Add docformatter to pre-commit hooks --- .pre-commit-config.yaml | 7 ++ miio/airconditioner_miot.py | 13 ++-- miio/airconditioningcompanion.py | 26 +++---- miio/airconditioningcompanionMCN.py | 10 +-- miio/airdehumidifier.py | 13 +++- miio/airfilter_util.py | 3 +- miio/airfresh_t2017.py | 5 +- miio/airhumidifier.py | 25 +++--- miio/airhumidifier_jsq.py | 13 ++-- miio/airhumidifier_mjjsq.py | 8 +- miio/airpurifier.py | 17 +++-- miio/airpurifier_airdog.py | 8 +- miio/airpurifier_miot.py | 5 +- miio/airqualitymonitor.py | 12 +-- miio/alarmclock.py | 6 +- miio/aqaracamera.py | 4 +- miio/ceil.py | 5 +- miio/chuangmi_camera.py | 8 +- miio/chuangmi_ir.py | 23 +++--- miio/chuangmi_plug.py | 4 +- miio/cooker.py | 44 ++++++----- miio/curtain_youpin.py | 5 +- miio/device.py | 32 ++++---- miio/discovery.py | 14 ++-- miio/exceptions.py | 12 +-- miio/extract_tokens.py | 14 ++-- miio/fan.py | 12 +-- miio/fan_leshow.py | 9 ++- miio/fan_miot.py | 3 +- miio/gateway.py | 84 ++++++++++----------- miio/heater.py | 4 +- miio/huizuo.py | 51 +++++++------ miio/miioprotocol.py | 31 ++++---- miio/philips_bulb.py | 2 +- miio/philips_eyecare.py | 2 +- miio/philips_moonlight.py | 7 +- miio/philips_rwread.py | 5 +- miio/powerstrip.py | 8 +- miio/protocol.py | 18 +++-- miio/pwzn_relay.py | 6 +- miio/tests/dummies.py | 13 ++-- miio/tests/test_airconditioningcompanion.py | 12 +-- miio/tests/test_airhumidifier_jsq.py | 2 +- miio/tests/test_airqualitymonitor.py | 4 +- miio/tests/test_chuangmi_plug.py | 6 +- miio/tests/test_fan.py | 27 ++++--- miio/tests/test_powerstrip.py | 5 +- miio/tests/test_toiletlid.py | 1 - miio/toiletlid.py | 8 +- miio/updater.py | 5 +- miio/utils.py | 6 +- miio/vacuum.py | 51 ++++++++----- miio/vacuum_cli.py | 7 +- miio/vacuumcontainers.py | 21 ++++-- miio/viomivacuum.py | 5 +- miio/waterpurifier_yunmi.py | 7 +- miio/wifirepeater.py | 3 +- miio/wifispeaker.py | 11 +-- miio/yeelight_dual_switch.py | 27 +++---- pyproject.toml | 1 + 60 files changed, 438 insertions(+), 362 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b98c1e567..71de4cbf5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,6 +15,13 @@ repos: - id: black language_version: python3 +- repo: https://github.com/myint/docformatter + rev: v1.3.1 + hooks: + - id: docformatter + args: [--in-place, --wrap-summaries, '88', --wrap-descriptions, '88'] + + - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.3.0 hooks: diff --git a/miio/airconditioner_miot.py b/miio/airconditioner_miot.py index 4363e0f53..749969b12 100644 --- a/miio/airconditioner_miot.py +++ b/miio/airconditioner_miot.py @@ -54,8 +54,7 @@ class AirConditionerMiotException(DeviceException): class CleaningStatus: def __init__(self, status: str): - """ - Auto clean mode indicator. + """Auto clean mode indicator. Value format: ,,, Integer 1: whether auto cleaning mode started. @@ -124,8 +123,7 @@ class FanSpeed(enum.Enum): class TimerStatus: def __init__(self, status): - """ - Countdown timer indicator. + """Countdown timer indicator. Value format: ,,, Integer 1: whether the timer is enabled. @@ -173,7 +171,8 @@ def __repr__(self) -> str: class AirConditionerMiotStatus: - """Container for status reports from the air conditioner which uses MIoT protocol.""" + """Container for status reports from the air conditioner which uses MIoT + protocol.""" def __init__(self, data: Dict[str, Any]) -> None: """ @@ -523,8 +522,8 @@ def set_fan_speed_percent(self, fan_speed_percent): ), ) def set_timer(self, minutes, delay_on): - """ - Set countdown timer minutes and if it would be turned on after timeout. + """Set countdown timer minutes and if it would be turned on after timeout. + Set minutes to 0 would disable the timer. """ return self.set_property( diff --git a/miio/airconditioningcompanion.py b/miio/airconditioningcompanion.py index 289fec35a..5e1ba2240 100644 --- a/miio/airconditioningcompanion.py +++ b/miio/airconditioningcompanion.py @@ -81,8 +81,7 @@ class AirConditioningCompanionStatus: """Container for status reports of the Xiaomi AC Companion.""" def __init__(self, data): - """ - Device model: lumi.acpartner.v2 + """Device model: lumi.acpartner.v2. Response of "get_model_and_state": ['010500978022222102', '010201190280222221', '2'] @@ -133,8 +132,7 @@ def device_type(self) -> int: @property def air_condition_brand(self) -> int: - """ - Brand of the air conditioner. + """Brand of the air conditioner. Known brand ids are 0x0182, 0x0097, 0x0037, 0x0202, 0x02782, 0x0197, 0x0192. """ @@ -142,24 +140,17 @@ def air_condition_brand(self) -> int: @property def air_condition_remote(self) -> int: - """ - Known remote ids: - - 0x80111111, 0x80111112 (brand: 0x0182) - 0x80222221 (brand: 0x0097) - 0x80333331 (brand: 0x0037) - 0x80444441 (brand: 0x0202) - 0x80555551 (brand: 0x2782) - 0x80777771 (brand: 0x0197) - 0x80666661 (brand: 0x0192) + """Known remote ids: + 0x80111111, 0x80111112 (brand: 0x0182) 0x80222221 (brand: 0x0097) 0x80333331 + (brand: 0x0037) 0x80444441 (brand: 0x0202) 0x80555551 (brand: 0x2782) 0x80777771 + (brand: 0x0197) 0x80666661 (brand: 0x0192) """ return int(self.air_condition_model[4:8].hex(), 16) @property def state_format(self) -> int: - """ - Version number of the state format. + """Version number of the state format. Known values are: 1, 2, 3 """ @@ -395,7 +386,8 @@ def send_ir_code(self, model: str, code: str, slot: int = 0): def send_command(self, command: str): """Send a command to the air conditioner. - :param str command: Command to execute""" + :param str command: Command to execute + """ return self.send("send_cmd", [str(command)]) @command( diff --git a/miio/airconditioningcompanionMCN.py b/miio/airconditioningcompanionMCN.py index 9727a0304..f795d96dc 100644 --- a/miio/airconditioningcompanionMCN.py +++ b/miio/airconditioningcompanionMCN.py @@ -40,11 +40,10 @@ class AirConditioningCompanionStatus: """Container for status reports of the Xiaomi AC Companion.""" def __init__(self, data): - """ - Device model: lumi.acpartner.mcn02 + """Device model: lumi.acpartner.mcn02. - Response of "get_prop, params:['power', 'mode', 'tar_temp', 'fan_level', 'ver_swing', 'load_power']": - ['on', 'dry', 16, 'small_fan', 'off', 84.0] + Response of "get_prop, params:['power', 'mode', 'tar_temp', 'fan_level', + 'ver_swing', 'load_power']": ['on', 'dry', 16, 'small_fan', 'off', 84.0] """ self.data = data @@ -174,5 +173,6 @@ def off(self): def send_command(self, command: str, parameters: Any = None) -> Any: """Send a command to the air conditioner. - :param str command: Command to execute""" + :param str command: Command to execute + """ return self.send(command, parameters) diff --git a/miio/airdehumidifier.py b/miio/airdehumidifier.py index 53567b7d4..caacd307f 100644 --- a/miio/airdehumidifier.py +++ b/miio/airdehumidifier.py @@ -55,8 +55,7 @@ class AirDehumidifierStatus: """Container for status reports from the air dehumidifier.""" def __init__(self, data: Dict[str, Any], device_info: DeviceInfo) -> None: - """ - Response of a Air Dehumidifier (nwt.derh.wdh318efw1): + """Response of a Air Dehumidifier (nwt.derh.wdh318efw1): {'on_off': 'on', 'mode': 'auto', 'fan_st': 2, 'buzzer': 'off', 'led': 'on', 'child_lock': 'off', @@ -80,7 +79,10 @@ def is_on(self) -> bool: @property def mode(self) -> OperationMode: - """Operation mode. Can be either on, auth or dry_cloth.""" + """Operation mode. + + Can be either on, auth or dry_cloth. + """ return OperationMode(self.data["mode"]) @property @@ -112,7 +114,10 @@ def child_lock(self) -> bool: @property def target_humidity(self) -> Optional[int]: - """Target humiditiy. Can be either 40, 50, 60 percent.""" + """Target humiditiy. + + Can be either 40, 50, 60 percent. + """ if "auto" in self.data and self.data["auto"] is not None: return self.data["auto"] return None diff --git a/miio/airfilter_util.py b/miio/airfilter_util.py index c74fc7c5f..d70e8c190 100644 --- a/miio/airfilter_util.py +++ b/miio/airfilter_util.py @@ -25,8 +25,7 @@ class FilterTypeUtil: def determine_filter_type( self, rfid_tag: Optional[str], product_id: Optional[str] ) -> Optional[FilterType]: - """ - Determine Xiaomi air filter type based on its product ID. + """Determine Xiaomi air filter type based on its product ID. :param rfid_tag: RFID tag value :param product_id: Product ID such as "0:0:30:33" diff --git a/miio/airfresh_t2017.py b/miio/airfresh_t2017.py index 7824ed56c..962b96f94 100644 --- a/miio/airfresh_t2017.py +++ b/miio/airfresh_t2017.py @@ -399,7 +399,10 @@ def set_ptc_timer(self): @command() def get_ptc_timer(self): - """Returns a list of PTC timers. Response unknown.""" + """Returns a list of PTC timers. + + Response unknown. + """ return self.send("get_ptc_timer") @command() diff --git a/miio/airhumidifier.py b/miio/airhumidifier.py index d023a33ef..d83a3a680 100644 --- a/miio/airhumidifier.py +++ b/miio/airhumidifier.py @@ -59,8 +59,7 @@ class AirHumidifierStatus: """Container for status reports from the air humidifier.""" def __init__(self, data: Dict[str, Any], device_info: DeviceInfo) -> None: - """ - Response of a Air Humidifier (zhimi.humidifier.v1): + """Response of a Air Humidifier (zhimi.humidifier.v1): {'power': 'off', 'mode': 'high', 'temp_dec': 294, 'humidity': 33, 'buzzer': 'on', 'led_b': 0, @@ -84,7 +83,10 @@ def is_on(self) -> bool: @property def mode(self) -> OperationMode: - """Operation mode. Can be either silent, medium or high.""" + """Operation mode. + + Can be either silent, medium or high. + """ return OperationMode(self.data["mode"]) @property @@ -120,13 +122,15 @@ def child_lock(self) -> bool: @property def target_humidity(self) -> int: - """Target humidity. Can be either 30, 40, 50, 60, 70, 80 percent.""" + """Target humidity. + + Can be either 30, 40, 50, 60, 70, 80 percent. + """ return self.data["limit_hum"] @property def trans_level(self) -> Optional[int]: - """ - The meaning of the property is unknown. + """The meaning of the property is unknown. The property is used to determine the strong mode is enabled on old firmware. """ @@ -147,7 +151,10 @@ def strong_mode_enabled(self) -> bool: @property def firmware_version(self) -> str: - """Returns the fw_ver of miIO.info. For example 1.2.9_5033.""" + """Returns the fw_ver of miIO.info. + + For example 1.2.9_5033. + """ return self.device_info.firmware_version @property @@ -179,8 +186,8 @@ def depth(self) -> Optional[int]: @property def dry(self) -> Optional[bool]: - """ - Dry mode: The amount of water is not enough to continue to work for about 8 hours. + """Dry mode: The amount of water is not enough to continue to work for about 8 + hours. Return True if dry mode is on if available. """ diff --git a/miio/airhumidifier_jsq.py b/miio/airhumidifier_jsq.py index b2d7288ee..6601120ef 100644 --- a/miio/airhumidifier_jsq.py +++ b/miio/airhumidifier_jsq.py @@ -47,8 +47,8 @@ class AirHumidifierStatus: """Container for status reports from the air humidifier jsq.""" def __init__(self, data: Dict[str, Any]) -> None: - """ - Status of an Air Humidifier (shuii.humidifier.jsq001): + """Status of an Air Humidifier (shuii.humidifier.jsq001): + [24, 30, 1, 1, 0, 2, 0, 0, 0] Parsed by AirHumidifierJsq device as: @@ -70,7 +70,10 @@ def is_on(self) -> bool: @property def mode(self) -> OperationMode: - """Operation mode. Can be either low, medium, high or humidity.""" + """Operation mode. + + Can be either low, medium, high or humidity. + """ try: mode = OperationMode(self.data["mode"]) @@ -153,9 +156,7 @@ def __repr__(self) -> str: class AirHumidifierJsq(Device): - """ - Implementation of Xiaomi Zero Fog Humidifier: shuii.humidifier.jsq001 - """ + """Implementation of Xiaomi Zero Fog Humidifier: shuii.humidifier.jsq001.""" def __init__( self, diff --git a/miio/airhumidifier_mjjsq.py b/miio/airhumidifier_mjjsq.py index ecd9b965e..1b305e1f5 100644 --- a/miio/airhumidifier_mjjsq.py +++ b/miio/airhumidifier_mjjsq.py @@ -49,8 +49,7 @@ class AirHumidifierStatus: """Container for status reports from the air humidifier mjjsq.""" def __init__(self, data: Dict[str, Any]) -> None: - """ - Response of a Air Humidifier (deerma.humidifier.mjjsq): + """Response of a Air Humidifier (deerma.humidifier.mjjsq): {'Humidifier_Gear': 4, 'Humidity_Value': 44, 'HumiSet_Value': 54, 'Led_State': 1, 'OnOff_State': 0, 'TemperatureValue': 21, @@ -71,7 +70,10 @@ def is_on(self) -> bool: @property def mode(self) -> OperationMode: - """Operation mode. Can be either low, medium, high or humidity.""" + """Operation mode. + + Can be either low, medium, high or humidity. + """ return OperationMode(self.data["Humidifier_Gear"]) @property diff --git a/miio/airpurifier.py b/miio/airpurifier.py index 1255ed49f..19f7da731 100644 --- a/miio/airpurifier.py +++ b/miio/airpurifier.py @@ -48,8 +48,7 @@ class AirPurifierStatus: _filter_type_cache = {} def __init__(self, data: Dict[str, Any]) -> None: - """ - Response of a Air Purifier Pro (zhimi.airpurifier.v6): + """Response of a Air Purifier Pro (zhimi.airpurifier.v6): {'power': 'off', 'aqi': 7, 'average_aqi': 18, 'humidity': 45, 'temp_dec': 234, 'mode': 'auto', 'favorite_level': 17, @@ -131,7 +130,10 @@ def mode(self) -> OperationMode: @property def sleep_mode(self) -> Optional[SleepMode]: - """Operation mode of the sleep state. (Idle vs. Silent)""" + """Operation mode of the sleep state. + + (Idle vs. Silent) + """ if self.data["sleep_mode"] is not None: return SleepMode(self.data["sleep_mode"]) @@ -156,7 +158,9 @@ def led_brightness(self) -> Optional[LedBrightness]: @property def illuminance(self) -> Optional[int]: """Environment illuminance level in lux [0-200]. - Sensor value is updated only when device is turned on.""" + + Sensor value is updated only when device is turned on. + """ return self.data["bright"] @property @@ -525,7 +529,10 @@ def set_learn_mode(self, learn_mode: bool): ), ) def set_auto_detect(self, auto_detect: bool): - """Set auto detect on/off. It's a feature of the AirPurifier V1 & V3""" + """Set auto detect on/off. + + It's a feature of the AirPurifier V1 & V3 + """ if auto_detect: return self.send("set_act_det", ["on"]) else: diff --git a/miio/airpurifier_airdog.py b/miio/airpurifier_airdog.py index 4b62b0346..6d4f2cd79 100644 --- a/miio/airpurifier_airdog.py +++ b/miio/airpurifier_airdog.py @@ -44,8 +44,7 @@ class AirDogStatus: """Container for status reports from the air dog x3.""" def __init__(self, data: Dict[str, Any]) -> None: - """ - Response of a Air Dog X3 (airdog.airpurifier.x3): + """Response of a Air Dog X3 (airdog.airpurifier.x3): {'power: 'on', 'mode': 'sleep', 'speed': 1, 'lock': 'unlock', 'clean': 'n', 'pm': 11, 'hcho': 0} @@ -65,7 +64,10 @@ def is_on(self) -> bool: @property def mode(self) -> OperationMode: - """Operation mode. Can be either auto, manual, sleep.""" + """Operation mode. + + Can be either auto, manual, sleep. + """ return OperationMode(self.data["mode"]) @property diff --git a/miio/airpurifier_miot.py b/miio/airpurifier_miot.py index 44d24d918..db35a72e8 100644 --- a/miio/airpurifier_miot.py +++ b/miio/airpurifier_miot.py @@ -357,9 +357,8 @@ def set_mode(self, mode: OperationMode): default_output=format_output("Setting favorite level to {level}"), ) def set_favorite_level(self, level: int): - """Set the favorite level used when the mode is `favorite`, - should be between 0 and 14. - """ + """Set the favorite level used when the mode is `favorite`, should be between 0 + and 14.""" if level < 0 or level > 14: raise AirPurifierMiotException("Invalid favorite level: %s" % level) diff --git a/miio/airqualitymonitor.py b/miio/airqualitymonitor.py index 4ab8a9383..9ec2c8685 100644 --- a/miio/airqualitymonitor.py +++ b/miio/airqualitymonitor.py @@ -45,8 +45,7 @@ class AirQualityMonitorStatus: """Container of air quality monitor status.""" def __init__(self, data): - """ - Response of a Xiaomi Air Quality Monitor (zhimi.airmonitor.v1): + """Response of a Xiaomi Air Quality Monitor (zhimi.airmonitor.v1): {'power': 'on', 'aqi': 34, 'battery': 100, 'usb_state': 'off', 'time_state': 'on'} @@ -81,7 +80,10 @@ def usb_power(self) -> Optional[bool]: @property def aqi(self) -> Optional[int]: - """Air quality index value. (0...600).""" + """Air quality index value. + + (0...600). + """ return self.data.get("aqi", None) @property @@ -200,7 +202,7 @@ def __init__( "Device model %s unsupported. Falling back to %s.", model, self.model ) else: - """Force autodetection""" + """Force autodetection.""" self.model = None @command( @@ -223,7 +225,7 @@ def status(self) -> AirQualityMonitorStatus: """Return device status.""" if self.model is None: - """Autodetection""" + """Autodetection.""" info = self.info() self.model = info.model diff --git a/miio/alarmclock.py b/miio/alarmclock.py index 8d792b14a..976398361 100644 --- a/miio/alarmclock.py +++ b/miio/alarmclock.py @@ -68,10 +68,8 @@ def __repr__(self): class AlarmClock(Device): - """ - Note, this device is not very responsive to the requests, so it may - take several seconds /tries to get an answer.. - """ + """Note, this device is not very responsive to the requests, so it may take several + seconds /tries to get an answer..""" @command() def get_config_version(self): diff --git a/miio/aqaracamera.py b/miio/aqaracamera.py index dd70573bc..1fc688b1c 100644 --- a/miio/aqaracamera.py +++ b/miio/aqaracamera.py @@ -54,6 +54,7 @@ class SDCardStatus(IntEnum): class MotionDetectionSensitivity(IntEnum): """'Default' values for md sensitivity. + Currently unused as the value can also be set arbitrarily. """ @@ -66,8 +67,7 @@ class CameraStatus: """Container for status reports from the Aqara Camera.""" def __init__(self, data: Dict[str, Any]) -> None: - """ - Response of a lumi.camera.aq1: + """Response of a lumi.camera.aq1: {"p2p_id":"#################","app_type":"celing", "offset_x":"0","offset_y":"0","offset_radius":"0", diff --git a/miio/ceil.py b/miio/ceil.py index be8e3778f..f86b84453 100644 --- a/miio/ceil.py +++ b/miio/ceil.py @@ -179,7 +179,10 @@ def delay_off(self, seconds: int): default_output=format_output("Setting fixed scene to {number}"), ) def set_scene(self, number: int): - """Set a fixed scene. 4 fixed scenes are available (1-4)""" + """Set a fixed scene. + + 4 fixed scenes are available (1-4) + """ if number < 1 or number > 4: raise CeilException("Invalid fixed scene number: %s" % number) diff --git a/miio/chuangmi_camera.py b/miio/chuangmi_camera.py index fa1185e82..b9025026e 100644 --- a/miio/chuangmi_camera.py +++ b/miio/chuangmi_camera.py @@ -369,7 +369,7 @@ def set_home_monitoring_config( notify: int = 1, interval: int = 5, ): - """Set home monitoring configuration""" + """Set home monitoring configuration.""" return self.send( "setAlarmConfig", [mode, start_hour, start_minute, end_hour, end_minute, notify, interval], @@ -377,12 +377,12 @@ def set_home_monitoring_config( @command(default_output=format_output("Clearing NAS directory")) def clear_nas_dir(self): - """Clear NAS directory""" + """Clear NAS directory.""" return self.send("nas_clear_dir", [[]]) @command(default_output=format_output("Getting NAS config info")) def get_nas_config(self): - """Get NAS config info""" + """Get NAS config info.""" return self.send("nas_get_config", {}) @command( @@ -399,7 +399,7 @@ def set_nas_config( sync_interval: NASSyncInterval = NASSyncInterval.Realtime, video_retention_time: NASVideoRetentionTime = NASVideoRetentionTime.Week, ): - """Set NAS configuration""" + """Set NAS configuration.""" return self.send( "nas_set_config", { diff --git a/miio/chuangmi_ir.py b/miio/chuangmi_ir.py index 595681c7a..370aa8ab9 100644 --- a/miio/chuangmi_ir.py +++ b/miio/chuangmi_ir.py @@ -39,7 +39,8 @@ class ChuangmiIr(Device): def learn(self, key: int = 1): """Learn an infrared command. - :param int key: Storage slot, must be between 1 and 1000000""" + :param int key: Storage slot, must be between 1 and 1000000 + """ if key < 1 or key > 1000000: raise ChuangmiIrException("Invalid storage slot.") @@ -61,7 +62,8 @@ def read(self, key: int = 1): Negative response (chuangmi.ir.v2): {'error': {'code': -5003, 'message': 'learn timeout'}, 'id': 17} - :param int key: Slot to read from""" + :param int key: Slot to read from + """ if key < 1 or key > 1000000: raise ChuangmiIrException("Invalid storage slot.") @@ -71,24 +73,27 @@ def play_raw(self, command: str, frequency: int = 38400): """Play a captured command. :param str command: Command to execute - :param int frequency: Execution frequency""" + :param int frequency: Execution frequency + """ return self.send("miIO.ir_play", {"freq": frequency, "code": command}) def play_pronto(self, pronto: str, repeats: int = 1): - """Play a Pronto Hex encoded IR command. - Supports only raw Pronto format, starting with 0000. + """Play a Pronto Hex encoded IR command. Supports only raw Pronto format, + starting with 0000. :param str pronto: Pronto Hex string. - :param int repeats: Number of extra signal repeats.""" + :param int repeats: Number of extra signal repeats. + """ return self.play_raw(*self.pronto_to_raw(pronto, repeats)) @classmethod def pronto_to_raw(cls, pronto: str, repeats: int = 1): - """Play a Pronto Hex encoded IR command. - Supports only raw Pronto format, starting with 0000. + """Play a Pronto Hex encoded IR command. Supports only raw Pronto format, + starting with 0000. :param str pronto: Pronto Hex string. - :param int repeats: Number of extra signal repeats.""" + :param int repeats: Number of extra signal repeats. + """ if repeats < 0: raise ChuangmiIrException("Invalid repeats value") diff --git a/miio/chuangmi_plug.py b/miio/chuangmi_plug.py index 16aaaa622..1e5aa4b90 100644 --- a/miio/chuangmi_plug.py +++ b/miio/chuangmi_plug.py @@ -35,8 +35,8 @@ class ChuangmiPlugStatus: """Container for status reports from the plug.""" def __init__(self, data: Dict[str, Any]) -> None: - """ - Response of a Chuangmi Plug V1 (chuangmi.plug.v1) + """Response of a Chuangmi Plug V1 (chuangmi.plug.v1) + { 'power': True, 'usb_on': True, 'temperature': 32 } Response of a Chuangmi Plug V3 (chuangmi.plug.v3): diff --git a/miio/cooker.py b/miio/cooker.py index 14a01c761..6954f02ac 100644 --- a/miio/cooker.py +++ b/miio/cooker.py @@ -99,8 +99,7 @@ class OperationMode(enum.Enum): class TemperatureHistory: def __init__(self, data: str): - """ - Container of temperatures recorded every 10-15 seconds while cooking. + """Container of temperatures recorded every 10-15 seconds while cooking. Example values: @@ -149,8 +148,7 @@ def __repr__(self) -> str: class CookerCustomizations: def __init__(self, custom: str): - """ - Container of different user customizations. + """Container of different user customizations. Example values: @@ -224,8 +222,7 @@ def __repr__(self) -> str: class CookingStage: def __init__(self, stage: str): - """ - Container of cooking stages. + """Container of cooking stages. Example timeouts: 'null', 02000000ff, 03000000ff, 0a000000ff, 1000000000 @@ -327,8 +324,7 @@ def __repr__(self) -> str: class InteractionTimeouts: def __init__(self, timeouts: str = None): - """ - Example timeouts: 05040f, 05060f + """Example timeouts: 05040f, 05060f. Data structure: @@ -382,8 +378,7 @@ def __repr__(self) -> str: class CookerSettings: def __init__(self, settings: str = None): - """ - Example settings: 1407, 0607, 0207 + """Example settings: 1407, 0607, 0207. Data structure: @@ -538,8 +533,7 @@ def __repr__(self) -> str: class CookerStatus: def __init__(self, data): - """ - Responses of a chunmi.cooker.normal2 (fw_ver: 1.2.8): + """Responses of a chunmi.cooker.normal2 (fw_ver: 1.2.8): { 'func': 'precook', 'menu': '0001', @@ -601,8 +595,7 @@ def stage(self) -> Optional[CookingStage]: @property def temperature(self) -> Optional[int]: - """ - Current temperature, if idle. + """Current temperature, if idle. Example values: *29*, 031e0b23, 031e0b23031e """ @@ -614,11 +607,10 @@ def temperature(self) -> Optional[int]: @property def start_time(self) -> Optional[time]: - """ - Start time of cooking? + """Start time of cooking? - The property "temp" is used for different purposes. - Example values: 29, *031e0b23*, 031e0b23031e + The property "temp" is used for different purposes. Example values: 29, + *031e0b23*, 031e0b23031e """ value = self.data["temp"] if len(value) == 8: @@ -668,7 +660,10 @@ def firmware_version(self) -> int: @property def favorite(self) -> int: - """Favored recipe id. Can be compared with the menu property.""" + """Favored recipe id. + + Can be compared with the menu property. + """ return int(self.data["favorite"], 16) @property @@ -807,7 +802,10 @@ def set_acknowledge(self): # FIXME: Add unified CLI support def set_interaction(self, settings: CookerSettings, timeouts: InteractionTimeouts): - """Set interaction. Supported by all cookers except MODEL_PRESS1""" + """Set interaction. + + Supported by all cookers except MODEL_PRESS1 + """ self.send( "set_interaction", [ @@ -823,7 +821,7 @@ def set_interaction(self, settings: CookerSettings, timeouts: InteractionTimeout default_output=format_output("Setting menu to {profile}"), ) def set_menu(self, profile: str): - """Select one of the default(?) cooking profiles""" + """Select one of the default(?) cooking profiles.""" if not self._validate_profile(profile): raise CookerException("Invalid cooking profile: %s" % profile) @@ -833,8 +831,8 @@ def set_menu(self, profile: str): def get_temperature_history(self) -> TemperatureHistory: """Retrieves a temperature history. - The temperature is only available while cooking. - Approx. six data points per minute. + The temperature is only available while cooking. Approx. six data points per + minute. """ data = self.send("get_temp_history") diff --git a/miio/curtain_youpin.py b/miio/curtain_youpin.py index f21acb60e..1145e3378 100644 --- a/miio/curtain_youpin.py +++ b/miio/curtain_youpin.py @@ -49,7 +49,8 @@ class Polarity(enum.Enum): class CurtainStatus: def __init__(self, data: Dict[str, Any]) -> None: - """Response from device + """Response from device. + {'id': 1, 'result': [ {'did': 'current_position', 'siid': 2, 'piid': 3, 'code': 0, 'value': 0}, {'did': 'status', 'siid': 2, 'piid': 6, 'code': 0, 'value': 0}, @@ -106,7 +107,7 @@ def target_position(self) -> int: @property def adjust_value(self) -> int: - """ Adjust value.""" + """Adjust value.""" return self.data["adjust_value"] def __repr__(self) -> str: diff --git a/miio/device.py b/miio/device.py index 00753c647..b3a1fdd19 100644 --- a/miio/device.py +++ b/miio/device.py @@ -20,12 +20,13 @@ class UpdateState(Enum): class DeviceInfo: """Container of miIO device information. - Hardware properties such as device model, MAC address, memory information, - and hardware and software information is contained here.""" + + Hardware properties such as device model, MAC address, memory information, and + hardware and software information is contained here. + """ def __init__(self, data): - """ - Response of a Xiaomi Smart WiFi Plug + """Response of a Xiaomi Smart WiFi Plug. {'ap': {'bssid': 'FF:FF:FF:FF:FF:FF', 'rssi': -68, 'ssid': 'network'}, 'cfg_time': 0, @@ -101,10 +102,11 @@ def raw(self): class Device(metaclass=DeviceGroupMeta): """Base class for all device implementations. - This is the main class providing the basic protocol handling for devices using - the ``miIO`` protocol. - This class should not be initialized directly but a device-specific class inheriting - it should be used instead of it.""" + + This is the main class providing the basic protocol handling for devices using the + ``miIO`` protocol. This class should not be initialized directly but a device- + specific class inheriting it should be used instead of it. + """ retry_count = 3 timeout = 5 @@ -161,12 +163,12 @@ def send_handshake(self): click.argument("parameters", type=LiteralParamType(), required=False), ) def raw_command(self, command, parameters): - """Send a raw command to the device. - This is mostly useful when trying out commands which are not - implemented by a given device instance. + """Send a raw command to the device. This is mostly useful when trying out + commands which are not implemented by a given device instance. :param str command: Command to send - :param dict parameters: Parameters to send""" + :param dict parameters: Parameters to send + """ return self.send(command, parameters) @command( @@ -179,8 +181,10 @@ def raw_command(self, command, parameters): ) def info(self) -> DeviceInfo: """Get miIO protocol information from the device. - This includes information about connected wlan network, - and hardware and software versions.""" + + This includes information about connected wlan network, and hardware and + software versions. + """ try: return DeviceInfo(self.send("miIO.info")) except PayloadDecodeException as ex: diff --git a/miio/discovery.py b/miio/discovery.py index 583956127..534872daf 100644 --- a/miio/discovery.py +++ b/miio/discovery.py @@ -245,8 +245,8 @@ def __init__(self): self.found_devices = {} # type: Dict[str, Device] def check_and_create_device(self, info, addr) -> Optional[Device]: - """Create a corresponding :class:`Device` implementation - for a given info and address..""" + """Create a corresponding :class:`Device` implementation for a given info and + address..""" name = info.name for identifier, v in DEVICE_MAP.items(): if name.startswith(identifier): @@ -280,13 +280,15 @@ def add_service(self, zeroconf, type, name): class Discovery: """mDNS discoverer for miIO based devices (_miio._udp.local). - Calling :func:`discover_mdns` will cause this to subscribe for updates - on ``_miio._udp.local`` until any key is pressed, after which a dict - of detected devices is returned.""" + + Calling :func:`discover_mdns` will cause this to subscribe for updates on + ``_miio._udp.local`` until any key is pressed, after which a dict of detected + devices is returned. + """ @staticmethod def discover_mdns() -> Dict[str, Device]: - """Discover devices with mdns until """ + """Discover devices with mdns until.""" _LOGGER.info("Discovering devices with mDNS, press any key to quit...") listener = Listener() diff --git a/miio/exceptions.py b/miio/exceptions.py index 78f6737bf..d433ad7fb 100644 --- a/miio/exceptions.py +++ b/miio/exceptions.py @@ -5,24 +5,24 @@ class DeviceException(Exception): class PayloadDecodeException(DeviceException): """Exception for failures in payload decoding. - This is raised when the json payload cannot be decoded, - indicating invalid response from a device. + This is raised when the json payload cannot be decoded, indicating invalid response + from a device. """ class DeviceInfoUnavailableException(DeviceException): """Exception raised when requesting miio.info fails. - This allows users to gracefully handle cases where the information unavailable. - This can happen, for instance, when the device has no cloud access. + This allows users to gracefully handle cases where the information unavailable. This + can happen, for instance, when the device has no cloud access. """ class DeviceError(DeviceException): """Exception communicating an error delivered by the target device. - The device given error code and message can be accessed with - `code` and `message` variables. + The device given error code and message can be accessed with `code` and `message` + variables. """ def __init__(self, error): diff --git a/miio/extract_tokens.py b/miio/extract_tokens.py index e12d13451..4bac7496b 100644 --- a/miio/extract_tokens.py +++ b/miio/extract_tokens.py @@ -52,8 +52,7 @@ def read_android_yeelight(db) -> Iterator[DeviceConfig]: class BackupDatabaseReader: - """Main class for reading backup files. - The main usage is following: + """Main class for reading backup files. The main usage is following: .. code-block:: python @@ -125,7 +124,8 @@ def read_android(self) -> Iterator[DeviceConfig]: def read_tokens(self, db) -> Iterator[DeviceConfig]: """Read device information out from a given database file. - :param str db: Database file""" + :param str db: Database file + """ self.db = db _LOGGER.info("Reading database from %s" % db) self.conn = sqlite3.connect(db) @@ -168,10 +168,10 @@ def read_tokens(self, db) -> Iterator[DeviceConfig]: @click.option("--dump-raw", is_flag=True, help="dumps raw rows") def main(backup, write_to_disk, password, dump_all, dump_raw): """Reads device information out from an sqlite3 DB. - If the given file is an Android backup (.ab), the database - will be extracted automatically. - If the given file is an iOS backup, the tokens will be - extracted (and decrypted if needed) automatically. + + If the given file is an Android backup (.ab), the database will be extracted + automatically. If the given file is an iOS backup, the tokens will be extracted (and + decrypted if needed) automatically. """ def read_miio_database(tar): diff --git a/miio/fan.py b/miio/fan.py index bf15f7854..4337304f7 100644 --- a/miio/fan.py +++ b/miio/fan.py @@ -67,8 +67,7 @@ class FanStatus: """Container for status reports from the Xiaomi Mi Smart Pedestal Fan.""" def __init__(self, data: Dict[str, Any]) -> None: - """ - Response of a Fan (zhimi.fan.v3): + """Response of a Fan (zhimi.fan.v3): {'temp_dec': 232, 'humidity': 46, 'angle': 118, 'speed': 298, 'poweroff_time': 0, 'power': 'on', 'ac_power': 'off', 'battery': 98, @@ -256,8 +255,8 @@ class FanStatusP5: """Container for status reports from the Xiaomi Mi Smart Pedestal Fan DMaker P5.""" def __init__(self, data: Dict[str, Any]) -> None: - """ - Response of a Fan (dmaker.fan.p5): + """Response of a Fan (dmaker.fan.p5): + {'power': False, 'mode': 'normal', 'speed': 35, 'roll_enable': False, 'roll_angle': 140, 'time_off': 0, 'light': True, 'beep_sound': False, 'child_lock': False} @@ -476,7 +475,10 @@ def set_led_brightness(self, brightness: LedBrightness): ), ) def set_led(self, led: bool): - """Turn led on/off. Not supported by model SA1.""" + """Turn led on/off. + + Not supported by model SA1. + """ if led: return self.send("set_led", ["on"]) else: diff --git a/miio/fan_leshow.py b/miio/fan_leshow.py index bac2b7ca8..2c9f98d78 100644 --- a/miio/fan_leshow.py +++ b/miio/fan_leshow.py @@ -42,12 +42,10 @@ class FanLeshowStatus: """Container for status reports from the Xiaomi Rosou SS4 Ventilator.""" def __init__(self, data: Dict[str, Any]) -> None: - """ - Response of a Leshow Fan SS4 (leshow.fan.ss4): + """Response of a Leshow Fan SS4 (leshow.fan.ss4): {'power': 1, 'mode': 2, 'blow': 100, 'timer': 0, 'sound': 1, 'yaw': 0, 'fault': 0} - """ self.data = data @@ -166,7 +164,10 @@ def off(self): default_output=format_output("Setting mode to '{mode.value}'"), ) def set_mode(self, mode: OperationMode): - """Set mode. Choose from manual, natural, sleep, strong.""" + """Set mode. + + Choose from manual, natural, sleep, strong. + """ return self.send("set_mode", [mode.value]) @command( diff --git a/miio/fan_miot.py b/miio/fan_miot.py index 636dd01d0..69cc7fb92 100644 --- a/miio/fan_miot.py +++ b/miio/fan_miot.py @@ -64,7 +64,8 @@ class OperationModeMiot(enum.Enum): class FanStatusMiot: - """Container for status reports from the Xiaomi Mi Smart Pedestal Fan DMaker P9/P10.""" + """Container for status reports from the Xiaomi Mi Smart Pedestal Fan DMaker + P9/P10.""" def __init__(self, data: Dict[str, Any]) -> None: """ diff --git a/miio/gateway.py b/miio/gateway.py index 96b158852..40964e461 100644 --- a/miio/gateway.py +++ b/miio/gateway.py @@ -160,7 +160,8 @@ class Gateway(Device): * get_device_prop_exp [[sid, list, of, properties]] ## scene - * get_lumi_bind ["scene", ] for rooms/devices""" + * get_lumi_bind ["scene", ] for rooms/devices + """ def __init__( self, @@ -214,10 +215,7 @@ def model(self): @command() def discover_devices(self): - """ - Discovers SubDevices - and returns a list of the discovered devices. - """ + """Discovers SubDevices and returns a list of the discovered devices.""" # from https://github.com/aholstenson/miio/issues/26 device_type_mapping = { DeviceType.Switch: Switch, @@ -341,7 +339,7 @@ def set_prop(self, property, value): @command() def clock(self): - """Alarm clock""" + """Alarm clock.""" # payload of clock volume ("get_clock_volume") # already in get_clock response return self.send("get_clock") @@ -362,7 +360,8 @@ def set_developer_key(self, key): @command() def enable_telnet(self): - """Enable root telnet acces to the operating system, use login "admin" or "app", no password.""" + """Enable root telnet acces to the operating system, use login "admin" or "app", + no password.""" try: return self.send("enable_telnet_service") except DeviceError: @@ -379,7 +378,10 @@ def timezone(self): @command() def get_illumination(self): - """Get illumination. In lux?""" + """Get illumination. + + In lux? + """ try: return self.send("get_illumination").pop() except Exception as ex: @@ -389,10 +391,8 @@ def get_illumination(self): class GatewayDevice(Device): - """ - GatewayDevice class - Specifies the init method for all gateway device functionalities. - """ + """GatewayDevice class Specifies the init method for all gateway device + functionalities.""" def __init__( self, @@ -433,10 +433,8 @@ def off(self): @command() def arming_time(self) -> int: - """ - Return time in seconds the alarm stays 'oning' - before transitioning to 'on' - """ + """Return time in seconds the alarm stays 'oning' before transitioning to + 'on'.""" # Response: 5, 15, 30, 60 return self._gateway.send("get_arm_wait_time").pop() @@ -458,10 +456,7 @@ def set_triggering_time(self, seconds): @command() def triggering_light(self) -> int: - """ - Return the time the gateway light blinks - when the alarm is triggerd - """ + """Return the time the gateway light blinks when the alarm is triggerd.""" # Response: 0=do not blink, 1=always blink, x>1=blink for x seconds return self._gateway.get_prop("en_alarm_light").pop() @@ -483,9 +478,7 @@ def set_triggering_volume(self, volume): @command() def last_status_change_time(self) -> datetime: - """ - Return the last time the alarm changed status. - """ + """Return the last time the alarm changed status.""" return datetime.fromtimestamp(self._gateway.send("get_arming_time").pop()) @@ -513,7 +506,10 @@ def zigbee_pair(self, timeout): return self._gateway.send("start_zigbee_join", [timeout]) def send_to_zigbee(self): - """How does this differ from writing? Unknown.""" + """How does this differ from writing? + + Unknown. + """ raise NotImplementedError() return self._gateway.send("send_to_zigbee") @@ -651,19 +647,19 @@ def set_default_music(self): class GatewayLight(GatewayDevice): - """ - Light controls for the gateway. + """Light controls for the gateway. - The gateway LEDs can be controlled using 'rgb' or 'night_light' methods. - The 'night_light' methods control the same light as the 'rgb' methods, but has a separate memory for brightness and color. - Changing the 'rgb' light does not affect the stored state of the 'night_light', while changing the 'night_light' does effect the state of the 'rgb' light. + The gateway LEDs can be controlled using 'rgb' or 'night_light' methods. The + 'night_light' methods control the same light as the 'rgb' methods, but has a + separate memory for brightness and color. Changing the 'rgb' light does not affect + the stored state of the 'night_light', while changing the 'night_light' does effect + the state of the 'rgb' light. """ @command() def rgb_status(self): - """ - Get current status of the light. - Always represents the current status of the light as opposed to 'night_light_status'. + """Get current status of the light. Always represents the current status of the + light as opposed to 'night_light_status'. Example: {"is_on": false, "brightness": 0, "rgb": (0, 0, 0)} @@ -678,9 +674,9 @@ def rgb_status(self): @command() def night_light_status(self): - """ - Get status of the night light. - This command only gives the correct status of the LEDs if the last command was a 'night_light' command and not a 'rgb' light command, otherwise it gives the stored values of the 'night_light'. + """Get status of the night light. This command only gives the correct status of + the LEDs if the last command was a 'night_light' command and not a 'rgb' light + command, otherwise it gives the stored values of the 'night_light'. Example: {"is_on": false, "brightness": 0, "rgb": (0, 0, 0)} @@ -732,7 +728,8 @@ def set_night_light_brightness(self, brightness: int): @command(click.argument("color_name", type=str)) def set_rgb_color(self, color_name: str): - """Set gateway light color using color name ('color_map' variable in the source holds the valid values).""" + """Set gateway light color using color name ('color_map' variable in the source + holds the valid values).""" if color_name not in color_map.keys(): raise Exception( "Cannot find {color} in {colors}".format( @@ -745,7 +742,8 @@ def set_rgb_color(self, color_name: str): @command(click.argument("color_name", type=str)) def set_night_light_color(self, color_name: str): - """Set night light color using color name ('color_map' variable in the source holds the valid values).""" + """Set night light color using color name ('color_map' variable in the source + holds the valid values).""" if color_name not in color_map.keys(): raise Exception( "Cannot find {color} in {colors}".format( @@ -761,7 +759,8 @@ def set_night_light_color(self, color_name: str): click.argument("brightness", type=int), ) def set_rgb_using_name(self, color_name: str, brightness: int): - """Set gateway light color (using color name, 'color_map' variable in the source holds the valid values) and brightness (0-100).""" + """Set gateway light color (using color name, 'color_map' variable in the source + holds the valid values) and brightness (0-100).""" if 100 < brightness < 0: raise Exception("Brightness must be between 0 and 100") if color_name not in color_map.keys(): @@ -778,7 +777,8 @@ def set_rgb_using_name(self, color_name: str, brightness: int): click.argument("brightness", type=int), ) def set_night_light_using_name(self, color_name: str, brightness: int): - """Set night light color (using color name, 'color_map' variable in the source holds the valid values) and brightness (0-100).""" + """Set night light color (using color name, 'color_map' variable in the source + holds the valid values) and brightness (0-100).""" if 100 < brightness < 0: raise Exception("Brightness must be between 0 and 100") if color_name not in color_map.keys(): @@ -792,10 +792,8 @@ def set_night_light_using_name(self, color_name: str, brightness: int): class SubDevice: - """ - Base class for all subdevices of the gateway - these devices are connected through zigbee. - """ + """Base class for all subdevices of the gateway these devices are connected through + zigbee.""" _zigbee_model = "unknown" _model = "unknown" diff --git a/miio/heater.py b/miio/heater.py index 92b7d7379..441047aa8 100644 --- a/miio/heater.py +++ b/miio/heater.py @@ -53,8 +53,8 @@ class HeaterStatus: """Container for status reports from the Smartmi Zhimi Heater.""" def __init__(self, data: Dict[str, Any]) -> None: - """ - Response of a Heater (zhimi.heater.za1): + """Response of a Heater (zhimi.heater.za1): + {'power': 'off', 'target_temperature': 24, 'brightness': 1, 'buzzer': 'on', 'child_lock': 'off', 'temperature': 22.3, 'use_time': 43117, 'poweroff_time': 0, 'relative_humidity': 34} diff --git a/miio/huizuo.py b/miio/huizuo.py index 8a7c9d832..358b72bc1 100644 --- a/miio/huizuo.py +++ b/miio/huizuo.py @@ -1,8 +1,7 @@ -""" -Basic implementation for HUAYI HUIZUO LAMPS (huayi.light.*) - -These lamps have a white color only and support dimming and control of the temperature from 3000K to 6400K +"""Basic implementation for HUAYI HUIZUO LAMPS (huayi.light.*) +These lamps have a white color only and support dimming and control of the temperature +from 3000K to 6400K """ import logging @@ -160,7 +159,7 @@ def is_fan_reverse(self) -> Optional[bool]: @property def fan_mode(self) -> Optional[int]: - """Return 0 if 'Basic' and 1 if 'Natural wind'""" + """Return 0 if 'Basic' and 1 if 'Natural wind'.""" if "fan_mode" in self.data: return self.data["fan_mode"] return None @@ -174,14 +173,17 @@ def is_heater_on(self) -> Optional[bool]: @property def heater_fault_code(self) -> Optional[int]: - """Return Heater's fault code. 0 - No Fault""" + """Return Heater's fault code. + + 0 - No Fault + """ if "heater_fault_code" in self.data: return self.data["heater_fault_code"] return None @property def heat_level(self) -> Optional[int]: - """Return Heater's heat level""" + """Return Heater's heat level.""" if "heat_level" in self.data: return self.data["heat_level"] return None @@ -211,7 +213,7 @@ def __repr__(self): class Huizuo(MiotDevice): - """A basic support for Huizuo Lamps + """A basic support for Huizuo Lamps. Example: response of a Huizuo Pisces For Bedroom (huayi.light.pis123) {'id': 1, 'result': [ @@ -326,11 +328,12 @@ def set_color_temp(self, color_temp): class HuizuoLampFan(Huizuo): - """Support for Huizuo Lamps with fan + """Support for Huizuo Lamps with fan. - The next section contains the fan management commands - Right now I have no devices with the fan for live testing, so the following section - generated based on device specitifations""" + The next section contains the fan management commands Right now I have no devices + with the fan for live testing, so the following section generated based on device + specitifations + """ @command( default_output=format_output("Fan powering on"), @@ -435,11 +438,12 @@ def fan_reverse_off(self): class HuizuoLampHeater(Huizuo): - """Support for Huizuo Lamps with heater + """Support for Huizuo Lamps with heater. - The next section contains the heater management commands - Right now I have no devices with the heater for live testing, so the following section - generated based on device specitifations""" + The next section contains the heater management commands Right now I have no devices + with the heater for live testing, so the following section generated based on device + specitifations + """ @command( default_output=format_output("Heater powering on"), @@ -501,11 +505,12 @@ def status(self) -> HuizuoStatus: class HuizuoLampScene(Huizuo): - """Support for Huizuo Lamps with additional scene commands + """Support for Huizuo Lamps with additional scene commands. - The next section contains the scene management commands - Right now I have no devices with the scenes for live testing, so the following section - generated based on device specitifations""" + The next section contains the scene management commands Right now I have no devices + with the scenes for live testing, so the following section generated based on device + specitifations + """ @command( default_output=format_output("On/Off switch"), @@ -571,7 +576,8 @@ def colortemp_decrease(self): default_output=format_output("Switch between the color temperatures"), ) def colortemp_switch(self): - """Switch between the color temperatures (only for models with scenes support).""" + """Switch between the color temperatures (only for models with scenes + support).""" if self.model in MODELS_WITH_SCENES: return self.set_property("colortemp_switch", 0) @@ -591,7 +597,8 @@ def on_or_increase_brightness(self): default_output=format_output("Switch on or increase color temperature"), ) def on_or_increase_colortemp(self): - """Switch on or increase color temperature (only for models with scenes support).""" + """Switch on or increase color temperature (only for models with scenes + support).""" if self.model in MODELS_WITH_SCENES: return self.set_property("on_or_increase_colortemp", 0) diff --git a/miio/miioprotocol.py b/miio/miioprotocol.py index 786149e6d..84f885971 100644 --- a/miio/miioprotocol.py +++ b/miio/miioprotocol.py @@ -1,7 +1,7 @@ -"""miIO protocol implementation +"""miIO protocol implementation. -This module contains the implementation of routines to send handshakes, send -commands and discover devices (MiIOProtocol). +This module contains the implementation of routines to send handshakes, send commands +and discover devices (MiIOProtocol). """ import binascii import codecs @@ -28,8 +28,8 @@ def __init__( lazy_discover: bool = True, timeout: int = 5, ) -> None: - """ - Create a :class:`Device` instance. + """Create a :class:`Device` instance. + :param ip: IP address or a hostname for the device :param token: Token used for encryption :param start_id: Running message id sent to the device @@ -91,13 +91,13 @@ def send_handshake(self, *, retry_count=3) -> Message: @staticmethod def discover(addr: str = None, timeout: int = 5) -> Any: - """Scan for devices in the network. - This method is used to discover supported devices by sending a - handshake message to the broadcast address on port 54321. - If the target IP address is given, the handshake will be send as - an unicast packet. + """Scan for devices in the network. This method is used to discover supported + devices by sending a handshake message to the broadcast address on port 54321. + If the target IP address is given, the handshake will be send as an unicast + packet. - :param str addr: Target IP address""" + :param str addr: Target IP address + """ is_broadcast = addr is None seen_addrs = [] # type: List[str] if is_broadcast: @@ -146,15 +146,16 @@ def send( *, extra_parameters: Dict = None ) -> Any: - """Build and send the given command. - Note that this will implicitly call :func:`send_handshake` to do a handshake, - and will re-try in case of errors while incrementing the `_id` by 100. + """Build and send the given command. Note that this will implicitly call + :func:`send_handshake` to do a handshake, and will re-try in case of errors + while incrementing the `_id` by 100. :param str command: Command to send :param dict parameters: Parameters to send, or an empty list :param retry_count: How many times to retry in case of failure, how many handshakes to send :param dict extra_parameters: Extra top-level parameters - :raises DeviceException: if an error has occurred during communication.""" + :raises DeviceException: if an error has occurred during communication. + """ if not self.lazy_discover or not self._discovered: self.send_handshake() diff --git a/miio/philips_bulb.py b/miio/philips_bulb.py index a90d83eca..aefedd2a5 100644 --- a/miio/philips_bulb.py +++ b/miio/philips_bulb.py @@ -26,7 +26,7 @@ class PhilipsBulbException(DeviceException): class PhilipsBulbStatus: - """Container for status reports from Xiaomi Philips LED Ceiling Lamp""" + """Container for status reports from Xiaomi Philips LED Ceiling Lamp.""" def __init__(self, data: Dict[str, Any]) -> None: # {'power': 'on', 'bright': 85, 'cct': 9, 'snm': 0, 'dv': 0} diff --git a/miio/philips_eyecare.py b/miio/philips_eyecare.py index 830a29bb2..bee749485 100644 --- a/miio/philips_eyecare.py +++ b/miio/philips_eyecare.py @@ -16,7 +16,7 @@ class PhilipsEyecareException(DeviceException): class PhilipsEyecareStatus: - """Container for status reports from Xiaomi Philips Eyecare Smart Lamp 2""" + """Container for status reports from Xiaomi Philips Eyecare Smart Lamp 2.""" def __init__(self, data: Dict[str, Any]) -> None: # ['power': 'off', 'bright': 5, 'notifystatus': 'off', diff --git a/miio/philips_moonlight.py b/miio/philips_moonlight.py index 3646f4673..ce1ab4ac4 100644 --- a/miio/philips_moonlight.py +++ b/miio/philips_moonlight.py @@ -20,8 +20,7 @@ class PhilipsMoonlightStatus: """Container for status reports from Xiaomi Philips Zhirui Bedside Lamp.""" def __init__(self, data: Dict[str, Any]) -> None: - """ - Response of a Moonlight (philips.light.moonlight): + """Response of a Moonlight (philips.light.moonlight): {'pow': 'off', 'sta': 0, 'bri': 1, 'rgb': 16741971, 'cct': 1, 'snm': 0, 'spr': 0, 'spt': 15, 'wke': 0, 'bl': 1, 'ms': 1, 'mb': 1, 'wkp': [0, 24, 0]} @@ -55,8 +54,7 @@ def scene(self) -> int: @property def sleep_assistant(self) -> int: - """ - Example values: + """Example values: 0: Unknown 1: Unknown @@ -131,7 +129,6 @@ class PhilipsMoonlight(Device): go_night # Night light / read mode get_wakeup_time enable_bl # Night light - """ @command( diff --git a/miio/philips_rwread.py b/miio/philips_rwread.py index ee02df70b..0d5e19b9f 100644 --- a/miio/philips_rwread.py +++ b/miio/philips_rwread.py @@ -29,11 +29,10 @@ class MotionDetectionSensitivity(enum.Enum): class PhilipsRwreadStatus: - """Container for status reports from Xiaomi Philips RW Read""" + """Container for status reports from Xiaomi Philips RW Read.""" def __init__(self, data: Dict[str, Any]) -> None: - """ - Response of a RW Read (philips.light.rwread): + """Response of a RW Read (philips.light.rwread): {'power': 'on', 'bright': 53, 'dv': 0, 'snm': 1, 'flm': 0, 'chl': 0, 'flmv': 0} diff --git a/miio/powerstrip.py b/miio/powerstrip.py index 000e4c0a9..85b7635ed 100644 --- a/miio/powerstrip.py +++ b/miio/powerstrip.py @@ -50,8 +50,7 @@ class PowerStripStatus: """Container for status reports from the power strip.""" def __init__(self, data: Dict[str, Any]) -> None: - """ - Supported device models: qmi.powerstrip.v1, zimi.powerstrip.v2 + """Supported device models: qmi.powerstrip.v1, zimi.powerstrip.v2. Response of a Power Strip 2 (zimi.powerstrip.v2): {'power','on', 'temperature': 48.7, 'current': 0.05, 'mode': None, @@ -76,7 +75,10 @@ def temperature(self) -> float: @property def current(self) -> Optional[float]: - """Current, if available. Meaning and voltage reference unknown.""" + """Current, if available. + + Meaning and voltage reference unknown. + """ if self.data["current"] is not None: return self.data["current"] return None diff --git a/miio/protocol.py b/miio/protocol.py index 2c4b3f99c..9a7d59ad3 100644 --- a/miio/protocol.py +++ b/miio/protocol.py @@ -1,4 +1,4 @@ -"""miIO protocol implementation +"""miIO protocol implementation. This module contains the implementation of the routines to encrypt and decrypt miIO payloads with a device-specific token. @@ -44,7 +44,7 @@ class Utils: - """ This class is adapted from the original xpn.py code by gst666 """ + """This class is adapted from the original xpn.py code by gst666.""" @staticmethod def verify_token(token: bytes): @@ -74,7 +74,8 @@ def encrypt(plaintext: bytes, token: bytes) -> bytes: :param bytes plaintext: Plaintext (json) to encrypt :param bytes token: Token to use - :return: Encrypted bytes""" + :return: Encrypted bytes + """ if not isinstance(plaintext, bytes): raise TypeError("plaintext requires bytes") Utils.verify_token(token) @@ -93,7 +94,8 @@ def decrypt(ciphertext: bytes, token: bytes) -> bytes: :param bytes ciphertext: Ciphertext to decrypt :param bytes token: Token to use - :return: Decrypted bytes object""" + :return: Decrypted bytes object + """ if not isinstance(ciphertext, bytes): raise TypeError("ciphertext requires bytes") Utils.verify_token(token) @@ -110,7 +112,7 @@ def decrypt(ciphertext: bytes, token: bytes) -> bytes: @staticmethod def checksum_field_bytes(ctx: Dict[str, Any]) -> bytearray: - """Gather bytes for checksum calculation""" + """Gather bytes for checksum calculation.""" x = bytearray(ctx["header"].data) x += ctx["_"]["token"] if "data" in ctx: @@ -153,7 +155,8 @@ class EncryptionAdapter(Adapter): def _encode(self, obj, context, path): """Encrypt the given payload with the token stored in the context. - :param obj: JSON object to encrypt""" + :param obj: JSON object to encrypt + """ # pp(context) return Utils.encrypt( json.dumps(obj).encode("utf-8") + b"\x00", context["_"]["token"] @@ -162,7 +165,8 @@ def _encode(self, obj, context, path): def _decode(self, obj, context, path): """Decrypts the given payload with the token stored in the context. - :return str: JSON object""" + :return str: JSON object + """ try: # pp(context) decrypted = Utils.decrypt(obj, context["_"]["token"]) diff --git a/miio/pwzn_relay.py b/miio/pwzn_relay.py index cc9ca4c34..9d84d1dc1 100644 --- a/miio/pwzn_relay.py +++ b/miio/pwzn_relay.py @@ -60,8 +60,8 @@ class PwznRelayStatus: """Container for status reports from the plug.""" def __init__(self, data: Dict[str, Any]) -> None: - """ - Response of a PWZN Relay Apple (pwzn.relay.apple) + """Response of a PWZN Relay Apple (pwzn.relay.apple) + { 'relay_status': 9, 'on_count': 2, 'name0': 'channel1', 'name1': '', 'name2': '', 'name3': '', 'name4': '', 'name5': '', 'name6': '', 'name7': '', 'name8': '', 'name9': '', 'name10': '', 'name11': '', @@ -78,7 +78,7 @@ def relay_state(self) -> int: @property def relay_names(self) -> Dict[int, str]: def _extract_index_from_key(name) -> int: - """extract the index from the variable""" + """extract the index from the variable.""" return int(name[4:]) return { diff --git a/miio/tests/dummies.py b/miio/tests/dummies.py index 333820c84..322ea1ae7 100644 --- a/miio/tests/dummies.py +++ b/miio/tests/dummies.py @@ -1,7 +1,5 @@ class DummyMiIOProtocol: - """ - DummyProtocol allows you mock MiIOProtocol. - """ + """DummyProtocol allows you mock MiIOProtocol.""" def __init__(self, dummy_device): # TODO: Ideally, return_values should be passed in here. Passing in dummy_device (which must have @@ -33,7 +31,6 @@ class DummyDevice: "get_prop": self._get_state, "power": lambda x: self._set_state("power", x) } - """ def __init__(self, *args, **kwargs): @@ -45,13 +42,13 @@ def _reset_state(self): self.state = self.start_state.copy() def _set_state(self, var, value): - """Set a state of a variable, - the value is expected to be an array with length of 1.""" + """Set a state of a variable, the value is expected to be an array with length + of 1.""" # print("setting %s = %s" % (var, value)) self.state[var] = value.pop(0) def _get_state(self, props): - """Return wanted properties""" + """Return wanted properties.""" return [self.state[x] for x in props if x in self.state] @@ -67,7 +64,7 @@ def get_properties_for_mapping(self): return self.state def get_properties(self, properties): - """Return values only for listed properties""" + """Return values only for listed properties.""" keys = [p["did"] for p in properties] props = [] for prop in self.state: diff --git a/miio/tests/test_airconditioningcompanion.py b/miio/tests/test_airconditioningcompanion.py index 348896b7c..ebd585081 100644 --- a/miio/tests/test_airconditioningcompanion.py +++ b/miio/tests/test_airconditioningcompanion.py @@ -85,11 +85,11 @@ def _reset_state(self): self.state = self.start_state.copy() def _get_state(self, props): - """Return the requested data""" + """Return the requested data.""" return self.state def _set_power(self, value: str): - """Set the requested power state""" + """Set the requested power state.""" if value == STATE_ON: self.state[1] = self.state[1][:2] + "1" + self.state[1][3:] @@ -239,15 +239,15 @@ def _reset_state(self): self.state = self.start_state.copy() def _get_state(self, props): - """Return the requested data""" + """Return the requested data.""" return self.state def _get_device_prop(self, props): - """Return the requested data""" + """Return the requested data.""" return self.device_prop[props[0]][props[1]] def _toggle_plug(self, props): - """Toggle the lumi.0 plug state""" + """Toggle the lumi.0 plug state.""" self.device_prop["lumi.0"]["plug_state"] = [props.pop()] @@ -324,7 +324,7 @@ def _reset_state(self): self.state = self.start_state.copy() def _get_state(self, props): - """Return the requested data""" + """Return the requested data.""" return self.state diff --git a/miio/tests/test_airhumidifier_jsq.py b/miio/tests/test_airhumidifier_jsq.py index 4857def2a..1266d6ea7 100644 --- a/miio/tests/test_airhumidifier_jsq.py +++ b/miio/tests/test_airhumidifier_jsq.py @@ -72,7 +72,7 @@ def _get_device_info(self, _): return self.dummy_device_info def _get_state(self, props): - """Return wanted properties""" + """Return wanted properties.""" return list(self.state.values()) diff --git a/miio/tests/test_airqualitymonitor.py b/miio/tests/test_airqualitymonitor.py index 53a500b0c..a78f73cad 100644 --- a/miio/tests/test_airqualitymonitor.py +++ b/miio/tests/test_airqualitymonitor.py @@ -98,7 +98,7 @@ def __init__(self, *args, **kwargs): super().__init__(args, kwargs) def _get_state(self, props): - """Return wanted properties""" + """Return wanted properties.""" return self.state @@ -148,7 +148,7 @@ def __init__(self, *args, **kwargs): super().__init__(args, kwargs) def _get_state(self, props): - """Return wanted properties""" + """Return wanted properties.""" return self.state diff --git a/miio/tests/test_chuangmi_plug.py b/miio/tests/test_chuangmi_plug.py index cee554809..5962da97b 100644 --- a/miio/tests/test_chuangmi_plug.py +++ b/miio/tests/test_chuangmi_plug.py @@ -28,7 +28,7 @@ def __init__(self, *args, **kwargs): super().__init__(args, kwargs) def _set_state_basic(self, var, value): - """Set a state of a variable""" + """Set a state of a variable.""" self.state[var] = value @@ -100,11 +100,11 @@ def __init__(self, *args, **kwargs): super().__init__(args, kwargs) def _set_state_basic(self, var, value): - """Set a state of a variable""" + """Set a state of a variable.""" self.state[var] = value def _get_load_power(self, props=None): - """Return load power""" + """Return load power.""" return [300] diff --git a/miio/tests/test_fan.py b/miio/tests/test_fan.py index ee688c93d..dd29d1562 100644 --- a/miio/tests/test_fan.py +++ b/miio/tests/test_fan.py @@ -175,15 +175,18 @@ def direct_speed(): self.device.set_direct_speed(101) def test_set_rotate(self): - """The method is open-loop. The new state cannot be retrieved.""" + """The method is open-loop. + + The new state cannot be retrieved. + """ self.device.set_rotate(MoveDirection.Left) self.device.set_rotate(MoveDirection.Right) def test_set_angle(self): """This test doesn't implement the real behaviour of the device may be. - The property "angle" doesn't provide the current setting. - It's a measurement of the current position probably. + The property "angle" doesn't provide the current setting. It's a measurement of + the current position probably. """ def angle(): @@ -428,15 +431,18 @@ def natural_speed(): self.device.set_natural_speed(101) def test_set_rotate(self): - """The method is open-loop. The new state cannot be retrieved.""" + """The method is open-loop. + + The new state cannot be retrieved. + """ self.device.set_rotate(MoveDirection.Left) self.device.set_rotate(MoveDirection.Right) def test_set_angle(self): """This test doesn't implement the real behaviour of the device may be. - The property "angle" doesn't provide the current setting. - It's a measurement of the current position probably. + The property "angle" doesn't provide the current setting. It's a measurement of + the current position probably. """ def angle(): @@ -643,15 +649,18 @@ def natural_speed(): self.device.set_natural_speed(101) def test_set_rotate(self): - """The method is open-loop. The new state cannot be retrieved.""" + """The method is open-loop. + + The new state cannot be retrieved. + """ self.device.set_rotate(MoveDirection.Left) self.device.set_rotate(MoveDirection.Right) def test_set_angle(self): """This test doesn't implement the real behaviour of the device may be. - The property "angle" doesn't provide the current setting. - It's a measurement of the current position probably. + The property "angle" doesn't provide the current setting. It's a measurement of + the current position probably. """ def angle(): diff --git a/miio/tests/test_powerstrip.py b/miio/tests/test_powerstrip.py index 57b947044..ebba6e39a 100644 --- a/miio/tests/test_powerstrip.py +++ b/miio/tests/test_powerstrip.py @@ -233,6 +233,9 @@ def test_status_without_power_price(self): assert self.state().power_price is None def test_set_realtime_power(self): - """The method is open-loop. The new state cannot be retrieved.""" + """The method is open-loop. + + The new state cannot be retrieved. + """ self.device.set_realtime_power(True) self.device.set_realtime_power(False) diff --git a/miio/tests/test_toiletlid.py b/miio/tests/test_toiletlid.py index 318425fbd..24d3d1242 100644 --- a/miio/tests/test_toiletlid.py +++ b/miio/tests/test_toiletlid.py @@ -8,7 +8,6 @@ Ambient Light: Yellow Filter remaining: 100% Filter remaining time: 180 - """ from unittest import TestCase diff --git a/miio/toiletlid.py b/miio/toiletlid.py index b7a32afb7..99ac5074d 100644 --- a/miio/toiletlid.py +++ b/miio/toiletlid.py @@ -42,12 +42,12 @@ def __init__(self, data: Dict[str, Any]) -> None: @property def work_state(self) -> int: - """Device state code""" + """Device state code.""" return self.data["work_state"] @property def work_mode(self) -> ToiletlidOperatingMode: - """Device working mode""" + """Device working mode.""" return ToiletlidOperatingMode((self.work_state - 1) // 16) @property @@ -56,12 +56,12 @@ def is_on(self) -> bool: @property def filter_use_percentage(self) -> str: - """Filter percentage of remaining life""" + """Filter percentage of remaining life.""" return "{}%".format(self.data["filter_use_flux"]) @property def filter_remaining_time(self) -> int: - """Filter remaining life days""" + """Filter remaining life days.""" return self.data["filter_use_time"] @property diff --git a/miio/updater.py b/miio/updater.py index 1958be9f5..9a446073f 100644 --- a/miio/updater.py +++ b/miio/updater.py @@ -35,8 +35,9 @@ def handle_one_request(self): class OneShotServer: """A simple HTTP server for serving an update file. - The server will be started in an emphemeral port, and will only accept - a single request to keep it simple.""" + The server will be started in an emphemeral port, and will only accept a single + request to keep it simple. + """ def __init__(self, file, interface=None): addr = ("", 0) diff --git a/miio/utils.py b/miio/utils.py index dda9cf1af..42b05658c 100644 --- a/miio/utils.py +++ b/miio/utils.py @@ -6,10 +6,8 @@ def deprecated(reason): - """ - This is a decorator which can be used to mark functions and classes - as deprecated. It will result in a warning being emitted - when the function is used. + """This is a decorator which can be used to mark functions and classes as + deprecated. It will result in a warning being emitted when the function is used. From https://stackoverflow.com/a/40301488 """ diff --git a/miio/vacuum.py b/miio/vacuum.py index 1f160f219..1c1f4915f 100644 --- a/miio/vacuum.py +++ b/miio/vacuum.py @@ -84,7 +84,7 @@ class FanspeedE2(enum.Enum): class WaterFlow(enum.Enum): - """Water flow strength on s5 max. """ + """Water flow strength on s5 max.""" Minimum = 200 Low = 201 @@ -115,8 +115,8 @@ def start(self): def stop(self): """Stop cleaning. - Note, prefer 'pause' instead of this for wider support. - Some newer vacuum models do not support this command. + Note, prefer 'pause' instead of this for wider support. Some newer vacuum models + do not support this command. """ return self.send("app_stop") @@ -150,14 +150,18 @@ def home(self): @command(click.argument("x_coord", type=int), click.argument("y_coord", type=int)) def goto(self, x_coord: int, y_coord: int): """Go to specific target. + :param int x_coord: x coordinate - :param int y_coord: y coordinate""" + :param int y_coord: y coordinate + """ return self.send("app_goto_target", [x_coord, y_coord]) @command(click.argument("zones", type=LiteralParamType(), required=True)) def zoned_clean(self, zones: List): """Clean zones. - :param List zones: List of zones to clean: [[x1,y1,x2,y2, iterations],[x1,y1,x2,y2, iterations]]""" + + :param List zones: List of zones to clean: [[x1,y1,x2,y2, iterations],[x1,y1,x2,y2, iterations]] + """ return self.send("app_zoned_clean", zones) @command() @@ -193,8 +197,8 @@ def manual_stop(self): def manual_control_once( self, rotation: int, velocity: float, duration: int = MANUAL_DURATION_DEFAULT ): - """Starts the remote control mode and executes - the action once before deactivating the mode.""" + """Starts the remote control mode and executes the action once before + deactivating the mode.""" number_of_tries = 3 self.manual_start() while number_of_tries > 0: @@ -343,8 +347,8 @@ def create_nogo_zone(self, x1, y1, x2, y2, x3, y3, x4, y4): def enable_lab_mode(self, enable): """Enable persistent maps and software barriers. - This is required to use create_nogo_zone and create_software_barrier - commands.""" + This is required to use create_nogo_zone and create_software_barrier commands. + """ return self.send("set_lab_status", int(enable))["ok"] @command() @@ -356,7 +360,8 @@ def clean_history(self) -> CleaningSummary: def last_clean_details(self) -> Optional[CleaningDetails]: """Return details from the last cleaning. - Returns None if there has been no cleanups.""" + Returns None if there has been no cleanups. + """ history = self.clean_history() if not history.ids: return None @@ -423,7 +428,8 @@ def add_timer(self, cron: str, command: str, parameters: str): :param cron: schedule in cron format :param command: ignored by the vacuum. - :param parameters: ignored by the vacuum.""" + :param parameters: ignored by the vacuum. + """ import time ts = int(round(time.time() * 1000)) @@ -433,7 +439,8 @@ def add_timer(self, cron: str, command: str, parameters: str): def delete_timer(self, timer_id: int): """Delete a timer with given ID. - :param int timer_id: Timer ID""" + :param int timer_id: Timer ID + """ return self.send("del_timer", [str(timer_id)]) @command( @@ -443,7 +450,8 @@ def update_timer(self, timer_id: int, mode: TimerState): """Update a timer with given ID. :param int timer_id: Timer ID - :param TimerStae mode: either On or Off""" + :param TimerStae mode: either On or Off + """ if mode != TimerState.On and mode != TimerState.Off: raise DeviceException("Only 'On' or 'Off' are allowed") return self.send("upd_timer", [str(timer_id), mode.value]) @@ -467,7 +475,8 @@ def set_dnd(self, start_hr: int, start_min: int, end_hr: int, end_min: int): :param int start_hr: Start hour :param int start_min: Start minute :param int end_hr: End hour - :param int end_min: End minute""" + :param int end_min: End minute + """ return self.send("set_dnd_timer", [start_hr, start_min, end_hr, end_min]) @command() @@ -479,7 +488,8 @@ def disable_dnd(self): def set_fan_speed(self, speed: int): """Set fan speed. - :param int speed: Fan speed to set""" + :param int speed: Fan speed to set + """ # speed = [38, 60 or 77] return self.send("set_custom_mode", [speed]) @@ -491,8 +501,9 @@ def fan_speed(self): def _autodetect_model(self): """Detect the model of the vacuum. - For the moment this is used only for the fanspeeds, - but that could be extended to cover other supported features.""" + For the moment this is used only for the fanspeeds, but that could be extended + to cover other supported features. + """ try: info = self.info() self.model = info.model @@ -613,7 +624,7 @@ def configure_wifi(self, ssid, password, uid=0, timezone=None): @command() def carpet_mode(self): - """Get carpet mode settings""" + """Get carpet mode settings.""" return CarpetModeStatus(self.send("get_carpet_mode")[0]) @command( @@ -660,7 +671,9 @@ def resume_segment_clean(self): @command(click.argument("segments", type=LiteralParamType(), required=True)) def segment_clean(self, segments: List): """Clean segments. - :param List segments: List of segments to clean: [16,17,18]""" + + :param List segments: List of segments to clean: [16,17,18] + """ return self.send("app_segment_clean", segments) @command() diff --git a/miio/vacuum_cli.py b/miio/vacuum_cli.py index ccc512119..f815a4a14 100644 --- a/miio/vacuum_cli.py +++ b/miio/vacuum_cli.py @@ -296,7 +296,7 @@ def backward(vac: miio.Vacuum, amount: float): @click.argument("velocity", type=float) @click.argument("duration", type=int) def move(vac: miio.Vacuum, rotation: int, velocity: float, duration: int): - """Pass raw manual values""" + """Pass raw manual values.""" return vac.manual_control(rotation, velocity, duration) @@ -564,8 +564,9 @@ def carpet_mode(vac: miio.Vacuum, enabled=None): def configure_wifi(vac: miio.Vacuum, ssid: str, password: str, uid: int, timezone: str): """Configure the wifi settings. - Note that some newer firmwares may expect you to define the timezone - by using --timezone.""" + Note that some newer firmwares may expect you to define the timezone by using + --timezone. + """ click.echo("Configuring wifi to SSID: %s" % ssid) click.echo(vac.configure_wifi(ssid, password, uid, timezone)) diff --git a/miio/vacuumcontainers.py b/miio/vacuumcontainers.py index 9ec292972..a95986d99 100644 --- a/miio/vacuumcontainers.py +++ b/miio/vacuumcontainers.py @@ -120,7 +120,7 @@ def error(self) -> str: @property def battery(self) -> int: - """Remaining battery in percentage. """ + """Remaining battery in percentage.""" return int(self.data["battery"]) @property @@ -267,7 +267,8 @@ def error(self) -> str: def complete(self) -> bool: """Return True if the cleaning run was complete (e.g. without errors). - see also :func:`error`.""" + see also :func:`error`. + """ return bool(self.data[5] == 1) def __repr__(self) -> str: @@ -280,9 +281,9 @@ def __repr__(self) -> str: class ConsumableStatus: - """Container for consumable status information, - including information about brushes and duration until they should be changed. - The methods returning time left are based on the following lifetimes: + """Container for consumable status information, including information about brushes + and duration until they should be changed. The methods returning time left are based + on the following lifetimes: - Sensor cleanup time: XXX FIXME - Main brush: 300 hours @@ -385,8 +386,10 @@ def __repr__(self): class Timer: """A container for scheduling. - The timers are accessed using an integer ID, which is based on the unix - timestamp of the creation time.""" + + The timers are accessed using an integer ID, which is based on the unix timestamp of + the creation time. + """ def __init__(self, data: List[Any], timezone: "datetime.tzinfo") -> None: # id / timestamp, enabled, ['', ['command', 'params'] @@ -424,7 +427,9 @@ def cron(self) -> str: @property def action(self) -> str: """The action to be taken on the given time. - Note, this seems to be always 'start'.""" + + Note, this seems to be always 'start'. + """ return str(self.data[2][1]) @property diff --git a/miio/viomivacuum.py b/miio/viomivacuum.py index d0575f9e8..a0bc64801 100644 --- a/miio/viomivacuum.py +++ b/miio/viomivacuum.py @@ -273,7 +273,7 @@ def has_new_map(self) -> bool: @property def mop_mode(self) -> ViomiMode: - """Whether mopping is enabled and if so which mode + """Whether mopping is enabled and if so which mode. TODO: is this really the same as mode? """ @@ -416,7 +416,8 @@ def set_dnd( :param int start_hr: Start hour :param int start_min: Start minute :param int end_hr: End hour - :param int end_min: End minute""" + :param int end_min: End minute + """ return self.send( "set_notdisturb", [0 if disable else 1, start_hr, start_min, end_hr, end_min], diff --git a/miio/waterpurifier_yunmi.py b/miio/waterpurifier_yunmi.py index 5b6f7671a..8f0348158 100644 --- a/miio/waterpurifier_yunmi.py +++ b/miio/waterpurifier_yunmi.py @@ -75,8 +75,7 @@ class OperationStatus: def __init__(self, operation_status: int): - """ - Operation status parser. + """Operation status parser. Return value of operation_status: @@ -106,8 +105,8 @@ class WaterPurifierYunmiStatus: """Container for status reports from the water purifier (Yunmi model).""" def __init__(self, data: Dict[str, Any]) -> None: - """ - Status of a Water Purifier C1 (yummi.waterpuri.lx11): + """Status of a Water Purifier C1 (yummi.waterpuri.lx11): + [0, 7200, 8640, 520, 379, 7200, 17280, 2110, 4544, 80, 4, 0, 31, 100, 7200, 8640, 1440, 3313] diff --git a/miio/wifirepeater.py b/miio/wifirepeater.py index eac3e1acd..3469cf8d4 100644 --- a/miio/wifirepeater.py +++ b/miio/wifirepeater.py @@ -49,8 +49,7 @@ def __repr__(self) -> str: class WifiRepeaterConfiguration: def __init__(self, data): - """ - Response of a xiaomi.repeater.v2: + """Response of a xiaomi.repeater.v2: {'ssid': 'SSID', 'pwd': 'PWD', 'hidden': 0} """ diff --git a/miio/wifispeaker.py b/miio/wifispeaker.py index 0dbfb6d46..0ef15e21e 100644 --- a/miio/wifispeaker.py +++ b/miio/wifispeaker.py @@ -30,12 +30,13 @@ class TransportChannel(enum.Enum): class WifiSpeakerStatus: """Container of a speaker state. - This contains information such as the name of the device, - and what is currently being played by it.""" + + This contains information such as the name of the device, and what is currently + being played by it. + """ def __init__(self, data): - """ - Example response of a xiaomi.wifispeaker.v2: + """Example response of a xiaomi.wifispeaker.v2: {"DeviceName": "Mi Internet Speaker", "channel_title\": "XXX", "current_state": "PLAYING", "hardware_version": "S602", @@ -87,7 +88,7 @@ def track_duration(self) -> str: @property def transport_channel(self) -> TransportChannel: - """Transport channel, e.g. PLAYLIST""" + """Transport channel, e.g. PLAYLIST.""" return TransportChannel(self.data["transport_channel"]) def __repr__(self) -> str: diff --git a/miio/yeelight_dual_switch.py b/miio/yeelight_dual_switch.py index 5b059075c..de0f1e9f5 100644 --- a/miio/yeelight_dual_switch.py +++ b/miio/yeelight_dual_switch.py @@ -59,47 +59,47 @@ def __init__(self, data: Dict[str, Any]) -> None: @property def switch_1_state(self) -> bool: - """First switch state""" + """First switch state.""" return bool(self.data["switch_1_state"]) @property def switch_1_default_state(self) -> bool: - """First switch default state""" + """First switch default state.""" return bool(self.data["switch_1_default_state"]) @property def switch_1_off_delay(self) -> int: - """First switch off delay""" + """First switch off delay.""" return self.data["switch_1_off_delay"] @property def switch_2_state(self) -> bool: - """Second switch state""" + """Second switch state.""" return bool(self.data["switch_2_state"]) @property def switch_2_default_state(self) -> bool: - """Second switch default state""" + """Second switch default state.""" return bool(self.data["switch_2_default_state"]) @property def switch_2_off_delay(self) -> int: - """Second switch off delay""" + """Second switch off delay.""" return self.data["switch_2_off_delay"] @property def interlock(self) -> bool: - """Interlock""" + """Interlock.""" return bool(self.data["interlock"]) @property def flex_mode(self) -> int: - """Flex mode""" + """Flex mode.""" return self.data["flex_mode"] @property def rc_list(self) -> str: - """List of paired remote controls""" + """List of paired remote controls.""" return self.data["rc_list"] def __repr__(self) -> str: @@ -130,7 +130,8 @@ def __repr__(self) -> str: class YeelightDualControlModule(MiotDevice): - """Main class representing the Yeelight Dual Control Module (yeelink.switch.sw1) which uses MIoT protocol.""" + """Main class representing the Yeelight Dual Control Module (yeelink.switch.sw1) + which uses MIoT protocol.""" def __init__( self, @@ -157,7 +158,7 @@ def __init__( ) ) def status(self) -> DualControlModuleStatus: - """Retrieve properties""" + """Retrieve properties.""" p = [ "switch_1_state", "switch_1_default_state", @@ -251,7 +252,7 @@ def set_flex_mode(self, flex_mode: bool): default_output=format_output("Delete remote control with MAC: {rc_mac}"), ) def delete_rc(self, rc_mac: str): - """Delete remote control by MAC""" + """Delete remote control by MAC.""" return self.set_property("rc_list_for_del", rc_mac) @command( @@ -259,5 +260,5 @@ def delete_rc(self, rc_mac: str): default_output=format_output("Set interlock to: {interlock}"), ) def set_interlock(self, interlock: bool): - """Set interlock""" + """Set interlock.""" return self.set_property("interlock", interlock) diff --git a/pyproject.toml b/pyproject.toml index 928ff304e..c69c172e4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,6 +54,7 @@ restructuredtext_lint = "^1" tox = "^3" isort = "^4" cffi = "^1" +docformatter = "*" [tool.isort] multi_line_output = 3 From 12e2a8aa2075c5dd50c22d383b88f461f910b013 Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Wed, 20 Jan 2021 18:34:21 +0100 Subject: [PATCH 2/4] Add version pinning for docformatter --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c69c172e4..958aa7d8f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,7 +54,7 @@ restructuredtext_lint = "^1" tox = "^3" isort = "^4" cffi = "^1" -docformatter = "*" +docformatter = "^1" [tool.isort] multi_line_output = 3 From bd648e0b174e8fec953adcc71afa41476d59744e Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Wed, 20 Jan 2021 18:37:28 +0100 Subject: [PATCH 3/4] Update poetry.lock --- poetry.lock | 147 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 91 insertions(+), 56 deletions(-) diff --git a/poetry.lock b/poetry.lock index c60b24c3c..859b22c80 100644 --- a/poetry.lock +++ b/poetry.lock @@ -132,7 +132,7 @@ toml = ["toml"] [[package]] name = "croniter" -version = "0.3.36" +version = "0.3.37" description = "croniter provides iteration for datetime object with cron like format" category = "main" optional = false @@ -185,6 +185,17 @@ restructuredtext-lint = ">=0.7" six = "*" stevedore = "*" +[[package]] +name = "docformatter" +version = "1.4" +description = "Formats docstrings to follow PEP 257." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +untokenize = "*" + [[package]] name = "docutils" version = "0.16" @@ -203,7 +214,7 @@ python-versions = "*" [[package]] name = "identify" -version = "1.5.10" +version = "1.5.13" description = "File identification library for Python" category = "dev" optional = false @@ -254,7 +265,7 @@ zipp = ">=0.5" [[package]] name = "importlib-resources" -version = "4.1.1" +version = "5.1.0" description = "Read resources from Python packages" category = "dev" optional = false @@ -262,8 +273,8 @@ python-versions = ">=3.6" marker = "python_version < \"3.7\"" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=3.5,<3.7.3 || >3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "pytest-black (>=0.3.7)", "pytest-mypy"] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=3.5,<3.7.3 || >3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "pytest-black (>=0.3.7)", "pytest-mypy"] [package.dependencies] [package.dependencies.zipp] @@ -419,7 +430,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pygments" -version = "2.7.3" +version = "2.7.4" description = "Pygments is a syntax highlighting package written in Python." category = "main" optional = false @@ -461,7 +472,7 @@ python = "<3.8" [[package]] name = "pytest-cov" -version = "2.10.1" +version = "2.11.1" description = "Pytest plugin for measuring coverage." category = "dev" optional = false @@ -471,12 +482,12 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" testing = ["fields", "hunter", "process-tests (2.0.2)", "six", "pytest-xdist", "virtualenv"] [package.dependencies] -coverage = ">=4.4" +coverage = ">=5.2.1" pytest = ">=4.6" [[package]] name = "pytest-mock" -version = "3.4.0" +version = "3.5.1" description = "Thin-wrapper around the mock package for easier use with pytest" category = "dev" optional = false @@ -509,11 +520,11 @@ python-versions = "*" [[package]] name = "pyyaml" -version = "5.3.1" +version = "5.4" description = "YAML parser and emitter for Python" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" [[package]] name = "requests" @@ -562,7 +573,7 @@ python-versions = "*" [[package]] name = "sphinx" -version = "3.4.1" +version = "3.4.3" description = "Python documentation generator" category = "main" optional = true @@ -606,7 +617,7 @@ sphinx = ">=1.5,<4.0" [[package]] name = "sphinx-rtd-theme" -version = "0.5.0" +version = "0.5.1" description = "Read the Docs theme for Sphinx" category = "main" optional = true @@ -726,7 +737,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "tox" -version = "3.20.1" +version = "3.21.2" description = "tox is a generic virtualenv management and test command line tool" category = "dev" optional = false @@ -734,7 +745,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [package.extras] docs = ["pygments-github-lexers (>=0.0.5)", "sphinx (>=2.0.0)", "sphinxcontrib-autoprogram (>=0.1.5)", "towncrier (>=18.5.0)"] -testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "pathlib2 (>=2.3.3)", "psutil (>=5.6.1)", "pytest (>=4.0.0)", "pytest-cov (>=2.5.1)", "pytest-mock (>=1.10.0)", "pytest-randomly (>=1.0.0)", "pytest-xdist (>=1.22.2)"] +testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "psutil (>=5.6.1)", "pytest (>=4.0.0)", "pytest-cov (>=2.5.1)", "pytest-mock (>=1.10.0)", "pytest-randomly (>=1.0.0)", "pytest-xdist (>=1.22.2)", "pathlib2 (>=2.3.3)"] [package.dependencies] colorama = ">=0.4.1" @@ -747,12 +758,12 @@ toml = ">=0.9.4" virtualenv = ">=16.0.0,<20.0.0 || >20.0.0,<20.0.1 || >20.0.1,<20.0.2 || >20.0.2,<20.0.3 || >20.0.3,<20.0.4 || >20.0.4,<20.0.5 || >20.0.5,<20.0.6 || >20.0.6,<20.0.7 || >20.0.7" [package.dependencies.importlib-metadata] -version = ">=0.12,<3" +version = ">=0.12" python = "<3.8" [[package]] name = "tqdm" -version = "4.55.0" +version = "4.56.0" description = "Fast, Extensible Progress Meter" category = "main" optional = false @@ -762,6 +773,14 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" dev = ["py-make (>=0.1.0)", "twine", "wheel"] telegram = ["requests"] +[[package]] +name = "untokenize" +version = "0.1.1" +description = "Transforms tokens into original source code (while preserving whitespace)." +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "urllib3" version = "1.26.2" @@ -777,7 +796,7 @@ socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] [[package]] name = "virtualenv" -version = "20.2.2" +version = "20.4.0" description = "Virtual Python Environment builder" category = "dev" optional = false @@ -785,7 +804,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" [package.extras] docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)"] -testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "pytest-xdist (>=1.31.0)", "packaging (>=20.0)", "xonsh (>=0.9.16)"] +testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "packaging (>=20.0)", "xonsh (>=0.9.16)"] [package.dependencies] appdirs = ">=1.4.3,<2" @@ -819,7 +838,7 @@ python-versions = "*" [[package]] name = "zeroconf" -version = "0.28.7" +version = "0.28.8" description = "Pure Python Multicast DNS Service Discovery Library (Bonjour/Avahi compatible)" category = "main" optional = false @@ -847,7 +866,7 @@ docs = ["sphinx", "sphinx_click", "sphinxcontrib-apidoc", "sphinx_rtd_theme"] [metadata] lock-version = "1.0" python-versions = "^3.6.5" -content-hash = "bc46f42face658f2dd1f31d94f02cb7a6632a11c1076bcad23a722499b21a2f5" +content-hash = "94ae90925ebb324489695a32c48375dccd8f6ed8b21da8f1e1fc83a316d1502e" [metadata.files] alabaster = [ @@ -986,8 +1005,8 @@ coverage = [ {file = "coverage-5.3.1.tar.gz", hash = "sha256:38f16b1317b8dd82df67ed5daa5f5e7c959e46579840d77a67a4ceb9cef0a50b"}, ] croniter = [ - {file = "croniter-0.3.36-py2.py3-none-any.whl", hash = "sha256:8ffe25deff39a2255bfbce32dc3f28f636d521686e12b00f5f0d229bef7da3e6"}, - {file = "croniter-0.3.36.tar.gz", hash = "sha256:9d3098e50f7edc7480470455d42f09c501fa1bb7e2fc113526ec6e90b068f32c"}, + {file = "croniter-0.3.37-py2.py3-none-any.whl", hash = "sha256:8f573a889ca9379e08c336193435c57c02698c2dd22659cdbe04fee57426d79b"}, + {file = "croniter-0.3.37.tar.gz", hash = "sha256:12ced475dfc107bf7c6c1440af031f34be14cd97bbbfaf0f62221a9c11e86404"}, ] cryptography = [ {file = "cryptography-3.3.1-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:c366df0401d1ec4e548bebe8f91d55ebcc0ec3137900d214dd7aac8427ef3030"}, @@ -1013,6 +1032,9 @@ doc8 = [ {file = "doc8-0.8.1-py2.py3-none-any.whl", hash = "sha256:4d58a5c8c56cedd2b2c9d6e3153be5d956cf72f6051128f0f2255c66227df721"}, {file = "doc8-0.8.1.tar.gz", hash = "sha256:4d1df12598807cf08ffa9a1d5ef42d229ee0de42519da01b768ff27211082c12"}, ] +docformatter = [ + {file = "docformatter-1.4.tar.gz", hash = "sha256:064e6d81f04ac96bc0d176cbaae953a0332482b22d3ad70d47c8a7f2732eef6f"}, +] docutils = [ {file = "docutils-0.16-py2.py3-none-any.whl", hash = "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af"}, {file = "docutils-0.16.tar.gz", hash = "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"}, @@ -1022,8 +1044,8 @@ filelock = [ {file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"}, ] identify = [ - {file = "identify-1.5.10-py2.py3-none-any.whl", hash = "sha256:cc86e6a9a390879dcc2976cef169dd9cc48843ed70b7380f321d1b118163c60e"}, - {file = "identify-1.5.10.tar.gz", hash = "sha256:943cd299ac7f5715fcb3f684e2fc1594c1e0f22a90d15398e5888143bd4144b5"}, + {file = "identify-1.5.13-py2.py3-none-any.whl", hash = "sha256:9dfb63a2e871b807e3ba62f029813552a24b5289504f5b071dea9b041aee9fe4"}, + {file = "identify-1.5.13.tar.gz", hash = "sha256:70b638cf4743f33042bebb3b51e25261a0a10e80f978739f17e7fd4837664a66"}, ] idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, @@ -1042,8 +1064,8 @@ importlib-metadata = [ {file = "importlib_metadata-1.7.0.tar.gz", hash = "sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83"}, ] importlib-resources = [ - {file = "importlib_resources-4.1.1-py3-none-any.whl", hash = "sha256:0a948d0c8c3f9344de62997e3f73444dbba233b1eaf24352933c2d264b9e4182"}, - {file = "importlib_resources-4.1.1.tar.gz", hash = "sha256:6b45007a479c4ec21165ae3ffbe37faf35404e2041fac6ae1da684f38530ca73"}, + {file = "importlib_resources-5.1.0-py3-none-any.whl", hash = "sha256:885b8eae589179f661c909d699a546cf10d83692553e34dca1bf5eb06f7f6217"}, + {file = "importlib_resources-5.1.0.tar.gz", hash = "sha256:bfdad047bce441405a49cf8eb48ddce5e56c696e185f59147a8b79e75e9e6380"}, ] isort = [ {file = "isort-4.3.21-py2.py3-none-any.whl", hash = "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd"}, @@ -1149,8 +1171,8 @@ pycparser = [ {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"}, ] pygments = [ - {file = "Pygments-2.7.3-py3-none-any.whl", hash = "sha256:f275b6c0909e5dafd2d6269a656aa90fa58ebf4a74f8fcf9053195d226b24a08"}, - {file = "Pygments-2.7.3.tar.gz", hash = "sha256:ccf3acacf3782cbed4a989426012f1c535c9a90d3a7fc3f16d231b9372d2b716"}, + {file = "Pygments-2.7.4-py3-none-any.whl", hash = "sha256:bc9591213a8f0e0ca1a5e68a479b4887fdc3e75d0774e5c71c31920c427de435"}, + {file = "Pygments-2.7.4.tar.gz", hash = "sha256:df49d09b498e83c1a73128295860250b0b7edd4c723a32e9bc0d295c7c2ec337"}, ] pyparsing = [ {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, @@ -1161,12 +1183,12 @@ pytest = [ {file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"}, ] pytest-cov = [ - {file = "pytest-cov-2.10.1.tar.gz", hash = "sha256:47bd0ce14056fdd79f93e1713f88fad7bdcc583dcd7783da86ef2f085a0bb88e"}, - {file = "pytest_cov-2.10.1-py2.py3-none-any.whl", hash = "sha256:45ec2d5182f89a81fc3eb29e3d1ed3113b9e9a873bcddb2a71faaab066110191"}, + {file = "pytest-cov-2.11.1.tar.gz", hash = "sha256:359952d9d39b9f822d9d29324483e7ba04a3a17dd7d05aa6beb7ea01e359e5f7"}, + {file = "pytest_cov-2.11.1-py2.py3-none-any.whl", hash = "sha256:bdb9fdb0b85a7cc825269a4c56b48ccaa5c7e365054b6038772c32ddcdc969da"}, ] pytest-mock = [ - {file = "pytest-mock-3.4.0.tar.gz", hash = "sha256:c3981f5edee6c4d1942250a60d9b39d38d5585398de1bfce057f925bdda720f4"}, - {file = "pytest_mock-3.4.0-py3-none-any.whl", hash = "sha256:c0fc979afac4aaba545cbd01e9c20736eb3fefb0a066558764b07d3de8f04ed3"}, + {file = "pytest-mock-3.5.1.tar.gz", hash = "sha256:a1e2aba6af9560d313c642dae7e00a2a12b022b80301d9d7fc8ec6858e1dd9fc"}, + {file = "pytest_mock-3.5.1-py3-none-any.whl", hash = "sha256:379b391cfad22422ea2e252bdfc008edd08509029bcde3c25b2c0bd741e0424e"}, ] python-dateutil = [ {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, @@ -1177,17 +1199,27 @@ pytz = [ {file = "pytz-2020.5.tar.gz", hash = "sha256:180befebb1927b16f6b57101720075a984c019ac16b1b7575673bea42c6c3da5"}, ] pyyaml = [ - {file = "PyYAML-5.3.1-cp27-cp27m-win32.whl", hash = "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f"}, - {file = "PyYAML-5.3.1-cp27-cp27m-win_amd64.whl", hash = "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76"}, - {file = "PyYAML-5.3.1-cp35-cp35m-win32.whl", hash = "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2"}, - {file = "PyYAML-5.3.1-cp35-cp35m-win_amd64.whl", hash = "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c"}, - {file = "PyYAML-5.3.1-cp36-cp36m-win32.whl", hash = "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2"}, - {file = "PyYAML-5.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648"}, - {file = "PyYAML-5.3.1-cp37-cp37m-win32.whl", hash = "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"}, - {file = "PyYAML-5.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf"}, - {file = "PyYAML-5.3.1-cp38-cp38-win32.whl", hash = "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97"}, - {file = "PyYAML-5.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee"}, - {file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"}, + {file = "PyYAML-5.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:f7a21e3d99aa3095ef0553e7ceba36fb693998fbb1226f1392ce33681047465f"}, + {file = "PyYAML-5.4-cp27-cp27m-win32.whl", hash = "sha256:52bf0930903818e600ae6c2901f748bc4869c0c406056f679ab9614e5d21a166"}, + {file = "PyYAML-5.4-cp27-cp27m-win_amd64.whl", hash = "sha256:a36a48a51e5471513a5aea920cdad84cbd56d70a5057cca3499a637496ea379c"}, + {file = "PyYAML-5.4-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:5e7ac4e0e79a53451dc2814f6876c2fa6f71452de1498bbe29c0b54b69a986f4"}, + {file = "PyYAML-5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc552b6434b90d9dbed6a4f13339625dc466fd82597119897e9489c953acbc22"}, + {file = "PyYAML-5.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0dc9f2eb2e3c97640928dec63fd8dc1dd91e6b6ed236bd5ac00332b99b5c2ff9"}, + {file = "PyYAML-5.4-cp36-cp36m-win32.whl", hash = "sha256:5a3f345acff76cad4aa9cb171ee76c590f37394186325d53d1aa25318b0d4a09"}, + {file = "PyYAML-5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:f3790156c606299ff499ec44db422f66f05a7363b39eb9d5b064f17bd7d7c47b"}, + {file = "PyYAML-5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:124fd7c7bc1e95b1eafc60825f2daf67c73ce7b33f1194731240d24b0d1bf628"}, + {file = "PyYAML-5.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:8b818b6c5a920cbe4203b5a6b14256f0e5244338244560da89b7b0f1313ea4b6"}, + {file = "PyYAML-5.4-cp37-cp37m-win32.whl", hash = "sha256:737bd70e454a284d456aa1fa71a0b429dd527bcbf52c5c33f7c8eee81ac16b89"}, + {file = "PyYAML-5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:7242790ab6c20316b8e7bb545be48d7ed36e26bbe279fd56f2c4a12510e60b4b"}, + {file = "PyYAML-5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cc547d3ead3754712223abb7b403f0a184e4c3eae18c9bb7fd15adef1597cc4b"}, + {file = "PyYAML-5.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8635d53223b1f561b081ff4adecb828fd484b8efffe542edcfdff471997f7c39"}, + {file = "PyYAML-5.4-cp38-cp38-win32.whl", hash = "sha256:26fcb33776857f4072601502d93e1a619f166c9c00befb52826e7b774efaa9db"}, + {file = "PyYAML-5.4-cp38-cp38-win_amd64.whl", hash = "sha256:b2243dd033fd02c01212ad5c601dafb44fbb293065f430b0d3dbf03f3254d615"}, + {file = "PyYAML-5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:31ba07c54ef4a897758563e3a0fcc60077698df10180abe4b8165d9895c00ebf"}, + {file = "PyYAML-5.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:02c78d77281d8f8d07a255e57abdbf43b02257f59f50cc6b636937d68efa5dd0"}, + {file = "PyYAML-5.4-cp39-cp39-win32.whl", hash = "sha256:fdc6b2cb4b19e431994f25a9160695cc59a4e861710cc6fc97161c5e845fc579"}, + {file = "PyYAML-5.4-cp39-cp39-win_amd64.whl", hash = "sha256:8bf38641b4713d77da19e91f8b5296b832e4db87338d6aeffe422d42f1ca896d"}, + {file = "PyYAML-5.4.tar.gz", hash = "sha256:3c49e39ac034fd64fd576d63bb4db53cda89b362768a67f07749d55f128ac18a"}, ] requests = [ {file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"}, @@ -1205,16 +1237,16 @@ snowballstemmer = [ {file = "snowballstemmer-2.0.0.tar.gz", hash = "sha256:df3bac3df4c2c01363f3dd2cfa78cce2840a79b9f1c2d2de9ce8d31683992f52"}, ] sphinx = [ - {file = "Sphinx-3.4.1-py3-none-any.whl", hash = "sha256:aeef652b14629431c82d3fe994ce39ead65b3fe87cf41b9a3714168ff8b83376"}, - {file = "Sphinx-3.4.1.tar.gz", hash = "sha256:e450cb205ff8924611085183bf1353da26802ae73d9251a8fcdf220a8f8712ef"}, + {file = "Sphinx-3.4.3-py3-none-any.whl", hash = "sha256:c314c857e7cd47c856d2c5adff514ac2e6495f8b8e0f886a8a37e9305dfea0d8"}, + {file = "Sphinx-3.4.3.tar.gz", hash = "sha256:41cad293f954f7d37f803d97eb184158cfd90f51195131e94875bc07cd08b93c"}, ] sphinx-click = [ {file = "sphinx-click-2.5.0.tar.gz", hash = "sha256:8ba44ca446ba4bb0585069b8aabaa81e833472d6669b36924a398405311d206f"}, {file = "sphinx_click-2.5.0-py2.py3-none-any.whl", hash = "sha256:6848ba2d084ef2feebae0ce3603c1c02a2ba5ded54fb6c0cf24fd01204a945f3"}, ] sphinx-rtd-theme = [ - {file = "sphinx_rtd_theme-0.5.0-py2.py3-none-any.whl", hash = "sha256:373413d0f82425aaa28fb288009bf0d0964711d347763af2f1b65cafcb028c82"}, - {file = "sphinx_rtd_theme-0.5.0.tar.gz", hash = "sha256:22c795ba2832a169ca301cd0a083f7a434e09c538c70beb42782c073651b707d"}, + {file = "sphinx_rtd_theme-0.5.1-py2.py3-none-any.whl", hash = "sha256:fa6bebd5ab9a73da8e102509a86f3fcc36dec04a0b52ea80e5a033b2aba00113"}, + {file = "sphinx_rtd_theme-0.5.1.tar.gz", hash = "sha256:eda689eda0c7301a80cf122dad28b1861e5605cbf455558f3775e1e8200e83a5"}, ] sphinxcontrib-apidoc = [ {file = "sphinxcontrib-apidoc-0.3.0.tar.gz", hash = "sha256:729bf592cf7b7dd57c4c05794f732dc026127275d785c2a5494521fdde773fb9"}, @@ -1253,20 +1285,23 @@ toml = [ {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] tox = [ - {file = "tox-3.20.1-py2.py3-none-any.whl", hash = "sha256:42ce19ce5dc2f6d6b1fdc5666c476e1f1e2897359b47e0aa3a5b774f335d57c2"}, - {file = "tox-3.20.1.tar.gz", hash = "sha256:4321052bfe28f9d85082341ca8e233e3ea901fdd14dab8a5d3fbd810269fbaf6"}, + {file = "tox-3.21.2-py2.py3-none-any.whl", hash = "sha256:0aa777ee466f2ef18e6f58428c793c32378779e0a321dbb8934848bc3e78998c"}, + {file = "tox-3.21.2.tar.gz", hash = "sha256:f501808381c01c6d7827c2f17328be59c0a715046e94605ddca15fb91e65827d"}, ] tqdm = [ - {file = "tqdm-4.55.0-py2.py3-none-any.whl", hash = "sha256:0cd81710de29754bf17b6fee07bdb86f956b4fa20d3078f02040f83e64309416"}, - {file = "tqdm-4.55.0.tar.gz", hash = "sha256:f4f80b96e2ceafea69add7bf971b8403b9cba8fb4451c1220f91c79be4ebd208"}, + {file = "tqdm-4.56.0-py2.py3-none-any.whl", hash = "sha256:4621f6823bab46a9cc33d48105753ccbea671b68bab2c50a9f0be23d4065cb5a"}, + {file = "tqdm-4.56.0.tar.gz", hash = "sha256:fe3d08dd00a526850568d542ff9de9bbc2a09a791da3c334f3213d8d0bbbca65"}, +] +untokenize = [ + {file = "untokenize-0.1.1.tar.gz", hash = "sha256:3865dbbbb8efb4bb5eaa72f1be7f3e0be00ea8b7f125c69cbd1f5fda926f37a2"}, ] urllib3 = [ {file = "urllib3-1.26.2-py2.py3-none-any.whl", hash = "sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473"}, {file = "urllib3-1.26.2.tar.gz", hash = "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08"}, ] virtualenv = [ - {file = "virtualenv-20.2.2-py2.py3-none-any.whl", hash = "sha256:54b05fc737ea9c9ee9f8340f579e5da5b09fb64fd010ab5757eb90268616907c"}, - {file = "virtualenv-20.2.2.tar.gz", hash = "sha256:b7a8ec323ee02fb2312f098b6b4c9de99559b462775bc8fe3627a73706603c1b"}, + {file = "virtualenv-20.4.0-py2.py3-none-any.whl", hash = "sha256:227a8fed626f2f20a6cdb0870054989f82dd27b2560a911935ba905a2a5e0034"}, + {file = "virtualenv-20.4.0.tar.gz", hash = "sha256:219ee956e38b08e32d5639289aaa5bd190cfbe7dafcb8fa65407fca08e808f9c"}, ] voluptuous = [ {file = "voluptuous-0.12.1-py3-none-any.whl", hash = "sha256:8ace33fcf9e6b1f59406bfaf6b8ec7bcc44266a9f29080b4deb4fe6ff2492386"}, @@ -1277,8 +1312,8 @@ wcwidth = [ {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, ] zeroconf = [ - {file = "zeroconf-0.28.7-py3-none-any.whl", hash = "sha256:9872b779cf290b6d623d3cb1024d5c88fd9b7c4b2dd35ce54397cf8887632ad1"}, - {file = "zeroconf-0.28.7.tar.gz", hash = "sha256:f6effbe36b2b65bdc4c282d3d44a3dbf6f18ac5903a50a2a21928dd7e0a68d8c"}, + {file = "zeroconf-0.28.8-py3-none-any.whl", hash = "sha256:3608be2db58f6f0dc70665e02ab420fb8bf428016f2c78403d879e066ecc9bff"}, + {file = "zeroconf-0.28.8.tar.gz", hash = "sha256:4be24a10aa9c73406f48d42a8b3b077c217b0e8d7ed1e57639630da520c25959"}, ] zipp = [ {file = "zipp-3.4.0-py3-none-any.whl", hash = "sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108"}, From 56b37b9f418a160604adcda1937f00b369999658 Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Wed, 20 Jan 2021 21:50:05 +0100 Subject: [PATCH 4/4] Improve docstring formatting for some cases where docformatter didn't do a nice job --- miio/airconditioner_miot.py | 3 +-- miio/airconditioningcompanion.py | 15 ++++++++++----- miio/airconditioningcompanionMCN.py | 7 ++++--- miio/airpurifier_miot.py | 6 ++++-- miio/airqualitymonitor.py | 10 +++------- miio/alarmclock.py | 7 +++++-- miio/ceil.py | 5 +---- miio/discovery.py | 2 +- miio/extract_tokens.py | 3 ++- miio/fan_leshow.py | 5 +---- miio/fan_miot.py | 3 +-- 11 files changed, 33 insertions(+), 33 deletions(-) diff --git a/miio/airconditioner_miot.py b/miio/airconditioner_miot.py index 749969b12..38079098f 100644 --- a/miio/airconditioner_miot.py +++ b/miio/airconditioner_miot.py @@ -171,8 +171,7 @@ def __repr__(self) -> str: class AirConditionerMiotStatus: - """Container for status reports from the air conditioner which uses MIoT - protocol.""" + """Container for status reports from the air conditioner (MIoT).""" def __init__(self, data: Dict[str, Any]) -> None: """ diff --git a/miio/airconditioningcompanion.py b/miio/airconditioningcompanion.py index 5e1ba2240..1dbe117fd 100644 --- a/miio/airconditioningcompanion.py +++ b/miio/airconditioningcompanion.py @@ -140,11 +140,16 @@ def air_condition_brand(self) -> int: @property def air_condition_remote(self) -> int: - """Known remote ids: - - 0x80111111, 0x80111112 (brand: 0x0182) 0x80222221 (brand: 0x0097) 0x80333331 - (brand: 0x0037) 0x80444441 (brand: 0x0202) 0x80555551 (brand: 0x2782) 0x80777771 - (brand: 0x0197) 0x80666661 (brand: 0x0192) + """Remote id. + + Known remote ids: + * 0x80111111, 0x80111112 (brand: 0x0182) + * 0x80222221 (brand: 0x0097) + * 0x80333331 (brand: 0x0037) + * 0x80444441 (brand: 0x0202) + * 0x80555551 (brand: 0x2782) + * 0x80777771 (brand: 0x0197) + * 0x80666661 (brand: 0x0192) """ return int(self.air_condition_model[4:8].hex(), 16) diff --git a/miio/airconditioningcompanionMCN.py b/miio/airconditioningcompanionMCN.py index f795d96dc..42e2c52b8 100644 --- a/miio/airconditioningcompanionMCN.py +++ b/miio/airconditioningcompanionMCN.py @@ -40,10 +40,11 @@ class AirConditioningCompanionStatus: """Container for status reports of the Xiaomi AC Companion.""" def __init__(self, data): - """Device model: lumi.acpartner.mcn02. + """Status constructor. - Response of "get_prop, params:['power', 'mode', 'tar_temp', 'fan_level', - 'ver_swing', 'load_power']": ['on', 'dry', 16, 'small_fan', 'off', 84.0] + Example response (lumi.acpartner.mcn02): + * ['power', 'mode', 'tar_temp', 'fan_level', 'ver_swing', 'load_power'] + * ['on', 'dry', 16, 'small_fan', 'off', 84.0] """ self.data = data diff --git a/miio/airpurifier_miot.py b/miio/airpurifier_miot.py index db35a72e8..1c9156027 100644 --- a/miio/airpurifier_miot.py +++ b/miio/airpurifier_miot.py @@ -357,8 +357,10 @@ def set_mode(self, mode: OperationMode): default_output=format_output("Setting favorite level to {level}"), ) def set_favorite_level(self, level: int): - """Set the favorite level used when the mode is `favorite`, should be between 0 - and 14.""" + """Set the favorite level used when the mode is `favorite`. + + Needs to be between 0 and 14. + """ if level < 0 or level > 14: raise AirPurifierMiotException("Invalid favorite level: %s" % level) diff --git a/miio/airqualitymonitor.py b/miio/airqualitymonitor.py index 9ec2c8685..90162093b 100644 --- a/miio/airqualitymonitor.py +++ b/miio/airqualitymonitor.py @@ -80,15 +80,12 @@ def usb_power(self) -> Optional[bool]: @property def aqi(self) -> Optional[int]: - """Air quality index value. - - (0...600). - """ + """Air quality index value (0..600).""" return self.data.get("aqi", None) @property def battery(self) -> Optional[int]: - """Current battery level (0...100).""" + """Current battery level (0..100).""" return self.data.get("battery", None) @property @@ -202,7 +199,7 @@ def __init__( "Device model %s unsupported. Falling back to %s.", model, self.model ) else: - """Force autodetection.""" + # Force autodetection. self.model = None @command( @@ -225,7 +222,6 @@ def status(self) -> AirQualityMonitorStatus: """Return device status.""" if self.model is None: - """Autodetection.""" info = self.info() self.model = info.model diff --git a/miio/alarmclock.py b/miio/alarmclock.py index 976398361..90f42e9bb 100644 --- a/miio/alarmclock.py +++ b/miio/alarmclock.py @@ -68,8 +68,11 @@ def __repr__(self): class AlarmClock(Device): - """Note, this device is not very responsive to the requests, so it may take several - seconds /tries to get an answer..""" + """Implementation of Xiao AI Smart Alarm Clock. + + Note, this device is not very responsive to the requests, so it may take several + seconds /tries to get an answer. + """ @command() def get_config_version(self): diff --git a/miio/ceil.py b/miio/ceil.py index f86b84453..5674d0cc9 100644 --- a/miio/ceil.py +++ b/miio/ceil.py @@ -179,10 +179,7 @@ def delay_off(self, seconds: int): default_output=format_output("Setting fixed scene to {number}"), ) def set_scene(self, number: int): - """Set a fixed scene. - - 4 fixed scenes are available (1-4) - """ + """Set a fixed scene (1-4).""" if number < 1 or number > 4: raise CeilException("Invalid fixed scene number: %s" % number) diff --git a/miio/discovery.py b/miio/discovery.py index 534872daf..1682dfe90 100644 --- a/miio/discovery.py +++ b/miio/discovery.py @@ -288,7 +288,7 @@ class Discovery: @staticmethod def discover_mdns() -> Dict[str, Device]: - """Discover devices with mdns until.""" + """Discover devices with mdns until any keyboard input.""" _LOGGER.info("Discovering devices with mDNS, press any key to quit...") listener = Listener() diff --git a/miio/extract_tokens.py b/miio/extract_tokens.py index 4bac7496b..59c9c9393 100644 --- a/miio/extract_tokens.py +++ b/miio/extract_tokens.py @@ -52,8 +52,9 @@ def read_android_yeelight(db) -> Iterator[DeviceConfig]: class BackupDatabaseReader: - """Main class for reading backup files. The main usage is following: + """Main class for reading backup files. + Example: .. code-block:: python r = BackupDatabaseReader() diff --git a/miio/fan_leshow.py b/miio/fan_leshow.py index 2c9f98d78..fe8583034 100644 --- a/miio/fan_leshow.py +++ b/miio/fan_leshow.py @@ -164,10 +164,7 @@ def off(self): default_output=format_output("Setting mode to '{mode.value}'"), ) def set_mode(self, mode: OperationMode): - """Set mode. - - Choose from manual, natural, sleep, strong. - """ + """Set mode (manual, natural, sleep, strong).""" return self.send("set_mode", [mode.value]) @command( diff --git a/miio/fan_miot.py b/miio/fan_miot.py index 69cc7fb92..2f4966c9d 100644 --- a/miio/fan_miot.py +++ b/miio/fan_miot.py @@ -64,8 +64,7 @@ class OperationModeMiot(enum.Enum): class FanStatusMiot: - """Container for status reports from the Xiaomi Mi Smart Pedestal Fan DMaker - P9/P10.""" + """Container for status reports for Xiaomi Mi Smart Pedestal Fan DMaker P9/P10.""" def __init__(self, data: Dict[str, Any]) -> None: """